diff --git a/lib/eventBus.ts b/lib/eventBus.ts index 027106c277..13110547c9 100644 --- a/lib/eventBus.ts +++ b/lib/eventBus.ts @@ -196,6 +196,11 @@ export default class EventBus { this.on('stateChange', callback, key); } + public emitExposesAndDevicesChanged(device: Device): void { + this.emitDevicesChanged(); + this.emitExposesChanged({device}); + } + private on(event: K, callback: EventBusListener, key: ListenerKey): void { if (!this.callbacksByExtension[key.constructor.name]) { this.callbacksByExtension[key.constructor.name] = []; diff --git a/lib/extension/onEvent.ts b/lib/extension/onEvent.ts index f666195d91..53d6a34f09 100644 --- a/lib/extension/onEvent.ts +++ b/lib/extension/onEvent.ts @@ -41,11 +41,13 @@ export default class OnEvent extends Extension { private async callOnEvent(device: Device, type: zhc.OnEventType, data: KeyValue): Promise { if (device.options.disabled) return; const state = this.state.get(device); - await zhc.onEvent(type, data, device.zh); + const deviceExposesChanged = (): void => this.eventBus.emitExposesAndDevicesChanged(data.device); + + await zhc.onEvent(type, data, device.zh, {deviceExposesChanged}); if (device.definition?.onEvent) { const options: KeyValue = device.options; - await device.definition.onEvent(type, data, device.zh, options, state); + await device.definition.onEvent(type, data, device.zh, options, state, {deviceExposesChanged}); } } } diff --git a/lib/extension/receive.ts b/lib/extension/receive.ts index 2d8dc23a3a..5cb3584e86 100755 --- a/lib/extension/receive.ts +++ b/lib/extension/receive.ts @@ -156,12 +156,12 @@ export default class Receive extends Extension { } }; - const deviceExposesChanged = (): void => { - this.eventBus.emitDevicesChanged(); - this.eventBus.emitExposesChanged({device: data.device}); + const meta = { + device: data.device.zh, + logger, + state: this.state.get(data.device), + deviceExposesChanged: (): void => this.eventBus.emitExposesAndDevicesChanged(data.device), }; - - const meta = {device: data.device.zh, logger, state: this.state.get(data.device), deviceExposesChanged: deviceExposesChanged}; let payload: KeyValue = {}; for (const converter of converters) { try { diff --git a/package-lock.json b/package-lock.json index dcf4507323..9e3e94c7d5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,7 @@ "winston-transport": "^4.9.0", "ws": "^8.18.0", "zigbee-herdsman": "2.1.9", - "zigbee-herdsman-converters": "20.52.0", + "zigbee-herdsman-converters": "20.53.0", "zigbee2mqtt-frontend": "0.7.5" }, "bin": { @@ -8582,9 +8582,9 @@ } }, "node_modules/zigbee-herdsman-converters": { - "version": "20.52.0", - "resolved": "https://registry.npmjs.org/zigbee-herdsman-converters/-/zigbee-herdsman-converters-20.52.0.tgz", - "integrity": "sha512-H4ESvxAfuHSSeFycwl0iA7d+GL+wKxjiZacKEo9DdBm5vN9S43FBhHl4wRDy/paW9rmU1XRqiG/fzB2vjBUoSg==", + "version": "20.53.0", + "resolved": "https://registry.npmjs.org/zigbee-herdsman-converters/-/zigbee-herdsman-converters-20.53.0.tgz", + "integrity": "sha512-Hk+15guAGmFozWMBs+vncoGh34kjNfIaFWg8LMuafTaXPqGLPpWco3NQqT/GHgXiDu/wolKZi4y/6J5JdO8s3g==", "license": "MIT", "dependencies": { "axios": "^1.7.7", @@ -8594,7 +8594,7 @@ "semver": "^7.6.3", "tar-stream": "^3.1.7", "uri-js": "^4.4.1", - "zigbee-herdsman": "^2.1.7" + "zigbee-herdsman": "^2.1.9" } }, "node_modules/zigbee2mqtt-frontend": { diff --git a/package.json b/package.json index 8ccff0ad11..6a7ae029b4 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "winston-transport": "^4.9.0", "ws": "^8.18.0", "zigbee-herdsman": "2.1.9", - "zigbee-herdsman-converters": "20.52.0", + "zigbee-herdsman-converters": "20.53.0", "zigbee2mqtt-frontend": "0.7.5" }, "devDependencies": { diff --git a/test/onEvent.test.js b/test/onEvent.test.js index 66385f9797..b84dbccfde 100644 --- a/test/onEvent.test.js +++ b/test/onEvent.test.js @@ -67,7 +67,21 @@ describe('On event', () => { await zigbeeHerdsman.events.deviceAnnounce({device}); await flushPromises(); expect(mockOnEvent).toHaveBeenCalledTimes(1); - expect(mockOnEvent).toHaveBeenCalledWith('deviceAnnounce', {device}, device, settings.getDevice(device.ieeeAddr), {}); + expect(mockOnEvent).toHaveBeenCalledWith( + 'deviceAnnounce', + {device}, + device, + settings.getDevice(device.ieeeAddr), + {}, + { + deviceExposesChanged: expect.any(Function), + }, + ); + + // Test deviceExposesChanged + MQTT.publish.mockClear(); + console.log(mockOnEvent.mock.calls[0][5].deviceExposesChanged()); + expect(MQTT.publish.mock.calls[0][0]).toStrictEqual('zigbee2mqtt/bridge/devices'); }); it('Should call index onEvent with zigbee event', async () => { @@ -75,6 +89,8 @@ describe('On event', () => { await zigbeeHerdsman.events.deviceAnnounce({device}); await flushPromises(); expect(zigbeeHerdsmanConverters.onEvent).toHaveBeenCalledTimes(1); - expect(zigbeeHerdsmanConverters.onEvent).toHaveBeenCalledWith('deviceAnnounce', {device}, device); + expect(zigbeeHerdsmanConverters.onEvent).toHaveBeenCalledWith('deviceAnnounce', {device}, device, { + deviceExposesChanged: expect.any(Function), + }); }); });