Let occupants disable a room sensor in the web UI #12

Open
opened 2026-10-28 16:04:11 +01:00 by pti · 0 comments
Owner

Why

The control temperature uses min aggregation on purpose: being too cold matters more than being too warm, so the coldest room sensor decides. That only works when every room sensor is at a spot someone is using. When the occupants are away from a spot for a longer time (e.g. a desk not used for a few weeks), they should be able to disable its sensor in the web UI, so an empty cold corner doesn't drive the heater.

The immediate trigger is a second study sensor at a desk that is being powered again.

Terms are in GLOSSARY.md (Sensors): room sensor, disabled sensor, always-enabled sensor, offline sensor.

Decisions

  1. A disable lasts until the sensor is enabled again. An "away until" date (like override_until on manual overrides) can come later.
  2. The bathroom sensor is always-enabled (config always_enabled: true on the DS1820) and has no toggle in the UI. Any other room sensor can be disabled. So there is always a control temperature, and there's no "can't disable the last sensor" rule.
    • The bathroom is always 2-4 °C warmer than the other rooms because a freezer dumps its heat into that small room. That warmth is welcome, but it makes the bathroom a poor thermostat for the study: with min it only takes over when the other sensors are disabled or offline, and then the rooms run somewhat cold. It is the right fallback anyway: wired, read every few seconds, and independent of batteries, Zigbee and the broker.
    • An open bathroom window can briefly make it the coldest spot and call for heat; that is consistent with "cold matters more".
  3. A disabled sensor's readings are still recorded, so the history and the analysis in #8 keep that spot's data. The history chart may show them dimmed.
  4. Disabled and offline are different states and the dashboard shows them differently: disabled is the occupants' choice, offline means the latest reading is too old (timeout).
  5. Enabling and disabling are recorded as history and replayed at startup, like the heating state (see "State across restarts" in CLAUDE.md). No separate state table.

Implementation notes

  • temperature.Sensor.Enabled already exists and makes IsHealthy false, so the aggregator already leaves disabled sensors out. The service sets every sensor to enabled at startup (internal/application/thermostat_service.go).
  • Needed: config always_enabled, a sensor-changes history table (migration), restoring the latest state per sensor at startup, an enable/disable endpoint that refuses always-enabled sensors, and the toggle on the dashboard's sensor list.
  • Consider renaming IsHealthy along the glossary (enabled and online).

Checklist

  • Config always_enabled, set on the bathroom DS1820 in configs/config.yaml.blub
  • Record enable/disable as history (migration) and restore it at startup
  • Enable/disable endpoint, refusing always-enabled sensors
  • Toggle in the dashboard sensor list; show disabled and offline differently
  • Add the desk sensor to configs/config.yaml.blub
## Why The control temperature uses `min` aggregation on purpose: being too cold matters more than being too warm, so the coldest room sensor decides. That only works when every room sensor is at a spot someone is using. When the occupants are away from a spot for a longer time (e.g. a desk not used for a few weeks), they should be able to disable its sensor in the web UI, so an empty cold corner doesn't drive the heater. The immediate trigger is a second study sensor at a desk that is being powered again. Terms are in GLOSSARY.md (Sensors): room sensor, disabled sensor, always-enabled sensor, offline sensor. ## Decisions 1. **A disable lasts until the sensor is enabled again.** An "away until" date (like `override_until` on manual overrides) can come later. 2. **The bathroom sensor is always-enabled** (config `always_enabled: true` on the DS1820) and has no toggle in the UI. Any other room sensor can be disabled. So there is always a control temperature, and there's no "can't disable the last sensor" rule. - The bathroom is always 2-4 °C warmer than the other rooms because a freezer dumps its heat into that small room. That warmth is welcome, but it makes the bathroom a poor thermostat for the study: with `min` it only takes over when the other sensors are disabled or offline, and then the rooms run somewhat cold. It is the right fallback anyway: wired, read every few seconds, and independent of batteries, Zigbee and the broker. - An open bathroom window can briefly make it the coldest spot and call for heat; that is consistent with "cold matters more". 3. **A disabled sensor's readings are still recorded**, so the history and the analysis in #8 keep that spot's data. The history chart may show them dimmed. 4. **Disabled and offline are different states** and the dashboard shows them differently: disabled is the occupants' choice, offline means the latest reading is too old (timeout). 5. **Enabling and disabling are recorded as history** and replayed at startup, like the heating state (see "State across restarts" in CLAUDE.md). No separate state table. ## Implementation notes - `temperature.Sensor.Enabled` already exists and makes `IsHealthy` false, so the aggregator already leaves disabled sensors out. The service sets every sensor to enabled at startup (`internal/application/thermostat_service.go`). - Needed: config `always_enabled`, a sensor-changes history table (migration), restoring the latest state per sensor at startup, an enable/disable endpoint that refuses always-enabled sensors, and the toggle on the dashboard's sensor list. - Consider renaming `IsHealthy` along the glossary (enabled and online). ## Checklist - [ ] Config `always_enabled`, set on the bathroom DS1820 in `configs/config.yaml.blub` - [ ] Record enable/disable as history (migration) and restore it at startup - [ ] Enable/disable endpoint, refusing always-enabled sensors - [ ] Toggle in the dashboard sensor list; show disabled and offline differently - [ ] Add the desk sensor to `configs/config.yaml.blub`
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
pti/blubgo#12
No description provided.