Webasto (now Ampure) Unite Wallbox Modbus Integration

"Hello! As a delighted user of the Webasto “Unite” (and Webasto Next soon) Charging Station, I’ve taken the initiative to integrate the Unite Modbus table register settings into Home Assistant.

In this initial phase, I’ve successfully added these settings, paving the way for enhanced functionality. Depending on your specific needs, it’s also feasible to configure the related register to adjust the charging power. This feature proves invaluable for scenarios like PV-Surcharge charging demands or Load Management requirements, especially if you plan to utilize multiple charging stations.

Below, you’ll find the Modbus sensor table, which you can seamlessly incorporate into your configuration.yaml. Alternatively, I’ve organized this information into a dedicated modbus.yaml file. In my configuration setup, I simply reference this modbus.yaml file within my configuration.yaml, streamlining the process. Here’s how it looks:"

modbus: !include modbus.yaml

Here’s the code for the modbus.yaml file::

# Protocol requirements
# The Webasto Unite charging station acts as a slave device in Modbus TCP/IP communication.
# Charging station should be in the same network with the master device, or proper routing should be applied to provide communication between slave and master devices in different sub networks.
# Each charging station should have a different IP address. There can only be one active Modbus master connection at any time.
# Parameter Modbus TCP
# Each Wallbox Unite must be given a unique IP.
# Parameter                     Value 
# IP-address:                   Any IP address; All Webasto Unite on the same subnet (e.g., xxx.xxx.xxx.xxx)
# Modbus Port:                  502
# Modbus Unit ID:               255
 
  - name: Webasto_Unite
    type: tcp
    timeout: 5
    host: 192.168.12.212
    port: 502
    sensors:
      - name: Webasto_Unite_Serial_Number
        unique_id: Webasto_Unite_Serial_Number
        slave: 255
        input_type: input
        address: 100
        data_type: string
        count: 25
        
      - name: Webasto_Unite_Charge_Point_ID
        unique_id: Webasto_Unite_Charge_Point_ID
        slave: 255
        input_type: input
        address: 130
        data_type: string
        count: 50
        
      - name: Webasto_Unite_Charge_Point_Brand
        unique_id: Webasto_Unite_Charge_Point_Brand
        slave: 255
        input_type: input
        address: 190
        data_type: string
        count: 10
        
      - name: Webasto_Unite_Charge_Point_Model
        unique_id: Webasto_Unite_Charge_Point_Model
        slave: 255
        input_type: input
        address: 210
        data_type: string
        count: 5
        
      - name: Webasto_Unite_Firmware_Version
        unique_id: Webasto_Unite_Firmware_Version
        slave: 255
        input_type: input
        address: 230
        data_type: string
        count: 50
        
      - name: Webasto_Unite_Date
        unique_id: Webasto_Unite_Date
        slave: 255
        input_type: input
        address: 290
        data_type: uint32
        
      - name: Webasto_Unite_Time
        unique_id: Webasto_Unite_Time
        slave: 255
        input_type: input
        address: 294
        data_type: uint32
        
      - name: Webasto_Unite_Charge_Point_Power
        unique_id: Webasto_Unite_Charge_Point_Power
        slave: 255
        input_type: input
        address: 400
        data_type: uint32
        offset: 0
        scale: 1
        precision: 2
        state_class: measurement
        unit_of_measurement: W
        
      - name: Webasto_Unite_Number_of_Phases
      # 0:1-phase, 1:3-phases
        unique_id: Webasto_Unite_Number_of_Phases
        slave: 255
        input_type: input
        address: 404
        data_type: uint16

      - name: Webasto_Unite_Charge_Point_State
# 0: "Available",
# 1: "Preparing",
# 2: "Charging",
# 3: "SuspendedEVSE",
# 4: "SuspendedEV",
# 5: "Finishing",
# 6: "Reserved",
# 7: "Unavailable",
# 8: "Faulted",
        unique_id: Webasto_Unite_Charge_Point_State
        slave: 255
        input_type: input
        address: 1000
        data_type: uint16
        
      - name: Webasto_Unite_Charging_State
# 0: Not Charging, State Ax, Bx, Dx or C1 1: Charging, state C2      
        unique_id: Webasto_Unite_Charging_State
        slave: 255
        input_type: input
        address: 1001
        data_type: uint16
        
      - name: Webasto_Unite_Equipment_State
# 0: Initializing
# 1: Running
# 2: Fault
# 3: Disabled
# 4: Updating      
        unique_id: Webasto_Unite_Equipment_State
        slave: 255
        input_type: input
        address: 1002
        data_type: uint16

      - name: Webasto_Unite_Cable_State
# 0: Cable not connected 1: Cable connected, vehicle not connected 2: Cable connected, vehicle connected 3: Cable connected, vehicle connected, cable locked
        unique_id: Webasto_Cable_State
        slave: 255
        input_type: input
        address: 1004
        data_type: uint16
        
      - name: Webasto_Unite_EVSE_Fault_Code
# 0: No fault
# Other: Fault code      
        unique_id: Webasto_Unite_EVSE_Fault_Code
        slave: 255
        input_type: input
        address: 1006
        data_type: uint16
        
      - name: Webasto_Unite_Charging_Current_L1
        unique_id: Webasto_Unite_Charging_Current_L1
        slave: 255
        input_type: input
        address: 1008
        data_type: uint16
        device_class: current
        offset: 0
        scale: 0.001
        precision: 0
        state_class: measurement
        unit_of_measurement: A

      - name: Webasto_Unite_Charging_Current_L2
        unique_id: Webasto_Unite_Charging_Current_L2
        slave: 255
        input_type: input
        address: 1010
        data_type: uint16
        device_class: current
        offset: 0
        scale: 0.001
        precision: 0
        state_class: measurement
        unit_of_measurement: A

      - name: Webasto_Unite_Charging_Current_L3
        unique_id: Webasto_Unite_Charging_Current_L3
        slave: 255
        input_type: input
        address: 1012
        data_type: uint16
        device_class: current
        offset: 0
        scale: 0.001
        precision: 0
        state_class: measurement
        unit_of_measurement: A
        
      - name: Webasto_Unite_Charging_Voltage_L1
        unique_id: Webasto_Unite_Charging_Voltage_L1
        slave: 255
        input_type: input
        address: 1014
        data_type: uint16
        device_class: voltage
        state_class: measurement
        unit_of_measurement: V
        
      - name: Webasto_Unite_Charging_Voltage_L2
        unique_id: Webasto_Unite_Charging_Voltage_L2
        slave: 255
        input_type: input
        address: 1016
        data_type: uint16
        device_class: voltage
        state_class: measurement
        unit_of_measurement: V
        
      - name: Webasto_Unite_Charging_Voltage_L3
        unique_id: Webasto_Unite_Charging_Voltage_L3
        slave: 255
        input_type: input
        address: 1018
        data_type: uint16
        device_class: voltage
        state_class: measurement
        unit_of_measurement: V        

      - name: Webasto_Unite_Active_Power_Total
        unique_id: Webasto_Unite_Active_Power_Total
        slave: 255
        input_type: input
        address: 1020
        data_type: uint32
        device_class: power
        state_class: measurement
        unit_of_measurement: W
        
      - name: Webasto_Unite_Active_Power_L1
        unique_id: Webasto_Unite_Active_Power_L1
        slave: 255
        input_type: input
        address: 1024
        data_type: uint32
        device_class: power
        state_class: measurement
        unit_of_measurement: W
        
      - name: Webasto_Unite_Active_Power_L2
        unique_id: Webasto_Unite_Active_Power_L2
        slave: 255
        input_type: input
        address: 1028
        data_type: uint32
        device_class: power
        state_class: measurement
        unit_of_measurement: W
        
      - name: Webasto_Unite_Active_Power_L3
        unique_id: Webasto_Unite_Active_Power_L3
        slave: 255
        input_type: input
        address: 1032
        data_type: uint32
        device_class: power
        state_class: measurement
        unit_of_measurement: W

      - name: Webasto_Unite_Meter_Reading
        unique_id: Webasto_Unite_Meter_Reading
        slave: 255
        input_type: input
        address: 1036
        data_type: uint32
        device_class: energy
        state_class: total_increasing
        offset: 0
        scale: 0.001
        precision: 3
        unit_of_measurement: kWh

      - name: Webasto_Unite_Session_Max_Current
        unique_id: Webasto_Unite_Session_Max_Current
        slave: 255
        input_type: input
        address: 1100
        data_type: uint16
        device_class: current
        state_class: measurement
        unit_of_measurement: A

      - name: Webasto_Unite_EVSE_Min_Current
        unique_id: Webasto_Unite_EVSE_Min_Current
        slave: 255
        input_type: input
        address: 1102
        data_type: uint16
        device_class: current
        state_class: measurement
        unit_of_measurement: A

      - name: Webasto_Unite_EVSE_Max_Current
        unique_id: Webasto_Unite_EVSE_Max_Current
        slave: 255
        input_type: input
        address: 1104
        data_type: uint16
        device_class: current
        state_class: measurement
        unit_of_measurement: A

      - name: Webasto_Unite_Cable_Max_Current
        unique_id: Webasto_Unite_Cable_Max_Current
        slave: 255
        input_type: input
        address: 1106
        data_type: uint16
        device_class: current
        state_class: measurement
        unit_of_measurement: A

      - name: Webasto_Unite_Charged_Energy
        unique_id: Webasto_Unite_Charged_Energy
        slave: 255
        input_type: input
        address: 1502
        data_type: uint32
        device_class: energy
        state_class: total
        offset: 0
        scale: 0.001
        precision: 3
        unit_of_measurement: kWh

      - name: Webasto_Unite_Session_Start_Time
        unique_id: Webasto_Unite_Session_Start_Time
        slave: 255
        input_type: input
        address: 1504
        data_type: uint32

      - name: Webasto_Unite_Session_Duration
        unique_id: Webasto_Unite_Session_Duration
        slave: 255
        input_type: input
        address: 1508
        data_type: uint32
        device_class: duration
        state_class: measurement
        unit_of_measurement: s

      - name: Webasto_Unite_Session_End_Time
        unique_id: Webasto_Unite_Session_End_Time
        slave: 255
        input_type: input
        address: 1512
        data_type: uint32
        
      - name: Webasto_Unite_Failsafe_Current
      # R/W: Can be set in the Unite WebUI (Standard:6A)
      # Charging power will fall back to 6A, if ALive Register 6000 not triggered with 1 within each 20 seconds 
        unique_id: Webasto_Unite_Failsafe_Current
        slave: 255
        input_type: holding
        address: 2000
        data_type: uint16
        device_class: current
        state_class: measurement
        unit_of_measurement: A
      # Failsafe charging current during communication failure

      - name: Webasto_Unite_Failsafe_Timeout
      # R/W: No need to change (Standard: 20 seconds)
        unique_id: Webasto_Unite_Failsafe_Timeout
        slave: 255
        input_type: holding
        address: 2002
        data_type: uint16
      # Communication timeout for switching to Failsafe charging current. If the timeout has occurred and the TCP socket is still active, TCP socket restarts. If set, Failsafe period is timeout/2, otherwise 20 sec.
        
      - name: Webasto_Unite_Charging_Current
      # R/W: 0-5A=Charging paused, 6-32A=Charging with set Amps
        unique_id: Webasto_Unite_Charging_Current
        slave: 255
        input_type: holding
        address: 5004
        data_type: uint16
        device_class: current
        state_class: measurement
        unit_of_measurement: A
      # Dynamic charging current

    switches:

      - name: Webasto_Unite_Alive_Register
      # R/W
        unique_id: Webasto_Unite_Alive_Register
        slave: 255
        write_type: holding
        address: 6000
        command_on: 1
        command_off: 0
        verify:
          delay: 5
      # EMS (Master) writes 1 EVSE (Slave) writes 0 (EVSE checks this register at a period of (Failsafe Timeout)/2 for a value of 1, and sets it to 0. Period cannot go less than 3 seconds)

I’ve included explanatory notes for the sensor statuses in the file. These explanations can prove beneficial if you plan to translate them into more user-friendly status messages using helper sensors, although I haven’t implemented this feature yet.

For instance, regarding the “charge point” state with register “1000,” a value of “2” signifies “charging.”

If you’re considering dynamically adjusting the charging power (the sole writable register “5004,” apart from the keep-alive register “6000”), you can incorporate a current value slider in your configuration.yaml:

webasto_unite_current_value_slider:
    name: webasto_unite_current_value_slider
    initial: 16
    min: 5
    max: 32
    step: 1

Moreover, alongside integrating the current slider, you’ll need to implement corresponding automation to ensure the seamless updating of register “5004”:

alias: Set Webasto Unite Current Limit
description: Set Webasto Unite Current Limit
trigger:
  - platform: state
    entity_id:
      - input_number.webasto_unite_current_value_slider
condition: []
action:
  - service: modbus.write_register
    data:
      hub: Webasto_Unite
      address: 5004
      slave: 255
      value:
        - "{{ (states.input_number.webasto_unite_current_value_slider.state) }}"
mode: single

Please Note: Every Amp value set below 6A (e.g. 5A) will not halt a charging session but rather pause it (this is wanted and normal!). This is indicated by the Webasto Unite LED indicator ring, which will shine purple.

To ensure this integration operates smoothly, you must activate Modbus in the Unite WebUI:

Additionally, for safety purposes, if Modbus register “6000” (Keep Alive Register) is not frequently triggered with a value of “1”, the wallbox will terminate the Modbus connection to Home Assistant.

Consequently, you need to implement an additional automation. The following setup has proven effective for me:

alias: Webasto Unite Keep Alive
description: Webasto Unite Keep Alive
trigger:
  - platform: time_pattern
    seconds: /5
condition: []
action:
  - service: switch.turn_on
    data: {}
    target:
      entity_id: switch.webasto_unite_alive_register
mode: single

Some general notes: This code may potentially be compatible with certain Vestel Charging Stations, although I haven’t personally tested it.

However, the primary advantage and unique selling point that led me to choose the Webasto Unite was its robust integration with a powerful OCPP backend—the Webasto Charge Connect Backend and accompanying app— which perfectly fulfills all my requirements. For instance, within the backend, I can effortlessly set up various automated charging reports, tailored to my specific needs. For instance, as a household with multiple EVs and a company car, it was crucial for me to have detailed charging reports segregated between private and company vehicle sessions. With the Webasto Charge Connect Backend, I can easily generate a report based on the RFID tag assigned to my company car.

As I’m planning to install the Webasto “Next” alongside the Unite in the near future, I’m also considering integrating it into Home Assistant.

I’m curious to know if there are others who own a Webasto Charging Station and have explored integrating it with Home Assistant. Any experiences or insights to share?

1 Like

Thank you very much for the great work you have done.

I have a Vestel evc04 without branding. Does OCPP have to be activated or deactivated on the WEB interface? I have inserted your code into my Home Assistant as you described, but the entities are not recognized and do not provide any data.

Which sensor is the charge control to activate the wallbox? Is there a way to switch between 1p and 3p in the Home Assistant?

No, OCPP must not been activated and does not influence our Modbus integration.

As discribed above, there is only one sensor controlling the Wallbox - see below.
To get this working, you also need to activated Modbus as shown above in your Carger Web-UI (but haven´t this tested this with a Vestel Box).

Sensor:

- name: Webasto_Unite_Charging_Current
      # R/W: 0-5A=Charging paused, 6-32A=Charging with set Amps
        unique_id: Webasto_Unite_Charging_Current
        slave: 255
        input_type: holding
        address: 5004
        data_type: uint16
        device_class: current
        state_class: measurement
        unit_of_measurement: A
      # Dynamic charging current

There is hardware wise no way for dynamic Phase Switching (1 Phase ↔ 3 Phase), as those chargers have only an internal 3-phase relay and not two separted 1-Phase/2-Phase relais.

1 Like

@lemuba Maybe you should also add the modbus specification file to this thread, so people can read the meaning of each register.
It is not officially published on the Ampure site. And I have seen a version from the Vestel EVC04 which is similar…

The official File does not provide any additional relevant info/descriptions as noted in my first post and code.

@lemuba I have found three (3) different modbus specifications: Vestel EVC04, Webasto Live & Webasto Next. All are generally the same, but have some differences. On my Webasto Unite I have tried to investigate which registers are supported.
But of course that’s only what I can determine in my setup.
So beware that is nu definite source of truth about this interface (available on the open internet).

Which leads to some specific questions about:

  • User priority (responds, but does not seems to contain information)
  • EV Battery state / SoC (responds, but does not seems to contain information)\
  • EV Battery capacity (responds, but does not seems to contain information)
  • EV required energy (responds, but does not seems to contain information)
  • Required battery state(responds, but does not seems to contain information)
  • Charged Energy (responds, but does not seems to contain information)
    Some of these can be explained, because the Unite does not know anything about de battery in de EV (the used protocols do not communicate this information). Others could have worked or may do in some setups.

So beware that these registers might not behave like expected.

Hello, please I have problem with webasto next chargeing and evcc, if I connect car, and dont have freeCharging enabled, it will not started charging, is there any way how to evcc or HA start charging with indetifier regarding vehicle?
Thank you in advance
Jozef

@joztoz I have no experience with EVCC. I think you can not use both EVCC and HA at the same time.
But it looks like your problem has to do with the wallbox itself.

You describe that freecharging works. In this mode you do not need to authorize the charging session. If freecharging is not enabled, you need to authorize the session.
You do this by holding the RFID card close to the wallbox. The RFID that is read by the wallbox needs to be recognized by the ‘backend’. Question is: which backend do you use?

EVCC is not a backend. It is a ‘local’ controller which uses the modbus TCP interface of the Webasto. Using this interface you can not do authorization. Also using HA using the modbus TCP interface will not do authorization. Neither is the ‘backend’.

By default the backend for the Websto Next is Webasto ChargeConnect App (or actually CPMS) which uses the OCPP interface. This is the interface that has the freecharging option. So assume this is the backend that you use right now.

This backend needs to do the authorization. So this backend must know the RFID card that you use. You can ‘add’ teh RFID card to the backend from the Webasto ChargeConnect app and/or in the CPMS website.

There is an alternative where you do not use a backend. That is called ‘Standalone mode’. If you use this mode, you can ‘store’ the allowed RFID cards in the wallbox itself.

There is much more you need to know to fully understand all (im)possibilities of RFID authorization. They have nothing to do with HA. The main thing to learn from this,is: your problem is not with HA but with configuring authorization in the Websasto Next.

Hey @lemuba, wanted to thank you for your work here so far. I’m very new to HA and have just gotten the register data from my inverter into HA (not easy… Don’t buy Sungrow if you’re wanting to use HA!)

As it happens, I have a Webasto Next Wallbox, and as the energy manager my PV system came with is so unreliable, I want to replace it with HA to regulate current based on how much energy is being generated by the system / battery state. Have you got your Next Wallbox yet? Any updates to share if so?

Thanks again so much for your work, it’s a fantastic starting point for me :+1: