Serial monitor redesign: Test box button, InfluxDB row in the checklist

- Test box: restart + start-up capture + online InfluxDB check (data newer
  than the restart), with a status strip; checklist and findings are the
  main view, live log / guided troubleshooting / box details are tabs,
  rarely used actions in a More menu
- light palette on all systems (macOS dark mode made the colours unreadable)
- new rule influx.invalid_value: -inf from a silent microphone makes
  InfluxDB reject every upload (HTTP 400); guide end names it
- exclusive serial port on macOS/Linux: two tool windows no longer split
  the log between them
- InfluxDB check: `since` filter, neutral wording when nothing new arrives

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
KrzyszurandClaude Opus 5.5 committed 2026-10-01 00:06:48 +02:00
1 parent 66cb804102
commit bb933ff748
13 files changed
+422 -83

No files matched your search

+1 -1
View File
@@ -73,7 +73,7 @@ MILESTONES = [
("wifi_connected", "Connected to Wi-Fi", False),
("time_synced", "Clock set from the Internet", False),
("clock_verified", "Clock keeps time (RTC verified)", True),
("data_uploaded", "Data uploaded to InfluxDB", False),
("data_uploaded", "Upload accepted by InfluxDB (box log)", False),
("ota_registered", "Registered for firmware updates", False),
("ota_checked", "Checked for firmware updates", False),
("ota_update_started", "Firmware update started", True),
+18 -2
View File
@@ -750,12 +750,18 @@ type = "influx"
text = "Checking in InfluxDB that this box's data arrives: device status, microphone and the sensors (AS7341, BME688, SEN66). Keep the box switched on and online. The tool checks again every 30 s for up to 4 minutes (the air sensor needs about 2 minutes after a restart). The laptop needs Internet for this check."
timeout_s = 240
poll_s = 30
outcomes = { ok = "end:data_ok", sensors_missing = "why", silent = "end:silent", never = "end:never", unavailable = "end:unavailable" }
outcomes = { ok = "end:data_ok", sensors_missing = "why", silent = "why_silent", never = "why_silent", unavailable = "end:unavailable" }
[[guide.step]]
id = "why_silent"
type = "route"
routes = { "influx.invalid_value" = "end:invalid_value" }
default = "end:silent"
[[guide.step]]
id = "why"
type = "route"
routes = { "kota.rtc_stopped" = "end:sensors_clock", "rtc.clock_not_running" = "end:sensors_clock", "kota.rtc_not_ticking" = "end:sensors_clock", "kota.time_invalid" = "end:sensors_clock", "kota.rtc_read_failed" = "guide:rtc_i2c", "rtc.init_failed" = "guide:rtc_i2c", "sensor.init_failed" = "guide:sensors", "kota.sensor_missing" = "guide:sensors" }
routes = { "influx.invalid_value" = "end:invalid_value", "kota.rtc_stopped" = "end:sensors_clock", "rtc.clock_not_running" = "end:sensors_clock", "kota.rtc_not_ticking" = "end:sensors_clock", "kota.time_invalid" = "end:sensors_clock", "kota.rtc_read_failed" = "guide:rtc_i2c", "rtc.init_failed" = "guide:rtc_i2c", "sensor.init_failed" = "guide:sensors", "kota.sensor_missing" = "guide:sensors" }
default = "end:sensors_missing"
[[guide.end]]
@@ -765,6 +771,16 @@ title = "Box is healthy and its sensor data reaches InfluxDB"
text = "Status, microphone and all sensor readings of this box arrived in InfluxDB in the last 15 minutes."
actions = []
[[guide.end]]
id = "invalid_value"
severity = "critical"
title = "InfluxDB rejects every upload of this box (invalid value -inf)"
text = "The box is online and uploads, but one measurement carries -inf (the microphone records pure silence). InfluxDB refuses the whole upload with HTTP 400, so neither the status nor the sensor data arrive."
actions = [
"Run the Microphone check: a working microphone (and its switch ON) avoids the -inf value.",
"Save the session log and send it to the firmware team: the firmware must skip invalid values.",
]
[[guide.end]]
id = "sensors_clock"
severity = "error"
+15 -1
View File
@@ -280,6 +280,20 @@ severity = "warning"
title = "InfluxDB refused some measurements (HTTP 400)"
meaning = "A measurement was malformed and dropped (firmware issue, not a hardware fault)."
actions = ["Save the session log and send it to the firmware team."]
explained_by = ["influx.invalid_value"]
[[rule]]
id = "influx.invalid_value"
# Line protocol printed by SENSOR_GATHERER / INFLUX: "-inf"/"nan" are not valid
# numbers, and one bad line makes InfluxDB reject the whole upload.
pattern = '^(?:.*format: )?(?P<measurement>[a-z0-9_]+),device=\S+ \S*=-?(?:inf|nan)\b'
severity = "critical"
title = "Box sends an invalid value (-inf/nan) - InfluxDB rejects all its data"
meaning = "A measurement contains -inf or nan (the microphone: pure silence gives -inf dB). InfluxDB refuses the whole upload with HTTP 400, so status and sensor data from this box are lost too. Firmware bug; a silent microphone triggers it."
actions = [
"Check the microphone (Microphone check): a working microphone avoids the -inf value.",
"Save the session log and send it to the firmware team: invalid values must be skipped, not uploaded.",
]
[[rule]]
id = "influx.env_missing"
@@ -713,7 +727,7 @@ actions = [
"Check the network has Internet (open a website on a phone on the same Wi-Fi).",
"Check INFLUX_URL / INFLUX_TOKEN in ENV.TXT (re-provision the SD card).",
]
explained_by = ["kota.time_invalid", "influx.auth", "influx.not_found", "status.conn.1", "net.dns_fail", "net.tls_fail", "influx.server_error"]
explained_by = ["influx.invalid_value", "kota.time_invalid", "influx.auth", "influx.not_found", "status.conn.1", "net.dns_fail", "net.tls_fail", "influx.server_error"]
[[rule]]
id = "kota.low_heap"