-
Notifications
You must be signed in to change notification settings - Fork 318
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(modify): Repair the issue of channel updating #1280
base: master
Are you sure you want to change the base?
fix(modify): Repair the issue of channel updating #1280
Conversation
… fail to be controlled.
src/controller/controller.ts
Outdated
let nwkUpdateId: number = 0x00; | ||
const isSupportsBackup = await this.adapter.supportsBackup(); | ||
if (isSupportsBackup) { | ||
const backup = await this.adapter.backup(this.getDeviceIeeeAddresses()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think making a new backup is necessary here? Can't we get the value from the existing backup?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed.
Probably the property should be added to the adapter type NetworkParameters, since it's part of that, and then can be used throughout controller without issue (cached on start).
Remains to see if all adapters provide it though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I will try to change it to the implementation method you suggested.
Was this tested against the described problem? From what I can tell, that quoted paragraph of the spec is for In the paragraph about the reception of nwk update req by a device, that value doesn't seem to matter.
As far as I can tell, the case where the nwkUpdateId would be used would be if a router decides to rejoin (for some reason), and it finds the same network on at least two different nodes, then it should pick the node with the higher nwkUpdateId (if any). But that scenario should not matter for a channel change, since routers receive the broadcast, and switch immediately. Leaving any offline router eventually powered back on, with only the new network available to rejoin. The spec is a bit lacking on that nwkUpdateId, which I noted in the implementation a while back: zigbee-herdsman/src/zspec/zdo/buffaloZdo.ts Lines 1199 to 1204 in 1c8d886
Short version: I don't expect it would solve the problem at hand? |
test/controller.test.ts
Outdated
@@ -56,6 +94,7 @@ const mocksendZclFrameToGroup = vi.fn(); | |||
const mocksendZclFrameToAll = vi.fn(); | |||
const mockAddInstallCode = vi.fn(); | |||
const mocksendZclFrameToEndpoint = vi.fn(); | |||
const mockApaterBackup = vi.fn().mockReturnValue(mockDummyBackup); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const mockAdapterBackup = vi.fn(() => Promise.resolve(mockDummyBackup));
should provide more accurate typing/testing (and fix typo).
(A lot of others also need refactoring, but might as well add new ones properly.)
…ue of nwkUpdateID, and implement the ember and ezsp adapters.
I added the same device to Home Assistant, then changed the channel. I found that it can be controlled normally in Home Assistant, and I also discovered that Home Assistant will increase the value of nwkUpdateID. |
Hi, @Koenkk. |
Was this tested in Z2M against the initial problem? |
I have already tested the code on z2m, my device can be controlled normally after the fix. |
After pulling the latest zigbee2mqtt code from the master branch, I started z2m using a Dongle that supports the zstack protocol stack and modified the channel. After changing the channel, the device could be controlled normally on zstack, and the nwkUpdateId incremented by 1. However, when using an Ember Dongle, the device control failed after changing the channel, and the nwkUpdateId remained unchanged, still at 0. Since our users are currently encountering related issues, this PR might help resolve the problem. Could you let me know about your plans for this PR? For example, are there any further changes needed, or do you have an estimated timeline for merging it? If there’s anything we can do to assist, such as providing devices for testing, please feel free to let us know. Looking forward to your reply, thank you! |
src/adapter/tstype.ts
Outdated
@@ -74,4 +74,5 @@ export interface NetworkParameters { | |||
panID: number; | |||
extendedPanID: string; // `0x${string}` same as IEEE address | |||
channel: number; | |||
nwkUpdateID?: number; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not be optional, and support should added be in all drivers.
The change should also be tested at least in zstack and ember (the two officially supporting change channel) with at least a few devices that worked before, to make sure they still work after this change. Since it doesn't appear to be required for a change channel (based on spec & previous testing with many devices), it might have negative impact on other aspects (like some devices not expecting a changed nwkUpdateID when receiving a change channel request, and ignoring the request entirely).
In that regard, can you confirm which devices (models) are having the issue in the first place?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently, the main devices we have seen issues with are S31ZB, S40ZBTPB and S26R2ZB.
Regarding the necessity of changing channels, I’d like to share some real-world user experiences: in some households with complex network conditions (e.g., high Wi-Fi interference), changing channels has significantly improved the operational experience of devices. That said, I fully acknowledge that this might introduce some negative impacts, such as potential incompatibility with certain devices.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My comment was not about changing channel (which, of course, is very useful), it was about the changes from this PR, which might fix a couple of oddly working devices, but create issues with others (since it's working without this PR for most devices, and ZigBee spec seems to mostly target PAN change for ID increment, not channel change). This is exacerbated by the fact that the 3 mentioned devices are likely the same internally (all basic sonoff plugs).
I'd like to confirm that other brands/models still work with this PR, at least Tuya, Hue, Inovelli, Ikea, Ledvance for a good sample, and including routers & end devices.
If this PR breaks any brand/model/firmware provider, it will break any according network that tries to change channel after this is merged... We need a good degree of certainty that it won't, hence actual tests with various networks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding the change of nwkUpdateID during channel changes, based on my understanding of the Zigbee specification (which I’ve uploaded as an image), incrementing the nwkUpdateID value is necessary. Additionally, when I performed channel changes using the same dongle on ZHA, devices that failed to work properly after a channel change in Z2M were able to function normally after a channel change in ZHA.
I fully understand your concerns about the potential impact of this PR on devices that are already working correctly. The brands you mentioned (Tuya, Hue, Inovelli, Ikea, Ledvance) indeed require comprehensive testing. However, due to limited device availability, I can only test with the devices I currently have. I will provide you with a detailed list of tested devices shortly, so you can see the coverage of my testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated images to latest rev.
I find that part of the spec is not very clear:
- could be specific:
Upon receipt of a Mgmt_NWK_Unsolicited_Enhanced_Update_notify message
- logic is optional/not strictly defined:
MAY do the following
Which, at best explains why it's not needed in most cases, most stacks likely just ignore it, because it's easier and not required.
There are two scenario that concern me:
- a device stack could ignore the update request if the nwkUpdateID is different from current due to some weirdness in implementation (or some leftovers from older spec revisions)
- a coordinator stack could be overriding the nwkUpdateID logic internally, resulting in mismatch
Also, it would seem the devices you mentioned have a firmware quirk no matter what, because it shouldn't matter for routers that are online at the time of broadcast (they should just switch channel).
I don't have enough devices either for something like this. I had a few users test it out when it was first implemented to confirm with a bigger sample.
Koenkk will confirm zstack impl (no other way than retrieving from NV?) and run some tests too.
Once we confirm with a few (non-affected) brands, it should be fine to merge.
Need to fix the zeroes for other stacks though:
- deconz: page 11 seems to indicate where the parameter is: deCONZ-Serial-Protocol_en_1.22.pdf
- zigate: no clue, doesn't seem mentioned in https://zigate.fr/documentation/commandes-zigate/ but change channel is not confirmed working either, so, zero should be fine for now...
- zboss: @kirovilya can you check how to retrieve the current nwkUpdateID?
And also, this is likely to require some tests to be updated in Z2M repo since it changes the return type of https://github.com/Koenkk/zigbee2mqtt/blob/dev/lib/zigbee.ts#L216
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to confirm that other brands/models still work with this PR, at least Tuya, Hue, Inovelli, Ikea, Ledvance for a good sample, and including routers & end devices.
I tried changing channel with this change and the following devices 3 times and it worked every time, so looks OK to me (Elivco = Tuya)
![Screenshot 2025-02-07 at 21 35 03](https://private-user-images.githubusercontent.com/2892853/411077407-8c7891f6-af03-49d5-8856-ceae7bcce0a9.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkwMDU3NzksIm5iZiI6MTczOTAwNTQ3OSwicGF0aCI6Ii8yODkyODUzLzQxMTA3NzQwNy04Yzc4OTFmNi1hZjAzLTQ5ZDUtODg1Ni1jZWFlN2JjY2UwYTkucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MDIwOCUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTAyMDhUMDkwNDM5WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9ODUzYzI5N2QwN2Y3MjFmMmQ0MTE1NGMxYjNhOWQ5ZTdiMDNkZTg3OTg3NGMyNjRkOTQ1ZjcxMGI3MGQxMjY2ZCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.90wEsKjwNTyvlgJkp1keSNTC5DkOhbsPWYWuJ52Zc3k)
When I update channels in zigbee2mqtt and restart, I find that some devices fail to be controlled. I discovered that when changing channels, the value of the nwkUpdateId field remains at 0.
I referred to the ZigBee specification and found the instructions regarding the modification of the nwkUpdateId field when changing channels:
"The network manager should broadcast a Mgmt_NWK_Update_req notifying devices of the new channel. The broadcast shall be to all devices with RxOnWhenIdle equal to TRUE. The network manager is responsible for incrementing the nwkUpdateId parameter from the NIB and including it in the Mgmt_NWK_Update_req. The network manager shall set a timer based on the value of apsChannelTimer upon issue of a Mgmt_NWK_Update_req that changes channels and shall not issue another such command until this timer expires. However, during this period, the network manager can complete the above analysis. However, instead of changing channels, the network manager would report to the local application using Mgmt_NWK_Update_notify and the application can force a channel change using the Mgmt_NWK_Update_req."