Skip to content

Commit

Permalink
fix: Fix Deconz Green power implementation (#1175)
Browse files Browse the repository at this point in the history
* fix: Fix Deconz Green power implementation Koenkk/zigbee2mqtt#23814

* process feedback
  • Loading branch information
Koenkk authored Sep 6, 2024
1 parent 0e9228f commit 4b99609
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 47 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
},
"scripts": {
"build": "tsc",
"start": "tsc -w",
"build:watch": "tsc -w",
"test": "jest test --silent --maxWorkers=50%",
"test-with-coverage": "jest test --silent --maxWorkers=50% --coverage",
"test-watch": "jest test --silent --maxWorkers=25% --watch",
Expand Down
50 changes: 21 additions & 29 deletions src/adapter/deconz/adapter/deconzAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import assert from 'assert';

import {ZSpec} from '../../..';
import Device from '../../../controller/model/device';
import * as Models from '../../../models';
import {Queue, Waitress} from '../../../utils';
Expand Down Expand Up @@ -1229,38 +1230,29 @@ class DeconzAdapter extends Adapter {
}

private checkReceivedGreenPowerIndication(ind: gpDataInd): void {
ind.clusterId = 0x21;

const gpFrame = [
ind.rspId!,
ind.seqNr!,
ind.id!,
0,
0, // 0, 0 for options is a temp fix until https://github.com/Koenkk/zigbee-herdsman/pull/536 is merged.
// ind.options & 0xff, (ind.options >> 8) & 0xff,
ind.srcId! & 0xff,
(ind.srcId! >> 8) & 0xff,
(ind.srcId! >> 16) & 0xff,
(ind.srcId! >> 24) & 0xff,
ind.frameCounter! & 0xff,
(ind.frameCounter! >> 8) & 0xff,
(ind.frameCounter! >> 16) & 0xff,
(ind.frameCounter! >> 24) & 0xff,
ind.commandId!,
ind.commandFrameSize!,
].concat(ind.commandFrame!);

const payBuf = Buffer.from(gpFrame);
const gpdHeader = Buffer.alloc(15); // applicationId === IEEE_ADDRESS ? 20 : 15
gpdHeader.writeUInt8(0b00000001, 0); // frameControl: FrameType.SPECIFIC + Direction.CLIENT_TO_SERVER + disableDefaultResponse=false
gpdHeader.writeUInt8(ind.seqNr!, 1);
gpdHeader.writeUInt8(ind.id!, 2); // commandIdentifier
gpdHeader.writeUInt16LE(0, 3); // options, only srcID present
gpdHeader.writeUInt32LE(ind.srcId!, 5);
// omitted: gpdIEEEAddr (ieeeAddr)
// omitted: gpdEndpoint (uint8)
gpdHeader.writeUInt32LE(ind.frameCounter!, 9);
gpdHeader.writeUInt8(ind.commandId!, 13);
gpdHeader.writeUInt8(ind.commandFrameSize!, 14);

const payBuf = Buffer.concat([gpdHeader, ind.commandFrame!]);
const payload: Events.ZclPayload = {
header: Zcl.Header.fromBuffer(payBuf),
data: payBuf,
clusterID: ind.clusterId,
address: ind.srcId!,
endpoint: 242, // GP endpoint
linkquality: 127,
groupID: 0x0b84,
wasBroadcast: false,
destinationEndpoint: 1,
clusterID: Zcl.Clusters.greenPower.ID,
address: ind.srcId! & 0xffff,
endpoint: ZSpec.GP_ENDPOINT,
linkquality: 0xff, // bogus
groupID: ZSpec.GP_GROUP_ID,
wasBroadcast: true, // Take the codepath that doesn't require `gppNwkAddr` as its not present in the payload
destinationEndpoint: ZSpec.GP_ENDPOINT,
};

this.waitress.resolve(payload);
Expand Down
2 changes: 1 addition & 1 deletion src/adapter/deconz/driver/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ interface gpDataInd {
frameCounter?: number;
commandId?: number;
commandFrameSize?: number;
commandFrame?: number[];
commandFrame?: Buffer;
}

interface DataStateResponse {
Expand Down
18 changes: 2 additions & 16 deletions src/adapter/deconz/driver/frameParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -381,14 +381,7 @@ function parseGreenPowerDataIndication(view: DataView): object | null {
ind.frameCounter = view.getUint32(13, littleEndian);
ind.commandId = view.getUint8(17);
ind.commandFrameSize = view.byteLength - 18 - 6; // cut 18 from begin and 4 (sec mic) and 2 from end (cfc)

const payload = [];
let i = 0;
for (let u = 18; u < ind.commandFrameSize + 18; u++) {
payload[i] = view.getUint8(u);
i++;
}
ind.commandFrame = payload;
ind.commandFrame = Buffer.from(view.buffer.slice(18, ind.commandFrameSize + 18));
} else {
logger.debug('GP commissioning notification', NS);
ind.id = 0x04; // 0 = notification, 4 = commissioning
Expand All @@ -398,14 +391,7 @@ function parseGreenPowerDataIndication(view: DataView): object | null {
ind.frameCounter = view.getUint32(36, littleEndian);
ind.commandId = view.getUint8(12);
ind.commandFrameSize = view.byteLength - 13 - 2; // cut 13 from begin and 2 from end (cfc)

const payload = [];
let i = 0;
for (let u = 13; u < ind.commandFrameSize + 13; u++) {
payload[i] = view.getUint8(u);
i++;
}
ind.commandFrame = payload;
ind.commandFrame = Buffer.from(view.buffer.slice(13, ind.commandFrameSize + 13));
}

if (
Expand Down

0 comments on commit 4b99609

Please sign in to comment.