Skip to content

Commit

Permalink
fix!: Fix some transmit power issues after #1139 (#1222)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nerivec authored and Koenkk committed Dec 1, 2024
1 parent 1d35a14 commit c016153
Show file tree
Hide file tree
Showing 13 changed files with 46 additions and 99 deletions.
2 changes: 0 additions & 2 deletions src/adapter/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,6 @@ abstract class Adapter extends events.EventEmitter<AdapterEventMap> {

public abstract getNetworkParameters(): Promise<TsType.NetworkParameters>;

public abstract setTransmitPower(value: number): Promise<void>;

public abstract addInstallCode(ieeeAddress: string, key: Buffer): Promise<void>;

public abstract waitFor(
Expand Down
5 changes: 0 additions & 5 deletions src/adapter/deconz/adapter/deconzAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -574,11 +574,6 @@ class DeconzAdapter extends Adapter {
throw new Error('not supported');
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
public async setTransmitPower(value: number): Promise<void> {
throw new Error('not supported');
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
public async sendZclFrameInterPANIeeeAddr(zclFrame: Zcl.Frame, ieeeAddr: string): Promise<void> {
throw new Error('not supported');
Expand Down
20 changes: 7 additions & 13 deletions src/adapter/ember/adapter/emberAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -725,8 +725,13 @@ export class EmberAdapter extends Adapter {
throw new Error(`Failed to get network parameters with status=${SLStatus[status]}.`);
}

if (this.adapterOptions.transmitPower != null && parameters.radioTxPower !== this.adapterOptions.transmitPower) {
await this.setTransmitPower(this.adapterOptions.transmitPower);
if (this.adapterOptions.transmitPower != undefined && parameters.radioTxPower !== this.adapterOptions.transmitPower) {
const status = await this.ezsp.ezspSetRadioPower(this.adapterOptions.transmitPower);

if (status !== SLStatus.OK) {
// soft-fail, don't prevent start
logger.error(`Failed to set transmit power to ${this.adapterOptions.transmitPower} status=${SLStatus[status]}.`, NS);
}
}

this.networkCache.parameters = parameters;
Expand Down Expand Up @@ -1713,17 +1718,6 @@ export class EmberAdapter extends Adapter {
});
}

// queued
public async setTransmitPower(value: number): Promise<void> {
return await this.queue.execute<void>(async () => {
const status = await this.ezsp.ezspSetRadioPower(value);

if (status !== SLStatus.OK) {
throw new Error(`Failed to set transmit power to ${value} status=${SLStatus[status]}.`);
}
});
}

// queued
public async addInstallCode(ieeeAddress: string, key: Buffer): Promise<void> {
// codes with CRC, check CRC before sending to NCP, otherwise let NCP handle
Expand Down
9 changes: 1 addition & 8 deletions src/adapter/ezsp/adapter/ezspAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ class EZSPAdapter extends Adapter {
`'ezsp' driver is deprecated and will only remain to provide support for older firmware (pre 7.4.x). Migration to 'ember' is recommended. If using Zigbee2MQTT see https://github.com/Koenkk/zigbee2mqtt/discussions/21462`,
NS,
);
return await this.driver.startup();
return await this.driver.startup(this.adapterOptions.transmitPower);
}

public async stop(): Promise<void> {
Expand Down Expand Up @@ -542,13 +542,6 @@ class EZSPAdapter extends Adapter {
});
}

public async setTransmitPower(value: number): Promise<void> {
logger.debug(`setTransmitPower to ${value}`, NS);
return await this.queue.execute<void>(async () => {
await this.driver.setRadioPower(value);
});
}

public async setChannelInterPAN(channel: number): Promise<void> {
return await this.queue.execute<void>(async () => {
this.interpanLock = true;
Expand Down
18 changes: 9 additions & 9 deletions src/adapter/ezsp/driver/driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ export class Driver extends EventEmitter {
}
}

public async startup(): Promise<TsType.StartResult> {
public async startup(transmitPower?: number): Promise<TsType.StartResult> {
let result: TsType.StartResult = 'resumed';
this.transactionID = 1;
// this.ezsp = undefined;
Expand Down Expand Up @@ -260,12 +260,12 @@ export class Driver extends EventEmitter {
if (restore) {
// restore
logger.info('Restore network from backup', NS);
await this.formNetwork(true);
await this.formNetwork(true, transmitPower);
result = 'restored';
} else {
// reset
logger.info('Form network', NS);
await this.formNetwork(false);
await this.formNetwork(false, transmitPower);
result = 'reset';
}
}
Expand Down Expand Up @@ -301,6 +301,10 @@ export class Driver extends EventEmitter {
await this.multicast.subscribe(ZSpec.GP_GROUP_ID, ZSpec.GP_ENDPOINT);
// await this.multicast.subscribe(1, 901);

if (transmitPower != undefined && this.networkParams.radioTxPower !== transmitPower) {
await this.ezsp.execCommand('setRadioPower', {power: transmitPower});
}

return result;
}

Expand All @@ -318,7 +322,7 @@ export class Driver extends EventEmitter {
return !valid;
}

private async formNetwork(restore: boolean): Promise<void> {
private async formNetwork(restore: boolean, transmitPower?: number): Promise<void> {
let backup;
await this.ezsp.execCommand('clearTransientLinkKeys');

Expand All @@ -341,7 +345,7 @@ export class Driver extends EventEmitter {
await this.ezsp.setInitialSecurityState(initial_security_state);

const parameters: EmberNetworkParameters = new EmberNetworkParameters();
parameters.radioTxPower = 5;
parameters.radioTxPower = transmitPower ?? 5;
parameters.joinMethod = EmberJoinMethod.USE_MAC_ASSOCIATION;
parameters.nwkManagerId = 0;
parameters.nwkUpdateId = 0;
Expand Down Expand Up @@ -864,10 +868,6 @@ export class Driver extends EventEmitter {
);
}

public setRadioPower(value: number): Promise<EZSPFrameData> {
return this.ezsp.execCommand('setRadioPower', {power: value});
}

public setChannel(channel: number): Promise<EZSPFrameData> {
return this.ezsp.execCommand('setLogicalAndRadioChannel', {radioChannel: channel});
}
Expand Down
8 changes: 1 addition & 7 deletions src/adapter/z-stack/adapter/zStackAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ class ZStackAdapter extends Adapter {
}

if (this.adapterOptions.transmitPower != null) {
await this.setTransmitPower(this.adapterOptions.transmitPower);
await this.znp.request(Subsystem.SYS, 'stackTune', {operation: 0, value: this.adapterOptions.transmitPower});
}

return await startResult;
Expand Down Expand Up @@ -953,12 +953,6 @@ class ZStackAdapter extends Adapter {
});
}

public async setTransmitPower(value: number): Promise<void> {
return await this.queue.execute<void>(async () => {
await this.znp.request(Subsystem.SYS, 'stackTune', {operation: 0, value});
});
}

private waitForInternal(
networkAddress: number | undefined,
endpoint: number,
Expand Down
10 changes: 1 addition & 9 deletions src/adapter/zboss/adapter/zbossAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export class ZBOSSAdapter extends Adapter {

await this.driver.connect();

return await this.driver.startup();
return await this.driver.startup(this.adapterOptions.transmitPower);
}

public async stop(): Promise<void> {
Expand Down Expand Up @@ -171,14 +171,6 @@ export class ZBOSSAdapter extends Adapter {
});
}

public async setTransmitPower(value: number): Promise<void> {
if (this.driver.isInitialized()) {
return await this.queue.execute<void>(async () => {
await this.driver.execCommand(CommandId.SET_TX_POWER, {txPower: value});
});
}
}

public async addInstallCode(ieeeAddress: string, key: Buffer): Promise<void> {
logger.error(() => `NOT SUPPORTED: sendZclFrameToGroup(${ieeeAddress},${key.toString('hex')}`, NS);
throw new Error(`Install code is not supported for 'zboss' yet`);
Expand Down
6 changes: 5 additions & 1 deletion src/adapter/zboss/driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export class ZBOSSDriver extends EventEmitter {
await this.execCommand(CommandId.NCP_RESET, {options}, 10000);
}

public async startup(): Promise<TsType.StartResult> {
public async startup(transmitPower?: number): Promise<TsType.StartResult> {
logger.info(`Driver startup`, NS);
let result: TsType.StartResult = 'resumed';

Expand Down Expand Up @@ -135,6 +135,10 @@ export class ZBOSSDriver extends EventEmitter {
//await this.execCommand(CommandId.SET_ED_TIMEOUT, {timeout: 8});
//await this.execCommand(CommandId.SET_MAX_CHILDREN, {children: 100});

if (transmitPower != undefined) {
await this.execCommand(CommandId.SET_TX_POWER, {txPower: transmitPower});
}

return result;
}

Expand Down
12 changes: 4 additions & 8 deletions src/adapter/zigate/adapter/zigateAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ class ZiGateAdapter extends Adapter {
destinationEndpoint: ZSpec.HA_ENDPOINT,
groupAddress: default_bind_group,
});

if (this.adapterOptions.transmitPower != undefined) {
await this.driver.sendCommand(ZiGateCommandCode.SetTXpower, {value: this.adapterOptions.transmitPower});
}
} catch (error) {
throw new Error('failed to connect to zigate adapter ' + (error as Error).message);
}
Expand Down Expand Up @@ -190,14 +194,6 @@ class ZiGateAdapter extends Adapter {
throw new Error('This adapter does not support backup');
}

public async setTransmitPower(value: number): Promise<void> {
try {
await this.driver.sendCommand(ZiGateCommandCode.SetTXpower, {value: value});
} catch (error) {
throw new Error(`Set transmitpower failed ${error}`);
}
}

public async sendZdo(
ieeeAddress: string,
networkAddress: number,
Expand Down
7 changes: 0 additions & 7 deletions src/controller/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -513,13 +513,6 @@ class Controller extends events.EventEmitter<ControllerEventMap> {
await Wait(12000);
}

/**
* Set transmit power of the adapter
*/
public async setTransmitPower(value: number): Promise<void> {
return await this.adapter.setTransmitPower(value);
}

public async identifyUnknownDevice(nwkAddress: number): Promise<Device | undefined> {
if (this.unknownDevices.has(nwkAddress)) {
// prevent duplicate triggering
Expand Down
30 changes: 18 additions & 12 deletions test/adapter/ember/emberAdapter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,24 @@ describe('Ember Adapter Layer', () => {
expect(mockEzspSetRadioPower).toHaveBeenCalledTimes(0);
});

it('Starts with mismatching transmit power, failure does not present start', async () => {
adapter = new EmberAdapter(
DEFAULT_NETWORK_OPTIONS,
DEFAULT_SERIAL_PORT_OPTIONS,
backupPath,
Object.assign({}, DEFAULT_ADAPTER_OPTIONS, {transmitPower: 12}),
);
mockEzspSetRadioPower.mockResolvedValueOnce(SLStatus.FAIL);

const result = adapter.start();

await jest.advanceTimersByTimeAsync(5000);
await expect(result).resolves.toStrictEqual('resumed');
expect(mockEzspSetRadioPower).toHaveBeenCalledTimes(1);
expect(mockEzspSetRadioPower).toHaveBeenCalledWith(12);
expect(loggerSpies.error).toHaveBeenCalledWith(`Failed to set transmit power to 12 status=FAIL.`, 'zh:ember');
});

it('Fails to start when EZSP layer fails to start', async () => {
adapter = new EmberAdapter(DEFAULT_NETWORK_OPTIONS, DEFAULT_SERIAL_PORT_OPTIONS, backupPath, DEFAULT_ADAPTER_OPTIONS);

Expand Down Expand Up @@ -2271,18 +2289,6 @@ describe('Ember Adapter Layer', () => {
expect(mockEzspGetNetworkParameters).toHaveBeenCalledTimes(1);
});

it('Adapter impl: setTransmitPower', async () => {
await expect(adapter.setTransmitPower(10)).resolves.toStrictEqual(undefined);
expect(mockEzspSetRadioPower).toHaveBeenCalledTimes(1);
});

it('Adapter impl: throws when setTransmitPower fails', async () => {
mockEzspSetRadioPower.mockResolvedValueOnce(SLStatus.FAIL);

await expect(adapter.setTransmitPower(10)).rejects.toThrow(`Failed to set transmit power to 10 status=FAIL.`);
expect(mockEzspSetRadioPower).toHaveBeenCalledTimes(1);
});

it('Adapter impl: addInstallCode without local CRC validation', async () => {
await expect(adapter.addInstallCode('0x1122334455667788', Buffer.alloc(16))).resolves.toStrictEqual(undefined);
expect(mockEzspAesMmoHash).toHaveBeenCalledTimes(1);
Expand Down
10 changes: 0 additions & 10 deletions test/adapter/z-stack/adapter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2182,16 +2182,6 @@ describe('zstack-adapter', () => {
expect(mockZnpRequest).toHaveBeenCalledWith(Subsystem.SYS, 'stackTune', {operation: 0, value: 2});
});

it('Set transmit power', async () => {
basicMocks();
await adapter.start();
mockZnpRequest.mockClear();
mockQueueExecute.mockClear();
await adapter.setTransmitPower(15);
expect(mockZnpRequest).toHaveBeenCalledTimes(1);
expect(mockZnpRequest).toHaveBeenCalledWith(Subsystem.SYS, 'stackTune', {operation: 0, value: 15});
});

it('Support LED should go to false when LED request fails', async () => {
basicMocks();
await adapter.start();
Expand Down
8 changes: 0 additions & 8 deletions test/controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ const mockAdapterSupportsBackup = jest.fn().mockReturnValue(true);
const mockAdapterReset = jest.fn();
const mockAdapterStop = jest.fn();
const mockAdapterStart = jest.fn().mockReturnValue('resumed');
const mockAdapterSetTransmitPower = jest.fn();
const mockAdapterGetCoordinatorIEEE = jest.fn().mockReturnValue('0x0000012300000000');
const mockAdapterGetNetworkParameters = jest.fn().mockReturnValue({panID: 1, extendedPanID: 3, channel: 15});
const mocksendZclFrameToGroup = jest.fn();
Expand Down Expand Up @@ -399,7 +398,6 @@ jest.mock('../src/adapter/z-stack/adapter/zStackAdapter', () => {
},
getNetworkParameters: mockAdapterGetNetworkParameters,
waitFor: mockAdapterWaitFor,
setTransmitPower: mockAdapterSetTransmitPower,
sendZclFrameToEndpoint: mocksendZclFrameToEndpoint,
sendZclFrameToGroup: mocksendZclFrameToGroup,
sendZclFrameToAll: mocksendZclFrameToAll,
Expand Down Expand Up @@ -1615,12 +1613,6 @@ describe('Controller', () => {
expect(changeChannelSpy).toHaveBeenCalledTimes(0);
});

it('Set transmit power', async () => {
await controller.start();
await controller.setTransmitPower(15);
expect(mockAdapterSetTransmitPower).toHaveBeenCalledWith(15);
});

it('Get coordinator version', async () => {
await controller.start();
expect(await controller.getCoordinatorVersion()).toEqual({type: 'zStack', meta: {version: 1}});
Expand Down

0 comments on commit c016153

Please sign in to comment.