"""Low-frequency read-only observation emits transitions, never frame writes.""" import json from pigway_frame_flow.storage.database import encode class DeviceObserver: def __init__(self, service): self.service = service def tick(self): for id, driver in self.service.registry.drivers.items(): try: device = driver.device() except Exception: # Cloud query failure is not evidence that the physical device is offline. continue low = ( device.power.battery_percent is not None and device.power.battery_percent <= 20 ) state = {"status": device.status, "low_battery": low} key = "device-observation:" + id row = self.service.db.one( "SELECT payload FROM app_config WHERE key=?", (key,) ) previous = json.loads(row["payload"]) if row else None if previous == state: continue if previous: if previous["status"] != state["status"] and state["status"] in ( "online", "offline", ): self.service.db.event( "device." + state["status"], {"device_id": id} ) if low and not previous["low_battery"]: self.service.db.event( "device.low_battery", { "device_id": id, "battery_percent": device.power.battery_percent, }, ) self.service.db.execute( "INSERT OR REPLACE INTO app_config VALUES(?,?)", (key, encode(state)) )