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 # 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: Responsibilities:
- Read battery/BMS data - Read JBD/Xiaoxiang BMS data over BLE
- Read temperature sensors - Read DS18B20 temperature sensors
- Control relay outputs - Control relay trigger outputs
- Store configuration - Store configuration
- Serve the HTTP API - Serve HTTP API
- Communicate with the Pico dashboard over UART - Serve local WebUI
- Maintain system status - Run WiFi AP mode
- Handle alarms - 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: Responsibilities:
- Request status from ESP32 - Native LVGL dashboard
- Display battery data - Connect to Cargo ESP32 AP as WiFi client
- Display temperature data - Poll Cargo ESP32 HTTP API
- Display relay states - Send simple control commands through HTTP API
- Send relay commands - Display battery, relay, temp, vehicle, and alert data
- Send configuration commands - Future CAN vehicle data
- Provide setup workflows - Future transmission temperature sender display
- Operate without internet
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: - Setup/configuration
- Relay names
- Status requests - Temperature sensor names
- Relay control
- Configuration updates
- BMS setup - 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 - Recovery
- Troubleshooting - API testing
- Emergency configuration
## Data Model Avoid complex configuration on the touchscreen dashboard.
The same generic data model should be used across: ## Network
- HTTP API Cargo ESP32 runs WPA2 AP mode continuously.
- UART protocol
- Pico dashboard 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 - 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 ## Generic IDs
@@ -109,9 +121,9 @@ Temperature sensors:
temp_7 temp_7
temp_8 temp_8
Installation-specific names belong only in saved configuration. Install-specific names belong in saved configuration only.
Examples of configuration names: Examples:
Fridge Fridge
Starlink Starlink
@@ -119,33 +131,11 @@ Examples of configuration names:
Outside Outside
House Battery 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. Expected status groups:
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:
battery battery
temps temps
@@ -156,176 +146,25 @@ ESP32 responds with the same shape as HTTP /status:
system system
config config
## Relay Control Flow ## Vehicle Data
Pico sends a generic relay command: Use standard OBD-II over CAN first.
relay_1 on Planned standard PIDs:
relay_1 off
relay_2 on
relay_2 off
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 Phone/PWA
scan_ble -> Home server HTTPS
scan_ble -> MQTT/WebSocket/HTTPS bridge
select_bms -> Cargo ESP32 outbound connection
save_config
The ESP32 handles BLE scanning and BMS selection. Remote features must not break local operation.
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.
+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 cargo ESP32 is the controller and source of truth.
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.
Responsibilities: Responsibilities:
- Battery monitoring - BMS BLE
- Temperature monitoring - Relays
- Relay control - DS18B20 temps
- Configuration storage - WebUI
- Local API server - HTTP API
- Dashboard communications - 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 Do not use OBD-II pin 16 for permanent dashboard power.
- Display battery information
- Display temperatures
- Control relays
- Configuration interface
- Alarm notifications
--- ## 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 OBD pin 5 -> board/system ground
- Voltage
- Current
- Capacity
- Temperature
- Cycle count
- Cell voltages
- Cell imbalance
--- 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 ## Transmission Temperature Sender
- Freezer compartment
- Cabin temperature
- Exterior temperature
- Electronics enclosure
- Battery compartment
--- 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 | Implementation:
|---------|---------|
| relay_1 | 16 |
| relay_2 | 17 |
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
--- Use lookup-table interpolation.
# 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