Skip to content

Commit 9c37b64

Browse files
authored
feat: add ability to abort OTA (#572)
* feat: add ability to abort OTA * fix: update z2m
1 parent cf4049c commit 9c37b64

34 files changed

Lines changed: 252 additions & 105 deletions

mocks/ws.ts

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export function startServer() {
4040
});
4141

4242
wss.on("connection", (ws) => {
43+
const otaUpdates = new Map<string, NodeJS.Timeout>();
4344
const bridgeInfo = merge({}, BRIDGE_INFO);
4445
bridgeInfo.payload.commit = randomString(8);
4546
bridgeInfo.payload.config.advanced.log_output = Math.random() < 0.25 ? ["syslog"] : Math.random() < 0.5 ? ["console", "file"] : ["console"];
@@ -260,6 +261,8 @@ export function startServer() {
260261
state: "updating",
261262
installed_version: 1,
262263
latest_version: 2,
264+
latest_source: null,
265+
latest_release_notes: null,
263266
};
264267

265268
const interval = setInterval(() => {
@@ -269,21 +272,57 @@ export function startServer() {
269272
updatedDeviceState.payload.update!.remaining! -= 1;
270273
}, 1000);
271274

275+
otaUpdates.set(msg.payload.id, interval);
272276
setTimeout(() => {
273277
clearInterval(interval);
274278
}, 25000);
275279
}
276280

277281
break;
278282
}
283+
case "bridge/request/device/ota_update/update/abort": {
284+
const otaUpdate = otaUpdates.get(msg.payload.id);
285+
286+
if (otaUpdate) {
287+
clearInterval(otaUpdate);
288+
}
289+
290+
sendResponseOK();
291+
292+
const updatedDeviceState = cloneDeviceState(msg.payload.id);
293+
294+
if (updatedDeviceState) {
295+
if (!updatedDeviceState.payload.update) {
296+
updatedDeviceState.payload.update = {
297+
state: "available",
298+
installed_version: 1,
299+
latest_version: 2,
300+
latest_source: null,
301+
latest_release_notes: null,
302+
};
303+
} else if (updatedDeviceState.payload.update?.state === "updating") {
304+
updatedDeviceState.payload.update.state = "available"; // simpler
305+
}
306+
307+
ws.send(JSON.stringify(updatedDeviceState));
308+
}
309+
310+
break;
311+
}
279312
case "bridge/request/device/ota_update/schedule": {
280313
sendResponseOK();
281314

282315
const updatedDeviceState = cloneDeviceState(msg.payload.id);
283316

284317
if (updatedDeviceState) {
285318
if (!updatedDeviceState.payload.update) {
286-
updatedDeviceState.payload.update = { state: "scheduled", installed_version: null, latest_version: null };
319+
updatedDeviceState.payload.update = {
320+
state: "scheduled",
321+
installed_version: null,
322+
latest_version: null,
323+
latest_source: null,
324+
latest_release_notes: null,
325+
};
287326
} else {
288327
updatedDeviceState.payload.update.state = "scheduled";
289328
}
@@ -300,7 +339,13 @@ export function startServer() {
300339

301340
if (updatedDeviceState) {
302341
if (!updatedDeviceState.payload.update) {
303-
updatedDeviceState.payload.update = { state: "idle", installed_version: null, latest_version: null };
342+
updatedDeviceState.payload.update = {
343+
state: "idle",
344+
installed_version: null,
345+
latest_version: null,
346+
latest_source: null,
347+
latest_release_notes: null,
348+
};
304349
} else if (updatedDeviceState.payload.update?.state === "scheduled") {
305350
updatedDeviceState.payload.update.state = "idle"; // simpler
306351
}

package-lock.json

Lines changed: 14 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "zigbee2mqtt-windfront",
3-
"version": "2.11.4",
3+
"version": "2.12.0",
44
"license": "GPL-3.0-or-later",
55
"type": "module",
66
"main": "./index.js",

src/components/ota-page/OtaControlGroup.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ const OtaControlGroup = memo(
306306
sourceHexRef.current.value = "";
307307
}
308308
}}
309-
className="btn btn-square btn-outline btn-warning btn-primary join-item"
309+
className="btn btn-square btn-outline btn-warning btn-primary join-item tooltip-left"
310310
disabled={!sourceHex}
311311
title={t(($) => $.clear, { ns: "common" })}
312312
>
@@ -338,7 +338,7 @@ const OtaControlGroup = memo(
338338
</div>
339339
<div className="card-actions justify-end py-2">
340340
<Button
341-
className="btn btn-square btn-outline btn-primary join-item"
341+
className="btn btn-square btn-outline btn-primary join-item tooltip-left"
342342
onClick={handleAction}
343343
item="check"
344344
title={t(($) => $.check)}
@@ -347,7 +347,7 @@ const OtaControlGroup = memo(
347347
<FontAwesomeIcon icon={faCloudArrowDown} />
348348
</Button>
349349
<Button
350-
className="btn btn-square btn-outline btn-error join-item"
350+
className="btn btn-square btn-outline btn-error join-item tooltip-left"
351351
onClick={handleAction}
352352
item="update"
353353
title={t(($) => $.update)}
@@ -356,7 +356,7 @@ const OtaControlGroup = memo(
356356
<FontAwesomeIcon icon={faUpload} />
357357
</Button>
358358
<Button
359-
className="btn btn-square btn-outline btn-info join-item"
359+
className="btn btn-square btn-outline btn-info join-item tooltip-left"
360360
onClick={handleAction}
361361
item="schedule"
362362
title={t(($) => $.schedule)}

src/components/ota-page/OtaUpdateButton.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,15 +183,15 @@ const OtaUpdateButton = memo(({ sourceIdx, device, state, otaSettings, onUpdateC
183183
</div>
184184
<div className="card-actions justify-end py-2">
185185
<Button
186-
className="btn btn-square btn-outline btn-error join-item"
186+
className="btn btn-square btn-outline btn-error join-item tooltip-left"
187187
onClick={handleAction}
188188
item="update"
189189
title={t(($) => $.update)}
190190
>
191191
<FontAwesomeIcon icon={faUpload} />
192192
</Button>
193193
<Button
194-
className="btn btn-square btn-outline btn-info join-item"
194+
className="btn btn-square btn-outline btn-info join-item tooltip-left"
195195
onClick={handleAction}
196196
item="schedule"
197197
title={t(($) => $.schedule)}

src/components/ota-page/OtaUpdating.tsx

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/components/ota-page/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ export type OnUnscheduleClickPayload = {
1919
sourceIdx: number;
2020
ieee: string;
2121
} & Omit<Zigbee2MQTTAPI["bridge/request/device/ota_update/unschedule"], "id">;
22+
export type OnAbortClickPayload = {
23+
sourceIdx: number;
24+
ieee: string;
25+
} & Omit<Zigbee2MQTTAPI["bridge/request/device/ota_update/update/abort"], "id">;
2226

2327
export type OtaImageHeader = {
2428
otaUpgradeFileIdentifier: Uint8Array;

src/i18n/locales/bg.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,8 @@
310310
"update": "Обнови фърмуер",
311311
"update_selected": "Обнови избраните",
312312
"update_selected_info": "OTA натоварва мрежата силно – уверете се, че е стабилно.",
313-
"updating": "Актуализира се"
313+
"updating": "Актуализира се",
314+
"abort": "Abort"
314315
},
315316
"scene": {
316317
"add_update_header": "Добавяне/обновяване сцена",
@@ -482,7 +483,10 @@
482483
"serial-baudrate": "Baudrate",
483484
"serial-disable_led": "Изключи LED",
484485
"serial-port": "Порт (null авто)",
485-
"serial-rtscts": "RTS/CTS"
486+
"serial-rtscts": "RTS/CTS",
487+
"advanced-enable_external_js": "Enable external JavaScript (extensions and converters) that can execute arbitrary user-provided code. WARNING: If unused, it is advised to disable this.",
488+
"definitions-group-optimistic": "Publish the expected state of group members after set",
489+
"definitions-group-retain": "Retain MQTT messages of this group"
486490
},
487491
"stats": {
488492
"byModel": "По модел",

src/i18n/locales/ca.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,8 @@
310310
"update": "Actualitza firmware",
311311
"update_selected": "Actualitza seleccionats",
312312
"update_selected_info": "Una OTA carrega molt la xarxa.",
313-
"updating": "Actualitzant"
313+
"updating": "Actualitzant",
314+
"abort": "Abort"
314315
},
315316
"scene": {
316317
"add_update_header": "Afegeix/actualitza escena",
@@ -482,7 +483,10 @@
482483
"serial-baudrate": "Baud rate",
483484
"serial-disable_led": "Desactiva LED adaptador",
484485
"serial-port": "Local adaptador (null auto)",
485-
"serial-rtscts": "Flux RTS/CTS"
486+
"serial-rtscts": "Flux RTS/CTS",
487+
"advanced-enable_external_js": "Enable external JavaScript (extensions and converters) that can execute arbitrary user-provided code. WARNING: If unused, it is advised to disable this.",
488+
"definitions-group-optimistic": "Publish the expected state of group members after set",
489+
"definitions-group-retain": "Retain MQTT messages of this group"
486490
},
487491
"stats": {
488492
"byModel": "Per model",

src/i18n/locales/cs.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,8 @@
310310
"update": "Aktualizovat firmware zařízení",
311311
"update_selected": "Aktualizovat vybrané",
312312
"update_selected_info": "OTA aktualizace výrazně zatěžuje síť. Doporučujeme spustit aktualizaci v době menšího zatížení sítě.",
313-
"updating": "Aktualizuje se"
313+
"updating": "Aktualizuje se",
314+
"abort": "Abort"
314315
},
315316
"scene": {
316317
"add_update_header": "Přidat nebo aktualizovat scénu",
@@ -482,7 +483,10 @@
482483
"serial-baudrate": "Rychlost přenosu (baud rate) sériového portu. Musí odpovídat nastavení firmwaru adaptéru (nejčastěji 115200).",
483484
"serial-disable_led": "Vypnout LED indikátor na adaptéru (pokud to firmware podporuje)",
484485
"serial-port": "Cesta k adaptéru (port). Pro automatické rozpoznání nastavte hodnotu na `null`.",
485-
"serial-rtscts": "Hardwarové řízení toku RTS/CTS pro sériový port"
486+
"serial-rtscts": "Hardwarové řízení toku RTS/CTS pro sériový port",
487+
"advanced-enable_external_js": "Enable external JavaScript (extensions and converters) that can execute arbitrary user-provided code. WARNING: If unused, it is advised to disable this.",
488+
"definitions-group-optimistic": "Publish the expected state of group members after set",
489+
"definitions-group-retain": "Retain MQTT messages of this group"
486490
},
487491
"stats": {
488492
"byModel": "Podle modelu",

0 commit comments

Comments
 (0)