website update version display and ota handler

This commit is contained in:
2026-05-10 16:45:06 +02:00
parent 08ee9018cf
commit e3b7648a3f
4 changed files with 103 additions and 28 deletions

View File

@@ -157,7 +157,13 @@ export interface Moistures {
export interface VersionInfo {
git_hash: string,
build_time: string,
partition: string
current: string,
slot0_state: string,
slot1_state: string,
heap_total: number,
heap_used: number,
heap_free: number,
heap_max_used: number,
}
export interface BatteryState {
@@ -189,4 +195,4 @@ export interface TankInfo {
/// water temperature
water_temp: number | null,
temp_sensor_error: string | null
}
}

View File

@@ -201,15 +201,22 @@ export class Controller {
}, false);
ajax.addEventListener("load", () => {
controller.progressview.removeProgress("ota_upload")
controller.reboot();
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", () => {
alert("Error ota")
controller.progressview.removeProgress("ota_upload")
toast.error("OTA upload failed due to a network error.");
}, false);
ajax.addEventListener("abort", () => {
alert("abort ota")
controller.progressview.removeProgress("ota_upload")
toast.error("OTA upload was aborted.");
}, false);
ajax.open("POST", PUBLIC_URL + "/ota");
ajax.send(file);
@@ -570,4 +577,4 @@ window.addEventListener("beforeunload", (event) => {
event.returnValue = confirmationMessage; // This will trigger the browser's default dialog
return confirmationMessage;
}
});
});

View File

@@ -1,23 +1,27 @@
<style>
.otakey{
min-width: 100px;
}
.otavalue{
flex-grow: 1;
}
.otaform {
min-width: 100px;
flex-grow: 1;
}
.otachooser {
min-width: 100px;
width: 100%;
}
.otakey {
min-width: 100px;
}
.otavalue {
flex-grow: 1;
}
.otaform {
min-width: 100px;
flex-grow: 1;
}
.otachooser {
min-width: 100px;
width: 100%;
}
</style>
<div class="flexcontainer">
<div class="subtitle">
Current Firmware
</div>
<button style="margin-left: auto;" type="button" id="refresh_firmware_info">Refresh</button>
</div>
<div class="flexcontainer">
<span class="otakey">Buildtime:</span>
@@ -28,14 +32,46 @@
<span class="otavalue" id="firmware_githash"></span>
</div>
<div class="flexcontainer">
<span class="otakey">Partition:</span>
<span class="otavalue" id="firmware_partition"></span>
<span class="otakey">Partition:</span>
<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>
</div>
<div class="flexcontainer">
<form class="otaform" id="upload_form" method="post">
<input class="otachooser" type="file" name="file1" id="firmware_file"><br>
</form>
</div>
<div class="flexcontainer">
<div class="subtitle">
Heap Memory
</div>
<div></div>
</div>
<div class="flexcontainer">
<span class="otakey">Free:</span>
<span class="otavalue" id="heap_free"></span>
</div>
<div class="flexcontainer">
<span class="otakey">Used:</span>
<span class="otavalue" id="heap_used"></span>
</div>
<div class="flexcontainer">
<span class="otakey">Total:</span>
<span class="otavalue" id="heap_total"></span>
</div>
<div class="flexcontainer">
<span class="otakey">Peak used:</span>
<span class="otavalue" id="heap_max_used"></span>
</div>
<div class="display:flex">
<button style="margin-left: 16px; margin-top: 8px;" class="col-6" type="button" id="test">Self-Test</button>
</div>
</div>

View File

@@ -1,22 +1,38 @@
import { Controller } from "./main";
import {Controller} from "./main";
import {VersionInfo} from "./api";
function fmtBytes(n: number): string {
return `${n} B (${(n / 1024).toFixed(1)} KiB)`;
}
export class OTAView {
readonly file1Upload: HTMLInputElement;
readonly firmware_buildtime: HTMLDivElement;
readonly firmware_githash: HTMLDivElement;
readonly firmware_partition: HTMLDivElement;
readonly firmware_state0: HTMLDivElement;
readonly firmware_state1: HTMLDivElement;
readonly heap_free: HTMLDivElement;
readonly heap_used: HTMLDivElement;
readonly heap_total: HTMLDivElement;
readonly heap_max_used: HTMLDivElement;
constructor(controller: Controller) {
(document.getElementById("firmwareview") as HTMLElement).innerHTML = require("./ota.html")
let test = document.getElementById("test") as HTMLButtonElement;
let test = document.getElementById("test") as HTMLButtonElement;
let refresh = document.getElementById("refresh_firmware_info") as HTMLButtonElement;
this.firmware_buildtime = document.getElementById("firmware_buildtime") as HTMLDivElement;
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.heap_free = document.getElementById("heap_free") as HTMLDivElement;
this.heap_used = document.getElementById("heap_used") as HTMLDivElement;
this.heap_total = document.getElementById("heap_total") as HTMLDivElement;
this.heap_max_used = document.getElementById("heap_max_used") as HTMLDivElement;
const file = document.getElementById("firmware_file") as HTMLInputElement;
this.file1Upload = file
this.file1Upload.onchange = () => {
@@ -31,11 +47,21 @@ export class OTAView {
test.onclick = () => {
controller.selfTest();
}
refresh.onclick = () => {
controller.version();
}
}
setVersion(versionInfo: VersionInfo) {
this.firmware_buildtime.innerText = versionInfo.build_time;
this.firmware_githash.innerText = versionInfo.git_hash;
this.firmware_partition.innerText = versionInfo.partition;
this.firmware_partition.innerText = versionInfo.current;
this.firmware_state0.innerText = versionInfo.slot0_state;
this.firmware_state1.innerText = versionInfo.slot1_state;
this.heap_free.innerText = fmtBytes(versionInfo.heap_free);
this.heap_used.innerText = fmtBytes(versionInfo.heap_used);
this.heap_total.innerText = fmtBytes(versionInfo.heap_total);
this.heap_max_used.innerText = fmtBytes(versionInfo.heap_max_used);
}
}
}