mirror of
https://github.com/Koenkk/zigbee2mqtt.git
synced 2026-08-23 19:19:52 +00:00
Iterate objects recursively and support array output (#1573)
* Iterate objects recursively and support array output * Fix eslint errors * Improve array handling and expand related test * Improve tests and array support, add special case for color attributes
This commit is contained in:
+27
-10
@@ -248,19 +248,36 @@ class Controller {
|
||||
if (settings.get().experimental.output === 'json') {
|
||||
this.mqtt.publish(entity.friendlyName, JSON.stringify(messagePayload), options);
|
||||
} else if (settings.get().experimental.output === 'attribute') {
|
||||
Object.keys(messagePayload).forEach((key) => {
|
||||
if (typeof messagePayload[key] == 'object') {
|
||||
Object.keys(messagePayload[key]).forEach((subKey) => {
|
||||
this.mqtt.publish(`${entity.friendlyName}/${key}-${subKey}`,
|
||||
`${messagePayload[key][subKey]}`, options);
|
||||
});
|
||||
} else {
|
||||
this.mqtt.publish(`${entity.friendlyName}/${key}`, `${messagePayload[key]}`, options);
|
||||
}
|
||||
});
|
||||
this.iteratePayloadForAttrOutput(entity.friendlyName+'/', messagePayload, options);
|
||||
}
|
||||
}
|
||||
|
||||
iteratePayloadForAttrOutput(topicRoot, payload, options) {
|
||||
Object.keys(payload).forEach((key) => {
|
||||
let subPayload = payload[key];
|
||||
let message;
|
||||
|
||||
// Special cases
|
||||
if (key === 'color' &&
|
||||
subPayload.r !== undefined &&
|
||||
subPayload.g !== undefined &&
|
||||
subPayload.b !== undefined) {
|
||||
subPayload = [subPayload.r, subPayload.g, subPayload.b];
|
||||
}
|
||||
|
||||
// Check Array first, since it is also an Object
|
||||
if (Array.isArray(subPayload)) {
|
||||
message = subPayload.map((x) => `${x}`).join(',');
|
||||
} else if (typeof subPayload === 'object') {
|
||||
return this.iteratePayloadForAttrOutput(topicRoot+key+'-', subPayload, options);
|
||||
} else {
|
||||
message = typeof subPayload === 'string' ? subPayload : JSON.stringify(subPayload);
|
||||
}
|
||||
|
||||
this.mqtt.publish(`${topicRoot}${key}`, message, options);
|
||||
});
|
||||
}
|
||||
|
||||
getDeviceInfoForMqtt(ieeeAddr) {
|
||||
const device = this.zigbee.getDevice(ieeeAddr);
|
||||
const {
|
||||
|
||||
+20
-6
@@ -91,13 +91,27 @@ describe('Controller', () => {
|
||||
},
|
||||
});
|
||||
|
||||
const payload = {temperature: 1, humidity: 2};
|
||||
const payload = {
|
||||
temperature: 1,
|
||||
humidity: 2,
|
||||
state: 'ON',
|
||||
allowedStates: ['ON', 'OFF'],
|
||||
color: {r: 100, g: 0, b: 102, a: 0},
|
||||
nested: {
|
||||
state: 'OFF',
|
||||
color: {r: 1, g: 0, b: 2},
|
||||
},
|
||||
};
|
||||
controller.publishEntityState('0x12345678', payload);
|
||||
expect(mqttPublish).toHaveBeenCalledTimes(2);
|
||||
expect(mqttPublish.mock.calls[0][0]).toBe('test/temperature');
|
||||
expect(mqttPublish.mock.calls[0][1]).toBe('1');
|
||||
expect(mqttPublish.mock.calls[1][0]).toBe('test/humidity');
|
||||
expect(mqttPublish.mock.calls[1][1]).toBe('2');
|
||||
expect(mqttPublish.mock.calls.map((x) => [x[0], x[1]])).toEqual([
|
||||
['test/temperature', '1'],
|
||||
['test/humidity', '2'],
|
||||
['test/state', 'ON'],
|
||||
['test/allowedStates', 'ON,OFF'],
|
||||
['test/color', '100,0,102'],
|
||||
['test/nested-state', 'OFF'],
|
||||
['test/nested-color', '1,0,2'],
|
||||
]);
|
||||
});
|
||||
|
||||
it('Should cache state', () => {
|
||||
|
||||
Reference in New Issue
Block a user