mirror of
https://github.com/Koenkk/zigbee2mqtt.git
synced 2026-08-28 13:34:24 +00:00
Major OTA improvements. https://github.com/Koenkk/zigbee2mqtt/issues/2921
This commit is contained in:
@@ -1203,6 +1203,7 @@ const mapping = {
|
||||
'GP-LBU019BBAWU': [cfg.light_brightness],
|
||||
'371000001': [cfg.light_brightness_colortemp],
|
||||
'10011725': [cfg.light_brightness_colortemp_colorxy],
|
||||
'929002277501': [cfg.light_brightness],
|
||||
};
|
||||
|
||||
Object.keys(mapping).forEach((key) => {
|
||||
|
||||
+53
-14
@@ -5,11 +5,29 @@ const topicRegex = new RegExp(`^${settings.get().mqtt.base_topic}/bridge/ota_upd
|
||||
const BaseExtension = require('./baseExtension');
|
||||
|
||||
class OTAUpdate extends BaseExtension {
|
||||
constructor(zigbee, mqtt, state, publishEntityState, eventBus) {
|
||||
super(zigbee, mqtt, state, publishEntityState, eventBus);
|
||||
this.inProgress = new Set();
|
||||
}
|
||||
|
||||
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`);
|
||||
}
|
||||
|
||||
async readSoftwareBuildIDAndDateCode(device, update) {
|
||||
const endpoint = device.endpoints.find((e) => e.supportsInputCluster('genBasic'));
|
||||
const result = await endpoint.read('genBasic', ['dateCode', 'swBuildId']);
|
||||
|
||||
if (update) {
|
||||
device.softwareBuildID = result.swBuildId;
|
||||
device.dateCode = result.dateCode;
|
||||
device.save();
|
||||
}
|
||||
|
||||
return {softwareBuildID: result.swBuildId, dateCode: result.dateCode};
|
||||
}
|
||||
|
||||
async onMQTTMessage(topic, message) {
|
||||
if (!topic.match(topicRegex)) {
|
||||
return null;
|
||||
@@ -23,25 +41,46 @@ class OTAUpdate extends BaseExtension {
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info(`Checking if update available for '${device.name}'`);
|
||||
if (this.inProgress.has(device.device.ieeeAddr)) {
|
||||
logger.error(`Update or check already in progress for '${device.name}', skipping...`);
|
||||
return;
|
||||
}
|
||||
this.inProgress.add(device.device.ieeeAddr);
|
||||
|
||||
const updateAvailable = await device.mapped.ota.isUpdateAvailable(device.device, logger);
|
||||
const type = topic.split('/')[3];
|
||||
if (type === 'check') {
|
||||
logger.info(`Checking if update available for '${device.name}'`);
|
||||
try {
|
||||
const available = await device.mapped.ota.isUpdateAvailable(device.device, logger);
|
||||
logger.info(available ?
|
||||
`Update available for '${device.name}'` : `No update available for '${device.name}'`,
|
||||
);
|
||||
} catch (error) {
|
||||
logger.error(`Failed to check if update available for '${device.name}' (${error.message})`);
|
||||
}
|
||||
} else { // type === 'update'
|
||||
logger.info(`Updating '${device.name}' to latest firmware`);
|
||||
try {
|
||||
const onProgress = (progress, remaining) => {
|
||||
let message = `Update of '${device.name}' at ${progress}%`;
|
||||
if (remaining) {
|
||||
message += `, +- ${Math.round(remaining / 60)} minutes remaining`;
|
||||
}
|
||||
|
||||
if (updateAvailable) {
|
||||
logger.info(`Update available for '${device.name}'`);
|
||||
} else {
|
||||
const level = type === 'update' ? 'error' : 'info';
|
||||
logger[level](`No update available for '${device.name}'`);
|
||||
logger.info(message);
|
||||
};
|
||||
|
||||
const from_ = await this.readSoftwareBuildIDAndDateCode(device.device, false);
|
||||
await device.mapped.ota.updateToLatest(device.device, logger, onProgress);
|
||||
const to = await this.readSoftwareBuildIDAndDateCode(device.device, true);
|
||||
const [fromS, toS] = [JSON.stringify(from_), JSON.stringify(to)];
|
||||
logger.info(`Finished update of '${device.name}', from '${fromS}' to '${toS}'`);
|
||||
} catch (error) {
|
||||
logger.error(`Update of '${device.name}' failed (${error.message})`);
|
||||
}
|
||||
}
|
||||
|
||||
if (type === 'update' && updateAvailable) {
|
||||
logger.info(`Starting update of '${device.name}'`);
|
||||
const onProgress = (progress) => logger.info(`Update of '${device.name}' at ${progress}%`);
|
||||
const result = await device.mapped.ota.updateToLatest(device.device, logger, onProgress);
|
||||
const [from, to] = [JSON.stringify(result.from), JSON.stringify(result.to)];
|
||||
logger.info(`Finished update of '${device.name}', from '${from}' to '${to}'`);
|
||||
}
|
||||
this.inProgress.delete(device.device.ieeeAddr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user