Allow to specify endpoint via property. #2356

This commit is contained in:
Koen Kanters
2019-11-20 17:36:36 +01:00
parent ef16fcd505
commit fdc8fcc02b
2 changed files with 35 additions and 7 deletions
+22 -7
View File
@@ -124,7 +124,22 @@ class EntityPublish extends BaseExtension {
// For each attribute call the corresponding converter
const usedConverters = [];
for (const [key, value] of entries) {
for (let [key, value] of entries) {
let postfix = topic.postfix;
let actualTarget = target;
// When the key has a postfix included (e.g. state_right), this will override the target.
if (entity.type === 'device' && key.includes('_')) {
const underscoreIndex = key.lastIndexOf('_');
const possiblePostfix = key.substring(underscoreIndex + 1, key.length);
if (utils.getPostfixes().includes(possiblePostfix)) {
postfix = possiblePostfix;
key = key.substring(0, underscoreIndex);
const device = target.getDevice();
actualTarget = device.getEndpoint(mapped.endpoint(device)[postfix]);
}
}
const converter = converters.find((c) => c.key.includes(key));
if (usedConverters.includes(converter)) {
@@ -139,7 +154,7 @@ class EntityPublish extends BaseExtension {
// Converter didn't return a result, skip
const meta = {
endpoint_name: topic.postfix,
endpoint_name: postfix,
options,
message: json,
logger,
@@ -151,12 +166,12 @@ class EntityPublish extends BaseExtension {
try {
if (topic.type === 'set' && converter && converter.convertSet) {
logger.debug(`Publishing '${topic.type}' '${key}' to '${entity.name}'`);
const result = await converter.convertSet(target, key, value, meta);
const result = await converter.convertSet(actualTarget, key, value, meta);
if (result && result.hasOwnProperty('state')) {
const msg = result.state;
if (topic.postfix) {
msg[`state_${topic.postfix}`] = msg.state;
if (postfix) {
msg[`state_${postfix}`] = msg.state;
delete msg.state;
}
@@ -174,11 +189,11 @@ class EntityPublish extends BaseExtension {
entity.type === 'device' && result && result.hasOwnProperty('readAfterWriteTime') &&
entity.settings.retrieve_state
) {
setTimeout(() => converter.convertGet(target, key, meta), result.readAfterWriteTime);
setTimeout(() => converter.convertGet(actualTarget, key, meta), result.readAfterWriteTime);
}
} else if (topic.type === 'get' && converter && converter.convertGet) {
logger.debug(`Publishing get '${topic.type}' '${key}' to '${entity.name}'`);
await converter.convertGet(target, key, meta);
await converter.convertGet(actualTarget, key, meta);
} else {
logger.error(`No converter available for '${topic.type}' '${key}' (${json[key]})`);
continue;
+13
View File
@@ -168,6 +168,19 @@ describe('Entity publish', () => {
expect(MQTT.publish.mock.calls[0][2]).toStrictEqual({"qos": 0, "retain": false});
});
it('Should publish messages to zigbee devices to non default-ep with state_[EP]', async () => {
const device = zigbeeHerdsman.devices.QBKG03LM;
const endpoint = device.getEndpoint(3);
await MQTT.events.message('zigbee2mqtt/wall_switch_double/set', JSON.stringify({state_right: 'OFF'}));
await flushPromises();
expect(endpoint.command).toHaveBeenCalledTimes(1);
expect(endpoint.command).toHaveBeenCalledWith("genOnOff", "off", {}, {});
expect(MQTT.publish).toHaveBeenCalledTimes(1);
expect(MQTT.publish.mock.calls[0][0]).toStrictEqual('zigbee2mqtt/wall_switch_double');
expect(JSON.parse(MQTT.publish.mock.calls[0][1])).toStrictEqual({state_right: 'OFF'});
expect(MQTT.publish.mock.calls[0][2]).toStrictEqual({"qos": 0, "retain": false});
});
it('Should publish messages to zigbee devices with color xy', async () => {
const device = zigbeeHerdsman.devices.bulb_color;
const endpoint = device.getEndpoint(1);