Victron integrated with HA and EMHASS - My Single Guide

I wanted to consolidate my experience of connection my Victron Grid Connected MultiPlus II (or any Victron inverter) into HA. I then extended that into EMHASS to allow manage of import/export.

My Hardware:

  • Victron MulitPlus II 5.0 (x3)
  • Victron SmartShunt (500A)
  • Victron CerboGX (but you can use a GX MP, or Raspberri Pi)
  • Victron Smart Meter to monitor AC loads. (not needed if your solar is Victron, or AC coupled on ACout, and your entire house load is also on ACout. If you have Solar or loads on ACin, you need the smart meter).
  • 80kw of 3v LifePO4 Chinese Cells
  • 5x Chinese BMSā€™s
  • HA (mine runs as HAos on a Virtual Machine on my NAS, but any HA install will do).
  • Mosquitto Broker is installed on HA and operating.(add ons). (auto start, watchdog turned ON)

Assumptions:

  • Your Victron setup is working, connected on on the same ethernet as the HA

  • Your Victron Inverter/Shunt/etc are all connected to your GX Device (Victron setup outside scope of this guide)

  • Youā€™ve assigned static IPā€™s to your Victron GX device and HA

  • Constant internet connection is NOT required

  • You have installed the ESS Grid Assistant on your Victron Inverters, and ESS is available in your GX Device. This menu will show in your GX device.

  • If you have solar, your Victron GX device is aware of the Solar, and it shows on the GX device. (I have Fronius AC Coupled solar, the the GX device found it with no setup)

  • I am single phase. if your 3 phase, you will need to copy quite a few parameters or modify.

How this works:
The Victron gear is fully responsible for managing the load, solar, batteries and monitoring of AC state. The HA is simply a co-pilot of the Victron, leveraging the ESS Assistant on the Victron device, and just feeding instructions to it. We also capture the monitoring details for HA to record and render.

The communication layer between HA and Victron GX (which in turn talks to all the Victron gear, on the Victron Network) is via a method called MQTT, which is a very basic instructional set that HA does quite well. (additional ModBus reading: https://www.victronenergy.com/live/ccgx:modbustcp_faq)

There are 2 main parameters when using MQTT and Victron. The Device ID, which is literally the physical Victron Device, and the Address ID, which is a parameter that is read only or writeable, which is set by Victron.

Device IDā€™s are assigned by the Victron GX device, and Address IDā€™s are set by Victron. Full list of Victron Addresses available here by requesting the ModBus TCP List (delivered by email instantly).

In HA, the only variable we can play with and write back to Victron is the ESS Set Point. this is a number in watts. ie/ +5000 is pull 5000W from Grid. -5000 is Export 5000W from the Grid (solar first and then batteries).
That updates this value in Victron:

If ESS is enabled, you will have this menu in your GX Device.

Step 1: Enable MQTT on your Victron GX device.


Step 2: Indentify the Device IDā€™s on your Victron Network

Step 3: Enable HomeAssistant to communicate with your Victron GX Device.

Add the following code to your Configuration.yaml on HA, update your Device IDā€™s and IP, and reboot the entire HA device.

modbus:
  - name: victron
    type: tcp
    host: 192.168.10.137  # use the IP address of your CCGX
    port: 502
    sensors:
    - name: 'ESS Grid Target' #This is the value your Inverter will attempt to import/export to and from the grid AFTER it takes into account your load and solar.  This is the only writeable value.
      unit_of_measurement: "W"
      slave: 100 #HUB - Slave is your device ID you found when looking in the Device List on the Victron GX.
      address: 2700 #ESS Control Loop Set Point
      data_type: uint16
      scan_interval: 5
      device_class: power
    
    - name: 'Victron AC L1' #I am single phase, if your 3 phase, you will need to add this 3 times and update the addresses using the link above for the full address list
      unit_of_measurement: "W"
      slave: 100 #HUB
      address: 817 #AC Consumption L1
      data_type: uint16
      scan_interval: 5
      device_class: power
      
    - name: 'Victron Grid Load'
      unit_of_measurement: "W"
      slave: 100 #HUB
      address: 820 #GridL1 Net
      data_type: int16
      scan_interval: 5
      device_class: power
      
    - name: 'Victron Energy from Grid'
      unit_of_measurement: "kWh"
      slave: 30 #GRID METER NOTE THE DIFFERENT SLAVE ID
      address: 2603 #Energy From Netowrk L1
      data_type: uint16
      scale: 0.01
      precision: 1
      scan_interval: 5
      device_class: energy
      state_class: total_increasing
      
    - name: 'Victron Energy to Grid'
      unit_of_measurement: "kWh"
      slave: 30 #GRID METER
      address: 2606 #L1 Energy to Network
      data_type: uint16
      scale: 0.01
      precision: 1
      scan_interval: 5
      device_class: energy
      state_class: total_increasing
      
    - name: 'Victron Energy Meter Voltage'
      unit_of_measurement: "V"
      slave: 30 #GRID METER
      address: 2616 #Grid Meter Voltage
      data_type: uint16
      scale: 0.1
      precision: 1
      scan_interval: 5
      device_class: voltage
      state_class: total_increasing
      
    - name: 'Victron Energy Meter Amperage'
      unit_of_measurement: "A"
      slave: 30 #GRID METER
      address: 2617 #Grid Meter Amps
      data_type: int16
      scale: 0.1
      precision: 1
      scan_interval: 5
      device_class: current
      state_class: total_increasing
      
    - name: 'Victron Solar power'
      unit_of_measurement: "W"
      slave: 100 #HUB
      address: 850
      data_type: uint16
      device_class: power
      
    - name: 'Victron ESS Minimum SoC setpoint'
      unit_of_measurement: "%"
      data_type: uint16
      slave: 100 #HUB
      address: 2901
      scan_interval: 5
      scale: 0.1
      
    - name: 'Victron Maximum System Grid Feed In'
      unit_of_measurement: "W"
      data_type: uint16
      slave: 100 #HUB
      address: 2706
      scale: 0.01
      device_class: power
      # command_on: 4000
      # command_off: 40
      # verify_state: false
#Battery 
    - name: 'Victron Battery current'
      unit_of_measurement: "A"
      slave: 100 #HUB
      address: 841
      data_type: int16
      scale: 0.1
      precision: 0
      device_class: current
      
    - name: 'Victron Battery Power System'
      unit_of_measurement: "W"
      slave: 100  #HUB
      address: 842
      data_type: int16
      scale: 1.0
      precision: 0
      device_class: power
 
    - name: 'Victron Charge Power System'
      unit_of_measurement: "W"
      slave: 100 #HUB
      address: 860
      data_type: int16
      scale: 10.0
      precision: 0
      device_class: power
      
    - name: 'Victron Battery State of Charge System'
      unit_of_measurement: "%"
      slave: 100 #HUB
      address: 843
      data_type: uint16
      scale: 1
      precision: 0
      
    - name: 'Victron Inverter AC IN L1 V'
      unit_of_measurement: "V"
      slave: 227
      address: 3
      data_type: uint16
      scale: 0.1
      precision: 1
      device_class: voltage

    - name: 'Victron Inverter AC IN L1 A'
      unit_of_measurement: "A"
      slave: 227
      address: 6
      data_type: uint16
      scale: 0.1
      precision: 1
      device_class: current

    - name: 'Victron Inverter Max Over V Feed In L1'
      unit_of_measurement: "V"
      slave: 227
      address: 66
      data_type: uint16
      scale: 0.1
      precision: 1
      device_class: voltage

    - name: 'Victron Battery Voltage'
      unit_of_measurement: "V"
      slave: 226
      address: 259
      data_type: uint16
      scale: 0.01
      precision: 1
      device_class: voltage

    - name: 'Victron Battery Amperage'
      unit_of_measurement: "A"
      slave: 226
      address: 261
      data_type: uint16
      scale: 0.1
      precision: 1
      device_class: current

    - name: 'Victron Battery Consumed Amphours'
      unit_of_measurement: "A"
      slave: 226
      address: 265
      data_type: uint16
      scale: 0.1
      precision: 1
      device_class: current

    - name: 'Victron Battery State Of Charge'
      unit_of_measurement: "%"
      slave: 226
      address: 266
      data_type: uint16
      scale: 0.1
      precision: 1
      device_class: power

    - name: 'Victron Battery Capacity'
      unit_of_measurement: "A"
      slave: 226
      address: 309
      data_type: uint16
      scale: 0.1
      precision: 1
      device_class: current

Step 4: Check its connected.
At this point, you should be able to search under entities in HA for Victron, and a good old list of values and data should be coming in. Congrats. Youā€™ve connected Victron and HA together. Now, lets get that Grid Set point sorted.

If at this point you dont have data coming in, STOP. You need to troubleshoot why.

Step 5: Lets setup a slider

The slider is my way of easily in the UI being able to update the ESS Grid Set Point. You can choose your own destiny, but this is how I did it.

In Configuration.Yaml, add the following and reboot the entire HA device.

input_number:
  input_current_slider:
    name: ESS Grid Target Value
    min: -15000 #update this to your maximum inverter capacity
    max: 15000 #update this to your maximum inverter capacity
    step: 100 #this is the increment of the slider in watts.  It can be as low as increments of 10.

We now have a slider, but we need to connect it to Victron.

Step 6: Automations to bring it together
We need to setup 3 automations to connect the Slider to Victron, and do some maths.

Automation 1: This automations sets your Input Slider in HA to the value in Victron. (in case you update it in the Victron UI)

alias: 990.3 Input Current Limiter - Updater
trigger:
  - platform: state
    entity_id: sensor.input_current_limit
action:
  - service: input_number.set_value
    target:
      entity_id: input_number.input_current_slider
    data:
      value: "{{ states('sensor.input_current_limit') | int }}"

Automation 2: Send the Input Slider value to Victron if its below 0
We do some maths on this one, as Victron doesnā€™t expect negatives, its just reverse from 65536 and the victron works it out on the fly. 65536 = 0W, 65535 = -1W, 64536 = -1000W etc. (Dont even ask me how bloody long this took to work out)

alias: 990.1 ESS Grid Set Point - SEND NEGATIVE
description: ""
trigger:
  - platform: state
    entity_id: input_number.input_current_slider
condition:
  - condition: numeric_state
    entity_id: input_number.input_current_slider
    below: "0"
action:
  - service: modbus.write_register
    data:
      address: 2700
      unit: 100
      value: "{{ states('input_number.input_current_slider') |  float + 65536 }}"
      hub: victron
mode: single

Automation 3: Send the Input Slider value to Victron if its 0 or above

alias: 990.2 ESS Grid Set Point - SEND POSITIVE
description: ""
trigger:
  - platform: state
    entity_id: input_number.input_current_slider
condition:
  - condition: numeric_state
    entity_id: input_number.input_current_slider
    above: "-0.01"
action:
  - service: modbus.write_register
    data:
      address: 2700
      unit: 100
      value: "{{ states('input_number.input_current_slider') |  float }}"
      hub: victron
mode: single

OK, So at this point you have:

  1. Connected Victron to HA
  2. Enabled a UI Slider to manage and view the ESS Setting
  3. Setup automations to apply data changes in either device to and from each other

At this point you can start the fun of building dashboards and automations on the new data set your receiving.

For those playing in the EMHASS space. I dont want to get into setting up EMHASS, but my script for those playing at home is below. I call post_amber_forecast daily at 5.30am, and I can MPC every 5 mins. This works, but I`m still working on some of the parameters.

### EMHASS ADD ON SCRIPT in Configuration.yaml
shell_command:
  dayahead_optim: "curl -i -H \"Content-Type: application/json\" -X POST -d '{}' http://localhost:5000/action/dayahead-optim"
  publish_data: "curl -i -H \"Content-Type: application/json\" -X POST -d '{}' http://localhost:5000/action/publish-data "
  post_amber_forecast: "curl -i -H 'Content-Type: application/json' -X POST -d '{\"prod_price_forecast\":{{(
          state_attr('sensor.amber_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list)
          }},\"load_cost_forecast\":{{(
          state_attr('sensor.amber_general_forecast', 'forecasts') |map(attribute='per_kwh')|list)
          }}}' http://localhost:5000/action/dayahead-optim"
 
  post_mpc_optim: "curl -i -H \"Content-Type: application/json\" -X POST -d '{\"load_cost_forecast\":{{(
          ([states('sensor.amber_general_price')|float(0)] +
          state_attr('sensor.amber_general_forecast', 'forecasts') |map(attribute='per_kwh')|list)[:48])
          }}, \"prod_price_forecast\":{{(
          ([states('sensor.amber_feed_in_price')|float(0)] +
          state_attr('sensor.amber_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list)[:48]) 
          }}, \"prediction_horizon\":{{min(48,
          (state_attr('sensor.amber_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list|length)+1)
          }},\"soc_init\":{{states('sensor.victron_battery_state_of_charge')|float(0)/100}},\"soc_final\":0.05,\"def_total_hours\":[8,3,2,2]}' http://localhost:5000/action/naive-mpc-optim"
  

If you get stuck, comment below. I set this up over a long period of time, so I may have forgot/missed something along the way.

So, a massive thank you to @markpurcell as well for his help with EMHASS.

18 Likes

Hi there, thanks for your tutorial. Iā€™m setting up my Multiplus II GX and Iā€™ve followed the instructions and set up the configuration.YAML, but Iā€™m seeing this on all the Victron Entities in HA, and I canā€™t understand how to update the IDā€™s image

Iā€™ve cut down the number of entitites to make sure it works firstā€¦

How to make the slider bigger?

Or how to make buttons for set values? Like Grid target -10000w or +3000w

Hallo, Dit is exact wat ik zoek. Zelf heb ik 86 kWh Pylontech batterijen, en het Victron systeem is 3 fasen. Ik ben nog maar net 2 dagen bezig met HA en is voor mij volledig nieuw, moet alles nog ontdekken.
Mijn vraag hoe stel ik bovenstaande code in als 3 fase systeem in ? Kun je ondersteuning bieden?

Thamks! This really helped me.

Only thing I would like to add is to tell how to tie the Slave # & address.

When you look on the Venus Modbus page that has the Slave addresses for your devices,
before the Slave address is a web address (such as com.victronenergy.vebus). When you
look at the Spreadsheet with the addresses (CCGX-Modbus-TCP-register-list-2.90.xlsx)
you will see the web address in the first column. The addresses to the right are the only
ones that pertain to that web address.(eg vebus only between 3 & 92)
If you copy then edit another setup, this may not be obvious! (Doh!)

Hello,

Iā€™ve successfully setup the integration for my Victron system and itā€™s working nicely. Except for 3 values, those three are not being fetched periodically. I only get a measurement for those when HA is restarted.
The ones Iā€™m struggling with are all related to ESS:
ESS BatteryLife state - slave:100 address 2900
ESS Minimum SoC (unless grid fails) - slave:100 address 2901
ESS BatteryLife SoC limit (read only) - slave:100 address 2903

Iā€™ve tried different scan_intervalsā€¦ but nothing works.
Iā€™m running the latest version core_2022.11.4 which includes the modbux reload fix.

Any ideas?

I just figured out what seems to happen. I update the Minimum SOC value in the victron console and HA picked up the new value without a problem. Seems that the values are only getting update in case there is a change.

1 Like

Hi @gchramm Yeah, it seems to go loopy updating unless a change is made in the HA value for ESS via a write, or the value changes in ESS.

Using EMHASS the value changes every 5 mins anyway, so it clears itself.

@dsb82 I have buttons to set values. I created a button in Helper and then setup this automation to export at 15kw when clicked. Setup another one for import and self-serve

alias: 990.3 Input Current Limiter - link to Button EXPORT
description: ""
trigger:
  - platform: state
    entity_id:
      - input_button.export
condition: []
action:
  - service: input_number.set_value
    target:
      entity_id: input_number.input_current_slider
    data:
      value: "-15000"
mode: single

@Derek_Foley - yeah there has been a change to the way HA treats this, I havenā€™t fixed the code since the HA change, as it still works, but you just need to set an ID value thatā€™s unique in the YAML

HACS has an add-on in the last few weeks which support GX devices: https://github.com/sfstar/hass-victron.

1 Like

Hi! Thanks for these tips. I wonder why do you need to enable MQTT on the GX device if you are using modbus protocol.

Hi ā€“ thanks for sharing all this info.

Do you know of any way to schedule or automate the ā€˜Minimum SOC (unless Grid Fails)ā€™ value? Using HA or internally within the Victron unit itself? What I need is the following:

07:00-11:00 && drawing load > 8kW = Minimum SOC 40%
11:00-07:00 = Minimum SOC 80%

And Iā€™ve not been able to determine how. Thanks again, Dan

Hi everybody,

i have a general question about this. Is it possible to control the DC charger output current (controllable via VictronConnect Windows Software) of a MultiPlus 12/500 system via HA with the following Hardware:

  • Victron MultiPlus 12/500 (attached 12,8v/100ah LifePo4 Cell)
  • Victron Venus OS * i would use the Raspberri Pi to save money - as far as i understood is that functionally (speaking of accessability to the MultiPlus) equal to the victron solution CerboGX ?
  • Interface MK3-USB
  • Running HA instance for sure with Mosquitto Broker.

Is that in fact possible or do i need some of the other Hardware you mentioned above?

I need to controll the charge current in relation to my current pv energy production - my current load. Thats why i need to change the DC charger output current on the fly controlled by my HA.

Beste, heb je dit in orde gekregen?

you can control the DC charge current using Venus OSā€™ MQTT server. If you want to create simple schedules of when to charge you can install the VenusOS large image that comes with node red and use inject nodes to set charge current to 0 value to stop charging and to > 0 value to allow charging. I can confirm this works with CAN-Bus batteries. With other batteries your mileage may vary. Keep in mind that some of the Interfaces you need for the raspberry to communicate the price might be en par as Cerbo. This was my case so I got a cerbo, which gives me a lot more connectivity options.

I donā€™t use any any windows software to achieve this - just VenusOSā€™ node red and via MQTT connected it to my HASS

I think you can achieve this via NodeRed which is available on the VenusOS large image.

1 Like

Iā€™ve hit another issue Iā€™m not getting over at the moment:

my goal:
The local powergrid is saturated, so we have a limitation for feeding power to the grid.
Whenever the inverters switch to absorption (= too much energy being produced) Iā€™d like to switch on a heater in our hot water tank.

The problem:
I canā€™t get the inverter state, itā€™s always returning 252.

Iā€™ve tried different objects:
com.victronenergy.vebus - VE.Bus state - address: 31
com.victronenergy.solarcharger - Charge state - address: 775

If Iā€™m checking the installation I can see that itā€™s in the ā€œ4=absorptionā€ state, however the modbus values are still ā€œ252 = external controlā€.

Possible values:
0=Off;1=Low, Power;2=Fault;3=Bulk;4=Absorption;5=Float;6=Storage;7=Equalize;8=Passthru;9=Inverting;10=Power assist;11=Power supply;252=External control

Any ideas?

2 Likes

Do you have access to the Victron VRM online dashboard?

On the ā€˜Advancedā€™ page ā€“ at least for my installation ā€“ the inverter state is shown as being provided from ā€˜VE.Bus State [ID 276]ā€™ ā€¦ which corresponds to modbus slave ID 227 and also therefore address 31. Perhaps yours specific source is also listed.

https://vrm.victronenergy.com/installation/YOUR-INSTALL-ID/advanced

I think there are four possible candidates depending on your install ā€¦
com.victronenergy.vebus
com.victronenergy.solarcharger
com.victronenergy.charger
com.victronenergy.multi

Thanks for the hint with the dashboard, didnā€™t think about that.

Unfortunately I only got the VE.Bus State in there it shows 252 as well.

All other options from the list are not available.