diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 8e31a6697..a968c4b70 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -14150,9 +14150,9 @@ } }, "zigbee-herdsman-converters": { - "version": "12.0.96", - "resolved": "https://registry.npmjs.org/zigbee-herdsman-converters/-/zigbee-herdsman-converters-12.0.96.tgz", - "integrity": "sha512-HX2SoIDDKv6XaEEbwf+HY/ZMa+V/QaT5XbALMOAeyL9EfEx54ZVaws23aEBIAKUWUpoctvImTWpVumsugb0qkg==", + "version": "12.0.97", + "resolved": "https://registry.npmjs.org/zigbee-herdsman-converters/-/zigbee-herdsman-converters-12.0.97.tgz", + "integrity": "sha512-xCSKijGogHevCrPLbGhpAPYsFAIUTRR3g7BEynCt/RGpxzCcoVkqGadk3yXYafWAiXigD41NezOdZN+e64k2IA==", "requires": { "axios": "*", "https-proxy-agent": "*", diff --git a/package.json b/package.json index 12cb66c23..3950106b0 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "semver": "*", "winston": "*", "zigbee-herdsman": "0.12.90", - "zigbee-herdsman-converters": "12.0.96" + "zigbee-herdsman-converters": "12.0.97" }, "devDependencies": { "eslint": "*", diff --git a/test/group.test.js b/test/group.test.js index e59671640..147b28a4a 100644 --- a/test/group.test.js +++ b/test/group.test.js @@ -1,6 +1,7 @@ const data = require('./stub/data'); const logger = require('./stub/logger'); const zigbeeHerdsman = require('./stub/zigbeeHerdsman'); +const zigbeeHerdsmanConverters = require('zigbee-herdsman-converters'); zigbeeHerdsman.returnDevices.push('0x00124b00120144ae'); zigbeeHerdsman.returnDevices.push('0x000b57fffec6a5b3'); zigbeeHerdsman.returnDevices.push('0x000b57fffec6a5b2'); @@ -20,6 +21,7 @@ describe('Groups', () => { data.writeDefaultConfiguration(); settings._reRead(); MQTT.publish.mockClear(); + zigbeeHerdsmanConverters.toZigbeeConverters.__clearStore__(); }) it('Apply group updates add', async () => { @@ -375,7 +377,7 @@ describe('Groups', () => { await MQTT.events.message('zigbee2mqtt/bulb_color/set', JSON.stringify({state: 'OFF'})); await flushPromises(); expect(MQTT.publish).toHaveBeenCalledTimes(1); - expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb_color", '{"state":"OFF"}', {"retain": false, qos: 0}, expect.any(Function)); + expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb_color", '{"state":"OFF","brightness":0}', {"retain": false, qos: 0}, expect.any(Function)); }); it('Should not publish state change off if any lights within are still on when changed via shared group', async () => { @@ -400,8 +402,8 @@ describe('Groups', () => { await MQTT.events.message('zigbee2mqtt/group_2/set', JSON.stringify({state: 'OFF'})); await flushPromises(); expect(MQTT.publish).toHaveBeenCalledTimes(2); - expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/group_2", '{"state":"OFF"}', {"retain": false, qos: 0}, expect.any(Function)); - expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb_color", '{"state":"OFF"}', {"retain": false, qos: 0}, expect.any(Function)); + expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/group_2", '{"state":"OFF","brightness":0}', {"retain": false, qos: 0}, expect.any(Function)); + expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb_color", '{"state":"OFF","brightness":0}', {"retain": false, qos: 0}, expect.any(Function)); }); it('Should publish state change off if all lights within turn off', async () => { @@ -426,9 +428,9 @@ describe('Groups', () => { await MQTT.events.message('zigbee2mqtt/bulb/set', JSON.stringify({state: 'OFF'})); await flushPromises(); expect(MQTT.publish).toHaveBeenCalledTimes(3); - expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb_color", '{"state":"OFF"}', {"retain": false, qos: 0}, expect.any(Function)); - expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb", '{"state":"OFF"}', {"retain": true, qos: 0}, expect.any(Function)); - expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/group_1", '{"state":"OFF"}', {"retain": false, qos: 0}, expect.any(Function)); + expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb_color", '{"state":"OFF","brightness":0}', {"retain": false, qos: 0}, expect.any(Function)); + expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb", '{"state":"OFF","brightness":0}', {"retain": true, qos: 0}, expect.any(Function)); + expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/group_1", '{"state":"OFF","brightness":0}', {"retain": false, qos: 0}, expect.any(Function)); }); it('Should publish state change off even when missing current state', async () => { @@ -454,7 +456,7 @@ describe('Groups', () => { await flushPromises(); expect(MQTT.publish).toHaveBeenCalledTimes(2); - expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb_color", '{"state":"OFF"}', {"retain": false, qos: 0}, expect.any(Function)); - expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/group_1", '{"state":"OFF"}', {"retain": false, qos: 0}, expect.any(Function)); + expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb_color", '{"state":"OFF","brightness":0}', {"retain": false, qos: 0}, expect.any(Function)); + expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/group_1", '{"state":"OFF","brightness":0}', {"retain": false, qos: 0}, expect.any(Function)); }); }); \ No newline at end of file diff --git a/test/publish.test.js b/test/publish.test.js index b5c4748b7..ee53ebe0d 100644 --- a/test/publish.test.js +++ b/test/publish.test.js @@ -259,7 +259,7 @@ describe('Publish', () => { expect(JSON.parse(MQTT.publish.mock.calls[0][1])).toStrictEqual({color: {x: 100, y: 50}, color_temp: 62}); expect(MQTT.publish.mock.calls[0][2]).toStrictEqual({"qos": 0, "retain": false}); expect(MQTT.publish.mock.calls[1][0]).toStrictEqual('zigbee2mqtt/bulb_color'); - expect(JSON.parse(MQTT.publish.mock.calls[1][1])).toStrictEqual({color: {x: 100, y: 50}, color_temp: 62, state: 'OFF'}); + expect(JSON.parse(MQTT.publish.mock.calls[1][1])).toStrictEqual({color: {x: 100, y: 50}, color_temp: 62, state: 'OFF', brightness: 0}); expect(MQTT.publish.mock.calls[1][2]).toStrictEqual({"qos": 0, "retain": false}); }); @@ -340,7 +340,7 @@ describe('Publish', () => { expect(group.command).toHaveBeenCalledWith("genOnOff", "off", {}, {}); expect(MQTT.publish).toHaveBeenCalledTimes(1); expect(MQTT.publish.mock.calls[0][0]).toStrictEqual('zigbee2mqtt/group_1'); - expect(JSON.parse(MQTT.publish.mock.calls[0][1])).toStrictEqual({state: 'OFF'}); + expect(JSON.parse(MQTT.publish.mock.calls[0][1])).toStrictEqual({state: 'OFF', brightness: 0}); }); it('Should publish messages to groups color', async () => { @@ -686,11 +686,20 @@ describe('Publish', () => { it('Should turn device off when brightness 0 is send', async () => { const device = zigbeeHerdsman.devices.bulb_color; const endpoint = device.getEndpoint(1); - const payload = {'brightness': 0}; - await MQTT.events.message('zigbee2mqtt/bulb_color/set', JSON.stringify(payload)); + await MQTT.events.message('zigbee2mqtt/bulb_color/set', JSON.stringify({brightness: 50, state: 'ON'})); await flushPromises(); - expect(endpoint.command).toHaveBeenCalledTimes(1); - expect(endpoint.command.mock.calls[0]).toEqual(["genOnOff", "off", {}, {}]); + await MQTT.events.message('zigbee2mqtt/bulb_color/set', JSON.stringify({brightness: 0})); + await flushPromises(); + await MQTT.events.message('zigbee2mqtt/bulb_color/set', JSON.stringify({state: 'ON'})); + await flushPromises(); + expect(endpoint.command).toHaveBeenCalledTimes(3); + expect(endpoint.command.mock.calls[0]).toEqual(["genLevelCtrl", "moveToLevelWithOnOff", {level: 50, transtime: 0}, {}]); + expect(endpoint.command.mock.calls[1]).toEqual(["genOnOff", "off", {}, {}]); + expect(endpoint.command.mock.calls[2]).toEqual(["genOnOff", "on", {}, {}]); + expect(MQTT.publish).toHaveBeenCalledTimes(3); + expect(MQTT.publish.mock.calls[0]).toEqual(["zigbee2mqtt/bulb_color", JSON.stringify({state: 'ON', brightness: 50}), {"qos": 0, "retain": false}, expect.any(Function)]); + expect(MQTT.publish.mock.calls[1]).toEqual(["zigbee2mqtt/bulb_color", JSON.stringify({state: 'OFF', brightness: 0}), {"qos": 0, "retain": false}, expect.any(Function)]); + expect(MQTT.publish.mock.calls[2]).toEqual(["zigbee2mqtt/bulb_color", JSON.stringify({state: 'ON', brightness: 50}), {"qos": 0, "retain": false}, expect.any(Function)]); }); it('Should turn device off when brightness 0 is send with light_brightness converter', async () => { @@ -786,7 +795,7 @@ describe('Publish', () => { expect(endpoint.command.mock.calls[0]).toEqual(["genLevelCtrl", "moveToLevelWithOnOff", {level: 0, transtime: 10}, {}]); expect(MQTT.publish).toHaveBeenCalledTimes(1); expect(MQTT.publish.mock.calls[0][0]).toStrictEqual('zigbee2mqtt/bulb_color'); - expect(JSON.parse(MQTT.publish.mock.calls[0][1])).toStrictEqual({state: 'OFF'}); + expect(JSON.parse(MQTT.publish.mock.calls[0][1])).toStrictEqual({state: 'OFF', brightness: 0}); }); it('When device is turned off and on with transition with report enabled it should restore correct brightness', async () => { @@ -804,7 +813,7 @@ describe('Publish', () => { expect(endpoint.command).toHaveBeenCalledTimes(1); expect(endpoint.command.mock.calls[0]).toEqual(["genLevelCtrl", "moveToLevelWithOnOff", {level: 0, transtime: 30}, {}]); expect(MQTT.publish).toHaveBeenCalledTimes(1); - expect(MQTT.publish.mock.calls[0]).toEqual(["zigbee2mqtt/bulb_color", JSON.stringify({state: 'OFF', brightness: 200}), {"qos": 0, "retain": false}, expect.any(Function)]); + expect(MQTT.publish.mock.calls[0]).toEqual(["zigbee2mqtt/bulb_color", JSON.stringify({state: 'OFF', brightness: 0}), {"qos": 0, "retain": false}, expect.any(Function)]); // Bulb reports brightness while decreasing brightness await zigbeeHerdsman.events.message({data: {currentLevel: 1}, cluster: 'genLevelCtrl', device, endpoint, type: 'attributeReport', linkquality: 10}); @@ -836,7 +845,7 @@ describe('Publish', () => { expect(endpoint.command).toHaveBeenCalledTimes(1); expect(endpoint.command.mock.calls[0]).toEqual(["genLevelCtrl", "moveToLevelWithOnOff", {level: 0, transtime: 30}, {}]); expect(MQTT.publish).toHaveBeenCalledTimes(1); - expect(MQTT.publish.mock.calls[0]).toEqual(["zigbee2mqtt/bulb_color", JSON.stringify({state: 'OFF', brightness: 200}), {"qos": 0, "retain": false}, expect.any(Function)]); + expect(MQTT.publish.mock.calls[0]).toEqual(["zigbee2mqtt/bulb_color", JSON.stringify({state: 'OFF', brightness: 0}), {"qos": 0, "retain": false}, expect.any(Function)]); // Turn on again await MQTT.events.message('zigbee2mqtt/bulb_color/set', JSON.stringify({state: 'ON'})); @@ -929,7 +938,7 @@ describe('Publish', () => { expect(endpoint.command).toHaveBeenCalledTimes(3); expect(MQTT.publish).toHaveBeenCalledTimes(2); expect(MQTT.publish.mock.calls[1][0]).toStrictEqual('zigbee2mqtt/bulb_color'); - expect(JSON.parse(MQTT.publish.mock.calls[1][1])).toStrictEqual({state: 'ON'}); + expect(JSON.parse(MQTT.publish.mock.calls[1][1])).toStrictEqual({state: 'ON', brightness: 0}); expect(MQTT.publish.mock.calls[1][2]).toStrictEqual({"qos": 0, "retain": false}); }); @@ -942,7 +951,7 @@ describe('Publish', () => { expect(endpoint.command).toHaveBeenCalledWith("genOnOff", "off", {}, {disableDefaultResponse: true}); expect(MQTT.publish).toHaveBeenCalledTimes(1); expect(MQTT.publish.mock.calls[0][0]).toStrictEqual('zigbee2mqtt/led_controller_1'); - expect(JSON.parse(MQTT.publish.mock.calls[0][1])).toStrictEqual({state: 'OFF'}); + expect(JSON.parse(MQTT.publish.mock.calls[0][1])).toStrictEqual({state: 'OFF', brightness: 0}); expect(MQTT.publish.mock.calls[0][2]).toStrictEqual({"qos": 0, "retain": false}); }); @@ -1119,7 +1128,7 @@ describe('Publish', () => { expect(MQTT.publish).toHaveBeenCalledTimes(4); expect(MQTT.publish.mock.calls[0]).toEqual([ 'zigbee2mqtt/bulb_color', '{"state":"ON"}', { qos: 0, retain: false }, expect.any(Function)]); expect(MQTT.publish.mock.calls[1]).toEqual([ 'zigbee2mqtt/bulb_color', '{"state":"ON","brightness":150}', { qos: 0, retain: false }, expect.any(Function)]); - expect(MQTT.publish.mock.calls[2]).toEqual([ 'zigbee2mqtt/bulb_color', '{"state":"OFF","brightness":150}', { qos: 0, retain: false }, expect.any(Function)]); + expect(MQTT.publish.mock.calls[2]).toEqual([ 'zigbee2mqtt/bulb_color', '{"state":"OFF","brightness":0}', { qos: 0, retain: false }, expect.any(Function)]); expect(MQTT.publish.mock.calls[3]).toEqual([ 'zigbee2mqtt/bulb_color', '{"state":"ON","brightness":150}', { qos: 0, retain: false }, expect.any(Function)]); }); });