What problem does this solve?
OTA updates for battery-powered devices (remotes, battery sensors, some Legrand devices) almost always fail because the device is asleep and unreachable when the user taps Update. Today the only workaround is to physically press a button on the device at the exact moment the OTA request is sent, to wake it up long enough to start the transfer. This is awkward for remotes that aren't on hand and impossible for embedded sensors.
The original headline I had in mind was "Force Update" — but after investigating, there is no way to force a sleepy Zigbee End Device awake from the coordinator side. The radio is off by spec until the device itself polls its parent. Z2M's docs even confirm the button-press trick is the canonical workaround:
"For battery powered end-devices you may need to trigger them by e.g. pushing a button right before checking for an OTA."
— Z2M OTA docs
However, Z2M already exposes the right primitive for this: schedule. It tells Z2M "next time this device wakes up on its own and asks for an image, give it one." This is persisted in the coordinator's database, survives Z2M restart, retries automatically forever, and adds a scheduled state to the device's update field. The Z2M web frontend already wires this up.
What would you like Shellbee to do?
Add Schedule update and Cancel scheduled update actions to the OTA UI, alongside the existing "Check for updates" and "Update now" actions. Surface the new scheduled state in device cards.
MQTT plumbing (already in Z2M, no bridge changes needed):
- Schedule:
POST bridge/request/device/ota_update/schedule payload {"id": "<friendlyName>"}
- Unschedule:
POST bridge/request/device/ota_update/unschedule payload {"id": "<friendlyName>"}
- Downgrade variant:
bridge/request/device/ota_update/schedule/downgrade
- New device state:
update.state can be scheduled (joins idle | available | updating)
UX behavior:
- Battery devices (
power_source: "Battery"): primary CTA becomes Schedule update. Show a hint: "This device is battery-powered. After scheduling, press a button on the device to trigger the update." Secondary action: Update now (kept as an escape hatch for users who want to try the immediate path or are about to physically wake the device).
- Mains-powered devices: primary CTA stays Update now. Schedule still available as a secondary option.
- Scheduled state: device card shows a "Scheduled" badge. OTA list view includes a Scheduled section. Tapping a scheduled device exposes Cancel scheduled update.
- Optimistic UI: tapping Schedule should immediately show Scheduled badge while waiting for
bridge/response/device/ota_update/schedule (consistent with the optimistic remove/rename pattern already used in Shellbee).
Reference implementation:
The Z2M web frontend (zigbee2mqtt-windfront) already implements this in src/pages/OtaPage.tsx — the actOnFilteredSelected handler wires all four topics: check, update, schedule, unschedule. Mirror its terminology for consistency (translation keys live under i18n namespace "ota").
Does the Z2M web frontend already do this?
Yes — and Shellbee should match it. See OtaPage.tsx / OtaControlGroup.tsx / OtaUpdateButton.tsx in zigbee2mqtt-windfront.
Alternatives you've considered
- "Force Update" button that loops
update requests — wouldn't help. The device still has to wake up on its own; spamming update from the coordinator just wastes bandwidth and times out repeatedly.
- Keep doing the manual button-press workaround — works but unergonomic for remotes that are stored away or sensors that don't have buttons.
- Wait for Z2M / firmware to add a wake-on-rx mechanism — not coming. This is a fundamental Zigbee protocol property for sleepy ZEDs.
What problem does this solve?
OTA updates for battery-powered devices (remotes, battery sensors, some Legrand devices) almost always fail because the device is asleep and unreachable when the user taps Update. Today the only workaround is to physically press a button on the device at the exact moment the OTA request is sent, to wake it up long enough to start the transfer. This is awkward for remotes that aren't on hand and impossible for embedded sensors.
The original headline I had in mind was "Force Update" — but after investigating, there is no way to force a sleepy Zigbee End Device awake from the coordinator side. The radio is off by spec until the device itself polls its parent. Z2M's docs even confirm the button-press trick is the canonical workaround:
However, Z2M already exposes the right primitive for this:
schedule. It tells Z2M "next time this device wakes up on its own and asks for an image, give it one." This is persisted in the coordinator's database, survives Z2M restart, retries automatically forever, and adds ascheduledstate to the device'supdatefield. The Z2M web frontend already wires this up.What would you like Shellbee to do?
Add Schedule update and Cancel scheduled update actions to the OTA UI, alongside the existing "Check for updates" and "Update now" actions. Surface the new
scheduledstate in device cards.MQTT plumbing (already in Z2M, no bridge changes needed):
POST bridge/request/device/ota_update/schedulepayload{"id": "<friendlyName>"}POST bridge/request/device/ota_update/unschedulepayload{"id": "<friendlyName>"}bridge/request/device/ota_update/schedule/downgradeupdate.statecan bescheduled(joinsidle | available | updating)UX behavior:
power_source: "Battery"): primary CTA becomes Schedule update. Show a hint: "This device is battery-powered. After scheduling, press a button on the device to trigger the update." Secondary action: Update now (kept as an escape hatch for users who want to try the immediate path or are about to physically wake the device).bridge/response/device/ota_update/schedule(consistent with the optimistic remove/rename pattern already used in Shellbee).Reference implementation:
The Z2M web frontend (
zigbee2mqtt-windfront) already implements this insrc/pages/OtaPage.tsx— theactOnFilteredSelectedhandler wires all four topics:check,update,schedule,unschedule. Mirror its terminology for consistency (translation keys live underi18nnamespace"ota").Does the Z2M web frontend already do this?
Yes — and Shellbee should match it. See
OtaPage.tsx/OtaControlGroup.tsx/OtaUpdateButton.tsxin zigbee2mqtt-windfront.Alternatives you've considered
updaterequests — wouldn't help. The device still has to wake up on its own; spammingupdatefrom the coordinator just wastes bandwidth and times out repeatedly.