diff --git a/lib/extension/devicePublish.js b/lib/extension/devicePublish.js index 69909b0e4..c8c309a25 100644 --- a/lib/extension/devicePublish.js +++ b/lib/extension/devicePublish.js @@ -131,8 +131,12 @@ class DevicePublish { delete json.state; } + // Ensure that state and brightness are executed before other commands. + const keys = Object.keys(json); + keys.sort((a, b) => (['state', 'brightness'].includes(a) ? -1 : 1)); + // For each key in the JSON message find the matching converter. - Object.keys(json).forEach((key) => { + keys.forEach((key) => { const converter = converters.find((c) => c.key.includes(key)); if (!converter) { logger.error(`No converter available for '${key}' (${json[key]})`); diff --git a/test/devicePublish.test.js b/test/devicePublish.test.js index 9836819a4..05cd7df82 100644 --- a/test/devicePublish.test.js +++ b/test/devicePublish.test.js @@ -399,4 +399,24 @@ describe('DevicePublish', () => { devicePublish.onMQTTMessage('zigbee2mqtt/0x12345678/set', JSON.stringify({state: 1})); chai.assert.isTrue(zigbee.publish.notCalled); }); + + it('Should set state before color', () => { + zigbee.publish.resetHistory(); + zigbee.getDevice = sinon.fake.returns({modelId: 'LCT001'}); + const msg = {'state': 'ON', 'color': {'x': 0.701, 'y': 0.299}}; + devicePublish.onMQTTMessage('zigbee2mqtt/0x12345678/set', JSON.stringify(msg)); + chai.assert.isTrue(zigbee.publish.calledTwice); + chai.assert.equal(zigbee.publish.getCall(0).args[2], 'genOnOff'); + chai.assert.equal(zigbee.publish.getCall(1).args[2], 'lightingColorCtrl'); + }); + + it('Should set state with brightness before color', () => { + zigbee.publish.resetHistory(); + zigbee.getDevice = sinon.fake.returns({modelId: 'LCT001'}); + const msg = {'state': 'ON', 'color': {'x': 0.701, 'y': 0.299}, 'transition': 3, 'brightness': 100}; + devicePublish.onMQTTMessage('zigbee2mqtt/0x12345678/set', JSON.stringify(msg)); + chai.assert.isTrue(zigbee.publish.calledTwice); + chai.assert.equal(zigbee.publish.getCall(0).args[2], 'genLevelCtrl'); + chai.assert.equal(zigbee.publish.getCall(1).args[2], 'lightingColorCtrl'); + }); });