Add silent mode for sensor detection and moisture measurement

- Introduced the `silent` parameter to prevent UI progress updates during automatic operations.
- Enhanced CAN robustness with improved bus-off management, retransmission settings, and jitter tolerance.
- Added auto-refresh functionality for plant moisture and sensor detection with configurable enablement.
This commit is contained in:
2026-03-29 14:21:12 +02:00
parent 4cf5f6d151
commit 7121dd0fae
4 changed files with 274 additions and 194 deletions

View File

@@ -362,16 +362,21 @@ export class Controller {
)
}
async detectSensors(detection: Detection) {
async detectSensors(detection: Detection, silent: boolean = false) {
let counter = 0
let limit = 5
controller.progressview.addProgress("detect_sensors", counter / limit * 100, "Detecting sensors " + (limit - counter) + "s")
if (!silent) {
controller.progressview.addProgress("detect_sensors", counter / limit * 100, "Detecting sensors " + (limit - counter) + "s")
}
let timerId: string | number | NodeJS.Timeout | undefined
function updateProgress() {
counter++;
controller.progressview.addProgress("detect_sensors", counter / limit * 100, "Detecting sensors " + (limit - counter) + "s")
if (!silent) {
controller.progressview.addProgress("detect_sensors", counter / limit * 100, "Detecting sensors " + (limit - counter) + "s")
}
timerId = setTimeout(updateProgress, 1000);
}
@@ -379,12 +384,15 @@ export class Controller {
var pretty = JSON.stringify(detection, undefined, 1);
fetch(PUBLIC_URL + "/detect_sensors", {method: "POST", body: pretty})
return fetch(PUBLIC_URL + "/detect_sensors", {method: "POST", body: pretty})
.then(response => response.json())
.then(json => json as Detection)
.then(json => {
clearTimeout(timerId);
controller.progressview.removeProgress("detect_sensors");
if (!silent) {
controller.progressview.removeProgress("detect_sensors");
}
const pretty = JSON.stringify(json);
toast.info("Detection result: " + pretty);
console.log(pretty);
@@ -393,7 +401,9 @@ export class Controller {
})
.catch(error => {
clearTimeout(timerId);
controller.progressview.removeProgress("detect_sensors");
if (!silent) {
controller.progressview.removeProgress("detect_sensors");
}
toast.error("Autodetect failed: " + error);
});
}
@@ -426,7 +436,7 @@ export class Controller {
timerId = setTimeout(updateProgress, 1000);
var ajax = new XMLHttpRequest();
const ajax = new XMLHttpRequest();
ajax.responseType = 'json';
ajax.onreadystatechange = () => {
if (ajax.readyState === 4) {
@@ -435,7 +445,7 @@ export class Controller {
this.networkView.setScanResult(ajax.response as SSIDList)
}
};
ajax.onerror = (evt) => {
ajax.onerror = (_) => {
clearTimeout(timerId);
controller.progressview.removeProgress("scan_ssid");
alert("Failed to start see console")
@@ -459,16 +469,22 @@ export class Controller {
this.hardwareView.setConfig(current.hardware);
}
measure_moisture() {
measure_moisture(silent: boolean = false) {
let counter = 0
let limit = 2
controller.progressview.addProgress("measure_moisture", counter / limit * 100, "Measure Moisture " + (limit - counter) + "s")
if (!silent) {
controller.progressview.addProgress("measure_moisture", counter / limit * 100, "Measure Moisture " + (limit - counter) + "s")
}
let timerId: string | number | NodeJS.Timeout | undefined
function updateProgress() {
counter++;
controller.progressview.addProgress("measure_moisture", counter / limit * 100, "Measure Moisture " + (limit - counter) + "s")
if (!silent) {
controller.progressview.addProgress("measure_moisture", counter / limit * 100, "Measure Moisture " + (limit - counter) + "s")
}
timerId = setTimeout(updateProgress, 1000);
}
@@ -476,17 +492,22 @@ export class Controller {
timerId = setTimeout(updateProgress, 1000);
fetch(PUBLIC_URL + "/moisture")
return fetch(PUBLIC_URL + "/moisture")
.then(response => response.json())
.then(json => json as Moistures)
.then(time => {
controller.plantViews.update(time.moisture_a, time.moisture_b)
clearTimeout(timerId);
controller.progressview.removeProgress("measure_moisture");
if (!silent) {
controller.progressview.removeProgress("measure_moisture");
}
})
.catch(error => {
clearTimeout(timerId);
controller.progressview.removeProgress("measure_moisture");
if (!silent) {
controller.progressview.removeProgress("measure_moisture");
}
console.log(error);
});
}
@@ -516,7 +537,7 @@ export class Controller {
}, 2000);
}
})
.catch(err => {
.catch(_ => {
console.log("Not reached yet, retrying")
setTimeout(controller.waitForReboot, 1000)
})
@@ -560,6 +581,8 @@ export class Controller {
readonly logView: LogView
readonly detectBtn: HTMLButtonElement
readonly can_power: HTMLInputElement;
readonly auto_refresh_moisture_sensors: HTMLInputElement;
private auto_refresh_timer: NodeJS.Timeout | undefined;
constructor() {
this.timeView = new TimeView(this)
@@ -597,6 +620,38 @@ export class Controller {
this.can_power.onchange = () => {
controller.setCanPower(this.can_power.checked);
}
this.auto_refresh_moisture_sensors = document.getElementById("auto_refresh_moisture_sensors") as HTMLInputElement
this.auto_refresh_moisture_sensors.onchange = () => {
if (this.auto_refresh_timer) {
clearTimeout(this.auto_refresh_timer)
}
if (this.auto_refresh_moisture_sensors.checked) {
this.autoRefreshLoop()
}
}
}
private async autoRefreshLoop() {
if (!this.auto_refresh_moisture_sensors.checked) {
return;
}
try {
await this.measure_moisture(true);
const detection: Detection = {
plant: Array.from({length: PLANT_COUNT}, () => ({
sensor_a: true,
sensor_b: true,
})),
};
await this.detectSensors(detection, true);
} catch (e) {
console.error("Auto-refresh error", e);
}
if (this.auto_refresh_moisture_sensors.checked) {
this.auto_refresh_timer = setTimeout(() => this.autoRefreshLoop(), 1000);
}
}