"""Quick-start cheat sheet shown on launch. LED table for firmware 1.0.16+ (firmware-diagnostics-what-changed.md, status.cpp Status::pattern_for): colour AND pattern name the fault. Older boxes (v1.0, built Jun 29 2026) show the same colours, always solid. """ # (swatch colour, LED name, pattern -> meaning, first action) LED_TABLE = [ ("#2e9e44", "Green", "solid: everything OK.", "Nothing to do."), ("#1fc8d8", "Cyan", "breathing: not paired in Matter yet
fast blink: a phone is connected for pairing.", "Pair the box in the Matter app (QR sticker or the QR code in the tool)."), ("#f4f4f4", "White", "fast blink: SD card or ENV.TXT error
solid: factory reset (Matter button held 5 s)
" "breathing: Wi-Fi setup portal.", "SD card is inside the case: re-seat or re-provision it. Setup portal: short-press the button to leave."), ("#d64541", "Red", "1-6 pulses: 1 BME688, 2 SEN66, 3 AS7341, 4 microphone, 5 flicker, 6 self-check failed
" "solid: other internal error / out of memory.", "Count the pulses, then check that sensor's cable. The box restarts itself after 150 s."), ("#2f6fd6", "Blue", "1 pulse: clock (RTC) not responding
2 pulses: I2C bus stuck (shorted / broken sensor cable).", "Check the I2C cable between the boards first, then the RTC module."), ("#8e44ad", "Purple", "solid: no network
blinking: server rejected the box (wrong ENV.TXT credentials).", "Solid: check Wi-Fi / Internet. Blinking: re-provision the SD card with the current ENV.TXT."), ("#e6c229", "Yellow", "blinking, faster over time: downloading an update.", "Do not switch off. Wait."), ("#f08c1a", "Orange", "solid: self-check after an update (~2.5 min).", "Wait; should turn green (or red on failure)."), ("#444444", "Off", "Firmware did not start (or crashed very early).", "Check power switch & USB cable. If the small LED is also dark: re-flash."), ] HINTS = [ "Before a self-restart the LED flashes the error colour 3 times; after the restart it " "shows the previous error for 3 s. So a reboot loop shows its cause. Connect serial and press " "Reset & capture: the tool reads the restart reason from the box.", "Small LED next to the RGB LED (heartbeat): blinks once per second while online, " "double-blinks while offline. Dark or steady = firmware hung or not running.", "Serial monitor: lines starting with KOTA: are the box's own diagnosis (boot, I2C, SD, " "clock, Matter, microphone, status, LED, and a health line every 60 s). The Diagnosis panel reads them " "directly; filter the view with KOTA diagnostics + errors. Error lines carry a code like " "[E-SD-03] - the tool shows the recommended action for it.", "Outside the case (back): power switch, the microphone switch just above it " "(off = no noise measurements), and the Matter button. Holding the " "Matter button 5 s factory-resets the box (it forgets its Matter " "network and must be commissioned again with the sticker QR code).", "Inside the case (unscrew): RESET and BOOT buttons and the SD card. " "Normally not needed - the tool resets the board over USB.", "Flashing uses only the firmware files in the tool's firmware folder; choose the build " "by its compile date.", ] STEPS = [ "Switch the sensorbox power switch ON.", "Connect the laptop to the box's native USB port with a data-capable cable.", "Open the Serial monitor tab, choose the sensorbox port, press " "Connect.", "Press Reset & capture to record a full boot log from the first line.", "Read the Diagnosis panel on the right, then open Guided troubleshooting " "and start Quick check: the tool asks what you see and checks the log live.", ] def cheatsheet_html() -> str: rows = "".join( f"      {name}" f"{meaning}{action}" for c, name, meaning, action in LED_TABLE ) steps = "".join(f"
  • {s}
  • " for s in STEPS) hints = "".join(f"
  • {h}
  • " for h in HINTS) return f"""

    Sensorbox quick start

      {steps}

    RGB status LED - colour and pattern

    {rows}
    LED Pattern: meaning First action

    Good to know

    """