Koenkk / zigbee-herdsman

A Node.js Zigbee library
MIT License
456 stars 277 forks source link

Base support for channel switching without re-pairing #977

Closed Nerivec closed 2 months ago

Nerivec commented 2 months ago

Adds base for supporting channel switching without having to re-pair devices. Whenever channel is changed in configuration.yaml, after restart, Z2M will trigger the switch after Adapter.start(), as long as no other network parameters was changed, of course, otherwise the previous logic will kick in. Done via standard ZDO broadcast of Mgmt_NWK_Update_req (see 2.4.3.3.9 of Zigbee spec), so all stacks should be able to implement this eventually (for now a supports function takes care of ignoring the logic if not implemented).

Obviously, there will be cases where devices do not follow instructions at all (bad firmware...) and will have to be re-paired manually after the channel change; expected with brands like Aqara. In general, battery-powered devices are likely to cause more trouble than routers with this feature, but thankfully, they usually are easier to access than in-wall routers & the likes. Still, whatever percentage of the network automatically changes is a bonus!

Observations with ember driver:

TODOs:

Nerivec commented 2 months ago

I'm out of ideas to make that coverage happy, it doesn't seem to like the spyOn, but without it, setTimeout breaks the tests 😢

@Koenkk I set zStack & its test to false for support for now. Please adjust when support is done.

Nerivec commented 2 months ago

Removed setTimeout (makes the tests/coverage happy too!). Ran immediately post NCP init, and blocking handled at adapter level as needed/available to stack.

ember: use stack status event to detect change over (async frames can start to come in within a few ms after that).

Basically, just needed to move the logic up in the scope; it's much simpler and just works 😉

Hedda commented 2 months ago

Adds base for supporting channel switching without having to re-pair devices.

FYI, puddly implemented a similar channel switching feature in zigpy (for ZHA) last year and a tip from that implementation is different Zigbee stack adapters/drivers handle is different, and at least for z-stack/znp he implemented it do that it resends the channel change broadcast command a few times with various delay before the Zigbee Coordinator actually switches channel, as that way you give devices that did not recieve the message the first time for whatever a chance a few chances recieve that message

https://github.com/zigpy/zigpy/pull/1190

Also see related PR for ConBee

https://github.com/zigpy/zigpy/pull/1194

and the original RFC discussion here:

https://github.com/zigpy/zigpy/discussions/1185

PS: For end-users this channel change feature is summarized in the ZHA integration documentation for Home Assistant here:

https://www.home-assistant.io/integrations/zha#defining-zigbee-channel-to-use

Koenkk commented 2 months ago

There are still some TODOs here which I will follow up on: