Merge branch 'develop' of ssh://git.mannheim.ccc.de:1337/C3MA/PlantCtrl into develop

This commit is contained in:
2026-03-18 01:25:29 +01:00
10 changed files with 225 additions and 129 deletions

View File

@@ -191,36 +191,72 @@ export class Controller {
}
uploadNewFirmware(file: File) {
let current = 0;
let max = 100;
controller.progressview.addProgress("ota_upload", (current / max) * 100, "Uploading firmeware (" + current + "/" + max + ")")
const ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", event => {
current = event.loaded / 1000;
max = event.total / 1000;
const reader = new FileReader();
reader.onload = () => {
const arrayBuffer = reader.result as ArrayBuffer;
const data = new Uint8Array(arrayBuffer);
const crc = this.crc32(data);
const size = data.length;
console.log("Uploading new firmware with size " + size + " and crc " + crc + "")
const payload = new Uint8Array(size + 8);
const view = new DataView(payload.buffer);
view.setUint32(0, size, true);
view.setUint32(4, crc, true);
payload.set(data, 8);
let current = 0;
let max = 100;
controller.progressview.addProgress("ota_upload", (current / max) * 100, "Uploading firmeware (" + current + "/" + max + ")")
}, false);
ajax.addEventListener("load", () => {
controller.progressview.removeProgress("ota_upload")
const status = ajax.status;
if (status >= 200 && status < 300) {
controller.reboot();
} else {
const statusText = ajax.statusText || "";
const body = ajax.responseText || "";
toast.error(`OTA update error (${status}${statusText ? ' ' + statusText : ''}): ${body}`);
const ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", event => {
current = event.loaded / 1000;
max = event.total / 1000;
controller.progressview.addProgress("ota_upload", (current / max) * 100, "Uploading firmeware (" + current + "/" + max + ")")
}, false);
ajax.addEventListener("load", () => {
controller.progressview.removeProgress("ota_upload")
const status = ajax.status;
if (status >= 200 && status < 300) {
controller.reboot();
} else {
const statusText = ajax.statusText || "";
const body = ajax.responseText || "";
toast.error(`OTA update error (${status}${statusText ? ' ' + statusText : ''}): ${body}`);
}
}, false);
ajax.addEventListener("error", () => {
controller.progressview.removeProgress("ota_upload")
toast.error("OTA upload failed due to a network error.");
}, false);
ajax.addEventListener("abort", () => {
controller.progressview.removeProgress("ota_upload")
toast.error("OTA upload was aborted.");
}, false);
ajax.open("POST", PUBLIC_URL + "/ota");
ajax.send(payload);
};
reader.onerror = () => {
toast.error("Error reading firmware file.");
};
reader.readAsArrayBuffer(file);
}
private crc32(data: Uint8Array): number {
let crc = 0xFFFFFFFF;
for (let i = 0; i < data.length; i++) {
let byte = data[i];
crc ^= byte;
for (let j = 0; j < 8; j++) {
if (crc & 1) {
crc = (crc >>> 1) ^ 0xEDB88320;
} else {
crc = crc >>> 1;
}
}
}, false);
ajax.addEventListener("error", () => {
controller.progressview.removeProgress("ota_upload")
toast.error("OTA upload failed due to a network error.");
}, false);
ajax.addEventListener("abort", () => {
controller.progressview.removeProgress("ota_upload")
toast.error("OTA upload was aborted.");
}, false);
ajax.open("POST", PUBLIC_URL + "/ota");
ajax.send(file);
}
return (crc ^ 0xFFFFFFFF) >>> 0;
}
async version(): Promise<void> {
@@ -264,12 +300,14 @@ export class Controller {
method: "POST",
body: json,
})
.then(response => response.text())
.then(text => statusCallback(text))
.then( _ => {
controller.progressview.removeProgress("set_config");
setTimeout(() => { controller.downloadConfig() }, 250)
})
.then(response => response.text())
.then(text => statusCallback(text))
.then(_ => {
controller.progressview.removeProgress("set_config");
setTimeout(() => {
controller.downloadConfig()
}, 250)
})
}
async backupConfig(json: string): Promise<string> {
@@ -290,7 +328,6 @@ export class Controller {
method: "POST",
body: pretty
}).then(
_ => controller.progressview.removeProgress("write_rtc")
)
}

View File

@@ -35,12 +35,8 @@
<span class="otavalue" id="firmware_partition"></span>
</div>
<div class="flexcontainer">
<span class="otakey">State0:</span>
<span class="otavalue" id="firmware_state0"></span>
</div>
<div class="flexcontainer">
<span class="otakey">State1:</span>
<span class="otavalue" id="firmware_state1"></span>
<span class="otakey">State:</span>
<span class="otavalue" id="firmware_state"></span>
</div>
<div class="flexcontainer">