Files
kota-technician-tool/kota_tech/diag/guides.toml
T
kkallasandClaude Opus 5.5 0d21c5c205 Store all text files with LF line endings
Some files had been saved with CRLF on Windows, so a one-line change
showed as a whole-file diff. .gitattributes now stores text as LF
(.bat stays CRLF for cmd, .command/.sh LF for macOS).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 17:30:25 +02:00

741 lines
26 KiB
TOML

# Guided troubleshooting: decision trees that combine technician answers
# with live log evidence (diag.guides.GuideRunner executes them).
#
# Guide: id, title, summary, recommend (rule ids / "led:<COLOUR>" / "always"),
# start (first step id), [[guide.step]], [[guide.end]]
# Step types:
# led technician picks the LED colour; `route` maps colour -> target.
# Colours: GREEN PURPLE RED BLUE YELLOW ORANGE WHITE OFF CYCLING
# The answer is compared with the colour the firmware log implies.
# question `options` = [{label, next}]
# info instruction + Continue (`next`)
# wait optional `tool_action` ("reset"), then watch the log:
# `until` (regex) / `until_milestone`, `fail_on` (regex),
# `timeout_s`; go to on_ok / on_fail / on_timeout.
# `pass_on_timeout = true`: reaching the timeout without fail_on
# counts as ok (used for "watch for N seconds").
# route automatic: first current root finding whose rule id is in
# `routes` decides; otherwise `default`.
# Targets: "<step id>", "end:<end id>", "guide:<guide id>".
# Optional on any step: skip_if_finding / skip_unless_feature (+ skip_to).
# Text placeholders: {expected_led} {failing_sensors} {top_finding}
# End severity: ok | info | warning | error | critical
# ================================================================= quick
[[guide]]
id = "quick"
title = "Quick check - start here"
summary = "Tell the tool what the LED shows; it picks the right checks."
recommend = ["always"]
start = "led"
[[guide.step]]
id = "led"
type = "led"
text = "Look at the RGB status LED on the box (no need to open it). Which colour is it?"
route = { GREEN = "heartbeat", PURPLE = "guide:network", RED = "guide:sensors", BLUE = "guide:rtc_i2c", WHITE = "guide:white", YELLOW = "guide:update", ORANGE = "guide:update", CYAN = "guide:network", OFF = "guide:power", CYCLING = "guide:reboot_loop" }
[[guide.step]]
id = "heartbeat"
type = "question"
text = "Is the small LED next to the RGB LED blinking about once per second?"
options = [
{ label = "Yes, blinking", next = "green_route" },
{ label = "No - steady on or off", next = "end:hung" },
]
[[guide.step]]
id = "green_route"
type = "route"
routes = { "rtc.clock_not_running" = "guide:clock", "mic.silent" = "guide:mic", "mic.disabled" = "guide:mic", "matter.not_commissioned" = "guide:network", "net.dns_fail" = "guide:network" }
default = "end:healthy"
[[guide.end]]
id = "healthy"
severity = "ok"
title = "Box looks healthy"
text = "Green LED, firmware running and no problems in the log."
actions = ["If the customer still reports missing data, keep the tool connected for 5 minutes and check that 'Data uploaded to InfluxDB' gets ticked."]
[[guide.end]]
id = "hung"
severity = "error"
title = "Firmware is not running normally"
text = "The heartbeat LED should blink once per second whenever the firmware runs. A steady heartbeat LED means the firmware has frozen."
actions = [
"Switch the box off and on with the power switch.",
"If it happens again: save the session log and re-flash the official firmware (Flash firmware tab, App only).",
]
# =============================================================== network
[[guide]]
id = "network"
title = "Purple LED / no Internet"
summary = "Pairing in Matter, site Wi-Fi and Internet checks, with live confirmation."
recommend = ["led:PURPLE", "led:CYAN", "matter.not_commissioned", "net.dns_fail", "influx.buffer_fail", "ota.registration_failed",
"status.conn", "status.conn.1", "kota.wifi_down", "kota.no_upload", "kota.weak_wifi", "kota.ota_unregistered"]
start = "paired"
[[guide.step]]
id = "paired"
type = "question"
skip_if_finding = "matter.not_commissioned"
skip_to = "pair_intro"
text = "Was this box already added to the customer's Matter app (Apple Home, Google Home, ...) at this site?"
options = [
{ label = "Yes, it was paired before", next = "internet" },
{ label = "No / not sure", next = "pair_intro" },
]
[[guide.step]]
id = "internet"
type = "question"
text = "Does the site Wi-Fi have working Internet? Check with a phone connected to the same Wi-Fi (open any website)."
options = [
{ label = "Yes, Internet works", next = "changed" },
{ label = "No Internet on the site Wi-Fi", next = "end:site_offline" },
]
[[guide.step]]
id = "changed"
type = "question"
text = "Was the Wi-Fi name or password changed, or the router replaced, since the box was installed?"
options = [
{ label = "Yes / possibly", next = "end:repair_needed" },
{ label = "No", next = "end:offline_unknown" },
]
[[guide.step]]
id = "pair_intro"
type = "info"
text = "The box is not on any Wi-Fi yet: it must be paired in Matter. You need: a phone with Bluetooth on, the customer's Matter app, the 2.4 GHz Wi-Fi password, and the QR sticker of this box. Keep the tool connected - it follows the pairing live."
next = "pair_start"
[[guide.step]]
id = "pair_start"
type = "wait"
text = "In the Matter app choose 'Add device' and scan the QR code shown here (the same as the sticker), or type the 11-digit manual code. Keep the phone within 1 m of the box."
show_qr = true
until = 'MAIN: Commissioning session started'
timeout_s = 300
on_ok = "pair_wifi"
on_timeout = "not_found"
[[guide.step]]
id = "not_found"
type = "question"
text = "The box has not seen the phone connect yet. What does the app show?"
options = [
{ label = "Still searching / let me try again", next = "pair_start" },
{ label = "'Device not found' or similar", next = "end:ble_not_found" },
]
[[guide.step]]
id = "pair_wifi"
type = "wait"
text = "The phone is connected to the box. Follow the app: choose the 2.4 GHz Wi-Fi network and enter its password."
until = 'MAIN: Commissioning complete|MAIN: Fabric is committed'
fail_on = 'Commissioning failed, fail safe timer expired'
timeout_s = 300
on_ok = "pair_time"
on_fail = "end:pair_failed"
on_timeout = "end:pair_failed"
[[guide.step]]
id = "pair_time"
type = "wait"
text = "Paired! The box is joining the Wi-Fi and getting the time from the Internet..."
until_milestone = "time_synced"
timeout_s = 120
on_ok = "pair_upload"
on_timeout = "end:joined_no_internet"
[[guide.step]]
id = "pair_upload"
type = "wait"
text = "Online. Waiting for the first measurements to reach the database (up to 4 minutes)..."
until = 'INFLUX: HTTP request performed, status code: 2\d\d'
fail_on = 'INFLUX: Failed to perform HTTP request: (401|403|404)'
timeout_s = 240
on_ok = "end:online"
on_fail = "end:influx_rejected"
on_timeout = "end:no_upload"
[[guide.end]]
id = "online"
severity = "ok"
title = "Box is paired and uploading data"
text = "Pairing, Internet time and the first upload all worked."
actions = [
"The box may now download a firmware update (yellow, then orange LED, a few minutes). Do not switch it off.",
"It should end green.",
]
[[guide.end]]
id = "site_offline"
severity = "warning"
title = "Site network has no Internet"
text = "The box cannot work until the site Wi-Fi reaches the Internet. This is not a box fault."
actions = ["Ask the customer to fix the Internet connection, then power-cycle the box."]
[[guide.end]]
id = "repair_needed"
severity = "warning"
title = "Box must be paired again"
text = "The box still remembers the old Wi-Fi. It needs a factory reset and new pairing."
actions = [
"Hold the Matter button for 5 seconds (LED turns white) - this erases the old pairing.",
"Remove the box from the customer's Matter app, then run this guide again and choose 'No / not sure'.",
]
[[guide.end]]
id = "offline_unknown"
severity = "error"
title = "Box is paired but cannot reach the Internet - cause unclear"
text = "The network works for other devices, but not for this box."
actions = [
"Check the router does not block new devices (guest isolation, MAC filter). Box MAC is shown in the port list.",
"Move the box closer to the router to rule out weak signal.",
"If nothing helps: factory reset (hold the Matter button 5 s) and pair again.",
]
[[guide.end]]
id = "ble_not_found"
severity = "error"
title = "Phone cannot find the box over Bluetooth"
text = "The box only accepts pairing for a limited time after start-up."
actions = [
"Switch the box off and on to reopen the pairing window, then try again within 10 minutes.",
"Check Bluetooth and location permission are on for the Matter app.",
"If the box was paired to another app before: hold the Matter button 5 s (factory reset) first.",
]
[[guide.end]]
id = "pair_failed"
severity = "error"
title = "Pairing did not finish"
text = "The phone connected but the box did not join the Wi-Fi."
actions = [
"Use a 2.4 GHz network (many routers have a separate 2.4 GHz name).",
"Re-enter the Wi-Fi password carefully.",
"Switch the box off and on, then pair again.",
]
[[guide.end]]
id = "joined_no_internet"
severity = "error"
title = "Box joined the Wi-Fi but has no Internet"
text = "Pairing worked, but the box cannot reach time or data servers."
actions = [
"Check the network allows outgoing connections (HTTPS, NTP) for new devices.",
"Try a phone hotspot to rule out the site network.",
]
[[guide.end]]
id = "influx_rejected"
severity = "critical"
title = "Database rejected the box (token / bucket)"
text = "The box is online but InfluxDB refused the upload. The SD card settings are wrong."
actions = ["Re-provision the SD card with the current ENV.TXT (SD card is inside the case)."]
[[guide.end]]
id = "no_upload"
severity = "warning"
title = "Online, but no upload seen yet"
text = "Uploads happen every minute; the first one can be delayed while the air sensor warms up."
actions = ["Keep the tool connected a few more minutes and watch the Diagnosis tab."]
# ================================================================= RTC / I2C
[[guide]]
id = "rtc_i2c"
title = "Blue LED - clock / I2C cable"
summary = "Re-seat the I2C cable and verify the start-up live."
recommend = ["led:BLUE", "rtc.init_failed", "i2c.errors", "kota.i2c_stuck", "kota.rtc_read_failed", "status.rtc.1", "status.rtc.2"]
start = "explain"
[[guide.step]]
id = "explain"
type = "info"
text = "Blue means the clock chip did not answer. It is the first chip on the shared I2C cable between the boards, so a loose cable is the most common cause. This check needs the case opened."
next = "reseat"
[[guide.step]]
id = "reseat"
type = "info"
text = "Switch the power OFF. Open the case. Unplug and firmly re-plug the I2C cable between the boards at both ends. Close the case and switch the power ON. Then press Continue."
next = "verify"
[[guide.step]]
id = "verify"
type = "wait"
text = "Watching the start-up (up to 60 s)..."
until_milestone = "sensors_ready"
fail_on = 'MAIN: Failed to initialize RTC'
timeout_s = 60
on_ok = "end:i2c_fixed"
on_fail = "damaged"
on_timeout = "damaged"
[[guide.step]]
id = "damaged"
type = "question"
text = "The clock still does not answer. Is the I2C cable or its connector visibly damaged (pinched, broken wire, bent pin)?"
options = [
{ label = "Yes, damaged", next = "end:replace_cable" },
{ label = "No, looks fine", next = "end:rtc_module" },
]
[[guide.end]]
id = "i2c_fixed"
severity = "ok"
title = "Fixed - all sensors start again"
text = "After re-seating the cable the clock and all sensors started."
actions = ["Make sure the cable is routed without strain before closing the case."]
[[guide.end]]
id = "replace_cable"
severity = "error"
title = "Replace the I2C cable"
text = "A damaged I2C cable stops the clock and all sensors."
actions = ["Replace the cable, then run this check again."]
[[guide.end]]
id = "rtc_module"
severity = "error"
title = "Clock (RTC) module is probably faulty"
text = "The cable is fine but the clock chip does not answer."
actions = ["Replace the RTC module, or send the box for repair with the session log."]
# ==================================================================== white
[[guide]]
id = "white"
title = "White LED - SD card / reset / setup mode"
summary = "Tell apart the three white states and check the SD card."
recommend = ["led:WHITE", "sd.card_fail", "sd.mount_fail", "sd.env_open_fail", "influx.env_missing", "influx.init_fail",
"kota.sd_unmounted", "status.sd", "status.portal", "status.reset"]
start = "button"
[[guide.step]]
id = "button"
type = "question"
text = "Did anyone hold the Matter button (outside the case) for about 5 seconds just before the LED turned white?"
options = [
{ label = "Yes", next = "end:factory_reset" },
{ label = "No / don't know", next = "portal" },
]
[[guide.step]]
id = "portal"
type = "question"
skip_unless_feature = "setup_portal"
skip_to = "sd_reseat"
text = "On a phone, look at the Wi-Fi list: is there a network called 'KotaSensorBox-....'?"
options = [
{ label = "Yes", next = "end:setup_mode" },
{ label = "No", next = "sd_reseat" },
]
[[guide.step]]
id = "sd_reseat"
type = "info"
text = "The SD card is probably not readable. This needs the case opened: switch the power OFF, open the case, push the SD card in until it clicks (or remove and re-insert it). Close the case, switch the power ON, then press Continue."
next = "sd_verify"
[[guide.step]]
id = "sd_verify"
type = "wait"
text = "Watching the SD card start-up (up to 60 s)..."
until = 'Read INFLUX_URL from \.env file'
fail_on = 'Failed to initialize the card|Failed to mount filesystem|Failed to read INFLUX_(URL|TOKEN)|Failed to open \.env file'
timeout_s = 60
on_ok = "end:sd_fixed"
on_fail = "end:sd_reprovision"
on_timeout = "end:sd_reprovision"
[[guide.end]]
id = "factory_reset"
severity = "info"
title = "White = factory reset in progress"
text = "The box erased its Matter pairing and restarts."
actions = ["Pair it again in the Matter app (Purple LED guide)."]
[[guide.end]]
id = "setup_mode"
severity = "info"
title = "White = Wi-Fi setup mode"
text = "The box is waiting for Wi-Fi settings on its own network."
actions = [
"Connect a phone to KotaSensorBox-.... and open http://sensorbox.local/ to enter the Wi-Fi,",
"or short-press the Matter button (< 2 s) to leave setup mode.",
]
[[guide.end]]
id = "sd_fixed"
severity = "ok"
title = "Fixed - SD card is read again"
text = "The box found the SD card and read ENV.TXT."
actions = ["Close the case and watch the Diagnosis tab for a minute."]
[[guide.end]]
id = "sd_reprovision"
severity = "critical"
title = "SD card is unreadable or has wrong settings"
text = "Even after re-seating, the card or its ENV.TXT cannot be used."
actions = [
"Re-provision the card with the tool (SD card tab) or use a new card.",
"The Diagnosis tab shows which step failed (card, file system or ENV.TXT keys).",
]
# ================================================================== sensors
[[guide]]
id = "sensors"
title = "Red LED - sensor or hardware fault"
summary = "Find the failing sensor and verify after re-seating its cable."
recommend = ["led:RED", "sensor.init_failed", "sensor.selfcheck_failed", "sys.out_of_resources", "ota.selfcheck_failed",
"kota.sensor_missing", "status.error", "status.error.1", "status.error.2", "status.error.3", "status.error.4",
"status.error.5", "status.error.6", "status.oom"]
start = "which"
[[guide.step]]
id = "which"
type = "route"
routes = { "sensor.init_failed" = "reseat", "rtc.init_failed" = "guide:rtc_i2c", "ota.selfcheck_failed" = "end:selfcheck", "sensor.selfcheck_failed" = "end:selfcheck", "sys.out_of_resources" = "end:oom" }
default = "capture"
[[guide.step]]
id = "capture"
type = "wait"
text = "The log does not show the cause yet. The tool restarts the box and records its start-up (45 s)..."
tool_action = "reset"
timeout_s = 45
pass_on_timeout = true
on_ok = "which_again"
[[guide.step]]
id = "which_again"
type = "route"
routes = { "sensor.init_failed" = "reseat", "rtc.init_failed" = "guide:rtc_i2c", "sys.out_of_resources" = "end:oom" }
default = "end:red_unclear"
[[guide.step]]
id = "reseat"
type = "info"
text = "Failing: {failing_sensors}. This needs the case opened: switch the power OFF, open the case and re-seat the cable of that sensor. Close the case, switch the power ON, then press Continue."
next = "verify"
[[guide.step]]
id = "verify"
type = "wait"
text = "Watching the sensor start-up (up to 60 s)..."
until_milestone = "sensors_ready"
fail_on = 'MAIN: Failed to initialize'
timeout_s = 60
on_ok = "end:sensor_fixed"
on_fail = "end:sensor_replace"
on_timeout = "end:sensor_replace"
[[guide.end]]
id = "sensor_fixed"
severity = "ok"
title = "Fixed - all sensors start again"
text = "After re-seating, every sensor started."
actions = ["Close the case and watch the Diagnosis tab for a minute."]
[[guide.end]]
id = "sensor_replace"
severity = "error"
title = "Sensor still fails - replace it"
text = "The sensor does not start even with a re-seated cable."
actions = ["Replace the named sensor (or its cable) and run this check again."]
[[guide.end]]
id = "selfcheck"
severity = "error"
title = "A firmware update was rejected by its self-check"
text = "The box rolled back to its previous firmware because a sensor failed the test."
actions = ["Check the sensor named in the Diagnosis tab (inside the case), then power-cycle."]
[[guide.end]]
id = "oom"
severity = "error"
title = "Firmware ran out of memory"
text = "Not a hardware fault; the firmware restarts itself."
actions = ["Power-cycle. If it repeats, send the session log to the firmware team."]
[[guide.end]]
id = "red_unclear"
severity = "warning"
title = "Red LED without a clear cause in the log"
text = "The start-up did not show a failing sensor."
actions = ["Save the session log and send it to the firmware team."]
# ============================================================= reboot loop
[[guide]]
id = "reboot_loop"
title = "LED keeps changing / box restarts"
summary = "Record several start-ups and find the error just before each restart."
recommend = ["led:CYCLING", "reboot.loop", "sys.crash", "reboot.unexpected", "reboot.brownout", "reboot.watchdog",
"reboot.crash", "reboot.status_watchdog", "reboot.status_oom_watchdog"]
start = "record"
[[guide.step]]
id = "record"
type = "wait"
text = "The tool restarts the box and records 45 seconds of start-up..."
tool_action = "reset"
timeout_s = 45
pass_on_timeout = true
on_ok = "cause"
[[guide.step]]
id = "cause"
type = "route"
routes = { "rtc.init_failed" = "guide:rtc_i2c", "sd.card_fail" = "guide:white", "sd.mount_fail" = "guide:white", "sd.env_open_fail" = "guide:white", "influx.env_missing" = "guide:white", "influx.init_fail" = "guide:white", "sensor.init_failed" = "guide:sensors", "reboot.brownout" = "end:power_supply", "matter.not_commissioned" = "guide:network", "net.dns_fail" = "guide:network", "influx.buffer_fail" = "guide:network" }
default = "end:loop_unclear"
[[guide.end]]
id = "power_supply"
severity = "error"
title = "Power supply is too weak or unstable"
text = "The chip reset itself because the voltage dropped."
actions = ["Check the power supply, cable and connectors; try another supply."]
[[guide.end]]
id = "loop_unclear"
severity = "warning"
title = "No clear restart cause in 45 s"
text = "The box did not show a known start-up error during the recording."
actions = ["Keep the tool connected for 5 minutes, then save the session log for the firmware team."]
# ================================================================== update
[[guide]]
id = "update"
title = "Yellow / orange LED - firmware update"
summary = "Wait for the update and its self-check to finish."
recommend = ["led:YELLOW", "led:ORANGE", "ota.updating", "ota.selfcheck"]
start = "wait"
[[guide.step]]
id = "wait"
type = "wait"
text = "A firmware update or its self-check is running. Do NOT switch the box off. Waiting up to 10 minutes..."
until = 'Passing selfcheck|OTA update successful'
fail_on = 'OTA update failed|Failing selfcheck'
timeout_s = 600
on_ok = "end:update_ok"
on_fail = "end:update_failed"
on_timeout = "end:update_slow"
[[guide.end]]
id = "update_ok"
severity = "ok"
title = "Update finished"
text = "The new firmware was installed or accepted."
actions = ["Wait for the green LED."]
[[guide.end]]
id = "update_failed"
severity = "error"
title = "Update failed"
text = "The box keeps its current firmware and retries later."
actions = ["Check the Wi-Fi is stable. The Diagnosis tab shows why it failed."]
[[guide.end]]
id = "update_slow"
severity = "warning"
title = "Update is taking very long"
text = "No end of the update was seen in 10 minutes."
actions = ["Check the Wi-Fi signal; leave the box powered and check again later."]
# =================================================================== power
[[guide]]
id = "power"
title = "LED off"
summary = "Power switch, heartbeat LED and USB connection."
recommend = ["led:OFF"]
start = "switch"
[[guide.step]]
id = "switch"
type = "question"
text = "Is the power switch on the outside of the case set to ON?"
options = [
{ label = "It was OFF - I switched it on", next = "boot" },
{ label = "It is ON", next = "heartbeat" },
]
[[guide.step]]
id = "boot"
type = "wait"
text = "Waiting for the box to start (up to 30 s)..."
until_milestone = "app_started"
timeout_s = 30
on_ok = "end:was_off"
on_timeout = "heartbeat"
[[guide.step]]
id = "heartbeat"
type = "question"
text = "Is the small LED next to the RGB LED blinking?"
options = [
{ label = "Yes, blinking", next = "end:rgb_led_fault" },
{ label = "No", next = "end:no_power" },
]
[[guide.end]]
id = "was_off"
severity = "ok"
title = "Box was switched off"
text = "It starts normally after switching on."
actions = ["Run the Quick check again once the LED shows a colour."]
[[guide.end]]
id = "rgb_led_fault"
severity = "warning"
title = "Firmware runs, but the RGB LED stays dark"
text = "The heartbeat LED shows the firmware is running; the RGB LED or its wiring is faulty."
actions = ["Use the Diagnosis tab instead of the LED; replace the LED board when convenient."]
[[guide.end]]
id = "no_power"
severity = "error"
title = "Box does not start"
text = "Neither LED is lit: no power or the firmware does not start."
actions = [
"Check the power supply and cable.",
"If the USB port shows up in this tool, re-flash the official firmware (Flash firmware tab, App only).",
]
# =================================================================== clock
[[guide]]
id = "clock"
title = "Clock not set"
summary = "Why readings are on hold and when the coin cell matters."
recommend = ["rtc.clock_not_running", "rtc.lost_after_sync", "kota.rtc_stopped", "kota.rtc_not_ticking", "kota.time_invalid"]
start = "internet"
[[guide.step]]
id = "internet"
type = "question"
text = "The box clock is not set, so readings are on hold. Will the box have Internet at its installation site?"
options = [
{ label = "Yes", next = "end:clock_auto" },
{ label = "No / not yet", next = "end:clock_offline" },
]
[[guide.end]]
id = "clock_auto"
severity = "info"
title = "Clock will be set automatically"
text = "On its first Internet connection the box sets its clock and starts recording."
actions = ["If the clock is lost again after every power-off, replace the RTC coin cell (inside the case)."]
[[guide.end]]
id = "clock_offline"
severity = "error"
title = "Box will not record data without Internet"
text = "Without the Internet the clock cannot be set, and the firmware holds all readings until it is."
actions = [
"Give the box Internet access (pair it in Matter).",
"Replace the RTC coin cell (inside the case) so the time survives power-offs.",
]
# ===================================================================== mic
[[guide]]
id = "mic"
title = "Microphone check"
summary = "Switched-off or silent microphone."
recommend = ["mic.disabled", "mic.silent", "mic.read_fail"]
start = "which"
[[guide.step]]
id = "which"
type = "route"
routes = { "mic.disabled" = "switch", "mic.silent" = "clap", "mic.read_fail" = "end:mic_faulty" }
default = "clap"
[[guide.step]]
id = "switch"
type = "question"
text = "The box reads its microphone switch as OFF. The switch is on the back of the case, just above the power switch (no need to open the box). Should this box measure noise?"
options = [
{ label = "Yes - I flipped the microphone switch", next = "switch_verify" },
{ label = "No - it is meant to be off", next = "end:mic_off_ok" },
]
[[guide.step]]
id = "switch_verify"
type = "wait"
# The firmware re-reads the switch before every reading (~10 s): no restart needed.
text = "Waiting for the next microphone reading (up to 30 s)..."
until = 'MICROPHONE: Read \d+ bytes'
fail_on = 'Microphone is in shutdown state'
timeout_s = 30
on_ok = "end:mic_on"
on_fail = "flip_back"
on_timeout = "flip_back"
[[guide.step]]
id = "flip_back"
type = "question"
text = "The box still reads the switch as OFF. Flip the microphone switch to the other position (it may have been ON already)."
options = [
{ label = "Done - I flipped it to the other position", next = "switch_verify2" },
{ label = "Leave it off", next = "end:mic_off_ok" },
]
[[guide.step]]
id = "switch_verify2"
type = "wait"
text = "Waiting for the next microphone reading (up to 30 s)..."
until = 'MICROPHONE: Read \d+ bytes'
fail_on = 'Microphone is in shutdown state'
timeout_s = 30
on_ok = "end:mic_on"
on_fail = "end:mic_switch_faulty"
on_timeout = "end:mic_switch_faulty"
[[guide.step]]
id = "clap"
type = "wait"
text = "Check the microphone switch (back of the case, above the power switch) is ON. Then clap your hands or speak loudly right next to the box for about 20 seconds..."
until = 'dB peak: (?!-inf)'
timeout_s = 45
on_ok = "end:mic_ok"
on_timeout = "end:mic_faulty"
[[guide.end]]
id = "mic_on"
severity = "ok"
title = "Microphone is on and recording"
text = "The firmware reads audio samples again."
actions = ["Leave the microphone switch in this position."]
[[guide.end]]
id = "mic_off_ok"
severity = "info"
title = "Microphone intentionally off"
text = "No noise data is recorded for this box; everything else works."
actions = []
[[guide.end]]
id = "mic_switch_faulty"
severity = "warning"
title = "Microphone switch has no effect"
text = "The box reads the microphone as OFF in both switch positions (enable line GPIO3)."
actions = ["Check the switch and its cable to the main board (inside the case); replace the switch if needed."]
[[guide.end]]
id = "mic_ok"
severity = "ok"
title = "Microphone works"
text = "It picked up sound - the earlier silence was just a very quiet room."
actions = []
[[guide.end]]
id = "mic_faulty"
severity = "error"
title = "Microphone records nothing"
text = "Even loud noise next to the box gives no signal, although the switch is on."
actions = ["Check the microphone board/cable (inside the case); replace the microphone if needed."]