Elbil og opladning
Intelligent opladning af Nissan Leaf med solenergi
Jeg har opsat et smart og fleksibelt system, der oplader min Nissan Leaf med overskudsstrøm fra solcellerne. Systemet bruger en ETEK EKEPC2 EV ladekontrolenhed, som styres via ESPHome og Home Assistant.
Hvordan fungerer det?
- ETEK EKEPC2 taler Modbus RTU.
- En ESP8266 (Wemos D1 Mini) kører ESPHome og håndterer al kommunikation.
- Home Assistant overvåger og styrer automatisk opladning baseret på solproduktion.
Funktioner:
- Start/Stop opladning fjernstyret via ESPHome og Home Assistant
- Statusindikatorer: klar, tilsluttet, lader, fejl
- Temperatur, spænding og PWM duty cycle aflæsning
- Web interface direkte på ESP-enheden
Komponenter
| Komponent | Funktion |
|---|---|
| ETEK EKEPC2 EV | EVSE-controller til Mode 3 opladning |
| ESP8266 (Wemos D1 Mini) | WiFi-styring og Modbus via UART |
| MAX485 | RS485 Converter Adapter |
| Home Assistant | Overvågning og automatisering |
| Victron solcelleanlæg | Leverer data om strømproduktion |
Producentens side for laderen: ETEK EKEPC2 EV
ESPHome-koden
esphome:
name: ev-charger
friendly_name: ev_charger
esp8266:
board: d1_mini
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "G0qTV5ILLwbNmakxFwXOnNAzYsDbgMRAF/V/Bot4fIE="
ota:
- platform: esphome
password: "aa20e1c24135c9a6c4a310ce768213f0"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Ev-Charger Fallback Hotspot"
password: "lqsjJtQU67Jj"
captive_portal:
binary_sensor:
- platform: status
name: "ESP Status"
switch:
- platform: restart
name: "ESP Restart"
time:
- platform: homeassistant
id: esptime
web_server:
local: true
uart:
id: modbus_serial
tx_pin: 5 # D2 ESP8266 tx pin for soft serial uart
rx_pin: 4 # D1 ESP8266 rx pin for soft serial uart
#rx_buffer_size: 512
baud_rate: 9600
stop_bits: 1
#debug:
# direction: BOTH
# dummy_receiver: true
modbus:
flow_control_pin: 0
id: modbus1
uart_id: modbus_serial
send_wait_time: 10ms
modbus_controller:
- id: ETEK
update_interval: 5s
address: 255
command_throttle: 100ms
setup_priority: -10
modbus_id: modbus1
max_cmd_retries: 0
text_sensor:
- platform: template
name: "Current working status text"
id: status_text
- platform: template
name: "Current working status desc"
id: status_desc
- platform: template
name: "Remote start and stop"
id: status_mode
output:
- platform: modbus_controller
modbus_controller_id: ETEK
address: 255
register_type: holding
value_type: S_WORD
id: WallBoxStartStop
button:
- platform: template
id: ChargeStop
name: "Remote start"
on_press:
then:
- lambda: |-
modbus_controller::ModbusController *controller = id(ETEK);
modbus_controller::ModbusCommandItem ChargeStop = modbus_controller::ModbusCommandItem::create_write_single_command(controller, 0x59, 1);
controller->queue_command(ChargeStop);
- platform: template
id: ChargeStart
name: "Remote Stop"
on_press:
then:
- lambda: |-
modbus_controller::ModbusController *controller = id(ETEK);
modbus_controller::ModbusCommandItem ChargeStart = modbus_controller::ModbusCommandItem::create_write_single_command(controller, 0x59, 2);
controller->queue_command(ChargeStart);
sensor:
- platform: uptime
name: "ESP Uptime"
unit_of_measurement: "s"
- platform: modbus_controller
name: "Remote start and stop Internal"
address: 0x59 #Remote start and stop (0 invalid, 1 start, 2 stop)
register_type: holding
modbus_controller_id: ETEK
value_type: S_WORD
internal: true
on_value:
then:
lambda: |-
if (x == 0) {id(status_mode).publish_state("0-Invalid"); }
else if (x == 1) {id(status_mode).publish_state("1-Start"); }
else if (x == 2) {id(status_mode).publish_state("2-Stop"); }
else {id(status_mode).publish_state("other");}
- platform: modbus_controller
name: "Current working status"
address: 0x8D #Current working status
register_type: holding
modbus_controller_id: ETEK
value_type: S_WORD
skip_updates: 0
on_value:
then:
lambda: |-
if (x == 0) {id(status_text).publish_state("0-Fault--1#"); id(status_desc).publish_state("Power self detect failed"); }
else if (x == 1) {id(status_text).publish_state("1-Ready"); id(status_desc).publish_state("CP disconnection"); }
else if (x == 2) {id(status_text).publish_state("2-RFID Waiting"); id(status_desc).publish_state("Waiting for IC card"); }
else if (x == 3) {id(status_text).publish_state("3-Connected"); id(status_desc).publish_state("CP connect to diode+2.7KQ"); }
else if (x == 4) {id(status_text).publish_state("3-Connected"); id(status_desc).publish_state("CP connect to diode+1.3KQ"); }
else if (x == 5) {id(status_text).publish_state("5-Charging"); id(status_desc).publish_state("CP connect to diode+2.7KQ parallel connect1.3KO"); }
else if (x == 6) {id(status_text).publish_state("6-Fault--2#"); id(status_desc).publish_state("CP connect to diode+2.7KQ parallel connect 1.3KQ parallel connect 270F ..."); }
else if (x == 7) {id(status_text).publish_state("7-Fault--3#"); id(status_desc).publish_state("CP line short circuit with PE line"); }
else if (x == 8) {id(status_text).publish_state("8-Fault--4#"); id(status_desc).publish_state("RCMU occurs residual current or self detect failed"); }
else if (x == 9) {id(status_text).publish_state("9-Fault--5#"); id(status_desc).publish_state("Diode short circuit (Requirement waiting the CP disconnected)"); }
else if (x == 10) {id(status_text).publish_state("10-Fault--6#"); id(status_desc).publish_state("PP line disconnection"); }
else if (x == 11) {id(status_text).publish_state("11-Fault--7#"); id(status_desc).publish_state("Electromagnetic Lock failed"); }
else if (x == 12) {id(status_text).publish_state("12-Fault--8#"); id(status_desc).publish_state("IC card failed"); }
else if (x == 13) {id(status_text).publish_state("13-Fault--9#"); id(status_desc).publish_state("Circuit overload,DLB Mode activated"); }
else if (x == 13) {id(status_text).publish_state("19-Remote stop"); id(status_desc).publish_state("Remote stop"); }
else {id(status_text).publish_state("Unknown"); id(status_desc).publish_state(""); }
- platform: wifi_signal
name: "WiFiSignalWallBox"
update_interval: 360s
- platform: modbus_controller
name: "Temp"
address: 0x9d
unit_of_measurement: "ºC"
register_type: holding
modbus_controller_id: ETEK
value_type: S_WORD
#accuracy_decimals: 1
filters:
- multiply: 0.1
device_class: temperature
skip_updates: 5
- platform: modbus_controller # CP positive voltage
name: "CP positive voltage"
address: 0x99
unit_of_measurement: "V"
register_type: holding
modbus_controller_id: ETEK
value_type: S_WORD
device_class: voltage
skip_updates: 5
- platform: modbus_controller # CP negative voltage
name: "CP negative voltage"
address: 0x9A
unit_of_measurement: "V"
register_type: holding
modbus_controller_id: ETEK
value_type: S_WORD
device_class: voltage
skip_updates: 5
- platform: modbus_controller
name: "VM1"
address: 0x5A
unit_of_measurement: "V"
register_type: holding
modbus_controller_id: ETEK
value_type: S_WORD
device_class: voltage
skip_updates: 5
- platform: modbus_controller
name: "V1"
address: 0x9F #1# meter A phase voltage
unit_of_measurement: "V"
register_type: holding
modbus_controller_id: ETEK
value_type: S_WORD
device_class: voltage
skip_updates: 5
- platform: modbus_controller
name: "PWM duty cycle Switch (current)"
address: 0x97 #PWM duty cycle corresponding to the current set by the rotary switch
register_type: holding
modbus_controller_id: ETEK
value_type: S_WORD
filters:
- multiply: 0.006
device_class: current
skip_updates: 5
- platform: modbus_controller #Current output PWM duty cycle
name: "Current output PWM duty cycle"
address: 0x98
register_type: holding
modbus_controller_id: ETEK
value_type: S_WORD
filters:
- multiply: 0.006
device_class: current
skip_updates: 5
- platform: modbus_controller
name: "PWM duty cycle MAX"
address: 0x6D #Max Output Current PWM Duty cycle(*100)
register_type: holding
modbus_controller_id: ETEK
value_type: S_WORD
filters:
- multiply: 0.006
device_class: current
skip_updates: 60
- platform: modbus_controller #The 1 gear current setting value PWM
name: "PWM duty cycle 1"
address: 0x80
register_type: holding
modbus_controller_id: ETEK
value_type: S_WORD
filters:
- multiply: 0.006
device_class: current
skip_updates: 60
- platform: modbus_controller #The 2 gear current setting value PWM
name: "PWM duty cycle 2"
address: 0x81
register_type: holding
modbus_controller_id: ETEK
value_type: S_WORD
filters:
- multiply: 0.006
device_class: current
skip_updates: 60
- platform: modbus_controller #The 3 gear current setting value PWM
name: "PWM duty cycle 3"
address: 0x82
register_type: holding
modbus_controller_id: ETEK
value_type: S_WORD
filters:
- multiply: 0.006
device_class: current
skip_updates: 60
- platform: modbus_controller #The 4 gear current setting value PWM
name: "PWM duty cycle 4"
address: 0x83
register_type: holding
modbus_controller_id: ETEK
value_type: S_WORD
filters:
- multiply: 0.006
device_class: current
skip_updates: 60
- platform: modbus_controller #The 5 gear current setting value PWM
name: "PWM duty cycle 5"
address: 0x84
register_type: holding
modbus_controller_id: ETEK
value_type: S_WORD
filters:
- multiply: 0.006
device_class: current
skip_updates: 60
- platform: modbus_controller #The 6 gear current setting value PWM
name: "PWM duty cycle 6"
address: 0x85
register_type: holding
modbus_controller_id: ETEK
value_type: S_WORD
filters:
- multiply: 0.006
device_class: current
skip_updates: 60