diff --git a/lib/extension/otaUpdate.js b/lib/extension/otaUpdate.js index 722fc967f..4508cf8de 100644 --- a/lib/extension/otaUpdate.js +++ b/lib/extension/otaUpdate.js @@ -1,7 +1,7 @@ const settings = require('../util/settings'); const logger = require('../util/logger'); const assert = require('assert'); -const topicRegex = new RegExp(`^${settings.get().mqtt.base_topic}/bridge/ota_update/.+$`); +const legacyTopicRegex = new RegExp(`^${settings.get().mqtt.base_topic}/bridge/ota_update/.+$`); const Extension = require('./extension'); const MINUTES_10 = 1000 * 60 * 10; @@ -10,11 +10,15 @@ class OTAUpdate extends Extension { super(zigbee, mqtt, state, publishEntityState, eventBus); this.inProgress = new Set(); this.lastChecked = {}; + this.legacyApi = settings.get().advanced.legacy_api; } onMQTTConnected() { - this.mqtt.subscribe(`${settings.get().mqtt.base_topic}/bridge/ota_update/check`); - this.mqtt.subscribe(`${settings.get().mqtt.base_topic}/bridge/ota_update/update`); + /* istanbul ignore else */ + if (this.legacyApi) { + this.mqtt.subscribe(`${settings.get().mqtt.base_topic}/bridge/ota_update/check`); + this.mqtt.subscribe(`${settings.get().mqtt.base_topic}/bridge/ota_update/update`); + } } async onZigbeeEvent(type, data, resolvedEntity) { @@ -73,19 +77,26 @@ class OTAUpdate extends Extension { } async onMQTTMessage(topic, message) { - if (!topic.match(topicRegex)) { + /* istanbul ignore else */ + let resolvedEntity = null; + if (this.legacyApi) { + if (!topic.match(legacyTopicRegex)) { + return null; + } + + resolvedEntity = this.zigbee.resolveEntity(message); + } else { return null; } - const device = this.zigbee.resolveEntity(message); - assert(device != null && device.type === 'device', 'Device not found or not a device'); - if (!device.definition || !device.definition.ota) { - const message = `Device '${device.name}' does not support OTA updates`; + assert(resolvedEntity != null && resolvedEntity.type === 'device', 'Device not found or not a device'); + if (!resolvedEntity.definition || !resolvedEntity.definition.ota) { + const message = `Device '${resolvedEntity.name}' does not support OTA updates`; logger.error(message); /* istanbul ignore else */ if (settings.get().advanced.legacy_api) { - const meta = {status: `not_supported`, device: device.name}; + const meta = {status: `not_supported`, device: resolvedEntity.name}; this.mqtt.publish( 'bridge/log', JSON.stringify({type: `ota_update`, message, meta}), @@ -95,20 +106,20 @@ class OTAUpdate extends Extension { return; } - if (this.inProgress.has(device.device.ieeeAddr)) { - logger.error(`Update or check already in progress for '${device.name}', skipping...`); + if (this.inProgress.has(resolvedEntity.device.ieeeAddr)) { + logger.error(`Update or check already in progress for '${resolvedEntity.name}', skipping...`); return; } - this.inProgress.add(device.device.ieeeAddr); + this.inProgress.add(resolvedEntity.device.ieeeAddr); const type = topic.substring(settings.get().mqtt.base_topic.length).split('/')[3]; if (type === 'check') { - const message = `Checking if update available for '${device.name}'`; + const message = `Checking if update available for '${resolvedEntity.name}'`; logger.info(message); /* istanbul ignore else */ if (settings.get().advanced.legacy_api) { - const meta = {status: `checking_if_available`, device: device.name}; + const meta = {status: `checking_if_available`, device: resolvedEntity.name}; this.mqtt.publish( 'bridge/log', JSON.stringify({type: `ota_update`, message, meta}), @@ -116,29 +127,28 @@ class OTAUpdate extends Extension { } try { - const available = await device.definition.ota.isUpdateAvailable(device.device, logger); - const message=(available ? - `Update available for '${device.name}'` : `No update available for '${device.name}'`); + const available = await resolvedEntity.definition.ota.isUpdateAvailable(resolvedEntity.device, logger); + const message = `${available ? 'Update' : 'No update'} available for '${resolvedEntity.name}'`; logger.info(message); /* istanbul ignore else */ if (settings.get().advanced.legacy_api) { - const meta = {status: available ? 'available' : 'not_available', device: device.name}; + const meta = {status: available ? 'available' : 'not_available', device: resolvedEntity.name}; this.mqtt.publish( 'bridge/log', JSON.stringify({type: `ota_update`, message, meta}), ); } - this.publishEntityState(device.device.ieeeAddr, {update_available: available}); - this.lastChecked[device.device.ieeeAddr] = Date.now(); + this.publishEntityState(resolvedEntity.device.ieeeAddr, {update_available: available}); + this.lastChecked[resolvedEntity.device.ieeeAddr] = Date.now(); } catch (error) { - const message = `Failed to check if update available for '${device.name}' (${error.message})`; + const message = `Failed to check if update available for '${resolvedEntity.name}' (${error.message})`; logger.error(message); /* istanbul ignore else */ if (settings.get().advanced.legacy_api) { - const meta = {status: `check_failed`, device: device.name}; + const meta = {status: `check_failed`, device: resolvedEntity.name}; this.mqtt.publish( 'bridge/log', JSON.stringify({type: `ota_update`, message, meta}), @@ -146,12 +156,12 @@ class OTAUpdate extends Extension { } } } else { // type === 'update' - const message = `Updating '${device.name}' to latest firmware`; + const message = `Updating '${resolvedEntity.name}' to latest firmware`; logger.info(message); /* istanbul ignore else */ if (settings.get().advanced.legacy_api) { - const meta = {status: `update_in_progress`, device: device.name}; + const meta = {status: `update_in_progress`, device: resolvedEntity.name}; this.mqtt.publish( 'bridge/log', JSON.stringify({type: `ota_update`, message, meta}), @@ -160,7 +170,7 @@ class OTAUpdate extends Extension { try { const onProgress = (progress, remaining) => { - let message = `Update of '${device.name}' at ${progress}%`; + let message = `Update of '${resolvedEntity.name}' at ${progress}%`; if (remaining) { message += `, +- ${Math.round(remaining / 60)} minutes remaining`; } @@ -169,37 +179,38 @@ class OTAUpdate extends Extension { /* istanbul ignore else */ if (settings.get().advanced.legacy_api) { - const meta = {status: `update_progress`, device: device.name, progress}; + const meta = {status: `update_progress`, device: resolvedEntity.name, progress}; this.mqtt.publish('bridge/log', JSON.stringify({type: `ota_update`, message, meta})); } }; - const from_ = await this.readSoftwareBuildIDAndDateCode(device.device, false); - await device.definition.ota.updateToLatest(device.device, logger, onProgress); - const to = await this.readSoftwareBuildIDAndDateCode(device.device, true); + const from_ = await this.readSoftwareBuildIDAndDateCode(resolvedEntity.device, false); + await resolvedEntity.definition.ota.updateToLatest(resolvedEntity.device, logger, onProgress); + const to = await this.readSoftwareBuildIDAndDateCode(resolvedEntity.device, true); const [fromS, toS] = [JSON.stringify(from_), JSON.stringify(to)]; - const message = `Finished update of '${device.name}'` + (to ? `, from '${fromS}' to '${toS}'` : ``); + const message = `Finished update of '${resolvedEntity.name}'` + + (to ? `, from '${fromS}' to '${toS}'` : ``); logger.info(message); - this.publishEntityState(device.device.ieeeAddr, {update_available: false}); + this.publishEntityState(resolvedEntity.device.ieeeAddr, {update_available: false}); /* istanbul ignore else */ if (settings.get().advanced.legacy_api) { - const meta = {status: `update_succeeded`, device: device.name, from: from_, to}; + const meta = {status: `update_succeeded`, device: resolvedEntity.name, from: from_, to}; this.mqtt.publish('bridge/log', JSON.stringify({type: `ota_update`, message, meta})); } } catch (error) { - const message = `Update of '${device.name}' failed (${error.message})`; + const message = `Update of '${resolvedEntity.name}' failed (${error.message})`; logger.error(message); /* istanbul ignore else */ if (settings.get().advanced.legacy_api) { - const meta = {status: `update_failed`, device: device.name}; + const meta = {status: `update_failed`, device: resolvedEntity.name}; this.mqtt.publish('bridge/log', JSON.stringify({type: `ota_update`, message, meta})); } } } - this.inProgress.delete(device.device.ieeeAddr); + this.inProgress.delete(resolvedEntity.device.ieeeAddr); } }