Skip to content

Commit

Permalink
Implement read for groups. Koenkk/zigbee2mqtt#4564
Browse files Browse the repository at this point in the history
  • Loading branch information
Koenkk committed Oct 6, 2020
1 parent e8a7ca5 commit ffc5ed3
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 0 deletions.
28 changes: 28 additions & 0 deletions src/controller/model/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,34 @@ class Group extends Entity {
}
}

public async read(
clusterKey: number | string, attributes: string[] | number [], options?: Options
): Promise<void> {
options = this.getOptionsWithDefaults(options, Zcl.Direction.CLIENT_TO_SERVER);
const cluster = Zcl.Utils.getCluster(clusterKey);
const payload: {attrId: number}[] = [];
for (const attribute of attributes) {
payload.push({attrId: typeof attribute === 'number' ? attribute : cluster.getAttribute(attribute).ID});
}

const frame = Zcl.ZclFrame.create(
Zcl.FrameType.GLOBAL, options.direction, true,
options.manufacturerCode, options.transactionSequenceNumber ?? ZclTransactionSequenceNumber.next(), 'read',
cluster.ID, payload, options.reservedBits
);

const log = `Read ${this.groupID} ${cluster.name}(${JSON.stringify(attributes)}, ${JSON.stringify(options)})`;
debug.info(log);

try {
await Entity.adapter.sendZclFrameToGroup(this.groupID, frame, options.srcEndpoint);
} catch (error) {
error.message = `${log} failed (${error.message})`;
debug.error(error.message);
throw error;
}
}

public async command(
clusterKey: number | string, commandKey: number | string, payload: KeyValue, options?: Options
): Promise<void> {
Expand Down
21 changes: 21 additions & 0 deletions test/controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2333,6 +2333,27 @@ describe('Controller', () => {
expect(deepClone(controller.getDeviceByIeeeAddr("0x90fd9ffffe4b64ae"))).toStrictEqual(expected);
});

it('Read from group', async () => {
await controller.start();
const group = await controller.createGroup(2);
await group.read('genBasic', ['modelId', 0x01], {});
expect(mocksendZclFrameToGroup).toBeCalledTimes(1);
expect(mocksendZclFrameToGroup.mock.calls[0][0]).toBe(2);
expect(deepClone(mocksendZclFrameToGroup.mock.calls[0][1])).toStrictEqual(deepClone(ZclFrame.create(Zcl.FrameType.GLOBAL, Zcl.Direction.CLIENT_TO_SERVER, true, null, 2, 'read', 0, [{"attrId": 5}, {"attrId": 1}])));
expect(mocksendZclFrameToGroup.mock.calls[0][2]).toBe(null);
});

it('Read from group fails', async () => {
await controller.start();
const group = await controller.createGroup(2);
mocksendZclFrameToGroup.mockRejectedValueOnce(new Error('timeout'));
let error;
try {
await group.read('genBasic', ['modelId', 0x01], {});
} catch (e) { error = e; }
expect(error).toStrictEqual(new Error(`Read 2 genBasic(["modelId",1], {"direction":0,"srcEndpoint":null,"reservedBits":0,"manufacturerCode":null,"transactionSequenceNumber":null}) failed (timeout)`));
});

it('Write to group', async () => {
await controller.start();
const group = await controller.createGroup(2);
Expand Down

0 comments on commit ffc5ed3

Please sign in to comment.