# 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.
