Monitor Sensor Thresholds
Send a notification whenever a sensor value rises above a configured limit — useful for temperature, humidity, CO2, or any numeric sensor in Home Assistant.
The code
from hassette import App, AppConfig, C, D, states
class ThresholdConfig(AppConfig):
entity_id: str = "sensor.living_room_temperature"
threshold: float = 28.0
notify_target: str = "mobile_app_my_phone"
class SensorThresholdApp(App[ThresholdConfig]):
"""Alert when a sensor value exceeds a configured threshold."""
async def on_initialize(self) -> None:
await self.bus.on_state_change(
self.app_config.entity_id,
handler=self.on_threshold_exceeded,
changed_to=C.Comparison("gt", self.app_config.threshold),
name="threshold_monitor",
)
async def on_threshold_exceeded(
self,
new_state: D.StateNew[states.SensorState],
entity_id: D.EntityId,
) -> None:
value = new_state.value
unit = new_state.attributes.unit_of_measurement or ""
name = new_state.attributes.friendly_name or entity_id
self.logger.warning("%s crossed threshold: %s%s", name, value, unit)
await self.api.call_service(
"notify",
self.app_config.notify_target,
title="Sensor Alert",
message=f"{name} is now {value}{unit} (threshold: {self.app_config.threshold}{unit})",
)
How it works
- Typed config —
ThresholdConfigexposesentity_id,threshold, andnotify_targetas environment-backed settings. Override any of them per-instance without touching the code. - Threshold filter —
C.Comparison("gt", threshold)is passed tochanged_to, so the handler only fires when the new state value is greater than the configured limit. Events below the threshold are dropped before the handler runs. - DI extraction —
D.StateNew[states.SensorState]gives a typed state object.D.EntityIdprovides the entity ID as a plain string for logging. - Attributes —
new_state.attributes.unit_of_measurementandfriendly_nameare read directly from the typed model, keeping the notification message readable without manual string parsing. - Notification —
api.call_service("notify", ...)sends the alert via any Home Assistant notify target (mobile app, persistent notification, etc.).
Variations
Lower threshold (below-limit alert): Change "gt" to "lt" to alert when the value drops below the limit — for example, alerting when battery level or water pressure falls too low.
Hysteresis to prevent alert storms: Subscribe to a second listener with changed_to=C.Comparison("le", threshold) that sets a flag when the sensor recovers. Check the flag in on_threshold_exceeded and skip the notification if the sensor has not yet recovered, preventing repeated alerts while the value hovers near the threshold.
Multiple sensors: Register the same handler for several entities using a glob pattern ("sensor.temp_*") or call on_state_change once per entity inside a loop over a list[str] config field.
See also
- Filtering — full reference for
C.Comparisonand all other conditions - Dependency Injection — how
D.StateNewandD.EntityIdwork - States — typed state models and the
SensorStateattributes