Add firmware build timestamp support for sensors; update detection workflows and UI accordingly.
This commit is contained in:
@@ -199,9 +199,22 @@ export interface BatteryState {
|
||||
state_of_health: string
|
||||
}
|
||||
|
||||
export interface DetectionPlant {
|
||||
/// Request: which sensors to send IDENTIFY_CMD to.
|
||||
export interface SensorRequest {
|
||||
sensor_a: boolean,
|
||||
sensor_b: boolean
|
||||
sensor_b: boolean,
|
||||
}
|
||||
|
||||
export interface DetectionRequest {
|
||||
plant: SensorRequest[]
|
||||
}
|
||||
|
||||
/// Response: detection result per plant.
|
||||
/// sensor_a / sensor_b: firmware build timestamp in minutes since Unix epoch,
|
||||
/// or null if the sensor did not respond.
|
||||
export interface DetectionPlant {
|
||||
sensor_a: number | null,
|
||||
sensor_b: number | null,
|
||||
}
|
||||
|
||||
export interface Detection {
|
||||
|
||||
@@ -29,7 +29,7 @@ import {
|
||||
SetTime, SSIDList, TankInfo,
|
||||
TestPump,
|
||||
VersionInfo,
|
||||
SaveInfo, SolarState, PumpTestResult, Detection, CanPower
|
||||
SaveInfo, SolarState, PumpTestResult, Detection, DetectionRequest, CanPower
|
||||
} from "./api";
|
||||
import {SolarView} from "./solarview";
|
||||
import {toast} from "./toast";
|
||||
@@ -339,7 +339,7 @@ export class Controller {
|
||||
)
|
||||
}
|
||||
|
||||
async detectSensors(detection: Detection, silent: boolean = false) {
|
||||
async detectSensors(detection: DetectionRequest, silent: boolean = false) {
|
||||
let counter = 0
|
||||
let limit = 5
|
||||
if (!silent) {
|
||||
@@ -577,7 +577,7 @@ export class Controller {
|
||||
this.hardwareView = new HardwareConfigView(this)
|
||||
this.detectBtn = document.getElementById("detect_sensors") as HTMLButtonElement
|
||||
this.detectBtn.onclick = () => {
|
||||
const detection: Detection = {
|
||||
const detection: DetectionRequest = {
|
||||
plant: Array.from({length: PLANT_COUNT}, () => ({
|
||||
sensor_a: true,
|
||||
sensor_b: true,
|
||||
@@ -615,7 +615,7 @@ export class Controller {
|
||||
|
||||
try {
|
||||
await this.measure_moisture(true);
|
||||
const detection: Detection = {
|
||||
const detection: DetectionRequest = {
|
||||
plant: Array.from({length: PLANT_COUNT}, () => ({
|
||||
sensor_a: true,
|
||||
sensor_b: true,
|
||||
|
||||
@@ -133,10 +133,18 @@
|
||||
<span class="plantsensorkey">Sensor A:</span>
|
||||
<span class="plantsensorvalue" id="plant_${plantId}_moisture_a">not measured</span>
|
||||
</div>
|
||||
<div class="flexcontainer plantSensorEnabledOnly_${plantId}">
|
||||
<span class="plantsensorkey">Sensor A FW:</span>
|
||||
<span class="plantsensorvalue" id="plant_${plantId}_sensor_a_fw_build">unknown</span>
|
||||
</div>
|
||||
<div class="flexcontainer plantSensorEnabledOnly_${plantId}">
|
||||
<div class="plantsensorkey">Sensor B:</div>
|
||||
<span class="plantsensorvalue" id="plant_${plantId}_moisture_b">not measured</span>
|
||||
</div>
|
||||
<div class="flexcontainer plantSensorEnabledOnly_${plantId}">
|
||||
<span class="plantsensorkey">Sensor B FW:</span>
|
||||
<span class="plantsensorvalue" id="plant_${plantId}_sensor_b_fw_build">unknown</span>
|
||||
</div>
|
||||
<div class="flexcontainer plantPumpEnabledOnly_${plantId}">
|
||||
<div class="plantsensorkey">Max Current</div>
|
||||
<span class="plantsensorvalue" id="plant_${plantId}_pump_test_current_max">not_tested</span>
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
import {DetectionPlant, Detection, PlantConfig, PumpTestResult} from "./api";
|
||||
import {Detection, DetectionPlant, DetectionRequest, PlantConfig, PumpTestResult} from "./api";
|
||||
|
||||
export const PLANT_COUNT = 8;
|
||||
|
||||
/** Format a firmware build timestamp (minutes since Unix epoch) as a human-readable date/time. */
|
||||
function formatBuildMinutes(buildMinutes: number | null): string {
|
||||
if (buildMinutes === null) return "not detected";
|
||||
if (buildMinutes === 0) return "detected (no timestamp)";
|
||||
const ms = buildMinutes * 60 * 1000;
|
||||
return new Date(ms).toISOString().replace("T", " ").slice(0, 16) + " UTC";
|
||||
}
|
||||
|
||||
import {Controller} from "./main";
|
||||
|
||||
@@ -79,6 +86,8 @@ export class PlantView {
|
||||
private readonly mode: HTMLSelectElement;
|
||||
private readonly moistureA: HTMLElement;
|
||||
private readonly moistureB: HTMLElement;
|
||||
private readonly sensorAFwBuild: HTMLElement;
|
||||
private readonly sensorBFwBuild: HTMLElement;
|
||||
private readonly maxConsecutivePumpCount: HTMLInputElement;
|
||||
private readonly minPumpCurrentMa: HTMLInputElement;
|
||||
private readonly maxPumpCurrentMa: HTMLInputElement;
|
||||
@@ -109,6 +118,8 @@ export class PlantView {
|
||||
|
||||
this.moistureA = document.getElementById("plant_" + plantId + "_moisture_a")! as HTMLElement;
|
||||
this.moistureB = document.getElementById("plant_" + plantId + "_moisture_b")! as HTMLElement;
|
||||
this.sensorAFwBuild = document.getElementById("plant_" + plantId + "_sensor_a_fw_build")! as HTMLElement;
|
||||
this.sensorBFwBuild = document.getElementById("plant_" + plantId + "_sensor_b_fw_build")! as HTMLElement;
|
||||
|
||||
this.pump_test_current_max = document.getElementById("plant_" + plantId + "_pump_test_current_max")! as HTMLElement;
|
||||
this.pump_test_current_min = document.getElementById("plant_" + plantId + "_pump_test_current_min")! as HTMLElement;
|
||||
@@ -124,7 +135,7 @@ export class PlantView {
|
||||
|
||||
this.testSensorAButton = document.getElementById("plant_" + plantId + "_test_sensor_a")! as HTMLButtonElement;
|
||||
this.testSensorAButton.onclick = () => {
|
||||
const detection: Detection = {
|
||||
const detection: DetectionRequest = {
|
||||
plant: Array.from({length: PLANT_COUNT}, (_v, idx) => ({
|
||||
sensor_a: idx === plantId,
|
||||
sensor_b: false,
|
||||
@@ -135,7 +146,7 @@ export class PlantView {
|
||||
|
||||
this.testSensorBButton = document.getElementById("plant_" + plantId + "_test_sensor_b")! as HTMLButtonElement;
|
||||
this.testSensorBButton.onclick = () => {
|
||||
const detection: Detection = {
|
||||
const detection: DetectionRequest = {
|
||||
plant: Array.from({length: PLANT_COUNT}, (_v, idx) => ({
|
||||
sensor_a: false,
|
||||
sensor_b: idx === plantId,
|
||||
@@ -360,19 +371,23 @@ export class PlantView {
|
||||
}
|
||||
|
||||
setDetectionResult(plantResult: DetectionPlant) {
|
||||
console.log("setDetectionResult plantResult: " + plantResult.sensor_a + " " + plantResult.sensor_b)
|
||||
const sensorADetected = plantResult.sensor_a !== null;
|
||||
const sensorBDetected = plantResult.sensor_b !== null;
|
||||
console.log("setDetectionResult plantResult: a=" + plantResult.sensor_a + " b=" + plantResult.sensor_b);
|
||||
var changed = false;
|
||||
if (this.sensorAInstalled.checked != plantResult.sensor_a) {
|
||||
if (this.sensorAInstalled.checked != sensorADetected) {
|
||||
changed = true;
|
||||
this.sensorAInstalled.checked = plantResult.sensor_a;
|
||||
this.sensorAInstalled.checked = sensorADetected;
|
||||
}
|
||||
if (this.sensorBInstalled.checked != plantResult.sensor_b) {
|
||||
if (this.sensorBInstalled.checked != sensorBDetected) {
|
||||
changed = true;
|
||||
this.sensorBInstalled.checked = plantResult.sensor_b;
|
||||
this.sensorBInstalled.checked = sensorBDetected;
|
||||
}
|
||||
if (changed) {
|
||||
this.controller.configChanged();
|
||||
}
|
||||
|
||||
this.sensorAFwBuild.innerText = formatBuildMinutes(plantResult.sensor_a);
|
||||
this.sensorBFwBuild.innerText = formatBuildMinutes(plantResult.sensor_b);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user