Hey @ThomasMidgley. Great job!
How does this convert to 2kW?
value:
- 16656
- 0
I can’t seem to work it out from the floattohex link you provided.
Hey @ThomasMidgley. Great job!
How does this convert to 2kW?
value:
- 16656
- 0
I can’t seem to work it out from the floattohex link you provided.
@gisa, hi,
When you save a value to the lovelance card in the form of “value: [x,y]” it is saved in a different form:
value:
- a
- b
I never tried to figure out why and how this is working.
You don’t set the kW as such in charger, but the maximum aperage:
since I have only a 1phase 230V power supply: 2kW / 230V =~ 8A
8A = 0x41000000 = [0x4100, 0x0000]
in a lovelance card it is stored as:
value:
- 16656
- 0
other example:
32A = 0x42000000 = [0x4200, 0x0000]
or
value:
- 16640
- 0
in automations the original values are kept:
###################################
# #
# Instellen laadsnelheid laadpaal #
# #
###################################
# Floating Point to Hex Converter
# https://gregstoll.com/~gregstoll/floattohex/
# 23h00 - 07h30: 32A
# 07h30 - 13h00: 0A
# 13h00 - 17h00: 32A
# 17h00 - 22h00: 0A
# 21h15 - 23h00: 8A
- alias: "Laadsnelheid 00h00"
trigger:
- platform: time
at: "23:00:00"
condition:
- condition: state
entity_id: input_boolean.auto_charge
state: "on"
action:
- service: modbus.write_register
data:
address: 8
slave: 255
value: [0x4200, 0x0000] # 32A
hub: etrel_inch
- alias: "Laadsnelheid 07h30"
trigger:
- platform: time
at: "07:30:00"
condition:
- condition: state
entity_id: input_boolean.auto_charge
state: "on"
action:
- service: modbus.write_register
data:
address: 8
slave: 255
value: [0x0000, 0x0000] # 0A
hub: etrel_inch
- alias: "Laadsnelheid 13h00"
trigger:
- platform: time
at: "13:00:00"
condition:
- condition: state
entity_id: input_boolean.auto_charge
state: "on"
action:
- service: modbus.write_register
data:
address: 8
slave: 255
value: [0x4200, 0x0000] # 32A
hub: etrel_inch
- alias: "Laadsnelheid 17h00"
trigger:
- platform: time
at: "17:00:00"
condition:
- condition: state
entity_id: input_boolean.auto_charge
state: "on"
action:
- service: modbus.write_register
data:
address: 8
slave: 255
value: [0x0000, 0x0000] # 0A
hub: etrel_inch
- alias: "Laadsnelheid 21h15"
trigger:
- platform: time
at: "21:15:00"
condition:
- condition: state
entity_id: input_boolean.auto_charge
state: "on"
action:
- service: modbus.write_register
data:
address: 8
slave: 255
value: [0x4100, 0x0000] # 8A
hub: etrel_inch
- delay:
minutes: 1
- service: automation.trigger
data:
skip_condition: true
target:
entity_id: automation.notificatie_vermogen_laadpaal
hope this helps.
Great info @ThomasMidgley. It looks like it got things working!
The ultimate goal would be to use any excess solar pv production, but let’s see how this goes first
Hi Thomas, I like your code, I have the same ev charger. I would like to max the phase instead of max power. How did you know which variable is which in the modbus.
I would like to make a dynamic load balancing based on current available A in the house at that moment of charging.
Another question, I have two Etrel chargers, how can I control them both ? Add another modbus section ? but how to deal with the names and ids? I tried, but it gives errors.
Hi, in the first post there’s a link to the wiki of Etrel, containing an overview of the registers. Here’s a direct link to the excel
I don’t understand what you mean with “max the phase”. Nevertheless, I’m afraid HA will not be fast enough to react to momentarily surges in power use. Your fuse will pop faster than HA will update the set point for the maximum current.
I use an Etrel load guard for this purpose:
https://etrel.com/charging-solutions/load-guard/
according to the documentation you should setup multiple connections
https://www.home-assistant.io/integrations/modbus/#configuring-multiple-connections
# Example yaml: multiple tcp connections
modbus:
- name: modbus_hub
type: tcp
host: IP_ADDRESS_1
port: 2020
- name: modbus_hub2
type: tcp
host: IP_ADDRESS_2
port: 502
make sure they don’t use the same ports.
Hi Thomas, thanks for the info, yes I have also load guard installed. Dont know if there are settings for that as well, I have also heatpump and batteries who are heavy consumers. Would love to use the load guard for all these devices. I kind of want to build that in HA.
Not sure how I can change the port on the etrel, since I don’t have login / pwd…
I found a way in, but in the web interface of etrel you cannot change the port 501 to something else. Is there another way ?
The default login and password can be found on the inside of the maintenance door of the charger.
the charger uses port 502, where as the load balancer uses port 503. see the excel of Etrel
It might be easier if you use evcc.io as a controller for your Etrel box (setting all the price rules and plans for charging there) and then integrate evcc into HA.
Dear,
Could you share the modbus map table for the Etrel Inch, I can’t seem to find it anywhere…
Sorry, I was just a bit too fast in replying (although I already searched), I found the tabel.
I found it here
For future reference and for anyone who may find it usefull, this is how I got it implemented:
In configuration.yaml:
modbus: !include_dir_merge_list modbus/
In modbus/EVSE.yaml:
- name: modbus_etrel
type: tcp
host: 192.168.1.145
port: 502
delay: 2
timeout: 5
sensors:
- name: Etrel_Connnector_status
unique_id: "Etrel_Connnector_status"
scan_interval: 10
address: 0
input_type: input
data_type: int16
- name: Etrel_Measured_vehicle_number_of_phases
unique_id: "Etrel_Measured_vehicle_number_of_phases"
scan_interval: 10
address: 1
input_type: input
data_type: int16
- name: Etrel_EV_max_phase_current
unique_id: "Etrel_EV_max_phase_current"
scan_interval: 10
address: 2
input_type: input
data_type: float32
- name: Etrel_Target_current_from_power_mgm_or_modbus
unique_id: "Etrel_Target_current_from_power_mgm_or_modbus"
scan_interval: 10
address: 4
input_type: input
data_type: float32
- name: Etrel_Frequency
unique_id: "Etrel_Frequency"
scan_interval: 10
address: 6
input_type: input
data_type: float32
- name: Etrel_L-N_voltage_(L1)
unique_id: "Etrel_L-N_voltage_(L1)"
scan_interval: 10
address: 8
input_type: input
data_type: float32
- name: Etrel_L-N_voltage_(L2)
unique_id: "Etrel_L-N_voltage_(L2)"
scan_interval: 10
address: 10
input_type: input
data_type: float32
- name: Etrel_L-N_voltage_(L3)
unique_id: "Etrel_L-N_voltage_(L3)"
scan_interval: 10
address: 12
input_type: input
data_type: float32
- name: Etrel_Curent_(L1)
unique_id: "Etrel_Curent_(L1)"
scan_interval: 10
address: 14
input_type: input
data_type: float32
- name: Etrel_Curent_(L2)
unique_id: "Etrel_Curent_(L2)"
scan_interval: 10
address: 16
input_type: input
data_type: float32
- name: Etrel_Curent_(L3)
unique_id: "Etrel_Curent_(L3)"
scan_interval: 10
address: 18
input_type: input
data_type: float32
- name: Etrel_Active_power_(L1)
unique_id: "Etrel_Active_power_(L1)"
scan_interval: 10
address: 20
input_type: input
data_type: float32
- name: Etrel_Active_power_(L2)
unique_id: "Etrel_Active_power_(L2)"
scan_interval: 10
address: 22
input_type: input
data_type: float32
- name: Etrel_Active_power_(L3)
unique_id: "Etrel_Active_power_(L3)"
scan_interval: 10
address: 24
input_type: input
data_type: float32
- name: Etrel_Active_power_(total)
unique_id: "Etrel_Active_power_(total)"
scan_interval: 10
address: 26
input_type: input
data_type: float32
- name: Etrel_Power_factor
unique_id: "Etrel_Power_factor"
scan_interval: 10
address: 28
input_type: input
data_type: float32
- name: Etrel_Total_imported_active_energy_in_running_session
unique_id: "Etrel_Total_imported_active_energy_in_running_session"
scan_interval: 10
address: 30
input_type: input
data_type: float32
- name: Etrel_Running_session_duration
unique_id: "Etrel_Running_session_duration"
scan_interval: 10
address: 32
input_type: input
data_type: int64
- name: Etrel_Running_session_departure_time
unique_id: "Etrel_Running_session_departure_time"
scan_interval: 10
address: 36
input_type: input
data_type: int64
- name: Etrel_Running_session_ID
unique_id: "Etrel_Running_session_ID"
scan_interval: 10
address: 40
input_type: input
data_type: int64
- name: Etrel_EV_max_power
unique_id: "Etrel_EV_max_power"
scan_interval: 10
address: 44
input_type: input
data_type: float32
- name: Etrel_EV_planned_energy
unique_id: "Etrel_EV_planned_energy"
scan_interval: 10
address: 46
input_type: input
data_type: float32
- name: Etrel_Connector_type
unique_id: "Etrel_Connector_type"
scan_interval: 10
address: 1022
input_type: input
data_type: int16
- name: Etrel_Number_phases
unique_id: "Etrel_Number_phases"
scan_interval: 10
address: 1023
input_type: input
data_type: int16
- name: Etrel_L1_connected_to_phase
unique_id: "Etrel_L1_connected_to_phase"
scan_interval: 10
address: 1024
input_type: input
data_type: int16
- name: Etrel_L2_connected_to_phase
unique_id: "Etrel_L2_connected_to_phase"
scan_interval: 10
address: 1025
input_type: input
data_type: int16
- name: Etrel_L3_connected_to_phase
unique_id: "Etrel_L3_connected_to_phase"
scan_interval: 10
address: 1026
input_type: input
data_type: int16
- name: Etrel_Custom_max_current
unique_id: "Etrel_Custom_max_current"
scan_interval: 10
address: 1028
input_type: input
data_type: float32
- name: Etrel__Set_current_setpoint
unique_id: "Etrel__Set_current_setpoint"
scan_interval: 10
address: 8
input_type: holding
data_type: float32
unit_of_measurement: 'A'
scale: 1
precision: 1
switches:
- name: Etrel__Stop_charging
unique_id: "Etrel__Stop_charging"
scan_interval: 10
address: 1
write_type: holding
command_on: 1
command_off: 0
I don’t really use the switch.
I have an automation that monitors the ‘Etrel_Connnector_status’ and starts half a minute charge when connected, then monitors the grid interaction to adjust according to presets. For me it is keep the grid interaction close to zero if possible (adjusting the set current), and draw a maximum of 500W from the grid. So for now, basically only charge when the sun is shining.
I also have a pyscript to convert the decimal value of the setpoint to 2 registers and sends this to the charger:
import struct
@service
def send_current_setpoint(value=10.0):
# Float naar big-endian Float32 bytes
float_bytes = struct.pack(">f", value)
# Verdeel in 2 registers (16-bit woorden)
word1 = int.from_bytes(float_bytes[0:2], byteorder="big")
word2 = int.from_bytes(float_bytes[2:4], byteorder="big")
log.info(f"Setpoint {value} A wordt verstuurd als [{word1}, {word2}]")
# Modbus-register schrijven
service.call(
"modbus", "write_register",
hub="modbus_etrel", # Naam van je Modbus hub
unit=1, # Modbus unit ID
address=8, # Adres voor stroominstelling
value=[word1, word2] # Float32 in 2 woorden
)
Sorry for the dutch language, I asked chatGPT for help in dutch.
hi, how to use an automation to run this pyscript? I have pyscript installed on my instance.
edit: found it, forgot to add the “@service”