diff --git a/02-Architecture-Software/htracker-patches/2026-09-18_retranslator_phlg-v5-extra_phev_alertas.patch b/02-Architecture-Software/htracker-patches/2026-09-18_retranslator_phlg-v5-extra_phev_alertas.patch new file mode 100644 index 0000000..23063c2 --- /dev/null +++ b/02-Architecture-Software/htracker-patches/2026-09-18_retranslator_phlg-v5-extra_phev_alertas.patch @@ -0,0 +1,152 @@ +--- a/retranslator.py ++++ b/retranslator.py +@@ -712,6 +712,24 @@ + 'tair', 'rh', 'tbat', 'fan_rpm', 'fan_pwm', 'fan_fault', + ) + _PHLG_FIELDS_V3_EXTRA = ('tntc', 'chg', 'cflt', 'rxbad') ++# fw 0.5.1-fm (EinarBoard v5, bring-up/field-minimum) — append-only, campos 25..29: ++# up_s segundos desde el arranque del MCU (si baja ⇒ reinicio) ++# pwr VEH (5 V del vehículo presente) | BATT (en respaldo LTC4040) ++# v5min mínimo instantáneo del riel 5 V en la ventana de 30 s (caídas de ms por ráfaga LTE) ++# vbat_min mínimo instantáneo del paquete en la misma ventana ++# bkp_n respaldos de batería desde el arranque ++_PHLG_FIELDS_V5_EXTRA = ('up_s', 'pwr', 'v5min', 'vbat_min', 'bkp_n') ++PHLG_V5MIN_WARN_V = 4.60 # zona de disparo PFI del LTC4040 (divisor 270k/100k ⇒ 4.44 V) ++PHLG_VBAT_LOW_V = 3.50 ++ ++# ── $PHEV — eventos de la unidad, en banda (fw 0.5.1+) ────────────────────── ++# $PHEV,,,*CS — una línea por transición de estado ++# (STACK_ON/OFF, BACKUP_START/END, RECOVERY, LIMP, TEMP_CUT/REARM, V5_LOW/LOST/OK, ++# IGN_ON/OFF, SLEEP, MODOB_ON/OFF, BOOT). Se guardan los últimos PHEV_MAX por ++# unidad y se exponen en el status JSON como 'events' para el monitor. ++PHEV_MAX = 200 ++DEVICE_EVENTS: dict[str, deque] = {} # cell_id → deque de {'ts','up_s','code','detail'} ++_PHEV_WARN = {'RECOVERY', 'LIMP', 'TEMP_CUT', 'V5_LOW', 'SLEEP', 'BACKUP_START'} + + + def _nmea_checksum_ok(sentence: str) -> bool: +@@ -740,9 +758,33 @@ + names = list(_PHLG_FIELDS_V2) + if len(vals) >= len(_PHLG_FIELDS_V2) + len(_PHLG_FIELDS_V3_EXTRA): + names += list(_PHLG_FIELDS_V3_EXTRA) ++ if len(vals) >= len(names) + len(_PHLG_FIELDS_V5_EXTRA): ++ names += list(_PHLG_FIELDS_V5_EXTRA) + return dict(zip(names, vals)) + + ++def _parse_phev(sentence: str) -> dict | None: ++ """$PHEV,,, → dict, o None si el checksum/forma no cuadra.""" ++ if not _nmea_checksum_ok(sentence): ++ return None ++ parts = sentence[1:].partition('*')[0].split(',', 3) ++ if len(parts) < 3 or parts[0] != 'PHEV': ++ return None ++ try: ++ up_s = int(parts[1]) ++ except ValueError: ++ return None ++ return {'up_s': up_s, 'code': parts[2], 'detail': parts[3] if len(parts) > 3 else ''} ++ ++ ++def _note_event(cell_id: str, ev: dict, now_ts: float) -> None: ++ """Guarda el evento y lo registra en el log (WARNING para los que piden acción).""" ++ ev = dict(ev); ev['ts'] = now_ts ++ DEVICE_EVENTS.setdefault(cell_id, deque(maxlen=PHEV_MAX)).append(ev) ++ msg = f"[{cell_id}] $PHEV up={ev['up_s']}s {ev['code']} {ev['detail']}".rstrip() ++ (log.warning if ev['code'] in _PHEV_WARN else log.info)(msg) ++ ++ + def _parse_pubx00(sentence: str) -> dict | None: + """$PUBX,00 (u-blox propietaria): hAcc/vAcc/edad-DGPS/sats usados. + Índices verificados contra capturas reales de la flota (2026-08-10).""" +@@ -785,17 +827,58 @@ + f"(¿cargador pausado por NTC?).") + except ValueError: + pass ++ # ── Reglas de diagnóstico (fw 0.4.0+ / 0.5.1+) ────────────────────────── ++ # 1. reset_cause=IWDG ⇒ el MCU se colgó (watchdog). 2. up_s bajó ⇒ reinicio ++ # (contamos reinicios/hora: ≥2 = bucle de arranque). 3. recoveries subió ⇒ ++ # el F9P dejó de hablar. 4. v5min en zona PFI mientras sigue reportando. ++ # 5. pwr=BATT ⇒ en respaldo (con cargador OFF el paquete es de un solo uso). ++ if health.get('reset_cause') == 'IWDG' and (not prev or prev.get('reset_cause') != 'IWDG'): ++ log.warning(f"[{cell_id}] $PHLG reinicio por WATCHDOG (IWDG): el MCU se colgó.") ++ try: ++ up_now = int(health.get('up_s') or -1) ++ up_prev = int(prev.get('up_s') or -1) if prev else -1 ++ if 0 <= up_now < up_prev: ++ reboots = health['_reboots'] = [t for t in (prev.get('_reboots') or []) if now_ts - t < 3600] + [now_ts] ++ lvl = log.warning if len(reboots) >= 2 else log.info ++ lvl(f"[{cell_id}] $PHLG reinicio detectado (up {up_prev}s → {up_now}s), " ++ f"{len(reboots)} en la última hora{' — ¿BUCLE DE ARRANQUE?' if len(reboots) >= 2 else ''}.") ++ elif prev and prev.get('_reboots'): ++ health['_reboots'] = [t for t in prev['_reboots'] if now_ts - t < 3600] ++ rec_now = int(health.get('recoveries') or 0) ++ rec_prev = int(prev.get('recoveries') or 0) if prev else 0 ++ if rec_now > rec_prev: ++ log.warning(f"[{cell_id}] $PHLG recovery #{rec_now}: la unidad cicló la etapa RTK (F9P sin NMEA / RTK perdido).") ++ v5min = float(health.get('v5min') or 99) ++ if v5min < PHLG_V5MIN_WARN_V and float(health.get('v5v') or 0) > 3.8: ++ log.warning(f"[{cell_id}] $PHLG riel 5 V cayó a {v5min:.2f} V en los últimos 30 s " ++ f"(zona PFI del LTC4040): ajustar la fuente del gabinete a ~5.3 V.") ++ if health.get('pwr') == 'BATT' and (not prev or prev.get('pwr') != 'BATT'): ++ log.warning(f"[{cell_id}] $PHLG en RESPALDO de batería (vbat={health.get('vbat')} V, bkp #{health.get('bkp_n')}).") ++ if health.get('pwr') == 'VEH' and prev and prev.get('pwr') == 'BATT': ++ log.info(f"[{cell_id}] $PHLG regresó a alimentación del vehículo.") ++ except (ValueError, TypeError): ++ pass + health['ts'] = now_ts + DEVICE_HEALTH[cell_id] = health + + ++def _events_snapshot(cell_id: str, now: float, n: int = 20) -> list: ++ """Últimos n eventos $PHEV de la unidad (más reciente al final), con edad.""" ++ evs = DEVICE_EVENTS.get(cell_id) ++ if not evs: ++ return [] ++ return [{'age_s': round(now - e['ts'], 1), 'up_s': e['up_s'], 'code': e['code'], 'detail': e['detail']} ++ for e in list(evs)[-n:]] ++ ++ + def _health_snapshot(cell_id: str, now: float) -> dict | None: + """Copia del último $PHLG con su edad, para el status JSON (None si nunca).""" + h = DEVICE_HEALTH.get(cell_id) + if not h: + return None +- out = {k: v for k, v in h.items() if k != 'ts'} ++ out = {k: v for k, v in h.items() if k != 'ts' and not k.startswith('_')} + out['age_s'] = round(now - h['ts'], 1) ++ out['reboots_1h'] = len(h.get('_reboots') or []) + return out + + +@@ -916,6 +999,7 @@ + 'jump_rejects': device_jump_rejects.get(cid, 0), + # ── Telemetría en banda, si la unidad la manda ─────────── + 'health': _health_snapshot(cid, now), # $PHLG | None ++ 'events': _events_snapshot(cid, now), # $PHEV (fw 0.5.1+) | [] + 'hacc_m': info.get('hacc_m'), # $PUBX,00 + 'vacc_m': info.get('vacc_m'), + 'diff_age_s': info.get('diff_age_s'), +@@ -1436,6 +1520,22 @@ + device_total_online_s, device_last_seen_ever) + _note_health(cell_id, health, now_ts) + ++ # ── $PHEV — eventos de la unidad, en banda (firmware 0.5.1+) ── ++ elif raw.startswith('$PHEV'): ++ ev = _parse_phev(raw) ++ if ev: ++ entry = addr_to_cell_id.get(addr) ++ if not entry: ++ continue ++ cell_id = entry[0] ++ now_ts = time.time() ++ addr_to_cell_id[addr] = (cell_id, now_ts) ++ _mark_seen(cell_id, now_ts, device_last_seen, ++ device_first_seen, device_packet_count, ++ device_disconnected, device_first_connected, ++ device_total_online_s, device_last_seen_ever) ++ _note_event(cell_id, ev, now_ts) ++ + # ── $PUBX,00 — precisión estimada del F9P (configs nuevas) ──── + elif raw.startswith('$PUBX'): + pubx = _parse_pubx00(raw) diff --git a/02-Architecture-Software/htracker-patches/README.md b/02-Architecture-Software/htracker-patches/README.md new file mode 100644 index 0000000..5de542a --- /dev/null +++ b/02-Architecture-Software/htracker-patches/README.md @@ -0,0 +1,36 @@ +# Parches para htracker (rama `feature/test500unidades`) + +Parches propuestos al backend que **no** se aplican desde aquí: Gibran es el dueño de `htracker`. +Se generan contra la última `origin/feature/test500unidades` (`retranslator.py` no cambió entre +`d8dc4cf` y `2cdcb5e`) y se prueban con el parser real antes de proponerlos. + +## 2026-09-18 — `retranslator_phlg-v5-extra_phev_alertas.patch` (fw 0.5.1-fm) + +Aplicar en el clon del servidor o en el Mac: + +```bash +cd htracker && git checkout feature/test500unidades && git pull --ff-only +git apply --check ../../02-Architecture-Software/htracker-patches/2026-09-18_retranslator_phlg-v5-extra_phev_alertas.patch +git apply ../../02-Architecture-Software/htracker-patches/2026-09-18_retranslator_phlg-v5-extra_phev_alertas.patch +python3 -m py_compile retranslator.py +``` + +Qué hace (solo `retranslator.py`, 152 líneas; `web_monitor.py` queda para Gibran): + +1. **`$PHLG` de 29 campos** (`_PHLG_FIELDS_V5_EXTRA = up_s, pwr, v5min, vbat_min, bkp_n`). Append-only: + las tramas de 21 (v2.x) y 25 (v3.x) campos siguen parseando igual. +2. **`$PHEV,,,*CS`** — eventos en banda (STACK_ON/OFF, BACKUP_START/END, RECOVERY, + LIMP, TEMP_CUT/REARM, V5_LOW/LOST/OK, IGN_ON/OFF, SLEEP, MODOB_ON/OFF, BOOT). Se guardan los últimos 200 por + unidad (`DEVICE_EVENTS`) y salen en el status JSON como `events` (últimos 20, con `age_s`). +3. **Reglas de diagnóstico** en `_note_health` (van al log como WARNING → Loki/Grafana): + - `reset_cause=IWDG` → el MCU se colgó. + - `up_s` bajó → reinicio; ≥ 2 en una hora → «¿BUCLE DE ARRANQUE?». `reboots_1h` sale en el snapshot. + - `recoveries` subió → la unidad cicló la etapa RTK. + - `v5min < 4.60 V` con el riel presente → zona PFI del LTC4040: ajustar la fuente del gabinete a ~5.3 V. + - `pwr=BATT` → en respaldo (cargador OFF en 0.x: el paquete es de un solo uso); regreso a `VEH` en INFO. + +Probado con el parser real: tramas de 24 y 29 campos, `$PHEV`, checksum malo rechazado, y las cinco reglas disparan. + +Sugerencias para `web_monitor.py` (Gibran): columna «Eventos» (últimos `events`), badge `reboots_1h`, +`v5min` junto a `v5v` en el medidor de riel, `pwr=BATT` en amarillo, y graficar el RSSI que ya viene en +`$GPTXT,NET,H00xx,TELCEL,,…`. diff --git a/04-Source-Code/firmware b/04-Source-Code/firmware index a82ca4a..ab4d829 160000 --- a/04-Source-Code/firmware +++ b/04-Source-Code/firmware @@ -1 +1 @@ -Subproject commit a82ca4ace53106dd7f1d18ffb1fb92a1f4b0c65d +Subproject commit ab4d82973c2de361d454e489738f5487452cf812 diff --git a/06-Testing-Validation/2026-09-15_Drogheda_EinarBoard-v5_Procedimiento-Prueba-y-Flasheo_ES_v1.0.md b/06-Testing-Validation/2026-09-15_Drogheda_EinarBoard-v5_Procedimiento-Prueba-y-Flasheo_ES_v1.0.md index 4c4b8e1..a88e890 100644 --- a/06-Testing-Validation/2026-09-15_Drogheda_EinarBoard-v5_Procedimiento-Prueba-y-Flasheo_ES_v1.0.md +++ b/06-Testing-Validation/2026-09-15_Drogheda_EinarBoard-v5_Procedimiento-Prueba-y-Flasheo_ES_v1.0.md @@ -37,7 +37,7 @@ y dejarla flasheada con el firmware de arranque entregado por ingeniería. | 1 | Fuente de banco 0–30 V con límite de corriente ajustable | | 1 | Cable USB-C ↔ USB-C (o USB-A ↔ USB-C) **con datos** (no solo carga) | | 1 | Laptop con **STM32CubeProgrammer** instalado (o `dfu-util` en terminal) | -| 1 | Archivo de firmware: **`hbox-v5-bringup_0.5.0.bin`** — descarga: **https://drogheda.helgen.online/descargas/** (repo: `04-Source-Code/firmware/hbox_v5_bringup/release/`, SHA-256 inicia `98656ddc`) | +| 1 | Archivo de firmware: **`hbox-v5-bringup_0.5.1.bin`** — descarga: **https://drogheda.helgen.online/descargas/** (repo: `04-Source-Code/firmware/hbox_v5_bringup/release/`, SHA-256 inicia `e1f35108`) | | 1 | Jumper 2.54 mm para P11 (interruptor de corte) | | 1 | Lupa o lámpara con aumento | | — | Hoja de registro (sección 7) | @@ -183,7 +183,7 @@ Solo para tarjetas que pasaron las secciones 1 a 4. 2. Arriba a la derecha, en el selector de conexión elegir **USB**. Pulsar el botón de refrescar; debe aparecer `USB1`. Pulsar **Connect**. 3. Ir a la pestaña **Erasing & Programming** (icono de flecha hacia abajo, lado izquierdo). -4. **File path** → seleccionar `hbox-v5-bringup_0.5.0.bin`. +4. **File path** → seleccionar `hbox-v5-bringup_0.5.1.bin`. 5. **Start address** = `0x08000000`. Marcar **Verify programming** y **Run after programming**. 6. Pulsar **Start Programming**. Esperar "File download complete" y "Verify… successful". 7. Pulsar **Disconnect**. @@ -192,7 +192,7 @@ Solo para tarjetas que pasaron las secciones 1 a 4. ```bash dfu-util -l # debe listar [0483:df11] -dfu-util -a 0 -s 0x08000000:leave -D hbox-v5-bringup_0.5.0.bin +dfu-util -a 0 -s 0x08000000:leave -D hbox-v5-bringup_0.5.1.bin ``` ### 5d. Verificación después del flasheo @@ -206,7 +206,7 @@ dfu-util -a 0 -s 0x08000000:leave -D hbox-v5-bringup_0.5.0.bin | **D17** (LED azul) + LED de panel en P8 (si hay) | **Parpadean** a 1 Hz (MCU ejecutando el firmware) | | **DB1 → DB4** (LEDs del indicador de batería) | Se encienden **en secuencia** una vez, luego se apagan; después R, G, B en P14 si hay LED RGB conectado | | Laptop | Aparece un **puerto serie** nuevo ("STMicroelectronics Virtual COM Port" / `usbmodem…`) | -| Terminal serie a **115200 baud** | Encabezado `hbox-v5-bringup 0.5.0` (cualquier otra version: re-flashear), luego líneas `[PASS]` / `[FAIL]`, y al final **`>>> BOARD OK`** | +| Terminal serie a **115200 baud** | Encabezado `hbox-v5-bringup 0.5.1` (cualquier otra version: re-flashear), luego líneas `[PASS]` / `[FAIL]`, y al final **`>>> BOARD OK`** | 3. Si el terminal se abrió tarde y no se vio el reporte: teclear **`r`** en el terminal → repite todas las pruebas (y vuelve a encender los LEDs en secuencia). diff --git a/06-Testing-Validation/2026-09-17_Drogheda_HBOX-v5_Procedimiento-Ensamble_ES_v1.0.md b/06-Testing-Validation/2026-09-17_Drogheda_HBOX-v5_Procedimiento-Ensamble_ES_v1.0.md index 6002551..e726da7 100644 --- a/06-Testing-Validation/2026-09-17_Drogheda_HBOX-v5_Procedimiento-Ensamble_ES_v1.0.md +++ b/06-Testing-Validation/2026-09-17_Drogheda_HBOX-v5_Procedimiento-Ensamble_ES_v1.0.md @@ -53,7 +53,7 @@ si el módulo ya está asignado. | Ítem | Notas | |---|---| | Gabinete HBOX con panel perforado (GX16-5, 3 × SMA, RJ45, prensaestopas) | según el diseño mecánico vigente | -| EinarBoard **V5-NN** aprobada, con firmware de bring-up **0.5.0 o superior** | ver acta de tarjeta | +| EinarBoard **V5-NN** aprobada, con firmware de bring-up **0.5.1 o superior** | ver acta de tarjeta | | simpleRTK2B Pro **ARD-NNN** y módem 4G NTRIP Master **RTK-NNNN** aprobados e integrados | con sus bolsas | | Fuente **Mean Well SD-15B-05** (24 V → 5 V) | va dentro del HBOX | | Pack de batería **1S4P** con NTC (3 hilos → P4) | conectar al final | diff --git a/06-Testing-Validation/2026-09-18_Drogheda_HBOX-v5_Prueba-Final-Unidad-FW-0.4.0_ES_v1.0.md b/06-Testing-Validation/2026-09-18_Drogheda_HBOX-v5_Prueba-Final-Unidad-FW-0.4.0_ES_v1.0.md index ed10ded..e1f2773 100644 --- a/06-Testing-Validation/2026-09-18_Drogheda_HBOX-v5_Prueba-Final-Unidad-FW-0.4.0_ES_v1.0.md +++ b/06-Testing-Validation/2026-09-18_Drogheda_HBOX-v5_Prueba-Final-Unidad-FW-0.4.0_ES_v1.0.md @@ -1,13 +1,13 @@ -# HBOX v5 — Prueba final de unidad ensamblada con firmware 0.5.0 (field-minimum + telemetría) +# HBOX v5 — Prueba final de unidad ensamblada con firmware 0.5.1 (field-minimum + telemetría y eventos) **Alcance:** unidad completa (EinarBoard V5 + ArduSimple + módem 4G + batería + antenas) dentro del HBOX, antes de embarcar. -**Firmware:** `hbox-v5-bringup_0.5.0.bin` (SHA-256 `98656ddc…`) — descarga en . +**Firmware:** `hbox-v5-bringup_0.5.1.bin` (SHA-256 `e1f35108…`) — descarga en . **Duración:** ~45 min por unidad (P1–P6). Registrar todo en el acta de ensamble (`HBOX5-Exx-Axxx-Rxxxx`). -!!! warning "Lo que 0.5.0 NO hace" +!!! warning "Lo que 0.5.1 NO hace" **No carga la batería** (cargador apagado). El paquete es de un solo uso: sostiene la unidad cuando se va el 5 V del vehículo hasta 3.40 V y después la unidad solo funciona con alimentación del vehículo. Las unidades regresan a laptop (DFU en J11, 2 min) - cuando salga el firmware de producción. Anotar en el acta: *«fw 0.5.0-fm, cargador OFF»*. + cuando salga el firmware de producción. Anotar en el acta: *«fw 0.5.1-fm, cargador OFF»*. ## 0. Preparación - Consola: cable USB-C en **J11**, PuTTY/CoolTerm **115200**. Cada línea es `STAT`, `EVT` o `$PHLG`; teclear `l` para la leyenda. @@ -20,7 +20,7 @@ Energizar 24 V (con ignición) y **no tocar la consola**. | Esperado | Si falla | |---|---| -| Banner `hbox-v5-bringup 0.5.0` · `modo=AUTO` · `inputs at boot: v5=5.2–5.4V(ok) ign=ON` | otra versión → re-flashear; `ign=OFF` → arnés pin 3 / divisor 22k-10k | +| Banner `hbox-v5-bringup 0.5.1` · `modo=AUTO` · `inputs at boot: v5=5.2–5.4V(ok) ign=ON` | otra versión → re-flashear; `ign=OFF` → arnés pin 3 / divisor 22k-10k | | `---- RESULT: 12 PASS / 0 FAIL ----` · `>>> BOARD OK` | cualquier `[FAIL]` → tarjeta a revisión, no embarcar | | `EVT … STACK ON reason=auto` **sin teclear nada** (≈10 s tras el banner) | no enciende → `STAT` muestra `v5=` bajo 4.5 o `modo=MAN` (teclear `A`) | | `EVT … NMEA primera trama` < 3 s después · `EVT FAN ON (vehiculo: 5V+ign)` | sin NMEA → ArduSimple no arranca: medir SW_5V (MOD1 pin 5) ≈ 5 V | @@ -31,11 +31,11 @@ Dejar la unidad 10 min encendida con el módem registrándose (LEDs del módem / | Esperado | Si falla | |---|---| -| `STAT … v5=5.2x–5.3x(ok)` **todo el tiempo**; nunca `(BAJO)` ni `EVT V5 BAJO` | `BAJO` → el riel cae con la ráfaga LTE: SD-15B ajustado a ~5.3 V en P2 (memo 24-Jul, PFI LTC4040) | +| `STAT … v5=5.2x–5.3x(ok)` **todo el tiempo**; nunca `(BAJO)` ni `EVT V5 BAJO`; **`v5min` ≥ 4.9 V** en todas las STAT | `BAJO` o `v5min` < 4.6 → el riel cae con la ráfaga LTE: SD-15B ajustado a ~5.3 V en P2 (memo 24-Jul, PFI LTC4040) | | `tbat`/`tair`/`tmcu` estables (< 45 °C en banco) · `i2cerr=0` | `i2cerr` subiendo → bus I²C / soldadura U3/U4/U13 | -| `$PHLG,0.5.0-fm,RUN,…` cada 10 s, `rec=0`, sin `LIMP` | `rec` > 0 sin causa → NMEA intermitente: revisar MOD1 / UART1 F9P | +| `$PHLG,0.5.1-fm,RUN,…` cada 10 s, `rec=0`, sin `LIMP` | `rec` > 0 sin causa → NMEA intermitente: revisar MOD1 / UART1 F9P | | **Modo B:** ≈10 s tras la primera NMEA, `EVT MODOB ON`; luego `STAT … modoB=ON relay=` (sube cientos/s) `phlg_aire=` (+1 cada 30 s) | `modoB=off` permanente → sin NMEA en PA3 o `B` bloqueado; `relay=0` con `modoB=ON` → K1 / PA10 | -| **Servidor:** en ≤ 2 min la unidad `H00xx` muestra la columna **Salud** (fw `0.5.0-fm`, vbat, temperaturas) y sigue reportando posición 1 Hz | posición sí pero sin Salud → el módem no reenvía la `$PHLG`: revisar `$$$AS+` (modo transparente) | +| **Servidor:** en ≤ 2 min la unidad `H00xx` muestra la columna **Salud** (fw `0.5.1-fm`, vbat, temperaturas, `v5min`) y en el log del servidor los `$PHEV` (BOOT, STACK_ON, MODOB_ON) y sigue reportando posición 1 Hz | posición sí pero sin Salud → el módem no reenvía la `$PHLG`: revisar `$$$AS+` (modo transparente) | ## P3 — Respaldo de batería (6 min) — **la prueba que nunca se había hecho en v5** Con la etapa ON: **desconectar el 24 V** (se va el 5 V del SD-15B). Esperar 5 min. Reconectar. @@ -65,7 +65,7 @@ Con la etapa ON y > 90 s de encendida: **retirar el ArduSimple del socket** (o s ## P6 — Apagado y acta (2 min) - Quitar ignición: `EVT IGN OFF`, `EVT FAN OFF (bateria: termostato)`; la etapa sigue ON mientras haya 5 V (el SD-15B sigue con 24 V). - Quitar 24 V: si la batería está, entra `BACKUP` (P3); dejarla hasta `SLEEP` **no** es necesario — reconectar y apagar con `P`. -- Guardar el log. En el acta: versión (`0.5.0-fm`), `uid=` del banner, resultado P1–P5, `vbat` final, y la nota *cargador OFF*. +- Guardar el log. En el acta: versión (`0.5.1-fm`), `uid=` del banner, resultado P1–P5, `vbat` final, y la nota *cargador OFF*. ## Lectura rápida del LED RGB (para el técnico de campo) | Color | Significado | diff --git a/hbox-docs b/hbox-docs index caee07f..ade43bb 160000 --- a/hbox-docs +++ b/hbox-docs @@ -1 +1 @@ -Subproject commit caee07fde9ab9c807356806bb2f22a4a169c9678 +Subproject commit ade43bbc14ed1da637d82b93dd473d4dd5d71e17