-
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! |
@@ -144,10 +144,17 @@ export class Controller extends events.EventEmitter<ControllerEventMap> { | |||
const netParams = await this.getNetworkParameters(); | |||
const configuredChannel = this.options.network.channelList[0]; | |||
const adapterChannel = netParams.channel; | |||
// According to the Zigbee specification: |
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.
The increment should be done in changeChannel
so it only happens when the channel is actually changed (re-get getNetworkParameters
in the function instead of passing a param, it's cached anyway).
Also might need to deal with sendZdo
potentially failing (I think that will stop Z2M startup, so should be fine, but needs to be verified).
@@ -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?
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."