docs: add Codex handoff architecture docs

This commit is contained in:
2026-06-07 09:33:49 -06:00
parent e1ea6a19e0
commit fdf3d657b6
3 changed files with 208 additions and 492 deletions
+41
View File
@@ -0,0 +1,41 @@
# AGENTS.md
## Workflow
- Inspect the repo before changing code.
- Make minimal, targeted changes.
- Preserve existing architecture.
- Update docs when APIs, behavior, wiring, or hardware assumptions change.
- Run available validation/tests before finishing.
- Use meaningful commits.
- Explain what changed, why, and any side effects.
## Critical Constraints
- Do not modify JBD/Xiaoxiang BLE behavior without explicit approval.
- Do not change BLE timeout, reconnect, scan, or BMS-selection behavior without approval.
- Cargo ESP32 remains the controller, API server, WebUI host, and source of truth.
- Dashboard ESP32-S3 is a client only.
- Do not move relay/BMS/control authority into the dashboard.
- Do not hardcode install-specific names into firmware.
- Preserve API compatibility when practical.
- Prefer HTTP API integration over custom protocols.
## Hardware Rules
- ESP32 relay board outputs trigger external fused automotive relays/contactors.
- Do not route fridge, Starlink, inverter, or other major load current through the ESP32 relay board.
- Dashboard target is Waveshare ESP32-S3-Touch-LCD-5.
- Dashboard connects to Cargo ESP32 AP over WiFi.
- Dashboard is powered from ACC switched 12V into VIN.
- Do not power dashboard from OBD-II pin 16 in the permanent install.
- CAN termination must stay disabled when connected to vehicle CAN.
## Documentation
Primary docs:
- docs/ARCHITECTURE.md
- docs/HARDWARE.md
- docs/ROADMAP.md
- docs/API.md when API changes
+95 -256
View File
@@ -1,93 +1,105 @@
# Architecture
Overland Controller is a distributed monitoring and control platform for vehicles, trailers, campers, and mobile power systems.
Overland Controller is a distributed monitoring and control platform for the Nissan Xterra and future mobile power systems.
The system separates electrical control from user interface logic.
Core principle:
## Main Components
Cargo ESP32 = controller / source of truth
Waveshare ESP32-S3 dashboard = local touchscreen client
Phone/laptop WebUI = configuration interface
Home server = future optional remote access layer
### ESP32 Controller
The system must work locally without internet.
The ESP32 is the system authority.
## Cargo ESP32 Controller
The Cargo ESP32 owns critical control state and configuration.
Responsibilities:
- Read battery/BMS data
- Read temperature sensors
- Control relay outputs
- Read JBD/Xiaoxiang BMS data over BLE
- Read DS18B20 temperature sensors
- Control relay trigger outputs
- Store configuration
- Serve the HTTP API
- Communicate with the Pico dashboard over UART
- Maintain system status
- Handle alarms
- Serve HTTP API
- Serve local WebUI
- Run WiFi AP mode
- Maintain status, alarms, and fault state
### Pico Dashboard
The Cargo ESP32 should not depend on the dashboard, phone, home server, or internet for core operation.
The Pico is the primary user interface.
## Waveshare ESP32-S3 Dashboard
Target hardware:
- Waveshare ESP32-S3-Touch-LCD-5
- 5 inch 800x480 capacitive touchscreen
- ESP32-S3
- 16MB flash
- 8MB PSRAM
- WiFi + BLE
- CAN with onboard TJA1051 transceiver
- microSD
- 7-36V VIN support
Responsibilities:
- Request status from ESP32
- Display battery data
- Display temperature data
- Display relay states
- Send relay commands
- Send configuration commands
- Provide setup workflows
- Operate without internet
- Native LVGL dashboard
- Connect to Cargo ESP32 AP as WiFi client
- Poll Cargo ESP32 HTTP API
- Send simple control commands through HTTP API
- Display battery, relay, temp, vehicle, and alert data
- Future CAN vehicle data
- Future transmission temperature sender display
The Pico should not own critical control state. The ESP32 remains the source of truth.
The dashboard is a client only. It must not own relay state, BMS config, alarms, or persistent configuration.
## Communication Paths
## WebUI
### UART
The WebUI remains hosted by the Cargo ESP32.
Primary dashboard/control path.
Use WebUI for:
Used for:
- Status requests
- Relay control
- Configuration updates
- Setup/configuration
- Relay names
- Temperature sensor names
- BMS setup
- BLE scan requests
- BMS selection
UART should eventually support every core management action needed by the Pico.
### HTTP
Secondary setup/debug path.
Used for:
- Browser testing
- Phone/laptop setup
- Future web UI
- API debugging
HTTP should mirror the same data model as UART where practical.
### USB Serial
Service/debug path.
Used for:
- Development
- Recovery
- Troubleshooting
- Emergency configuration
- API testing
## Data Model
Avoid complex configuration on the touchscreen dashboard.
The same generic data model should be used across:
## Network
- HTTP API
- UART protocol
- Pico dashboard
Cargo ESP32 runs WPA2 AP mode continuously.
Expected local URL:
http://192.168.4.1
Dashboard connects to that AP and talks HTTP.
No UART cable is planned between dashboard and Cargo ESP32.
## HTTP API
HTTP is the primary integration contract for:
- WebUI
- Dashboard
- Simulator
- Future MQTT/Home Assistant integrations
- Future home server
- Future MQTT/Home Assistant/Grafana integrations
Preferred direction:
GET /api/status
GET /api/config
POST /api/relays/relay_1/on
POST /api/relays/relay_1/off
POST /api/relays/relay_1/toggle
Future versioning may move to /api/v1.
## Generic IDs
@@ -109,9 +121,9 @@ Temperature sensors:
temp_7
temp_8
Installation-specific names belong only in saved configuration.
Install-specific names belong in saved configuration only.
Examples of configuration names:
Examples:
Fridge
Starlink
@@ -119,33 +131,11 @@ Examples of configuration names:
Outside
House Battery
These names should not be hardcoded into firmware behavior.
## Status Model
## Configuration Ownership
Dashboard should be able to render from status/config responses without duplicating business logic.
Configuration is stored on the ESP32.
Stored configuration includes:
- Device name
- Relay names
- Relay enable states
- Temperature sensor names
- Temperature sensor addresses
- Temperature sensor enable states
- BMS name
- BMS BLE address
- BMS address type
The Pico may edit configuration through UART, but the ESP32 stores and owns it.
## Status Flow
Pico sends:
status_request
ESP32 responds with the same shape as HTTP /status:
Expected status groups:
battery
temps
@@ -156,176 +146,25 @@ ESP32 responds with the same shape as HTTP /status:
system
config
## Relay Control Flow
## Vehicle Data
Pico sends a generic relay command:
Use standard OBD-II over CAN first.
relay_1 on
relay_1 off
relay_2 on
relay_2 off
Planned standard PIDs:
ESP32 updates the relay output and reports the new state.
0105 coolant temperature
010C RPM
010D vehicle speed
## BMS Setup Flow
Transmission temperature is planned through a dedicated sender rather than Nissan CAN reverse engineering.
BMS setup can be started from the Pico.
## Future Home Server
Expected flow:
Future optional architecture:
enter_bms_setup
scan_ble
scan_ble
select_bms
save_config
Phone/PWA
-> Home server HTTPS
-> MQTT/WebSocket/HTTPS bridge
-> Cargo ESP32 outbound connection
The ESP32 handles BLE scanning and BMS selection.
The Pico only displays options and sends the selected index or address.
## HTTP / UART Parity
Long-term goal:
- HTTP /status equals UART status_request
- HTTP /config equals UART config_request
- HTTP /config/device equals UART config_device
- HTTP /config/relay equals UART config_relay
- HTTP /config/temp equals UART config_temp
- HTTP /config/bms equals UART config_bms
- HTTP relay control equals UART set_relay
- HTTP factory reset equals UART factory_reset
## Current Priority
The next implementation priority is UART parity.
The Pico should be able to do the important setup and control operations without relying on WiFi.
Minimum UART v1 scope:
- status_request
- set_relay
- config_request
- config_device
- config_relay
- config_temp
- config_bms
- save_config
- factory_reset
- enter_bms_setup
- scan_ble
- select_bms
- exit_bms_setup
## Future Integrations
Possible future integrations:
- MQTT
- Home Assistant
- Grafana
- InfluxDB
- OBD-II
- CAN bus
- GPS
- Data logging
- OTA updates
All future integrations should consume the same generic status/config model.
---
## Networking Architecture
### Current Network Mode
The ESP32 currently runs in Access Point mode.
Default access:
http://192.168.4.1
The AP is the recovery/setup network.
### Planned Network Mode
The planned long-term network mode is AP + STA.
AP mode:
Always available
Used for recovery and direct setup
STA mode:
Connects to a configured WiFi network
Used for camp/home access from phone or laptop
Example networks:
Starlink
Home WiFi
Shop WiFi
### Multiple WiFi Profiles
The ESP32 should eventually store multiple WiFi profiles and try them in priority order.
Example:
1. Starlink
2. Home WiFi
3. Shop WiFi
Expected behavior:
Start AP first
Try configured STA networks
Connect to the first available network
Keep AP available even after STA connects
Reason:
- Starlink may be off
- Home WiFi may only be available in the driveway
- AP must remain available for recovery
- User should not lose access because of a bad WiFi password
### Phone Dashboard Access
When connected to the ESP32 AP:
http://192.168.4.1
When connected through Starlink/home WiFi:
http://controller-ip
Future mDNS target:
http://overland-controller.local
### Dashboard Roles
ESP32:
Source of truth
Lightweight phone dashboard
HTTP API
Recovery AP
Pico 2 W:
Instant physical dashboard
UART client
Touchscreen UI
Optional future Pi Zero:
Advanced web dashboard
Logging
Charts
Integrations
The Pi Zero should be optional, not required for core operation.
Remote features must not break local operation.
+72 -236
View File
@@ -1,279 +1,115 @@
# HARDWARE.md
# Hardware
# Hardware Overview
## Cargo ESP32
Overland Controller is designed as a distributed system consisting of a control module and a dashboard module.
The architecture intentionally separates power management from user interface functions.
---
# System Architecture
text House Battery │ │ ▼ +-------------------+ | ESP32 Controller | +-------------------+ │ ├── JBD/Xiaoxiang BMS ├── DS18B20 Sensors ├── Relay Outputs ├── Local Web API └── WiFi Network ⇅ +-------------------+ | Pico 2 W Dashboard| +-------------------+ │ ├── Touchscreen ├── Dashboard UI ├── Vehicle Display └── User Controls
---
# ESP32 Controller
The ESP32 controller is installed near the house battery and electrical system.
The cargo ESP32 is the controller and source of truth.
Responsibilities:
- Battery monitoring
- Temperature monitoring
- Relay control
- Configuration storage
- Local API server
- Dashboard communications
- BMS BLE
- Relays
- DS18B20 temps
- WebUI
- HTTP API
- AP mode
- Alarms
Current development target:
Relay board outputs are trigger/control outputs only.
text ESP32 DevKit
High-current loads must use properly fused automotive relays or contactors.
Future hardware can be substituted without major firmware changes.
Do not directly route fridge, Starlink, inverter, lights, or other major loads through the ESP32 relay board.
---
## Dashboard
# Raspberry Pi Pico Dashboard
Target:
The dashboard provides the primary user interface.
Waveshare ESP32-S3-Touch-LCD-5
Current development target:
Reasons:
text Raspberry Pi Pico 2 W
- ESP32-S3 is mature enough for LVGL dashboard
- 5 inch 800x480 display gives enough UI space
- WiFi connects to Cargo ESP32 AP
- CAN interface with onboard TJA1051 supports future OBD-II vehicle data
- microSD allows future logging
- 7-36V VIN supports vehicle power
Planned display hardware:
## Dashboard Power
text 3.5" Touchscreen
Preferred:
Responsibilities:
ACC switched 12V
-> fuse
-> Waveshare VIN
- Display system status
- Display battery information
- Display temperatures
- Control relays
- Configuration interface
- Alarm notifications
Do not use OBD-II pin 16 for permanent dashboard power.
---
## CAN / OBD-II
# Battery Monitoring
OBD-II pins:
Supported BMS:
Pin 6 = CAN-H
Pin 14 = CAN-L
Pin 5 = Signal Ground, optional if needed
Pin 16 = Battery 12V, do not use for permanent display power
text JBD Xiaoxiang
Waveshare CAN termination must remain disabled on vehicle CAN.
Communication:
Preferred CAN wiring:
text Bluetooth Low Energy (BLE)
OBD pin 6 -> Waveshare CAN-H
OBD pin 14 -> Waveshare CAN-L
Data collected:
Optional:
- State of charge
- Voltage
- Current
- Capacity
- Temperature
- Cycle count
- Cell voltages
- Cell imbalance
OBD pin 5 -> board/system ground
---
Use twisted pair. Cat5e/Cat6 twisted pair is acceptable for short vehicle runs.
# Temperature Sensors
Avoid Scotchlok/vampire taps on vehicle CAN. Prefer OBD splitter or proper automotive splice.
Supported sensor type:
## Vehicle Data
text DS18B20
Coolant temp:
Connection:
Standard OBD-II PID 0105
text 1-Wire Bus
RPM:
Current firmware supports:
Standard OBD-II PID 010C
text Up to 8 sensors
Vehicle speed:
Recommended uses:
Standard OBD-II PID 010D
- Refrigerator compartment
- Freezer compartment
- Cabin temperature
- Exterior temperature
- Electronics enclosure
- Battery compartment
## Transmission Temperature Sender
---
Preferred over Nissan-specific trans-temp CAN reverse engineering.
# Relay Outputs
Candidate:
Current firmware supports:
Autometer 2258 / 2259 style sender
text 2 relay outputs
Resistance table:
Default GPIO assignments:
100F = 1123 ohms
120F = 708 ohms
140F = 460 ohms
150F = 374 ohms
170F = 253 ohms
190F = 175 ohms
210F = 123 ohms
230F = 89 ohms
250F = 65 ohms
280F = 42 ohms
300F = 32 ohms
320F = 25 ohms
340F = 20 ohms
| Relay | GPIO |
|---------|---------|
| relay_1 | 16 |
| relay_2 | 17 |
Implementation:
These outputs are intended to drive relay coils, not high-current loads directly.
- Sender to ADC voltage divider, or
- Sender to ADS1115 over I2C if no suitable exposed ADC exists
---
# High Current Loads
Recommended design:
text ESP32 GPIO │ ▼ Relay Module │ ▼ Automotive Relay │ ▼ Load
Examples:
- Refrigerator
- Starlink
- Inverter enable
- Lighting circuits
- Water pump
- Air compressor
---
# Automotive Relay Recommendation
Recommended relay type:
text Bosch-style 30A or 40A relay
Each high-current circuit should have:
- Dedicated fuse
- Appropriate wire gauge
- Proper grounding
- Automotive-rated connectors
---
# Power System
Typical installation:
text House Battery │ ├── Main Fuse │ ├── ESP32 Controller │ ├── Relay Circuits │ └── Accessories
The ESP32 should remain powered from the house battery so monitoring remains active when the vehicle is parked.
---
# Communications
Current communications:
## ESP32 ↔ BMS
text Bluetooth Low Energy
---
## ESP32 ↔ Dashboard
Current:
text UART
Future:
text WiFi HTTP API MQTT
---
# WiFi Network
The ESP32 currently provides:
text Access Point Mode
Default address:
text 192.168.4.1
The dashboard and user devices connect directly to the controller.
No internet connection is required.
---
# Future Hardware Support
Planned additions:
## Vehicle Telemetry
Possible interfaces:
text OBD-II ELM327 CAN Bus
Potential data:
- Engine RPM
- Coolant temperature
- Fuel level
- Vehicle speed
- Diagnostic trouble codes
---
## GPS
Potential features:
- Location tracking
- Trip logging
- Route history
- Speed tracking
---
## Environmental Sensors
Potential additions:
- Humidity
- Barometric pressure
- Air quality
- Water tank monitoring
---
# Current Bill of Materials
## Installed
- ESP32 Controller
- Raspberry Pi Pico 2 W
- ESP32 Relay Module
---
## Planned
- 3.5" Touchscreen
- DS18B20 Sensors
- Automotive Relays
- Fuse Block
- Wiring Harness
- Enclosures
---
# Design Goals
The hardware platform is intended to be:
- Modular
- Vehicle independent
- Serviceable
- Expandable
- Offline capable
- Easy to troubleshoot
- Suitable for long-term overland use
Use lookup-table interpolation.