# ChargeFlow EVSE Firmware (ESP32, ESP-IDF 5.x) Firmware for an AC EVSE (EV charger) based on ESP32 and ESP-IDF 5.x, with: - IEC-style EVSE state machine (Control Pilot A/B/C/D) - Wi-Fi (STA + AP for local configuration) - REST API served from SPIFFS - Local authentication and OCPP integration - Load balancing (master + slaves) - Scheduler (time windows) - Audible feedback (buzzer) and RGB LED status - On-device ring-buffer logger --- ## Features ### Core EVSE - EVSE manager (`evse_manager`) coordinating: - Hardware layer (`evse_hardware`) - State machine (`evse_state`) - Error handling (`evse_error`) - Energy metering (`evse_meter` / `meter_manager`) - Session tracking (`evse_session`) - Runs a periodic tick (`evse_manager_tick()`) in its own FreeRTOS task. - Supports multiple auth modes (OPEN / RFID / OCPP), with scheduling and load-balancer aware logic. ### Networking & REST - Wi-Fi: - Station mode for normal operation. - Access point mode for local configuration, enabled by a physical button. - REST server (`rest_main`) serving from `/data` SPIFFS mount: - For configuration, status, logs, etc. (exact endpoints depend on your REST implementation). ### Button & User Input - One physical button (configured via `board_config`): - **Short press** → Starts Wi-Fi AP mode for configuration. - **Long press (~30s)** → Erases NVS and reboots (factory-like reset). - Robust handling: - ISR with software debounce and spinlock. - Dedicated `user_input_task` that receives button press/release notifications via `xTaskNotify`. ### Storage - SPIFFS used for: - `/cfg` partition: persistent configuration. - `/data` partition: web assets, runtime data, logs, etc. - Two separate mounts: - `cfg_conf` → `/cfg` (label: `cfg`) - `data_conf` → `/data` (label: `data`) ### LED Subsystem - RGB LED driven by LEDC: - `ledc_driver` abstracts LEDC timer + channels. - `led` module maps EVSE state & sessions to colors/patterns. - LED patterns per EVSE state: - **IDLE** → Green solid. - **WAITING** (vehicle plugged, not charging) → Blue slow blink. - **CHARGING** → Blue “breathing” effect. - **FAULT** → Red fast blink. - Session effects: - Distinct visual patterns when a session starts/finishes. - Uses a one-shot timer and a dedicated effect state machine. ### Buzzer - Buzzer with multiple patterns (`buzzer` + `buzzer_events`): - Plugged/unplugged, card read/denied, AP start, charging, fault, etc. - Supported modes: - Active buzzer (ON/OFF). - Passive buzzer with LEDC PWM (frequency & duty configurable). - Features: - Central queue + dedicated `buzzer_task`. - Quiet hours support (optionally suppress non-critical sounds at night). - Anti-spam mechanism to avoid excessively frequent beeps. - Integrated with: - EVSE events (state changes & faults) - Auth events (RFID card success/denied/added) - Network events (AP/STA up) ### Load Balancer - `loadbalancer` component: - Monitors GRID meter and EVSE meter via `meter_events`. - Supports one master + up to 255 slaves (connectors array). - Fair distribution of current with: - Headroom calculation based on grid limit and measured current. - Min current guarantees (e.g. 6 A) using a “water-filling” algorithm. - Session-age based priority (oldest sessions first). - Per-connector hysteresis and LB suspension/resume flags. - Publishes limits via `LOADBALANCER_EVENTS`: - `LOADBALANCER_EVENT_MASTER_CURRENT_LIMIT` - `LOADBALANCER_EVENT_SLAVE_CURRENT_LIMIT` - Fail-safe behavior: - If GRID meter data times out, clamps connectors to minimum safe current instead of ramping up. ### Scheduler - Scheduler component (`scheduler`) emits `SCHED_EVENTS` with `allowed_now` flag: - EVSE manager revokes authorization when the window closes. - In OPEN mode, automatic re-authorization only happens when scheduler allows. ### OCPP - `ocpp` module integration: - Listens to OCPP events (`OCPP_EVENTS`). - Handles: - RemoteStart/Stop - Authorization results - ChangeAvailability (operative/inoperative) → mapped into local `enabled` config. - EVSE manager mediates OCPP decisions with scheduler + load balancer. ### Logger - `logger` + `output_buffer` components: - Central log sink with ring buffer in RAM. - Thread-safe via FreeRTOS mutex. - Integrated with ESP log system via `esp_log_set_vprintf(logger_vprintf);` - Optionally mirrors to UART (controlled via `CONFIG_ESP_CONSOLE_UART`). - Simple reader API: - Iterate entries using an index. - Handy for exposing logs over REST/Web UI. --- ## Project Structure (Relevant Parts) Approximate layout (names may vary slightly in your repo): ```text main/ main.c # System entrypoint, button setup, module init components/ evse/ evse_manager.c/.h # High-level EVSE orchestration evse_state.c/.h # State machine & events evse_error.c/.h # Error handling evse_hardware.c/.h # Hardware abstraction evse_session.c/.h # Session metrics loadbalancer/ src/ loadbalancer.c loadbalancer_events.c input_filter.c include/ loadbalancer.h loadbalancer_events.h input_filter.h buzzer/ src/ buzzer.c buzzer_events.c include/ buzzer.h buzzer_events.h led/ src/ led.c ledc_driver.c include/ led.h ledc_driver.h logger/ src/ logger.c output_buffer.c include/ logger.h output_buffer.h # ... other modules: auth, ocpp, scheduler, meter_manager, evse_link, etc.