Experiment record

SwitchBot CO2 alerts to a family LINE group with Google Apps Script

A roughly five-minute SwitchBot CO2 collection path was extended with persistence, hysteresis, and LINE group push notifications. Runtime tests verified the initial warning, one repeated warning exactly 30 minutes after the initial warning, the silent-reset effect after at least 10 minutes below 900 ppm, and a new INITIAL alert after reset.

Summary

An existing SwitchBot household-environment collector was extended with an automated ventilation-alert path to a private family LINE group.

The production notification path is SwitchBot MeterPro(CO2) → SwitchBot Hub Mini (W0202200) → SwitchBot Cloud → SwitchBot OpenAPI v1.1 → Google Apps Script → private Google Sheets measurement log → CO2 alert-state logic → LINE Messaging API Push → private family group.

During an initial functional test on August 16, 2026, CO2 near the sensor was deliberately raised by exhaling near it. At 16:38 JST the intended group received a ventilation warning showing 2812 ppm and a displayed high-CO2 continuation time of 4 minutes.

Follow-up tests then verified the remaining principal state branches. On August 26 an initial warning was followed by a repeated warning exactly 30 minutes later. The private measurement log later showed CO2 below 900 ppm for at least 10 minutes. On August 27, after CO2 was deliberately raised again, the next alert was delivered and logged as INITIAL rather than REPEAT. The principal alert-state behavior is therefore verified, and the Experiment Status is COMPLETED.

Background

The objective was not to add another dashboard, but to notify household members only when the configured high-CO2 condition persisted long enough to qualify for an alert. The existing environmental collector already obtained CO2 on a nominal five-minute schedule, so the alert decision was attached to the same collection path rather than adding another polling loop.

A simple rule that sends a message on every sample above 1000 ppm would create repeated LINE messages. The design therefore combines persistence, hysteresis, and a repeat-notification interval.

Methods

Experimental target

The Experiment evaluated whether CO2 measurements already collected from a SwitchBot MeterPro(CO2) could drive a stateful ventilation warning to a private LINE group.

Experimental environment

The Hub Mini used in this Experiment is the same physical unit whose equipment details were recorded in AIEL-2026-0006. In this configuration it served as the data-collection hub that made MeterPro(CO2) measurements available through the SwitchBot cloud/OpenAPI path.

Each CO2 observation is stored before notification logic is evaluated, keeping measurement data separate from alert state.

Alert-state design

NORMAL
  │
  │ CO2 > 1000 ppm on two consecutive samples
  ▼
ALERT
  │
  ├─ qualifying high-CO2 condition re-established
  │  and at least 30 min since the previous message
  │       → repeated warning
  │
  ├─ 900–1000 ppm
  │       → no message; remain ALERT
  │
  └─ CO2 < 900 ppm for at least 10 min
          → return to NORMAL silently

Using a lower clear threshold than the alert threshold provides hysteresis and reduces repeated switching between states near 1000 ppm. By design, missing CO2 samples or SwitchBot API errors are not treated as evidence that either the high or low condition continued through the missing interval.

Functional-test method

The initial and post-reset alert paths were tested by deliberately raising the CO2 concentration near the installed sensor through exhalation, then observing whether the state logic generated a LINE push to the intended private group. The repeat branch was tested by maintaining a qualifying high-CO2 episode long enough to cross the configured notification interval. The reset condition was checked against the private Google Sheets measurement log for a sustained interval below 900 ppm.

Deliberate fault injection for missing CO2 samples or SwitchBot API failures was outside the principal success criteria and was not performed.

Experiment Log

Configuring the LINE group destination

LINE Messaging API push delivery used the groupId of a private group that included the LINE Official Account used for the Experiment. The group ID and channel access token were stored privately in Google Apps Script Script Properties. The webhook steps described below were used only to obtain this group ID once.

Direct Apps Script Web App webhook — abandoned

A Google Apps Script Web App was first tested as a temporary LINE webhook receiver. During setup the verifier encountered HTTP 404; after correcting the URL and deployment, the tested verification path returned HTTP 302. This path was not retained for group-ID capture.

Temporary Cloudflare Worker workaround

A small Cloudflare Worker was then used only for group-ID capture. It received the LINE webhook POST, validated x-line-signature with HMAC-SHA256, made the group ID visible in controlled logs for one-time retrieval, and returned HTTP 200 directly. LINE webhook verification succeeded through this receiver.

After the group ID was stored in Script Properties, the Worker was deleted and LINE webhook delivery was disabled. Cloudflare is therefore not part of the current CO2 alert-delivery path.

2026-08-16 — initial-alert functional test

CO2 near the installed sensor was deliberately increased by exhaling near it for a short functional test.

At 16:38 JST the intended private family LINE group received a ventilation notification displaying:

This observation verified the initial path CO2 measurement → Hub Mini → SwitchBot Cloud/OpenAPI → automated threshold/state processing → LINE Messaging API Push → intended private group.

2026-08-26 — 30-minute repeated-warning runtime test

During a high-CO2 episode, the private LINE group received an initial ventilation warning at 07:18 and a repeated warning at 07:48.

The private Google Sheets execution log independently recorded CO2Alert / SUCCESS / INITIAL notification sent at 07:18:20 and CO2Alert / SUCCESS / REPEAT notification sent at 07:48:20. The runtime-log interval was therefore exactly 30 minutes, verifying the configured repeat branch in operation.

2026-08-26 to 2026-08-27 — silent reset and post-reset re-alert

After the repeated warning, the private Google Sheets measurement log showed living-room CO2 below 900 ppm for at least 10 minutes. No LINE clear-state message was sent, consistent with the silent-clear design.

On the following day, CO2 near the sensor was deliberately raised again. At 06:03 the private LINE group received a new ventilation warning showing:

The private Google Sheets execution log recorded CO2Alert / SUCCESS / INITIAL notification sent at 06:03:22. Because a continuation of the previous alert would have been classified as REPEAT, the new INITIAL event verifies the prior silent reset and shows that, after clearing, a later qualifying high-CO2 state was treated as a new initial alert.

Conclusion

The Experiment verifies the principal runtime branches of the CO2 ventilation-alert state machine using the existing SwitchBot collection path and LINE Messaging API push delivery.

Verified behavior includes the initial warning, one repeated warning observed exactly 30 minutes after the initial warning, the silent-reset effect after at least 10 minutes below 900 ppm, and a new INITIAL warning after reset. The Experiment Status is therefore COMPLETED.

Deliberate fault injection for missing CO2 samples or SwitchBot API failures was not performed. This is not an unresolved defect; it is additional validation that was outside the principal success criteria.

Evidence summary

The Evidence States for the information obtained in this Experiment are as follows.

Recorded contentEvidence StateBasis in this experiment
The initial end-to-end alert path operated successfullyVERIFIEDInitial alerts were directly observed in the private LINE group, including the 2812 ppm functional test
A repeated warning occurred exactly 30 minutes after the initial warning while the high-CO2 state continuedVERIFIEDThe 07:18:20 INITIAL and 07:48:20 REPEAT events were cross-checked between LINE observations and the private runtime log
The silent-clear condition produced the expected reset effect after at least 10 minutes below 900 ppmVERIFIEDSustained low CO2 in the private measurement log was followed by a new INITIAL rather than REPEAT alert
A later qualifying high-CO2 episode re-alerted as a new INITIAL eventVERIFIEDThe 2026-08-27 06:03:22 INITIAL event was verified in both the LINE observation and private runtime log

See Evidence State for the shared definitions.

Operational implications

Because alert evaluation runs inside the existing roughly five-minute collector, the design does not add a second SwitchBot API polling loop. The value used for notification and the value stored privately in Google Sheets come from the same observation path.

The timing of the first alert nevertheless depends on trigger execution times and the two-consecutive-sample rule. The displayed four-minute continuation value is state information retained by the alert logic and should not be generalized as proof that the sensor itself continuously sampled for exactly four minutes.

Because deliberate fault injection for missing samples or SwitchBot API errors was not performed, runtime behavior on those abnormal paths was not verified in this Experiment. For long-running use, the state machine should treat missing samples and API errors separately from valid high- or low-CO2 observations so that data gaps do not create false persistence or false clearing.

Reproduction resources

The equipment and experimental environment used in this experiment, together with current purchase information kept separate from the Experiment’s Evidence and Conclusion, are documented on SwitchBot CO2 ventilation alert — equipment, experimental environment, and purchase information.

Reproduction considerations

Keep authentication and destination-related sensitive information out of source code and public logs, using an appropriate secret/configuration store such as Script Properties. To reproduce the principal state transitions, test the initial alert, repeat path, clear path, and post-reset re-alert independently. Missing-data/API-error fault injection was not performed in this Experiment; treat it as separate optional robustness validation if needed.

Machine-readable experiment record

A machine-readable canonical record of this Experiment is published as JSON.

AIEL-2026-0004 experiment.json

The underlying roughly five-minute household environmental collection system is published separately as Long-term household environment collection, external weather integration, and analysis with SwitchBot and Google Apps Script.