Technician tool v0.2
Imported from the Google Drive folder 004-technician_tool/v0.2.
This commit is contained in:
1 parent
e5a33a1c34
commit
e8b72b743d
17 files changed
+2410
-283
No files matched your search
@@ -0,0 +1,91 @@
|
||||
"""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,
|
||||
),
|
||||
}
|
||||
|
||||
_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"
|
||||
Reference in new issue
Block a user