From ad84374046f64dae4aa6be104749bf8e8c8c3e59 Mon Sep 17 00:00:00 2001 From: Jorge Schrauwen Date: Sun, 23 Jun 2024 11:24:03 +0200 Subject: [PATCH] fix: Fix OTA overriding custom software version attribute (#23129) * fix: OTA loses version info for develco/frient This fix is not perfect, as it will still print that it got updated from null to null. We just moved the reconfigure later, which will trigger this https://github.com/Koenkk/zigbee-herdsman-converters/blob/000041cba216822dab151151c493b560678da91a/src/devices/develco.ts#L36 for develco/frient devices that have it in their configure. (Which should be all of them) Of note though, ZCL marks both dateCode and swBuildId as optional attributes, so Develco/Frient returning UNSUPPORTED_ATTRIBUTE here is not outside of spec. Although I'm not sure there is a cleaner way to do this. * Update otaUpdate.test.js * Update otaUpdate.ts --------- Co-authored-by: Koen Kanters --- lib/extension/otaUpdate.ts | 6 +++++- test/otaUpdate.test.js | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/extension/otaUpdate.ts b/lib/extension/otaUpdate.ts index fd28e1e24..6fd360f48 100644 --- a/lib/extension/otaUpdate.ts +++ b/lib/extension/otaUpdate.ts @@ -271,7 +271,6 @@ export default class OTAUpdate extends Extension { const from_ = await this.readSoftwareBuildIDAndDateCode(device, 'immediate'); const fileVersion = await device.definition.ota.updateToLatest(device.zh, onProgress); logger.info(`Finished update of '${device.name}'`); - this.eventBus.emitReconfigure({device}); this.removeProgressAndRemainingFromState(device); const payload = this.getEntityPublishPayload(device, {available: false, currentFileVersion: fileVersion, otaFileVersion: fileVersion}); @@ -281,6 +280,11 @@ export default class OTAUpdate extends Extension { logger.info(`Device '${device.name}' was updated from '${fromS}' to '${toS}'`); responseData.from = from_ ? utils.toSnakeCase(from_) : null; responseData.to = to ? utils.toSnakeCase(to) : null; + /** + * Re-configure after reading software build ID and date code, some devices use a + * custom attribute for this (e.g. Develco SMSZB-120) + */ + this.eventBus.emitReconfigure({device}); this.eventBus.emitDevicesChanged(); /* istanbul ignore else */ diff --git a/test/otaUpdate.test.js b/test/otaUpdate.test.js index b49b709b0..320dcd6d7 100644 --- a/test/otaUpdate.test.js +++ b/test/otaUpdate.test.js @@ -87,7 +87,7 @@ describe('OTA update', () => { expect(logger.info).toHaveBeenCalledWith(`Update of 'bulb' at 0.00%`); expect(logger.info).toHaveBeenCalledWith(`Update of 'bulb' at 10.00%, ≈ 60 minutes remaining`); expect(logger.info).toHaveBeenCalledWith(`Finished update of 'bulb'`); - expect(logger.info).toHaveBeenCalledWith(`Device 'bulb' was updated from '{"dateCode":"20190101","softwareBuildID":1}' to '{"dateCode":"20190104","softwareBuildID":4}'`); + expect(logger.info).toHaveBeenCalledWith(`Device 'bulb' was updated from '{"dateCode":"20190101","softwareBuildID":1}' to '{"dateCode":"20190102","softwareBuildID":2}'`); expect(device.save).toHaveBeenCalledTimes(2); expect(endpoint.read).toHaveBeenCalledWith('genBasic', ['dateCode', 'swBuildId'], {'sendPolicy': 'immediate'}); expect(endpoint.read).toHaveBeenCalledWith('genBasic', ['dateCode', 'swBuildId'], {'sendPolicy': undefined}); @@ -108,7 +108,7 @@ describe('OTA update', () => { ); expect(MQTT.publish).toHaveBeenCalledWith( 'zigbee2mqtt/bridge/response/device/ota_update/update', - stringify({"data":{"from":{"date_code":"20190101","software_build_id":1},"id":"bulb","to":{"date_code":"20190104","software_build_id":4}},"status":"ok"}), + stringify({"data":{"from":{"date_code":"20190101","software_build_id":1},"id":"bulb","to":{"date_code":"20190102","software_build_id":2}},"status":"ok"}), {retain: false, qos: 0}, expect.any(Function) ); expect(MQTT.publish).toHaveBeenCalledWith( @@ -389,7 +389,7 @@ describe('OTA update', () => { expect(logger.info).toHaveBeenCalledWith(`Update of 'bulb' at 0.00%`); expect(logger.info).toHaveBeenCalledWith(`Update of 'bulb' at 10.00%, ≈ 60 minutes remaining`); expect(logger.info).toHaveBeenCalledWith(`Finished update of 'bulb'`); - expect(logger.info).toHaveBeenCalledWith(`Device 'bulb' was updated from '{"dateCode":"20190101","softwareBuildID":1}' to '{"dateCode":"20190104","softwareBuildID":4}'`); + expect(logger.info).toHaveBeenCalledWith(`Device 'bulb' was updated from '{"dateCode":"20190101","softwareBuildID":1}' to '{"dateCode":"20190102","softwareBuildID":2}'`); expect(logger.error).toHaveBeenCalledTimes(0); expect(device.save).toHaveBeenCalledTimes(2); expect(endpoint.read).toHaveBeenCalledWith('genBasic', ['dateCode', 'swBuildId'], {'sendPolicy': 'immediate'});