new ota logic
This commit is contained in:
@@ -163,8 +163,7 @@ export interface VersionInfo {
|
||||
git_hash: string,
|
||||
build_time: string,
|
||||
current: string,
|
||||
slot0_state: string,
|
||||
slot1_state: string,
|
||||
state: string
|
||||
}
|
||||
|
||||
export interface BatteryState {
|
||||
|
||||
@@ -191,36 +191,70 @@ 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;
|
||||
|
||||
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 +298,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 +326,6 @@ export class Controller {
|
||||
method: "POST",
|
||||
body: pretty
|
||||
}).then(
|
||||
|
||||
_ => controller.progressview.removeProgress("write_rtc")
|
||||
)
|
||||
}
|
||||
@@ -378,9 +413,9 @@ export class Controller {
|
||||
|
||||
var pretty = JSON.stringify(detection, undefined, 1);
|
||||
|
||||
fetch(PUBLIC_URL + "/detect_sensors", { method: "POST", body: pretty })
|
||||
fetch(PUBLIC_URL + "/detect_sensors", {method: "POST", body: pretty})
|
||||
.then(response => response.json())
|
||||
.then (json => json as Detection)
|
||||
.then(json => json as Detection)
|
||||
.then(json => {
|
||||
clearTimeout(timerId);
|
||||
controller.progressview.removeProgress("detect_sensors");
|
||||
@@ -531,7 +566,7 @@ export class Controller {
|
||||
|
||||
private setCanPower(checked: boolean) {
|
||||
var body: CanPower = {
|
||||
state : checked
|
||||
state: checked
|
||||
}
|
||||
var pretty = JSON.stringify(body, undefined, 1);
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ export class OTAView {
|
||||
readonly firmware_buildtime: HTMLDivElement;
|
||||
readonly firmware_githash: HTMLDivElement;
|
||||
readonly firmware_partition: HTMLDivElement;
|
||||
readonly firmware_state0: HTMLDivElement;
|
||||
readonly firmware_state1: HTMLDivElement;
|
||||
readonly firmware_state: HTMLDivElement;
|
||||
|
||||
|
||||
constructor(controller: Controller) {
|
||||
(document.getElementById("firmwareview") as HTMLElement).innerHTML = require("./ota.html")
|
||||
@@ -18,8 +18,7 @@ export class OTAView {
|
||||
this.firmware_githash = document.getElementById("firmware_githash") as HTMLDivElement;
|
||||
this.firmware_partition = document.getElementById("firmware_partition") as HTMLDivElement;
|
||||
|
||||
this.firmware_state0 = document.getElementById("firmware_state0") as HTMLDivElement;
|
||||
this.firmware_state1 = document.getElementById("firmware_state1") as HTMLDivElement;
|
||||
this.firmware_state = document.getElementById("firmware_state") as HTMLDivElement;
|
||||
|
||||
|
||||
const file = document.getElementById("firmware_file") as HTMLInputElement;
|
||||
@@ -42,7 +41,6 @@ export class OTAView {
|
||||
this.firmware_buildtime.innerText = versionInfo.build_time;
|
||||
this.firmware_githash.innerText = versionInfo.git_hash;
|
||||
this.firmware_partition.innerText = versionInfo.current;
|
||||
this.firmware_state0.innerText = versionInfo.slot0_state;
|
||||
this.firmware_state1.innerText = versionInfo.slot1_state;
|
||||
this.firmware_state.innerText = versionInfo.state;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user