From 5a3afe5060fad60e67a3a0a07948315f3d9ada97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=91=E6=B3=BD=E6=B6=9B?= <1050713479@qq.com> Date: Mon, 30 Dec 2024 19:12:21 +0800 Subject: [PATCH 1/4] fix(modify): Repair the issue of channel switching where some devices fail to be controlled. --- src/controller/controller.ts | 15 ++++- test/controller.test.ts | 125 +++++++++++++++++++++++------------ 2 files changed, 98 insertions(+), 42 deletions(-) diff --git a/src/controller/controller.ts b/src/controller/controller.ts index d7e27817f9..e342740876 100644 --- a/src/controller/controller.ts +++ b/src/controller/controller.ts @@ -499,8 +499,21 @@ export class Controller extends events.EventEmitter { private async changeChannel(oldChannel: number, newChannel: number): Promise { logger.warning(`Changing channel from '${oldChannel}' to '${newChannel}'`, NS); + // According to the Zigbee specification: + // When broadcasting a Mgmt_NWK_Update_req to notify devices of a new channel, the nwkUpdateId parameter should be incremented in the NIB and included in the Mgmt_NWK_Update_req. + // The valid range of nwkUpdateId is 0x00 to 0xFF, and it should wrap back to 0 if necessary. + let nwkUpdateId: number = 0x00; + const isSupportsBackup = await this.adapter.supportsBackup(); + if (isSupportsBackup) { + const backup = await this.adapter.backup(this.getDeviceIeeeAddresses()); + nwkUpdateId = backup.networkUpdateId ?? 0x00; + } + if (++nwkUpdateId > 0xFF) { + nwkUpdateId = 0x00; + } + const clusterId = Zdo.ClusterId.NWK_UPDATE_REQUEST; - const zdoPayload = Zdo.Buffalo.buildRequest(this.adapter.hasZdoMessageOverhead, clusterId, [newChannel], 0xfe, undefined, 0, undefined); + const zdoPayload = Zdo.Buffalo.buildRequest(this.adapter.hasZdoMessageOverhead, clusterId, [newChannel], 0xfe, undefined, nwkUpdateId, undefined); await this.adapter.sendZdo(ZSpec.BLANK_EUI64, ZSpec.BroadcastAddress.SLEEPY, clusterId, zdoPayload, true); logger.info(`Channel changed to '${newChannel}'`, NS); diff --git a/test/controller.test.ts b/test/controller.test.ts index a120bbd6d4..2a9a314459 100755 --- a/test/controller.test.ts +++ b/test/controller.test.ts @@ -37,6 +37,44 @@ const mockLogger = { error: vi.fn(), }; +const mockDummyBackup: Models.Backup = { + networkOptions: { + panId: 6755, + extendedPanId: Buffer.from('deadbeef01020304', 'hex'), + channelList: [11], + networkKey: Buffer.from('a1a2a3a4a5a6a7a8b1b2b3b4b5b6b7b8', 'hex'), + networkKeyDistribute: false, + }, + coordinatorIeeeAddress: Buffer.from('0102030405060708', 'hex'), + logicalChannel: 11, + networkUpdateId: 0, + securityLevel: 5, + znp: { + version: 1, + }, + networkKeyInfo: { + sequenceNumber: 0, + frameCounter: 10000, + }, + devices: [ + { + networkAddress: 1001, + ieeeAddress: Buffer.from('c1c2c3c4c5c6c7c8', 'hex'), + isDirectChild: false, + }, + { + networkAddress: 1002, + ieeeAddress: Buffer.from('d1d2d3d4d5d6d7d8', 'hex'), + isDirectChild: false, + linkKey: { + key: Buffer.from('f8f7f6f5f4f3f2f1e1e2e3e4e5e6e7e8', 'hex'), + rxCounter: 10000, + txCounter: 5000, + }, + }, + ], +}; + const mockAdapterEvents = {}; const mockAdapterWaitFor = vi.fn(); const mockAdapterSupportsDiscoverRoute = vi.fn(); @@ -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); let sendZdoResponseStatus = Zdo.Status.SUCCESS; const mockAdapterSendZdo = vi .fn() @@ -318,44 +357,6 @@ const getCluster = (key) => { return cluster; }; -const mockDummyBackup: Models.Backup = { - networkOptions: { - panId: 6755, - extendedPanId: Buffer.from('deadbeef01020304', 'hex'), - channelList: [11], - networkKey: Buffer.from('a1a2a3a4a5a6a7a8b1b2b3b4b5b6b7b8', 'hex'), - networkKeyDistribute: false, - }, - coordinatorIeeeAddress: Buffer.from('0102030405060708', 'hex'), - logicalChannel: 11, - networkUpdateId: 0, - securityLevel: 5, - znp: { - version: 1, - }, - networkKeyInfo: { - sequenceNumber: 0, - frameCounter: 10000, - }, - devices: [ - { - networkAddress: 1001, - ieeeAddress: Buffer.from('c1c2c3c4c5c6c7c8', 'hex'), - isDirectChild: false, - }, - { - networkAddress: 1002, - ieeeAddress: Buffer.from('d1d2d3d4d5d6d7d8', 'hex'), - isDirectChild: false, - linkKey: { - key: Buffer.from('f8f7f6f5f4f3f2f1e1e2e3e4e5e6e7e8', 'hex'), - rxCounter: 10000, - txCounter: 5000, - }, - }, - ], -}; - let dummyBackup; vi.mock('../src/adapter/z-stack/adapter/zStackAdapter', () => ({ @@ -368,9 +369,7 @@ vi.mock('../src/adapter/z-stack/adapter/zStackAdapter', () => ({ getCoordinatorIEEE: mockAdapterGetCoordinatorIEEE, reset: mockAdapterReset, supportsBackup: mockAdapterSupportsBackup, - backup: () => { - return mockDummyBackup; - }, + backup: mockApaterBackup, getCoordinatorVersion: () => { return {type: 'zStack', meta: {version: 1}}; }, @@ -1558,6 +1557,28 @@ describe('Controller', () => { it('Change channel on start', async () => { mockAdapterStart.mockReturnValueOnce('resumed'); mockAdapterGetNetworkParameters.mockReturnValueOnce({panID: 1, extendedPanID: '0x64c5fd698daf0c00', channel: 25}); + // @ts-expect-error private + const changeChannelSpy = vi.spyOn(controller, 'changeChannel'); + await controller.start(); + expect(mockAdapterGetNetworkParameters).toHaveBeenCalledTimes(1); + const zdoPayload = Zdo.Buffalo.buildRequest(false, Zdo.ClusterId.NWK_UPDATE_REQUEST, [15], 0xfe, undefined, 1, undefined); + expect(mockAdapterSendZdo).toHaveBeenCalledWith( + ZSpec.BLANK_EUI64, + ZSpec.BroadcastAddress.SLEEPY, + Zdo.ClusterId.NWK_UPDATE_REQUEST, + zdoPayload, + true, + ); + expect(await controller.getNetworkParameters()).toEqual({panID: 1, channel: 15, extendedPanID: '0x64c5fd698daf0c00'}); + expect(changeChannelSpy).toHaveBeenCalledTimes(1); + }); + + it('Change channel on start when the nwkUpdateId increases to 0xFF', async () => { + mockAdapterStart.mockReturnValueOnce('resumed'); + mockAdapterGetNetworkParameters.mockReturnValueOnce({panID: 1, extendedPanID: '0x64c5fd698daf0c00', channel: 25}); + mockAdapterSupportsBackup.mockReturnValueOnce(true); + mockApaterBackup.mockReturnValueOnce(Object.assign({}, mockApaterBackup, { networkUpdateId: 0xFF })); + // @ts-expect-error private const changeChannelSpy = vi.spyOn(controller, 'changeChannel'); await controller.start(); @@ -1574,6 +1595,28 @@ describe('Controller', () => { expect(changeChannelSpy).toHaveBeenCalledTimes(1); }); + it('Change channel on start when the nwkUpdateId is undefinded', async () => { + mockAdapterStart.mockReturnValueOnce('resumed'); + mockAdapterGetNetworkParameters.mockReturnValueOnce({panID: 1, extendedPanID: '0x64c5fd698daf0c00', channel: 25}); + mockAdapterSupportsBackup.mockReturnValueOnce(true); + mockApaterBackup.mockReturnValueOnce({}); + + // @ts-expect-error private + const changeChannelSpy = vi.spyOn(controller, 'changeChannel'); + await controller.start(); + expect(mockAdapterGetNetworkParameters).toHaveBeenCalledTimes(1); + const zdoPayload = Zdo.Buffalo.buildRequest(false, Zdo.ClusterId.NWK_UPDATE_REQUEST, [15], 0xfe, undefined, 1, undefined); + expect(mockAdapterSendZdo).toHaveBeenCalledWith( + ZSpec.BLANK_EUI64, + ZSpec.BroadcastAddress.SLEEPY, + Zdo.ClusterId.NWK_UPDATE_REQUEST, + zdoPayload, + true, + ); + expect(await controller.getNetworkParameters()).toEqual({panID: 1, channel: 15, extendedPanID: '0x64c5fd698daf0c00'}); + expect(changeChannelSpy).toHaveBeenCalledTimes(1); + }); + it('Does not change channel on start if not changed', async () => { mockAdapterStart.mockReturnValueOnce('resumed'); // @ts-expect-error private From 48ee5a7b41b4fa74a678d5ad7b591d10f04576a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=91=E6=B3=BD=E6=B6=9B?= <1050713479@qq.com> Date: Mon, 30 Dec 2024 20:13:49 +0800 Subject: [PATCH 2/4] eslint prettier fix --- src/controller/controller.ts | 14 +++++++++++--- test/controller.test.ts | 6 +++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/controller/controller.ts b/src/controller/controller.ts index e342740876..9a37fae13c 100644 --- a/src/controller/controller.ts +++ b/src/controller/controller.ts @@ -500,7 +500,7 @@ export class Controller extends events.EventEmitter { logger.warning(`Changing channel from '${oldChannel}' to '${newChannel}'`, NS); // According to the Zigbee specification: - // When broadcasting a Mgmt_NWK_Update_req to notify devices of a new channel, the nwkUpdateId parameter should be incremented in the NIB and included in the Mgmt_NWK_Update_req. + // When broadcasting a Mgmt_NWK_Update_req to notify devices of a new channel, the nwkUpdateId parameter should be incremented in the NIB and included in the Mgmt_NWK_Update_req. // The valid range of nwkUpdateId is 0x00 to 0xFF, and it should wrap back to 0 if necessary. let nwkUpdateId: number = 0x00; const isSupportsBackup = await this.adapter.supportsBackup(); @@ -508,12 +508,20 @@ export class Controller extends events.EventEmitter { const backup = await this.adapter.backup(this.getDeviceIeeeAddresses()); nwkUpdateId = backup.networkUpdateId ?? 0x00; } - if (++nwkUpdateId > 0xFF) { + if (++nwkUpdateId > 0xff) { nwkUpdateId = 0x00; } const clusterId = Zdo.ClusterId.NWK_UPDATE_REQUEST; - const zdoPayload = Zdo.Buffalo.buildRequest(this.adapter.hasZdoMessageOverhead, clusterId, [newChannel], 0xfe, undefined, nwkUpdateId, undefined); + const zdoPayload = Zdo.Buffalo.buildRequest( + this.adapter.hasZdoMessageOverhead, + clusterId, + [newChannel], + 0xfe, + undefined, + nwkUpdateId, + undefined, + ); await this.adapter.sendZdo(ZSpec.BLANK_EUI64, ZSpec.BroadcastAddress.SLEEPY, clusterId, zdoPayload, true); logger.info(`Channel changed to '${newChannel}'`, NS); diff --git a/test/controller.test.ts b/test/controller.test.ts index 2a9a314459..6612ec2833 100755 --- a/test/controller.test.ts +++ b/test/controller.test.ts @@ -1577,8 +1577,8 @@ describe('Controller', () => { mockAdapterStart.mockReturnValueOnce('resumed'); mockAdapterGetNetworkParameters.mockReturnValueOnce({panID: 1, extendedPanID: '0x64c5fd698daf0c00', channel: 25}); mockAdapterSupportsBackup.mockReturnValueOnce(true); - mockApaterBackup.mockReturnValueOnce(Object.assign({}, mockApaterBackup, { networkUpdateId: 0xFF })); - + mockApaterBackup.mockReturnValueOnce(Object.assign({}, mockApaterBackup, {networkUpdateId: 0xff})); + // @ts-expect-error private const changeChannelSpy = vi.spyOn(controller, 'changeChannel'); await controller.start(); @@ -1600,7 +1600,7 @@ describe('Controller', () => { mockAdapterGetNetworkParameters.mockReturnValueOnce({panID: 1, extendedPanID: '0x64c5fd698daf0c00', channel: 25}); mockAdapterSupportsBackup.mockReturnValueOnce(true); mockApaterBackup.mockReturnValueOnce({}); - + // @ts-expect-error private const changeChannelSpy = vi.spyOn(controller, 'changeChannel'); await controller.start(); From e46ba7e7c1241224fcbb6de0c1c15fb9ff36ece6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=91=E6=B3=BD=E6=B6=9B?= <1050713479@qq.com> Date: Thu, 2 Jan 2025 10:07:32 +0800 Subject: [PATCH 3/4] fix(modify): Extend the getNetworkParameters method to obtain the value of nwkUpdateID, and implement the ember and ezsp adapters. --- src/adapter/ember/adapter/emberAdapter.ts | 1 + src/adapter/ezsp/adapter/ezspAdapter.ts | 1 + src/adapter/tstype.ts | 1 + src/controller/controller.ts | 22 ++++++++++------------ 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/adapter/ember/adapter/emberAdapter.ts b/src/adapter/ember/adapter/emberAdapter.ts index 13f08cb47f..1928c49ce3 100644 --- a/src/adapter/ember/adapter/emberAdapter.ts +++ b/src/adapter/ember/adapter/emberAdapter.ts @@ -1678,6 +1678,7 @@ export class EmberAdapter extends Adapter { panID, extendedPanID: ZSpec.Utils.eui64LEBufferToHex(Buffer.from(extendedPanID)), channel, + nwkUpdateID: this.networkCache.parameters.nwkUpdateId, }; }); } diff --git a/src/adapter/ezsp/adapter/ezspAdapter.ts b/src/adapter/ezsp/adapter/ezspAdapter.ts index f019a39937..2a1d331b72 100644 --- a/src/adapter/ezsp/adapter/ezspAdapter.ts +++ b/src/adapter/ezsp/adapter/ezspAdapter.ts @@ -462,6 +462,7 @@ export class EZSPAdapter extends Adapter { panID: this.driver.networkParams.panId, extendedPanID: ZSpec.Utils.eui64LEBufferToHex(this.driver.networkParams.extendedPanId), channel: this.driver.networkParams.radioChannel, + nwkUpdateID: this.driver.networkParams.nwkUpdateId }; } diff --git a/src/adapter/tstype.ts b/src/adapter/tstype.ts index 4b7e75801d..8f6b01d0df 100644 --- a/src/adapter/tstype.ts +++ b/src/adapter/tstype.ts @@ -74,4 +74,5 @@ export interface NetworkParameters { panID: number; extendedPanID: string; // `0x${string}` same as IEEE address channel: number; + nwkUpdateID?: number; } diff --git a/src/controller/controller.ts b/src/controller/controller.ts index 9a37fae13c..eec18bf2ba 100644 --- a/src/controller/controller.ts +++ b/src/controller/controller.ts @@ -144,10 +144,17 @@ export class Controller extends events.EventEmitter { const netParams = await this.getNetworkParameters(); const configuredChannel = this.options.network.channelList[0]; const adapterChannel = netParams.channel; + // According to the Zigbee specification: + // When broadcasting a Mgmt_NWK_Update_req to notify devices of a new channel, the nwkUpdateId parameter should be incremented in the NIB and included in the Mgmt_NWK_Update_req. + // The valid range of nwkUpdateId is 0x00 to 0xFF, and it should wrap back to 0 if necessary. + let nwkUpdateID = netParams.nwkUpdateID ?? 0; + if (++nwkUpdateID > 0xFF) { + nwkUpdateID = 0x00; + } if (configuredChannel != adapterChannel) { logger.info(`Configured channel '${configuredChannel}' does not match adapter channel '${adapterChannel}', changing channel`, NS); - await this.changeChannel(adapterChannel, configuredChannel); + await this.changeChannel(adapterChannel, configuredChannel, nwkUpdateID); } } @@ -496,21 +503,12 @@ export class Controller extends events.EventEmitter { /** * Broadcast a network-wide channel change. */ - private async changeChannel(oldChannel: number, newChannel: number): Promise { + private async changeChannel(oldChannel: number, newChannel: number, nwkUpdateID: number): Promise { logger.warning(`Changing channel from '${oldChannel}' to '${newChannel}'`, NS); // According to the Zigbee specification: // When broadcasting a Mgmt_NWK_Update_req to notify devices of a new channel, the nwkUpdateId parameter should be incremented in the NIB and included in the Mgmt_NWK_Update_req. // The valid range of nwkUpdateId is 0x00 to 0xFF, and it should wrap back to 0 if necessary. - let nwkUpdateId: number = 0x00; - const isSupportsBackup = await this.adapter.supportsBackup(); - if (isSupportsBackup) { - const backup = await this.adapter.backup(this.getDeviceIeeeAddresses()); - nwkUpdateId = backup.networkUpdateId ?? 0x00; - } - if (++nwkUpdateId > 0xff) { - nwkUpdateId = 0x00; - } const clusterId = Zdo.ClusterId.NWK_UPDATE_REQUEST; const zdoPayload = Zdo.Buffalo.buildRequest( @@ -519,7 +517,7 @@ export class Controller extends events.EventEmitter { [newChannel], 0xfe, undefined, - nwkUpdateId, + nwkUpdateID, undefined, ); From 629088f50046381b60c171dae3ea9f2a234fc832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=91=E6=B3=BD=E6=B6=9B?= <1050713479@qq.com> Date: Thu, 2 Jan 2025 11:01:57 +0800 Subject: [PATCH 4/4] eslint prettier fix --- src/adapter/ezsp/adapter/ezspAdapter.ts | 2 +- src/adapter/tstype.ts | 2 +- src/controller/controller.ts | 6 +---- test/adapter/ember/emberAdapter.test.ts | 2 ++ test/controller.test.ts | 31 +++---------------------- 5 files changed, 8 insertions(+), 35 deletions(-) diff --git a/src/adapter/ezsp/adapter/ezspAdapter.ts b/src/adapter/ezsp/adapter/ezspAdapter.ts index 2a1d331b72..d5c0f4d311 100644 --- a/src/adapter/ezsp/adapter/ezspAdapter.ts +++ b/src/adapter/ezsp/adapter/ezspAdapter.ts @@ -462,7 +462,7 @@ export class EZSPAdapter extends Adapter { panID: this.driver.networkParams.panId, extendedPanID: ZSpec.Utils.eui64LEBufferToHex(this.driver.networkParams.extendedPanId), channel: this.driver.networkParams.radioChannel, - nwkUpdateID: this.driver.networkParams.nwkUpdateId + nwkUpdateID: this.driver.networkParams.nwkUpdateId, }; } diff --git a/src/adapter/tstype.ts b/src/adapter/tstype.ts index 8f6b01d0df..e9ccd704a7 100644 --- a/src/adapter/tstype.ts +++ b/src/adapter/tstype.ts @@ -74,5 +74,5 @@ export interface NetworkParameters { panID: number; extendedPanID: string; // `0x${string}` same as IEEE address channel: number; - nwkUpdateID?: number; + nwkUpdateID?: number; } diff --git a/src/controller/controller.ts b/src/controller/controller.ts index eec18bf2ba..78ba098129 100644 --- a/src/controller/controller.ts +++ b/src/controller/controller.ts @@ -148,7 +148,7 @@ export class Controller extends events.EventEmitter { // When broadcasting a Mgmt_NWK_Update_req to notify devices of a new channel, the nwkUpdateId parameter should be incremented in the NIB and included in the Mgmt_NWK_Update_req. // The valid range of nwkUpdateId is 0x00 to 0xFF, and it should wrap back to 0 if necessary. let nwkUpdateID = netParams.nwkUpdateID ?? 0; - if (++nwkUpdateID > 0xFF) { + if (++nwkUpdateID > 0xff) { nwkUpdateID = 0x00; } @@ -506,10 +506,6 @@ export class Controller extends events.EventEmitter { private async changeChannel(oldChannel: number, newChannel: number, nwkUpdateID: number): Promise { logger.warning(`Changing channel from '${oldChannel}' to '${newChannel}'`, NS); - // According to the Zigbee specification: - // When broadcasting a Mgmt_NWK_Update_req to notify devices of a new channel, the nwkUpdateId parameter should be incremented in the NIB and included in the Mgmt_NWK_Update_req. - // The valid range of nwkUpdateId is 0x00 to 0xFF, and it should wrap back to 0 if necessary. - const clusterId = Zdo.ClusterId.NWK_UPDATE_REQUEST; const zdoPayload = Zdo.Buffalo.buildRequest( this.adapter.hasZdoMessageOverhead, diff --git a/test/adapter/ember/emberAdapter.test.ts b/test/adapter/ember/emberAdapter.test.ts index 4284e922d0..759e2a1b03 100644 --- a/test/adapter/ember/emberAdapter.test.ts +++ b/test/adapter/ember/emberAdapter.test.ts @@ -2249,6 +2249,7 @@ describe('Ember Adapter Layer', () => { panID: DEFAULT_NETWORK_OPTIONS.panID, extendedPanID: ZSpec.Utils.eui64LEBufferToHex(Buffer.from(DEFAULT_NETWORK_OPTIONS.extendedPanID!)), channel: DEFAULT_NETWORK_OPTIONS.channelList[0], + nwkUpdateID: 0, } as TsType.NetworkParameters); expect(mockEzspGetNetworkParameters).toHaveBeenCalledTimes(0); }); @@ -2260,6 +2261,7 @@ describe('Ember Adapter Layer', () => { panID: DEFAULT_NETWORK_OPTIONS.panID, extendedPanID: ZSpec.Utils.eui64LEBufferToHex(Buffer.from(DEFAULT_NETWORK_OPTIONS.extendedPanID!)), channel: DEFAULT_NETWORK_OPTIONS.channelList[0], + nwkUpdateID: 0, } as TsType.NetworkParameters); expect(mockEzspGetNetworkParameters).toHaveBeenCalledTimes(1); }); diff --git a/test/controller.test.ts b/test/controller.test.ts index 6612ec2833..fbc8f94c81 100755 --- a/test/controller.test.ts +++ b/test/controller.test.ts @@ -94,7 +94,7 @@ const mocksendZclFrameToGroup = vi.fn(); const mocksendZclFrameToAll = vi.fn(); const mockAddInstallCode = vi.fn(); const mocksendZclFrameToEndpoint = vi.fn(); -const mockApaterBackup = vi.fn().mockReturnValue(mockDummyBackup); +const mockApaterBackup = vi.fn(() => Promise.resolve(mockDummyBackup)); let sendZdoResponseStatus = Zdo.Status.SUCCESS; const mockAdapterSendZdo = vi .fn() @@ -1573,12 +1573,9 @@ describe('Controller', () => { expect(changeChannelSpy).toHaveBeenCalledTimes(1); }); - it('Change channel on start when the nwkUpdateId increases to 0xFF', async () => { + it('Change channel on start when nwkUpdateID is 0xff', async () => { mockAdapterStart.mockReturnValueOnce('resumed'); - mockAdapterGetNetworkParameters.mockReturnValueOnce({panID: 1, extendedPanID: '0x64c5fd698daf0c00', channel: 25}); - mockAdapterSupportsBackup.mockReturnValueOnce(true); - mockApaterBackup.mockReturnValueOnce(Object.assign({}, mockApaterBackup, {networkUpdateId: 0xff})); - + mockAdapterGetNetworkParameters.mockReturnValueOnce({panID: 1, extendedPanID: '0x64c5fd698daf0c00', channel: 25, nwkUpdateID: 0xff}); // @ts-expect-error private const changeChannelSpy = vi.spyOn(controller, 'changeChannel'); await controller.start(); @@ -1595,28 +1592,6 @@ describe('Controller', () => { expect(changeChannelSpy).toHaveBeenCalledTimes(1); }); - it('Change channel on start when the nwkUpdateId is undefinded', async () => { - mockAdapterStart.mockReturnValueOnce('resumed'); - mockAdapterGetNetworkParameters.mockReturnValueOnce({panID: 1, extendedPanID: '0x64c5fd698daf0c00', channel: 25}); - mockAdapterSupportsBackup.mockReturnValueOnce(true); - mockApaterBackup.mockReturnValueOnce({}); - - // @ts-expect-error private - const changeChannelSpy = vi.spyOn(controller, 'changeChannel'); - await controller.start(); - expect(mockAdapterGetNetworkParameters).toHaveBeenCalledTimes(1); - const zdoPayload = Zdo.Buffalo.buildRequest(false, Zdo.ClusterId.NWK_UPDATE_REQUEST, [15], 0xfe, undefined, 1, undefined); - expect(mockAdapterSendZdo).toHaveBeenCalledWith( - ZSpec.BLANK_EUI64, - ZSpec.BroadcastAddress.SLEEPY, - Zdo.ClusterId.NWK_UPDATE_REQUEST, - zdoPayload, - true, - ); - expect(await controller.getNetworkParameters()).toEqual({panID: 1, channel: 15, extendedPanID: '0x64c5fd698daf0c00'}); - expect(changeChannelSpy).toHaveBeenCalledTimes(1); - }); - it('Does not change channel on start if not changed', async () => { mockAdapterStart.mockReturnValueOnce('resumed'); // @ts-expect-error private