Diagnóstico fechado, app mobile com race screen e cloud client
Firmware ECU agora reporta DTCs vindos do safety e do watchdog automaticamente. Pistonix Ride ganhou tela de corrida espelhando o dashboard e cliente cloud pra falar com o Garage. Mais um dia hardware-free com leverage real.
O hardware Fase 0 ainda não chegou, mas o roadmap não para. Hoje fechei três frentes que estavam encostadas há semanas — o tipo de tarefa que não rende post sozinha mas, juntas, viram um pulo concreto de maturidade.
Firmware ECU — diagnóstico finalmente integrado
O diagnostics module em Rust existe há um tempo: DiagnosticManager
guarda DTCs com freeze frame, máquina de estado clean→active→pending,
threshold de N=3 ciclos pra setar e M=5 pra limpar, encode pro frame CAN
0x6FF. Tinha 200 testes verdes — e zero call-sites no resto do firmware.
Hoje virou de verdade. O novo módulo diagnostics::reporter é o
adaptador entre safety::SafetyInputs / safety::WatchdogStatus e o
manager. Em um único cycle:
- Sensor signal range (P0117/P0107/P0122) acende quando os flags de
integridade do ECT/MAP/TPS caem em
SafetyInputs. - Over-temp (P0217) ativa quando ECT cruza
safety_cfg.ect_warning_c. - Over-rev (P0219) ativa quando RPM cruza
safety_cfg.rpm_warning. - Catch-alls P1001 (limp) e P1002 (cutoff) traduzem o
SafetyStatedireto pra DTC informativo.
P0217 e P0219 são novos, então documentei no docs/dtc-catalog.md e
bumpei a versão pra 0.1.1.
Watchdog cooperativo agora também vira DTC. Cada subsistema (trigger,
fueling, ignition, sensors, can_tx, safety) mapeia pra P1011..P1017;
um failed_index fora do mapping conhecido cai pro P1010 genérico.
Severidade é Cutoff em todos — watchdog timeout é fatal por contrato.
Treze testes novos no reporter::tests cobrem o mapping caso a caso.
Total no core/: 200 testes. Próximo passo é o módulo de safety
escutar mgr.highest_active_severity() pra deixar de ser só categórico.
Pistonix Ride — race screen e cloud client
O app mobile vinha sendo só um esqueleto Flutter com home screen e mock
feed. Hoje saiu de hello world pra “dá pra ver e configurar”:
- Race screen espelhando o
screens/race.cdo dashboard — RPM gigantesco no centro (132pt), shift-light bar no topo que vira amber5500 RPM e vermelho > 6500, AFR + BOOST PSI lado a lado, GEAR enorme em ignite-red. Cabe o que importa numa olhada de pista.
- Repository pattern pra telemetria —
TelemetryRepositoryé a abstração;MockTelemetryRepositoryempacota o feed determinístico atual com broadcast pra múltiplos listeners (home + race simultâneo). BLE e cloud-replay caem na mesma interface depois. - CloudClient porta o cliente cloud do Tuner desktop pra Dart.
Mesma envelopagem de erro, mesmos endpoints (
/devices,/tunes), mesma autenticação Bearer. Cinco testes comMockClientvalidam envelope HTTP, parse de listas, erro 401, normalização de slash. - Settings screen — botão “Listar dispositivos” e “Listar tunes”
com banner colorido por status. Token fica em memória (persistência
via
flutter_secure_storageé Phase 5+, com BLE).
CI do app-mobile ainda só roda flutter analyze + flutter test no
GitHub Actions (flutter create regenera as platform folders); falta
build APK / IPA, o que vem quando hardware estabilizar.
/precos ganhou OG image
Detalhe pequeno mas faltava: /precos (PT) e /en/pricing agora têm
OG cards próprios, não o genérico do site. “A partir de R$ 2.800” /
“Starting at USD 560” no destaque, na mesma linguagem visual dos cards
de produto.
O que não fez parte desta sessão
- Push automático do tune ao salvar no Tuner (debounce de save).
- Smoke test E2E em produção (
api.pistonix.com.br/public/basemaps). - BLE service stub no app — depende do Pistonix Dash existir como gateway, então fica pra Phase 5.
- DB-backed integration tests no Garage com testcontainers — em fila, mas o backend já tem cobertura de timing/token-hash em unit-test.
Mas pelo menos o ciclo “sensor cai → DTC promove → CAN broadcast” finalmente fecha sem dependência de hardware. É o tipo de coisa que a gente só descobre que importava quando integra.