Merge remote-tracking branch 'origin/main' into feat/esp32c5-build

This commit is contained in:
cjkas 2026-10-29 16:15:01 +01:00
commit 247944bd2b
18 changed files with 198 additions and 39 deletions

View file

@ -4170,9 +4170,14 @@ class Firmware {
div.style.display = '';
}
updateFirmware() {
let chip = document.getElementById('divContainer').getAttribute('data-chipmodel') || '';
// Firmware from before the field leaves it out: undefined, not false.
if (proto.model.header.hasOtaSlot === false) {
ui.infoMessage(`This device has no OTA slot, so its firmware is flashed over USB with SomfyController.onboard.esp32${chip}.bin, from the release's SomfyController.onboard.esp32${chip}.bin.zip. That image holds the web UI and an empty configuration too, so take a backup first and restore it afterwards.`);
return;
}
let div = this.createFileUploader('/updateFirmware');
let inst = div.querySelector('div[id=divInstText]');
let chip = document.getElementById('divContainer').getAttribute('data-chipmodel') || '';
let html = `<div style="font-size:14px;margin-bottom:20px;">Select a binary file [SomfyController.ino.esp32${chip}.bin] containing the device firmware then press the Upload File button.</div>`;
if (this.isMobile()) {
html += `<div style="width:100%;color:red;text-align:center;font-weight:bold;"><span style="margin-top:7px;width:100%;background:yellow;padding:3px;display:inline-block;border-radius:5px;background:white;">WARNING<span></div>`;
@ -4303,18 +4308,15 @@ class Firmware {
security.tokenRefused();
return;
}
if (service !== '/restore' && (xhr.status < 200 || xhr.status >= 300)) {
ui.errorMessage(el, `The upload failed (${xhr.status}).`);
if (xhr.status < 200 || xhr.status >= 300) {
// The device's reason, when it sent one.
let desc = `The upload failed (${xhr.status}).`;
try { desc = JSON.parse(xhr.responseText).desc || desc; } catch (e) { }
ui.errorMessage(el, desc);
return;
}
switch (service) {
case '/restore':
if (xhr.status < 200 || xhr.status >= 300) {
let desc = 'The restore failed.';
try { desc = JSON.parse(xhr.responseText).desc || desc; } catch (e) { }
ui.errorMessage(el, desc);
break;
}
(async () => {
await somfy.init();
if (document.getElementById('divUploadFile')) document.getElementById('divUploadFile').remove();

View file

@ -140,7 +140,7 @@ ProtoModel.ITEMS = [
// have it.
ProtoModel.FIELDS = {
header: ['maxRooms', 'maxShades', 'maxGroups', 'maxGroupedShades', 'maxLinkedRemotes', 'startingAddress', 'bitLength',
'proto', 'serverId', 'hostname', 'model', 'chipModel', 'fw', 'connType'],
'proto', 'serverId', 'hostname', 'model', 'chipModel', 'hasOtaSlot', 'fw', 'connType'],
room: ['roomId', 'name', 'sortOrder'],
shadeState: ['shadeId', 'position', 'target', 'direction', 'myPos', 'tiltPosition', 'tiltTarget', 'tiltDirection',
'myTiltPos', 'flags', 'lastRollingCode'],