Skip to content

Commit

Permalink
fix: Fix Deconz Green power implementation Koenkk/zigbee2mqtt#23814
Browse files Browse the repository at this point in the history
  • Loading branch information
Koenkk committed Sep 5, 2024
1 parent 0e9228f commit 84b3029
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 33 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
4 changes: 2 additions & 2 deletions src/adapter/deconz/driver/frameParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ function parseGreenPowerDataIndication(view: DataView): object | null {
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 = [];
const payload = Buffer.alloc(ind.commandFrameSize);
let i = 0;
for (let u = 18; u < ind.commandFrameSize + 18; u++) {
payload[i] = view.getUint8(u);
Expand All @@ -399,7 +399,7 @@ function parseGreenPowerDataIndication(view: DataView): object | null {
ind.commandId = view.getUint8(12);
ind.commandFrameSize = view.byteLength - 13 - 2; // cut 13 from begin and 2 from end (cfc)

const payload = [];
const payload = Buffer.alloc(ind.commandFrameSize);
let i = 0;
for (let u = 13; u < ind.commandFrameSize + 13; u++) {
payload[i] = view.getUint8(u);
Expand Down

0 comments on commit 84b3029

Please sign in to comment.