Technician tool v0.7
Imported from the Google Drive folder 004-technician_tool/v0.7.
This commit is contained in:
1 parent
22bd853ecf
commit
dd915b5a74
29 files changed
+8429
-3981
No files matched your search
+999
-583
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,193 @@
|
||||
id,module,severity,message,action
|
||||
E-SD-01,SD,error,Failed to take SPI mutex,Internal error - send the log to the firmware team
|
||||
E-SD-02,SD,error,"Failed to mount filesystem. If you want the card to be formatted, set the CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option.",SD card is not FAT formatted or is corrupt; reformat it as FAT32 and restore ENV.TXT
|
||||
E-SD-03,SD,error,Failed to initialize the card (%s). Make sure SD card lines have pull-up resistors in place.,Reseat the SD card; if it persists replace the card or check the SD connector
|
||||
E-SD-04,SD,error,Failed to stat %s,Reseat the SD card; if it persists replace the card or check the SD connector
|
||||
E-SD-05,SD,error,Failed to take SPI mutex,Internal error - send the log to the firmware team
|
||||
E-ENV-01,ENV,error,Failed to take SPI mutex,Internal error - send the log to the firmware team
|
||||
E-ENV-02,ENV,error,Failed to open .env file for reading,Check ENV.TXT on the SD card exists and has NAME=VALUE lines
|
||||
E-ENV-03,ENV,error,Failed to take SPI mutex,Internal error - send the log to the firmware team
|
||||
E-ENV-04,ENV,error,Failed to open existing .env file for reading; aborting write to avoid losing other variables,Check ENV.TXT on the SD card exists and has NAME=VALUE lines
|
||||
E-ENV-05,ENV,error,Failed to open .env file for writing,Check ENV.TXT on the SD card exists and has NAME=VALUE lines
|
||||
E-ENV-06,ENV,error,Failed to take SPI mutex,Internal error - send the log to the firmware team
|
||||
E-ENV-07,ENV,error,Failed to open existing .env file for reading; aborting delete to avoid losing other variables,Check ENV.TXT on the SD card exists and has NAME=VALUE lines
|
||||
E-ENV-08,ENV,error,Failed to open .env file for writing,Check ENV.TXT on the SD card exists and has NAME=VALUE lines
|
||||
E-ENV-09,ENV,error,Failed to take SPI mutex,Internal error - send the log to the firmware team
|
||||
E-INF-01,INF,error,Error %d at %s:%d,Internal error - send the log to the firmware team
|
||||
E-INF-02,INF,error,Failed to initialize HTTP client,Internal error - send the log to the firmware team
|
||||
E-INF-03,INF,error,"Failed to perform HTTP request: %d, %s",Check the network connection and INFLUX_URL / INFLUX_TOKEN in ENV.TXT
|
||||
E-INF-04,INF,error,"Bad request, check line protocol format: %s",Check the network connection and INFLUX_URL / INFLUX_TOKEN in ENV.TXT
|
||||
E-INF-05,INF,error,Failed to read INFLUX_URL from .env file,Check the network connection and INFLUX_URL / INFLUX_TOKEN in ENV.TXT
|
||||
E-INF-06,INF,error,Failed to read INFLUX_TOKEN from .env file,Check the network connection and INFLUX_URL / INFLUX_TOKEN in ENV.TXT
|
||||
E-INF-07,INF,error,Failed to take SPI mutex,Internal error - send the log to the firmware team
|
||||
E-INF-08,INF,error,Failed to open buffer file for reading,Check the network connection and INFLUX_URL / INFLUX_TOKEN in ENV.TXT
|
||||
E-INF-09,INF,error,Failed to take SPI mutex,Internal error - send the log to the firmware team
|
||||
E-INF-10,INF,error,Failed to open buffer file for clearing,Check the network connection and INFLUX_URL / INFLUX_TOKEN in ENV.TXT
|
||||
E-INF-11,INF,error,Failed to take SPI mutex,Internal error - send the log to the firmware team
|
||||
E-INF-12,INF,error,Failed to create buffer file,Check the network connection and INFLUX_URL / INFLUX_TOKEN in ENV.TXT
|
||||
E-INF-13,INF,error,Failed to open buffer file for appending,Check the network connection and INFLUX_URL / INFLUX_TOKEN in ENV.TXT
|
||||
E-INF-14,INF,error,Failed to take SPI mutex,Internal error - send the log to the firmware team
|
||||
E-INF-15,INF,error,Failed to open buffer file for counting,Check the network connection and INFLUX_URL / INFLUX_TOKEN in ENV.TXT
|
||||
E-INF-16,INF,error,Failed to read buffer for flushing: %s,Check the network connection and INFLUX_URL / INFLUX_TOKEN in ENV.TXT
|
||||
E-INF-17,INF,error,Failed to write chunk to Influx: %s,Check the network connection and INFLUX_URL / INFLUX_TOKEN in ENV.TXT
|
||||
E-INF-18,INF,error,Failed to write chunk with 5 retries to Influx: %s,Check the network connection and INFLUX_URL / INFLUX_TOKEN in ENV.TXT
|
||||
E-INF-19,INF,error,Failed to clear buffer after flushing: %s,Check the network connection and INFLUX_URL / INFLUX_TOKEN in ENV.TXT
|
||||
E-INF-20,INF,error,Failed to flush buffer before writing: %s,Check the network connection and INFLUX_URL / INFLUX_TOKEN in ENV.TXT
|
||||
E-INF-21,INF,error,Failed to write to Influx: %s,Check the network connection and INFLUX_URL / INFLUX_TOKEN in ENV.TXT
|
||||
E-INF-22,INF,error,Failed to append new entry to buffer: %s,Check the network connection and INFLUX_URL / INFLUX_TOKEN in ENV.TXT
|
||||
E-OTA-01,OTA,error,Error %s at %s:%d,Internal error - send the log to the firmware team
|
||||
E-OTA-02,OTA,error,Failed to create OTA task,Internal error - send the log to the firmware team
|
||||
E-OTA-03,OTA,error,Failed to open NVS: %s,Internal error - send the log to the firmware team
|
||||
E-OTA-04,OTA,error,Failed to read OTA token from NVS: %s,Internal error - send the log to the firmware team
|
||||
E-OTA-05,OTA,error,Failed to read OTA token from NVS: %s,Internal error - send the log to the firmware team
|
||||
E-OTA-06,OTA,error,Failed to get running partition,Check the network connection; if it persists send the log to the firmware team
|
||||
E-OTA-07,OTA,error,Failed to get OTA state,Check the network connection; if it persists send the log to the firmware team
|
||||
E-OTA-08,OTA,error,Failed to read update metadata from NVS: %s,Internal error - send the log to the firmware team
|
||||
E-OTA-09,OTA,error,Failed to report failed selfcheck: %s,Check the network connection; if it persists send the log to the firmware team
|
||||
E-OTA-10,OTA,error,Failed to initialize HTTP client,Internal error - send the log to the firmware team
|
||||
E-OTA-11,OTA,error,Device registration failed with status code: %d,Check the network connection; if it persists send the log to the firmware team
|
||||
E-OTA-12,OTA,error,Device registration failed: %s,Check the network connection; if it persists send the log to the firmware team
|
||||
E-OTA-13,OTA,error,Failed to check for updates: %s,Check the network connection; if it persists send the log to the firmware team
|
||||
E-OTA-14,OTA,error,Free stack size decreased from %u to %u,Internal error - send the log to the firmware team
|
||||
E-OTA-15,OTA,error,Failed to initialize HTTP client,Internal error - send the log to the firmware team
|
||||
E-OTA-16,OTA,error,OTA Update check failed with status code: %d,Check the network connection; if it persists send the log to the firmware team
|
||||
E-OTA-17,OTA,error,"Update %s has already been tried %u times and failed, not trying again",Internal error - send the log to the firmware team
|
||||
E-OTA-18,OTA,error,OTA update failed: %s,Check the network connection; if it persists send the log to the firmware team
|
||||
E-OTA-19,OTA,error,Failed to read update metadata from NVS: %s,Internal error - send the log to the firmware team
|
||||
E-OTA-20,OTA,error,Failed to read update ID from NVS: %s,Internal error - send the log to the firmware team
|
||||
E-OTA-21,OTA,error,Failed to read update ID from NVS: %s,Internal error - send the log to the firmware team
|
||||
E-OTA-22,OTA,error,Failed to read update tries from NVS: %s,Internal error - send the log to the firmware team
|
||||
E-OTA-23,OTA,error,Failing selfcheck: %s,Firmware update failed its self check and will roll back; check the sensors listed in the log
|
||||
E-OTA-24,OTA,error,Failed to send update result: %s,Check the network connection; if it persists send the log to the firmware team
|
||||
E-OTA-25,OTA,error,Failed to mark app as invalid for rollback: %s,Internal error - send the log to the firmware team
|
||||
E-OTA-26,OTA,error,Failed to send update result: %s,Check the network connection; if it persists send the log to the firmware team
|
||||
E-OTA-27,OTA,error,Failed to mark app as valid to commit update: %s,Internal error - send the log to the firmware team
|
||||
E-OTA-28,OTA,error,Failed to initialize HTTP client,Internal error - send the log to the firmware team
|
||||
E-OTA-29,OTA,error,Failed to send update result with status code: %d,Check the network connection; if it persists send the log to the firmware team
|
||||
E-WIFI-01,WIFI,error,esp_netif_init() failed: %s,Check WiFi signal and credentials; re-run WiFi provisioning (short button press)
|
||||
E-WIFI-02,WIFI,error,esp_event_loop_create_default() failed: %s,Check WiFi signal and credentials; re-run WiFi provisioning (short button press)
|
||||
E-WIFI-03,WIFI,error,esp_wifi_init() failed: %s,Check WiFi signal and credentials; re-run WiFi provisioning (short button press)
|
||||
E-WIFI-04,WIFI,error,Failed to register WIFI_EVENT handler: %s,Check WiFi signal and credentials; re-run WiFi provisioning (short button press)
|
||||
E-WIFI-05,WIFI,error,Failed to register IP_EVENT handler: %s,Check WiFi signal and credentials; re-run WiFi provisioning (short button press)
|
||||
E-WIFI-06,WIFI,error,esp_wifi_set_mode() failed: %s,Check WiFi signal and credentials; re-run WiFi provisioning (short button press)
|
||||
E-WIFI-07,WIFI,error,esp_timer_create() failed: %s,Check WiFi signal and credentials; re-run WiFi provisioning (short button press)
|
||||
E-WIFI-08,WIFI,error,esp_wifi_start() failed: %s,Check WiFi signal and credentials; re-run WiFi provisioning (short button press)
|
||||
E-WIFI-09,WIFI,error,esp_wifi_set_config() failed: %s,Check WiFi signal and credentials; re-run WiFi provisioning (short button press)
|
||||
E-WIFI-10,WIFI,error,esp_wifi_connect() failed: %s,Check WiFi signal and credentials; re-run WiFi provisioning (short button press)
|
||||
E-WIFI-11,WIFI,error,esp_wifi_set_mode(APSTA) failed: %s,Check WiFi signal and credentials; re-run WiFi provisioning (short button press)
|
||||
E-WIFI-12,WIFI,error,esp_wifi_set_config(AP) failed: %s,Check WiFi signal and credentials; re-run WiFi provisioning (short button press)
|
||||
E-WIFI-13,WIFI,error,esp_wifi_connect() failed: %s,Check WiFi signal and credentials; re-run WiFi provisioning (short button press)
|
||||
E-WIFI-14,WIFI,error,esp_wifi_scan_start() failed: %s,Check WiFi signal and credentials; re-run WiFi provisioning (short button press)
|
||||
E-WIFI-15,WIFI,error,esp_wifi_scan_get_ap_num() failed: %s,Check WiFi signal and credentials; re-run WiFi provisioning (short button press)
|
||||
E-WIFI-16,WIFI,error,esp_wifi_scan_get_ap_records() failed: %s,Check WiFi signal and credentials; re-run WiFi provisioning (short button press)
|
||||
E-PROV-01,PROV,error,mdns_init() failed: %s,Retry WiFi provisioning (short button press); restart the device if it persists
|
||||
E-PROV-02,PROV,error,httpd_start() failed: %s,Retry WiFi provisioning (short button press); restart the device if it persists
|
||||
E-MAIN-01,MAIN,error,Error %d at %s:%d,Internal error - send the log to the firmware team
|
||||
E-MAIN-02,MAIN,error,"Failed to open commissioning window, err:%",Internal error - send the log to the firmware team
|
||||
E-MAIN-03,MAIN,error,"Attribute update callback: endpoint_id: %u, cluster_id: 0x%lx, attribute_id: 0x%lx",Internal error - send the log to the firmware team
|
||||
E-MAIN-04,MAIN,error,Device MAC address: %02X:%02X:%02X:%02X:%02X:%02X,Internal error - send the log to the firmware team
|
||||
E-MAIN-05,MAIN,error,Failed to initialize SD card: %s,Reseat the SD card; if it persists replace the card or check the SD connector
|
||||
E-MAIN-06,MAIN,error,Failed to initialize EnvironmentService: %s,Check ENV.TXT on the SD card exists and has NAME=VALUE lines
|
||||
E-MAIN-07,MAIN,error,Failed to initialize WifiCredentialsService: %s,Check ENV.TXT on the SD card exists and has NAME=VALUE lines
|
||||
E-MAIN-08,MAIN,error,WiFi provisioning server failed to start: %s; clearing HTTP_SERVER and restarting,Retry WiFi provisioning (short button press); restart the device if it persists
|
||||
E-MAIN-09,MAIN,error,Failed to create Matter node,Internal error - send the log to the firmware team
|
||||
E-MAIN-10,MAIN,error,Failed to start ESP-Matter,Internal error - send the log to the firmware team
|
||||
E-MAIN-11,MAIN,error,Failed to start WifiService: %s,Check WiFi signal and credentials; re-run WiFi provisioning (short button press)
|
||||
E-MAIN-12,MAIN,error,"Failed to initialized the encrypted OTA, err: %d",Internal error - send the log to the firmware team
|
||||
E-MAIN-13,MAIN,error,Failed to initialize RTC: %s,Check the RTC (DS1307) and the sensor cable
|
||||
E-MAIN-14,MAIN,error,Failed to initialize Influx buffer: %s,Check the network connection and INFLUX_URL / INFLUX_TOKEN in ENV.TXT
|
||||
E-MAIN-15,MAIN,error,Failed to initialize BME688: %s,Check the BME688 sensor and the sensor cable
|
||||
E-MAIN-16,MAIN,error,Failed to initialize SEN66: %s,"Check the SEN66 sensor, its power supply and the sensor cable"
|
||||
E-MAIN-17,MAIN,error,Failed to initialize AS7341: %s,Check the AS7341 light sensor and the sensor cable
|
||||
E-MAIN-18,MAIN,error,Failed to initialize Microphone: %s,Check the microphone board and its cable
|
||||
E-MAIN-19,MAIN,error,Failed to initialize Flicker sensor: %s,Check the flicker sensor and its cable
|
||||
E-MAIN-20,MAIN,error,Failed to initialize DeviceStatus: %s,Internal error - send the log to the firmware team
|
||||
E-MAIN-21,MAIN,error,BME688 self check failed: %s,Check the BME688 sensor and the sensor cable
|
||||
E-MAIN-22,MAIN,error,SEN66 self check failed: %s,"Check the SEN66 sensor, its power supply and the sensor cable"
|
||||
E-MAIN-23,MAIN,error,AS7341 self check failed: %s,Check the AS7341 light sensor and the sensor cable
|
||||
E-MAIN-24,MAIN,error,Microphone self check failed: %s,Check the microphone board and its cable
|
||||
E-MAIN-25,MAIN,error,Flicker sensor self check failed: %s,Check the flicker sensor and its cable
|
||||
E-MAIN-26,MAIN,error,Failed to report passed selfcheck: %s,Internal error - send the log to the firmware team
|
||||
E-MAIN-27,MAIN,error,Failed to flush Influx buffer: %s,Check the network connection and INFLUX_URL / INFLUX_TOKEN in ENV.TXT
|
||||
E-STAT-01,STAT,error,Failed to initialize LED strip: %s,Internal error - send the log to the firmware team
|
||||
E-SPI-01,SPI,error,Failed to take SPI mutex,Internal error - send the log to the firmware team
|
||||
E-RTC-01,RTC,error,Failed to take I2C mutex,Internal error - send the log to the firmware team
|
||||
E-RTC-02,RTC,error,Failed to add I2C device: %s,Check the RTC (DS1307) and the sensor cable
|
||||
E-RTC-03,RTC,error,Failed to initialize DS1307 control register: %s,Check the RTC (DS1307) and the sensor cable
|
||||
E-RTC-04,RTC,error,Attempted to set time on uninitialized DS1307,Internal error - send the log to the firmware team
|
||||
E-RTC-05,RTC,error,Failed to take I2C mutex,Internal error - send the log to the firmware team
|
||||
E-RTC-06,RTC,error,Attempted to get time on uninitialized DS1307,Internal error - send the log to the firmware team
|
||||
E-RTC-07,RTC,error,Failed to take I2C mutex,Internal error - send the log to the firmware team
|
||||
E-RTC-08,RTC,error,Attempted to start updating time on uninitialized DS1307,Internal error - send the log to the firmware team
|
||||
E-BME-01,BME,error,Failed to take I2C mutex,Internal error - send the log to the firmware team
|
||||
E-BME-02,BME,error,Failed to add I2C device: %d,Check the BME688 sensor and the sensor cable
|
||||
E-BME-03,BME,error,Failed to initialize BME688: %d,Check the BME688 sensor and the sensor cable
|
||||
E-BME-04,BME,error,Failed to set BME688 configuration: %d,Check the BME688 sensor and the sensor cable
|
||||
E-BME-05,BME,error,Failed to set BME688 heater configuration: %d,Check the BME688 sensor and the sensor cable
|
||||
E-BME-06,BME,error,Failed to set BME688 operation mode: %d,Check the BME688 sensor and the sensor cable
|
||||
E-BME-07,BME,error,Failed to get BME688 data: %d,Check the BME688 sensor and the sensor cable
|
||||
E-BME-08,BME,error,No new data available from BME688,Check the BME688 sensor and the sensor cable
|
||||
E-BME-09,BME,error,Failed to get data from BME688: %s,Check the BME688 sensor and the sensor cable
|
||||
E-BME-10,BME,error,Self check failed: %s,Check the BME688 sensor and the sensor cable
|
||||
E-BME-11,BME,error,Failed to take I2C mutex,Internal error - send the log to the firmware team
|
||||
E-BME-12,BME,error,I2C read failed: %s,Check the BME688 sensor and the sensor cable
|
||||
E-BME-13,BME,error,Failed to take I2C mutex,Internal error - send the log to the firmware team
|
||||
E-BME-14,BME,error,Failed to allocate memory for I2C write buffer,Internal error - send the log to the firmware team
|
||||
E-BME-15,BME,error,I2C write failed: %s,Check the BME688 sensor and the sensor cable
|
||||
E-SEN-01,SEN,error,Failed to take I2C mutex,Internal error - send the log to the firmware team
|
||||
E-SEN-02,SEN,error,Failed to add I2C device: %d,"Check the SEN66 sensor, its power supply and the sensor cable"
|
||||
E-SEN-03,SEN,error,Attempted to wake up uninitialized SEN66,Internal error - send the log to the firmware team
|
||||
E-SEN-04,SEN,error,Failed to take sensor mutex,Internal error - send the log to the firmware team
|
||||
E-SEN-05,SEN,error,Failed to send start measurement command: %d,"Check the SEN66 sensor, its power supply and the sensor cable"
|
||||
E-SEN-06,SEN,error,Attempted to sleep uninitialized SEN66,Internal error - send the log to the firmware team
|
||||
E-SEN-07,SEN,error,Failed to take sensor mutex,Internal error - send the log to the firmware team
|
||||
E-SEN-08,SEN,error,Failed to send stop measurement command: %d,"Check the SEN66 sensor, its power supply and the sensor cable"
|
||||
E-SEN-09,SEN,error,Failed to take I2C mutex,Internal error - send the log to the firmware team
|
||||
E-SEN-10,SEN,error,Failed to take I2C mutex,Internal error - send the log to the firmware team
|
||||
E-SEN-11,SEN,error,Failed to read ready status: %d,"Check the SEN66 sensor, its power supply and the sensor cable"
|
||||
E-SEN-12,SEN,error,"Sensor not ready after %d attempts, trying to wake it up","Check the SEN66 sensor, its power supply and the sensor cable"
|
||||
E-SEN-13,SEN,error,Failed to read measurement: %d,"Check the SEN66 sensor, its power supply and the sensor cable"
|
||||
E-SEN-14,SEN,error,Failed while awaiting sensor ready: %d,"Check the SEN66 sensor, its power supply and the sensor cable"
|
||||
E-SEN-15,SEN,error,Failed to read measurement for line protocol: %d,"Check the SEN66 sensor, its power supply and the sensor cable"
|
||||
E-SEN-16,SEN,error,Self-check failed: Sensor not ready: %d,"Check the SEN66 sensor, its power supply and the sensor cable"
|
||||
E-SEN-17,SEN,error,Self-check failed: Failed to read measurement: %d,"Check the SEN66 sensor, its power supply and the sensor cable"
|
||||
E-AS-01,AS,error,Failed to take I2C mutex,Internal error - send the log to the firmware team
|
||||
E-AS-02,AS,error,Failed to initialize AS7341: %s,Check the AS7341 light sensor and the sensor cable
|
||||
E-AS-03,AS,error,Attempted to wake up uninitialized AS7341,Internal error - send the log to the firmware team
|
||||
E-AS-04,AS,error,Failed to take I2C mutex,Internal error - send the log to the firmware team
|
||||
E-AS-05,AS,error,Failed to wake up AS7341: %s,Check the AS7341 light sensor and the sensor cable
|
||||
E-AS-06,AS,error,Attempted to put uninitialized AS7341 to sleep,Internal error - send the log to the firmware team
|
||||
E-AS-07,AS,error,Failed to take I2C mutex,Internal error - send the log to the firmware team
|
||||
E-AS-08,AS,error,Failed to put AS7341 to sleep: %s,Check the AS7341 light sensor and the sensor cable
|
||||
E-AS-09,AS,error,Attempted to get line protocol on uninitialized AS7341,Internal error - send the log to the firmware team
|
||||
E-AS-10,AS,error,Failed to take I2C mutex,Internal error - send the log to the firmware team
|
||||
E-AS-11,AS,error,Failed to read spectral data: %s,Check the AS7341 light sensor and the sensor cable
|
||||
E-AS-12,AS,error,Failed to read basic counts data: %s,Check the AS7341 light sensor and the sensor cable
|
||||
E-AS-13,AS,error,Failed to read flicker detection state: %s,Check the AS7341 light sensor and the sensor cable
|
||||
E-AS-14,AS,error,Self-check failed: Failed to read spectral data: %s,Check the AS7341 light sensor and the sensor cable
|
||||
E-MIC-01,MIC,error,Failed to create I2S channel: %s,Check the microphone board and its cable
|
||||
E-MIC-02,MIC,error,Failed to initialize I2S channel in standard mode: %s,Check the microphone board and its cable
|
||||
E-MIC-03,MIC,error,Failed to configure shutdown pin: %s,Check the microphone board and its cable
|
||||
E-MIC-04,MIC,error,Failed to read samples from I2S channel: %s,Check the microphone board and its cable
|
||||
E-MIC-05,MIC,error,Failed to read samples for line protocol: %s,Check the microphone board and its cable
|
||||
E-FLK-01,FLK,error,Error %s at %s:%d,Internal error - send the log to the firmware team
|
||||
E-FLK-02,FLK,error,Attempting to initialize sensor that is already initialized,Check the flicker sensor and its cable
|
||||
E-FLK-03,FLK,error,Failed to allocate memory for FFT buffers,Internal error - send the log to the firmware team
|
||||
E-FLK-04,FLK,error,Failed to initialize FFT: %s,Check the flicker sensor and its cable
|
||||
E-FLK-05,FLK,error,Attempting to read from uninitialized sensor,Internal error - send the log to the firmware team
|
||||
E-FLK-06,FLK,error,Failed to take I2C mutex,Internal error - send the log to the firmware team
|
||||
E-FLK-07,FLK,error,Failed to get dominant frequency: %s,Check the flicker sensor and its cable
|
||||
E-FLK-08,FLK,error,Attempting to read from uninitialized sensor,Internal error - send the log to the firmware team
|
||||
E-FLK-09,FLK,error,Failed to read ADC value: %s,Check the flicker sensor and its cable
|
||||
E-FLK-10,FLK,error,Failed to create gather task: %s,Internal error - send the log to the firmware team
|
||||
E-FLK-11,FLK,error,Attempting to self check uninitialized sensor,Internal error - send the log to the firmware team
|
||||
E-FLK-12,FLK,error,Self check failed to get dominant frequency: %s,Check the flicker sensor and its cable
|
||||
E-DEV-01,DEV,error,Failed to initialize ADC unit: %s,Internal error - send the log to the firmware team
|
||||
E-DEV-02,DEV,error,Failed to configure ADC channel: %s,Internal error - send the log to the firmware team
|
||||
E-DEV-03,DEV,error,Failed to install temperature sensor: %s,Internal error - send the log to the firmware team
|
||||
E-DEV-04,DEV,error,Failed to read ADC value: %s,Internal error - send the log to the firmware team
|
||||
E-DEV-05,DEV,error,Failed to allocate memory for task list buffer,Internal error - send the log to the firmware team
|
||||
E-GATH-01,GATH,error,Failed to take line protocol mutex,Internal error - send the log to the firmware team
|
||||
E-GATH-02,GATH,error,Failed to get line protocol from sensor,Device ran out of memory; restart it and send the log to the firmware team
|
||||
E-GATH-03,GATH,error,Failed to create task for sensor,Internal error - send the log to the firmware team
|
||||
E-GATH-04,GATH,error,Failed to create main gather task,Internal error - send the log to the firmware team
|
||||
|
+147
-97
@@ -1,97 +1,147 @@
|
||||
"""Firmware identification from the boot log.
|
||||
|
||||
The app version string is "1.0" in every build seen so far, so builds are
|
||||
told apart by the ELF SHA256 prefix printed by app_init. Boxes receive new
|
||||
firmware over OTA; an unknown SHA usually means a box has already updated.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class KnownFirmware:
|
||||
name: str
|
||||
source: str
|
||||
sd_wifi: bool # reads SSID/PASSWORD from ENV.TXT
|
||||
setup_portal: bool # short press -> Wi-Fi setup portal
|
||||
|
||||
|
||||
KNOWN: dict[str, KnownFirmware] = {
|
||||
"45fa9d5b9": KnownFirmware(
|
||||
name="v1.0 (built Jun 29 2026)",
|
||||
source="factory image new_system.bin",
|
||||
sd_wifi=False,
|
||||
setup_portal=False,
|
||||
),
|
||||
"c94ba0e9b": KnownFirmware(
|
||||
name="v1.0 source build (Sep 26 2026)",
|
||||
source="developer build, built by Krzysztof Kallas",
|
||||
sd_wifi=True,
|
||||
setup_portal=True,
|
||||
),
|
||||
}
|
||||
|
||||
_ELF = re.compile(r"app_init: ELF file SHA256:\s+(?P<sha>[0-9a-f]{6,})")
|
||||
_VER = re.compile(r"app_init: App version:\s+(?P<v>\S+)")
|
||||
_BUILT = re.compile(r"app_init: Compile time:\s+(?P<t>.+)$")
|
||||
_IDF = re.compile(r"app_init: ESP-IDF:\s+(?P<v>\S+)")
|
||||
# Evidence of features, for builds not in KNOWN.
|
||||
_FEATURE_SD_WIFI = re.compile(r"WIFI_CREDENTIALS: ")
|
||||
_FEATURE_PORTAL = re.compile(r"WIFI_PROVISIONING: |Short press: ")
|
||||
# Deployed v1.0 logs the SD mount under the INFLUX_BUFFER tag.
|
||||
_LEGACY_SD_TAG = re.compile(r"INFLUX_BUFFER: SD card mounted")
|
||||
|
||||
|
||||
@dataclass
|
||||
class FirmwareInfo:
|
||||
elf_sha: str | None = None
|
||||
version: str | None = None
|
||||
built: str | None = None
|
||||
idf: str | None = None
|
||||
evidence: set[str] = field(default_factory=set)
|
||||
|
||||
def observe(self, text: str) -> None:
|
||||
if m := _ELF.search(text):
|
||||
self.elf_sha = m.group("sha")
|
||||
elif m := _VER.search(text):
|
||||
self.version = m.group("v")
|
||||
elif m := _BUILT.search(text):
|
||||
self.built = m.group("t").strip()
|
||||
elif m := _IDF.search(text):
|
||||
self.idf = m.group("v")
|
||||
if _FEATURE_SD_WIFI.search(text):
|
||||
self.evidence.add("sd_wifi")
|
||||
if _FEATURE_PORTAL.search(text):
|
||||
self.evidence.add("setup_portal")
|
||||
if _LEGACY_SD_TAG.search(text):
|
||||
self.evidence.add("legacy_v1")
|
||||
|
||||
@property
|
||||
def known(self) -> KnownFirmware | None:
|
||||
if not self.elf_sha:
|
||||
return None
|
||||
return next((k for sha, k in KNOWN.items() if self.elf_sha.startswith(sha)), None)
|
||||
|
||||
@property
|
||||
def supports_sd_wifi(self) -> bool | None:
|
||||
"""True/False when determinable, None when unknown (no boot seen)."""
|
||||
if k := self.known:
|
||||
return k.sd_wifi
|
||||
if "sd_wifi" in self.evidence:
|
||||
return True
|
||||
if "legacy_v1" in self.evidence:
|
||||
return False
|
||||
return None
|
||||
|
||||
def describe(self) -> str:
|
||||
if k := self.known:
|
||||
return f"{k.name} - {k.source}"
|
||||
if self.elf_sha:
|
||||
built = f", built {self.built}" if self.built else ""
|
||||
return f"Unknown build {self.elf_sha[:9]}{built} (probably updated over OTA)"
|
||||
if "legacy_v1" in self.evidence:
|
||||
return "Probably v1.0 factory image (press Reset & capture to confirm)"
|
||||
return "Not identified yet - press Reset & capture"
|
||||
"""Firmware identification from the boot log.
|
||||
|
||||
Up to firmware 1.0 the app version string was "1.0" in every build, so
|
||||
builds are told apart by the ELF SHA256 prefix printed by app_init. Boxes
|
||||
receive new firmware over OTA; an unknown SHA usually means a box has already
|
||||
updated.
|
||||
|
||||
Firmware 1.0.16+ prints "KOTA: boot fw=1.0.16 build=4f10989e ..." (version
|
||||
unique per build, first 8 hex digits of the ELF SHA256). Builds found in the
|
||||
tool's firmware/ folder are registered with `register_local_build` so the
|
||||
box's build can be shown with its compile date.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class KnownFirmware:
|
||||
name: str
|
||||
source: str
|
||||
sd_wifi: bool # reads SSID/PASSWORD from ENV.TXT
|
||||
setup_portal: bool # short press -> Wi-Fi setup portal
|
||||
|
||||
|
||||
KNOWN: dict[str, KnownFirmware] = {
|
||||
"45fa9d5b9": KnownFirmware(
|
||||
name="v1.0 (built Jun 29 2026)",
|
||||
source="factory image new_system.bin",
|
||||
sd_wifi=False,
|
||||
setup_portal=False,
|
||||
),
|
||||
"c94ba0e9b": KnownFirmware(
|
||||
name="v1.0 source build (Sep 26 2026)",
|
||||
source="developer build, built by Krzysztof Kallas",
|
||||
sd_wifi=True,
|
||||
setup_portal=True,
|
||||
),
|
||||
}
|
||||
|
||||
# elf sha (full or prefix) -> (version, compile time, file name) of builds in firmware/
|
||||
LOCAL_BUILDS: dict[str, tuple[str, str, str]] = {}
|
||||
|
||||
|
||||
def register_local_build(elf_sha: str, version: str, built: str, file_name: str) -> None:
|
||||
LOCAL_BUILDS[elf_sha.lower()] = (version, built, file_name)
|
||||
|
||||
|
||||
def same_build(a: str | None, b: str | None) -> bool:
|
||||
"""ELF SHA prefixes of different lengths (8 from KOTA: boot, 9+ from
|
||||
app_init, 64 from an image) name the same build if they agree."""
|
||||
if not a or not b:
|
||||
return False
|
||||
n = min(len(a), len(b))
|
||||
return n >= 6 and a[:n].lower() == b[:n].lower()
|
||||
|
||||
|
||||
def local_build(elf_sha: str | None) -> tuple[str, str, str] | None:
|
||||
return next((v for sha, v in LOCAL_BUILDS.items() if same_build(sha, elf_sha)), None)
|
||||
|
||||
|
||||
_ELF = re.compile(r"app_init: ELF file SHA256:\s+(?P<sha>[0-9a-f]{6,})")
|
||||
_VER = re.compile(r"app_init: App version:\s+(?P<v>\S+)")
|
||||
_BUILT = re.compile(r"app_init: Compile time:\s+(?P<t>.+)$")
|
||||
_IDF = re.compile(r"app_init: ESP-IDF:\s+(?P<v>\S+)")
|
||||
# Evidence of features, for builds not in KNOWN.
|
||||
_FEATURE_SD_WIFI = re.compile(r"WIFI_CREDENTIALS: ")
|
||||
_FEATURE_PORTAL = re.compile(r"WIFI_PROVISIONING: |Short press: ")
|
||||
# Deployed v1.0 logs the SD mount under the INFLUX_BUFFER tag.
|
||||
_LEGACY_SD_TAG = re.compile(r"INFLUX_BUFFER: SD card mounted")
|
||||
|
||||
|
||||
@dataclass
|
||||
class FirmwareInfo:
|
||||
elf_sha: str | None = None
|
||||
version: str | None = None
|
||||
built: str | None = None
|
||||
idf: str | None = None
|
||||
hw: str | None = None
|
||||
evidence: set[str] = field(default_factory=set)
|
||||
|
||||
def observe_kota(self, fields: dict[str, str]) -> None:
|
||||
"""'KOTA: boot fw=1.0.16 build=4f10989e hw=2 ...'"""
|
||||
if fields.get("fw"):
|
||||
self.version = fields["fw"]
|
||||
build = fields.get("build", "")
|
||||
# app_init's longer prefix is kept if it agrees.
|
||||
if build and not same_build(self.elf_sha, build):
|
||||
self.elf_sha = build.lower()
|
||||
if fields.get("hw"):
|
||||
self.hw = fields["hw"]
|
||||
self.evidence.add("kota") # 1.0.16+: SD Wi-Fi and setup portal exist
|
||||
|
||||
def observe(self, text: str) -> None:
|
||||
if m := _ELF.search(text):
|
||||
self.elf_sha = m.group("sha")
|
||||
elif m := _VER.search(text):
|
||||
self.version = m.group("v")
|
||||
elif m := _BUILT.search(text):
|
||||
self.built = m.group("t").strip()
|
||||
elif m := _IDF.search(text):
|
||||
self.idf = m.group("v")
|
||||
if _FEATURE_SD_WIFI.search(text):
|
||||
self.evidence.add("sd_wifi")
|
||||
if _FEATURE_PORTAL.search(text):
|
||||
self.evidence.add("setup_portal")
|
||||
if _LEGACY_SD_TAG.search(text):
|
||||
self.evidence.add("legacy_v1")
|
||||
|
||||
@property
|
||||
def known(self) -> KnownFirmware | None:
|
||||
if not self.elf_sha:
|
||||
return None
|
||||
return next((k for sha, k in KNOWN.items() if same_build(self.elf_sha, sha)), None)
|
||||
|
||||
@property
|
||||
def supports_sd_wifi(self) -> bool | None:
|
||||
"""True/False when determinable, None when unknown (no boot seen)."""
|
||||
if k := self.known:
|
||||
return k.sd_wifi
|
||||
if "sd_wifi" in self.evidence or "kota" in self.evidence:
|
||||
return True
|
||||
if "legacy_v1" in self.evidence:
|
||||
return False
|
||||
return None
|
||||
|
||||
def describe(self) -> str:
|
||||
if k := self.known:
|
||||
return f"{k.name} - {k.source}"
|
||||
if self.elf_sha and (self.version not in (None, "1.0") or local_build(self.elf_sha)):
|
||||
local = local_build(self.elf_sha)
|
||||
built = self.built or (local[1] if local else None)
|
||||
text = f"v{self.version or (local[0] if local else '?')} (build {self.elf_sha[:8]}"
|
||||
text += f", compiled {built})" if built else ")"
|
||||
if self.hw:
|
||||
text += f", hardware {self.hw}"
|
||||
if local:
|
||||
text += f" - same as firmware/{local[2]}"
|
||||
return text
|
||||
if self.elf_sha:
|
||||
built = f", built {self.built}" if self.built else ""
|
||||
return f"Unknown build {self.elf_sha[:9]}{built} (probably updated over OTA)"
|
||||
if "legacy_v1" in self.evidence:
|
||||
return "Probably v1.0 factory image (press Reset & capture to confirm)"
|
||||
return "Not identified yet - press Reset & capture"
|
||||
@@ -21,7 +21,7 @@ from .engine import LED, DiagnosticsEngine, Severity
|
||||
|
||||
GUIDES_PATH = Path(__file__).with_name("guides.toml")
|
||||
# LED answers a technician can give (engine colours + a reboot-loop pattern).
|
||||
LED_ANSWERS = ["GREEN", "PURPLE", "RED", "BLUE", "WHITE", "YELLOW", "ORANGE", "OFF", "CYCLING"]
|
||||
LED_ANSWERS = ["GREEN", "PURPLE", "RED", "BLUE", "WHITE", "YELLOW", "ORANGE", "CYAN", "OFF", "CYCLING"]
|
||||
LED_ANSWER_LABELS = {**{k: v[0] for k, v in LED.items()},
|
||||
"CYCLING": "Keeps changing / goes dark every few seconds"}
|
||||
STEP_TYPES = {"led", "question", "info", "wait", "route"}
|
||||
|
||||
+740
-735
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,263 @@
|
||||
"""Knowledge about the structured "KOTA:" lines of firmware 1.0.16+.
|
||||
|
||||
Firmware source of truth (kota-sensorboard/main):
|
||||
boot_info.cpp "boot fw=.. build=.. hw=.. mac=.. reset=.. mode=.. commissioned=.. last_restart=.."
|
||||
"restart reason=.." (W, printed just before a self-restart)
|
||||
status.cpp "status A -> B [code=N] reason=x", "led color=.. pattern=.. [n=..|period=..ms]",
|
||||
"led previous_boot status=.. code=..", "led restart_flash color=.."
|
||||
i2c.cpp "i2c SDA=1 SCL=1 0x39=AS7341 0x68=DS1307(missing) .. [bus=stuck]"
|
||||
ds1307.cpp "rtc running=1 time=..", "rtc read_failed err=..", "rtc verify running=1 delta=2s ok=1"
|
||||
sd_card.cpp "sd type=.. size=.. fs=.. free=.. env_keys=A,B buffer_lines=N", "sd mounted=0 [err=..]"
|
||||
main.cpp "matter fabrics=N window=open|closed qr=MT:.. manual=.."
|
||||
microphone.cpp "mic enabled=0 (GPIO3=1, expected 0)"
|
||||
health.cpp "health up=60s status=OK wifi=connected rssi=-61 time_valid=1 sd=ok buffer=0
|
||||
heap=123456 psram=7.8M last_upload=12s|never ota=registered|unregistered|selfcheck"
|
||||
|
||||
Error IDs ("[E-SD-03] ...") come from error_ids.csv, a copy of the
|
||||
firmware's docs/error_ids.csv (the firmware build generates its IDs from it).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import csv
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
ERROR_IDS_PATH = Path(__file__).with_name("error_ids.csv")
|
||||
|
||||
# Firmware colour names (status.cpp colors[]) -> engine LED keys.
|
||||
LED_COLOURS = {
|
||||
"green": "GREEN", "cyan": "CYAN", "white": "WHITE", "red": "RED",
|
||||
"blue": "BLUE", "purple": "PURPLE", "yellow": "YELLOW", "orange": "ORANGE",
|
||||
}
|
||||
|
||||
RED_CODES = {1: "BME688", 2: "SEN66", 3: "AS7341", 4: "Microphone", 5: "Flicker sensor", 6: "Self-check"}
|
||||
I2C_DEVICES = {"0x39": "AS7341", "0x68": "DS1307", "0x6B": "SEN66", "0x76": "BME688"}
|
||||
|
||||
# last_restart values written by kota_restart() that are part of normal
|
||||
# operation (button presses, a finished setup, an installed update).
|
||||
INTENTIONAL_RESTARTS = {
|
||||
"ota_update", "button_provisioning_abort", "button_wifi_cleared",
|
||||
"button_provisioning_toggle", "provisioning_saved",
|
||||
}
|
||||
|
||||
MODULES = {
|
||||
"SD": "SD card", "ENV": "ENV.TXT", "INF": "InfluxDB upload", "OTA": "Firmware update",
|
||||
"WIFI": "Wi-Fi", "PROV": "Wi-Fi setup", "MAIN": "Start-up", "STAT": "Status LED", "SPI": "SPI bus",
|
||||
"RTC": "Clock (RTC)", "BME": "BME688", "SEN": "SEN66", "AS": "AS7341", "MIC": "Microphone",
|
||||
"FLK": "Flicker sensor", "DEV": "Device", "GATH": "Sensor readings",
|
||||
}
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ErrorId:
|
||||
id: str
|
||||
module: str
|
||||
severity: str # error | warning | retired
|
||||
message: str
|
||||
action: str
|
||||
|
||||
@property
|
||||
def module_name(self) -> str:
|
||||
return MODULES.get(self.module, self.module)
|
||||
|
||||
|
||||
def load_error_ids(path: Path = ERROR_IDS_PATH) -> dict[str, ErrorId]:
|
||||
if not path.exists():
|
||||
return {}
|
||||
with path.open(encoding="utf-8", newline="") as fh:
|
||||
return {r["id"]: ErrorId(r["id"], r["module"], r["severity"], r["message"], r["action"])
|
||||
for r in csv.DictReader(fh)}
|
||||
|
||||
|
||||
def led_for_status(status: str, code: int) -> tuple[str, str]:
|
||||
"""(LED key, pattern text) for a status - mirrors Status::pattern_for().
|
||||
Used when the box's own "led" line was not captured (connected mid-run)."""
|
||||
if status == "OK":
|
||||
return "GREEN", "solid"
|
||||
if status == "ERROR":
|
||||
return ("RED", f"{code} pulses") if 1 <= code <= 6 else ("RED", "solid")
|
||||
if status == "OUT_OF_RESOURCES":
|
||||
return "RED", "solid"
|
||||
if status == "UPDATING":
|
||||
return "YELLOW", "blinking"
|
||||
if status == "SELF_CHECK":
|
||||
return "ORANGE", "solid"
|
||||
if status == "CONNECTION_ERROR":
|
||||
return ("PURPLE", "blinking") if code == 1 else ("PURPLE", "solid")
|
||||
if status == "RTC_ERROR":
|
||||
return "BLUE", "2 pulses" if code == 2 else "1 pulse"
|
||||
if status == "SD_ERROR":
|
||||
return "WHITE", "fast blinking"
|
||||
if status == "RESETING":
|
||||
return "WHITE", "solid"
|
||||
if status == "HTTP_SERVER":
|
||||
return "WHITE", "breathing"
|
||||
return "UNKNOWN", ""
|
||||
|
||||
|
||||
def pattern_text(fields: dict[str, str]) -> str:
|
||||
"""'led color=red pattern=pulses n=2' -> '2 pulses'."""
|
||||
p = fields.get("pattern", "")
|
||||
if p == "pulses":
|
||||
n = fields.get("n", "?")
|
||||
return f"{n} pulse" if n == "1" else f"{n} pulses"
|
||||
if p == "blink":
|
||||
period = fields.get("period", "").removesuffix("ms")
|
||||
fast = period.isdigit() and int(period) <= 500
|
||||
return ("fast blinking" if fast else "blinking") + (f" ({period} ms)" if period else "")
|
||||
if p == "breathe":
|
||||
return "breathing"
|
||||
return p # solid / off
|
||||
|
||||
|
||||
def led_meaning(colour: str, pattern: str) -> str:
|
||||
"""Technician meaning of a colour + pattern (firmware diagnostics doc)."""
|
||||
if colour == "GREEN":
|
||||
return "OK"
|
||||
if colour == "CYAN":
|
||||
return "phone connected for pairing" if "fast" in pattern else "waiting to be paired in Matter"
|
||||
if colour == "WHITE":
|
||||
if "fast" in pattern:
|
||||
return "SD card or ENV.TXT error"
|
||||
if "breath" in pattern:
|
||||
return "Wi-Fi setup portal"
|
||||
return "factory reset"
|
||||
if colour == "RED":
|
||||
if "pulse" in pattern:
|
||||
n = int(pattern.split()[0]) if pattern.split()[0].isdigit() else 0
|
||||
return f"{RED_CODES.get(n, 'sensor')} failed"
|
||||
return "internal error / out of memory"
|
||||
if colour == "BLUE":
|
||||
return "I2C bus stuck (sensor cable)" if pattern.startswith("2") else "clock (RTC) not responding"
|
||||
if colour == "PURPLE":
|
||||
return "server rejected the box (check ENV.TXT credentials)" if "blink" in pattern else "no network"
|
||||
if colour == "YELLOW":
|
||||
return "downloading a firmware update"
|
||||
if colour == "ORANGE":
|
||||
return "self-check after an update"
|
||||
return ""
|
||||
|
||||
|
||||
# Finding for the current firmware status (Status::set_status). key suffix ->
|
||||
# (severity, title, meaning, actions, explained_by). The status finding is
|
||||
# grouped under a more specific finding when one explains it.
|
||||
_SENSOR_ROOTS = ("sensor.init_failed", "sensor.selfcheck_failed", "kota.i2c_stuck", "kota.sensor_missing",
|
||||
"sen66.not_ready", "bme688.read_fail", "as7341.read_fail", "mic.read_fail",
|
||||
"ota.selfcheck_failed")
|
||||
_NET_ROOTS = ("matter.not_commissioned", "wifi.disconnected", "wifi.setup_portal", "kota.wifi_down",
|
||||
"net.dns_fail", "net.tls_fail")
|
||||
|
||||
|
||||
def status_finding(status: str, code: int) -> tuple[str, str, str, str, tuple[str, ...], tuple[str, ...]] | None:
|
||||
"""(key, severity, title, meaning, actions, explained_by) or None for healthy states."""
|
||||
if status == "ERROR":
|
||||
if 1 <= code <= 5:
|
||||
s = RED_CODES[code]
|
||||
return (f"status.error.{code}", "critical", f"{s} fault (LED red, {code} pulses)",
|
||||
f"The firmware reports the {s} as failed.",
|
||||
(f"Open the case and check the {s} connector/cable.",
|
||||
"If several sensors fail: check the shared I2C cable.",
|
||||
"The box restarts itself after 150 s in this state."), _SENSOR_ROOTS)
|
||||
if code == 6:
|
||||
return ("status.error.6", "error", "Post-update self-check failed (LED red, 6 pulses)",
|
||||
"The new firmware failed its self-check and rolls back.",
|
||||
("Check the sensor named in the log (inside the case), then power-cycle.",), _SENSOR_ROOTS)
|
||||
return ("status.error", "error", "Internal error (LED red)",
|
||||
"The firmware is in its general error state.",
|
||||
("Save the session log and send it to the firmware team.",
|
||||
"The box restarts itself after 150 s in this state."), _SENSOR_ROOTS)
|
||||
if status == "OUT_OF_RESOURCES":
|
||||
return ("status.oom", "error", "Firmware ran out of memory (LED red)",
|
||||
"The firmware could not allocate memory; it restarts itself after 30 s.",
|
||||
("Power-cycle. If it repeats, save the session log for the firmware team.",),
|
||||
("sys.out_of_resources",))
|
||||
if status == "CONNECTION_ERROR":
|
||||
if code == 1:
|
||||
return ("status.conn.1", "critical", "Server rejected the box (LED purple, blinking)",
|
||||
"The network works but the server refused the box (HTTP 401/403/404): "
|
||||
"INFLUX_URL / INFLUX_TOKEN in ENV.TXT are wrong or revoked.",
|
||||
("Re-provision the SD card with the current ENV.TXT (SD card is inside the case).",),
|
||||
("influx.auth", "influx.not_found"))
|
||||
return ("status.conn", "error", "No connection to the servers (LED purple)",
|
||||
"Uploads or the update check fail: no Wi-Fi, no Internet or the server is unreachable.",
|
||||
("Check the box is paired/connected to Wi-Fi and the network has Internet.",),
|
||||
_NET_ROOTS + ("influx.buffer_fail", "ota.check_failed", "influx.server_error"))
|
||||
if status == "RTC_ERROR":
|
||||
if code == 2:
|
||||
return ("status.rtc.2", "critical", "I2C bus stuck (LED blue, 2 pulses)",
|
||||
"SDA or SCL is held low: a shorted or broken sensor cable, or a faulty sensor.",
|
||||
("Open the case and check the I2C cable between the boards.",
|
||||
"Unplug sensors one by one to find the one holding the bus."), ("kota.i2c_stuck",))
|
||||
return ("status.rtc.1", "critical", "Clock chip (RTC) not responding (LED blue, 1 pulse)",
|
||||
"The DS1307 clock does not answer on the I2C bus.",
|
||||
("Open the case and check the I2C cable/connector between the boards.",
|
||||
"If the cable is fine: the RTC module is faulty."),
|
||||
("rtc.init_failed", "kota.rtc_read_failed", "kota.sensor_missing"))
|
||||
if status == "SD_ERROR":
|
||||
return ("status.sd", "critical", "SD card or ENV.TXT error (LED white, fast blinking)",
|
||||
"The SD card cannot be read or ENV.TXT is missing settings.",
|
||||
("Open the case, re-seat the SD card or re-provision it with the tool.",),
|
||||
("kota.sd_unmounted", "influx.env_missing", "sd.card_fail", "sd.mount_fail",
|
||||
"sd.env_open_fail", "influx.init_fail"))
|
||||
if status == "RESETING":
|
||||
return ("status.reset", "warning", "Factory reset in progress (LED white, solid)",
|
||||
"The Matter button was held: the box forgets its Matter network.",
|
||||
("Pair the box again in the Matter app afterwards.",), ("sys.factory_reset",))
|
||||
if status == "HTTP_SERVER":
|
||||
return ("status.portal", "warning", "Box is in Wi-Fi setup mode (LED white, breathing)",
|
||||
"The box hosts its own Wi-Fi network for configuration.",
|
||||
("Connect a phone to the box's network and open http://sensorbox.local/,",
|
||||
"or short-press the Matter button to leave setup mode."), ("wifi.setup_portal",))
|
||||
return None # OK, UPDATING, SELF_CHECK: covered by milestones / OTA rules
|
||||
|
||||
|
||||
# last_restart -> (severity, title, meaning, actions); None = not a fault.
|
||||
def restart_finding(reason: str) -> tuple[str, str, str, tuple[str, ...]] | None:
|
||||
if reason in INTENTIONAL_RESTARTS or reason in ("none", "", "-"):
|
||||
return None
|
||||
if reason == "status_watchdog":
|
||||
return ("warning", "Box restarted itself after 150 s in the red error state",
|
||||
"By design the firmware restarts when it stays in the error state (red) for 150 s.",
|
||||
("Fix the grouped cause; the restarts stop by themselves.",))
|
||||
if reason == "status_oom_watchdog":
|
||||
return ("error", "Box restarted itself because it ran out of memory",
|
||||
"The firmware was out of memory for 30 s and restarted.",
|
||||
("Save the session log for the firmware team.",))
|
||||
if reason == "provisioning_failed":
|
||||
return ("warning", "Wi-Fi setup portal failed to start",
|
||||
"The setup portal could not start; the box cleared setup mode and restarted.",
|
||||
("Retry Wi-Fi setup (short button press); restart the device if it persists.",))
|
||||
if reason == "panic":
|
||||
return ("critical", "Firmware crashed (panic) and restarted",
|
||||
"The firmware hit a fatal error.",
|
||||
("Press Reset & capture to record the crash; save the session log for the firmware team.",))
|
||||
if reason in ("task_wdt", "int_wdt", "wdt"):
|
||||
return ("error", "Firmware froze and was restarted by the watchdog",
|
||||
f"The firmware stopped responding ({reason}); the watchdog restarted it.",
|
||||
("Save the session log for the firmware team.",))
|
||||
if reason == "brownout":
|
||||
return ("error", "Power supply voltage dropped (brown-out)",
|
||||
"The supply voltage fell too low and the chip reset itself.",
|
||||
("Check the power supply, cable and connectors.",))
|
||||
if reason == "unknown_sw":
|
||||
return ("warning", "Unexpected software restart",
|
||||
"The firmware restarted without recording a reason.",
|
||||
("Watch whether it repeats; save the session log for the firmware team.",))
|
||||
return ("warning", f"Box restarted itself ({reason})",
|
||||
f"The firmware recorded the restart reason '{reason}'.",
|
||||
("Save the session log for the firmware team if it repeats.",))
|
||||
|
||||
|
||||
def parse_size_gb(value: str) -> float | None:
|
||||
"""'7.3GB' -> 7.3 (sd_card.cpp format_gb)."""
|
||||
v = value.upper().removesuffix("GB")
|
||||
try:
|
||||
return float(v)
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
|
||||
def parse_seconds(value: str) -> int | None:
|
||||
v = value.removesuffix("s")
|
||||
return int(v) if v.lstrip("-").isdigit() else None
|
||||
+724
-572
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user