I love HomeAssistant and I also love my Victron Equipment. I knew they provided data over ModBus and MQTT and a while back I was determined to pull the data into HomeAssistant. I live fully off-grid and it's extremely helpful to know what the state of my system is whereever I am. I also built many automations that help me optimize my available power. Below is a walk through on pulling in Victron data to HomeAssistant over MQTT.
These are needed before proceeding:
- HomeAssistant (Duh!)
- Some type of VenusOS Device, you'll need the IP and it should be set to a static IP
- SSH & Web Terminal HomeAssistant Add-On (Used for editing a mosquitto conf file)
- FileEditor Add-On (Used to edit HomeAssistant config files and sensors)
- A MQTT GUI, I use MQTT Explorer (Not needed, but helpful to ensure things are working)
Note: I use HomeAssistant & HA interchangibly.
Go to the IP address of your Venus device in your web browser. From there go to Settings > Services and enable Modbus, MQTT (SSL) and MQTT (Plaintext)
From your HomeAssistant instance go to Settings > Add-Ons and click the AddOn Store button and search for Mosquitto broker. Select it and install.
In the Configuration tab of Mosquitto go to the Customize section and ensure active: true
and folder: mosquitto
are set:
This allows all data from Victron to be mirrored on your HomeAssistant's Mosquitto Broker. This is the corret way to setup MQTT from Venus on HA instead of using the VenusOS device as a MQTT server.
Open the Teriminal Web View in HomeAssistant, there should be a button in your Nav menu on the left if you already installed it into HomeAssitant. It should bring you to a HomeAssistant console like below:
From there lets go into the mosquitto directory with:
cd /share/mosquitto
Then lets create the file we'll use for victron config with:
touch victron.conf
Now lets edit that file and add some config. Open in nano editor with
nano victron.conf
Add the following config and replace your.venus.ip.address
with your VenusOS IP Address:
connection victron
address your.venus.ip.address:1883
topic N/# in 0 victron/
topic R/# out 0 victron/
topic W/# out 0 victron/
Hit cntrl + x
and then y
and enter
at the prompt to save. Go back to the Mosquitto Broker AddOn and restart the service.
In HA you need to create a User account that will be used to login to the MQTT Server you just setup. In HA go to Settings > People and select the Users tab at the top. Create a user with a username & password, note this for the next couple steps:
If you have issues on your network logging into your MQTT service try disabling Can only log in from the local network
.
The MQTT service on Victron needs to be kept alive. We do this by sending a keep-alive message every 30-seconds.
In HomeAssistant go to Settings > Automations & Scenes, create a new Automation called Victron MQTT KeepAlive
. The trigger
should be Time Pattern
and set to every 30 seconds which is expressed as /30
Then the action should be Call Service
and select MQTT: Publish
. The topic is victron/R/your-venus-id/system/0/Serial
, payload: {}
. Hit save and you're done.
Open the MQTT GUI/Application (I use MQTT Explorer). For the Host provide the IP Address of your HomeAssistant. For User/Pass use the one you just created:
If everything is setup properly, you should start to see data from your Victron Equipment show up. It will be under the victron/N
key. Make note of the ID beneath that, mine below is b827eb5c4de
. This is the unique ID for your Victron System and you'll need to reference in your sensors later.
If this is working, you've done all the hard stuff!
This integration allows HA to use data from MQTT as sensors..etc. Go to Settings > Devices & Services and click Add Integration at the bottom. When prompted add the IP of your HomeAssistant instance, and the username/password of the mqtt user you created.
You should now be able to start adding sensors in HomeAssistant that pull data from your VenusOS Device. Use the FileEditor in HomeAssistant, there should be a button in the left Navigation Pane if you've installed the AddOn. From there open the configuration.yaml
file and add this line:
mqtt: !include mqtt.yaml
Please note the organization of my config, I breakout sensor
, template
, mqtt
...etc, into their own files. This makes organization and editing way easier then stuffing everying in one file. Mine looks like this:
Now create a new file in the config
dir called mqtt.yaml
to match. Do this by clicking the folder icon in the top left and then clicking the New File
icon.
Once you're in that new file you can start adding sensors. Below are some sensors to get you started. Replace your-venus-id
with the unique ID we noted above. Note that the exact paths for your system may be different than mine. Use the MQTT Explorer to find the data you might want
sensor:
# Battery percentage
- state_topic: "victron/N/your-venus-id/system/0/Batteries"
name: "Battery Percent"
unique_id: "battery_percent"
device_class: battery
value_template: '{{ value_json.value[0].soc | round(0) }}'
unit_of_measurement: "%"
# AC Loads
- state_topic: "victron/N/your-venus-id/system/0/Ac/Consumption/L1/Power"
name: "AC Loads"
unique_id: "ac_loads"
device_class: power
value_template: '{{ value_json.value }}'
unit_of_measurement: "W"
icon: mdi:power-socket-uk
# DC Loads
- name: "DC Loads"
device_class: power
unique_id: "dc_loads"
state_topic: "victron/N/your-venus-id/system/0/Dc/System/Power"
value_template: '{{ value_json.value|float(0)|round(0) }}'
unit_of_measurement: "W"
icon: mdi:power
# Net Solar Production
- name: "Current Solar Production"
unique_id: "net_solar_production"
device_class: power
state_topic: "victron/N/your-venus-id/system/0/Dc/Pv/Power"
value_template: '{{ value_json.value|float(0)|round(0) }}'
unit_of_measurement: "W"
icon: mdi:solar-power
# Battery Voltage
- name: "Battery Voltage"
unique_id: "battery_voltage"
device_class: voltage
state_topic: "victron/N/your-venus-id/system/0/Dc/Battery/Voltage"
value_template: '{{ value_json.value|float(0)|round(1) }}'
unit_of_measurement: "V"
# Battery Temp (If you have a temp sensor)
- name: "Battery Temp"
device_class: temperature
unique_id: "battery_temperature"
state_topic: "victron/N/your-venus-id/system/0/Dc/Battery/Temperature"
value_template: '{{ ((value_json.value * 9/5) + 32) | round(0) }}'
unit_of_measurement: "°F"
# Net load going in/out of your battery
- name: "Battery Load"
unique_id: "battery_load"
device_class: power
state_topic: "victron/N/your-venus-id/system/0/Batteries"
value_template: '{{ value_json.value[0].power|float(0)|round(0) }}'
unit_of_measurement: "W"
# Current State of your Inverter
- name: "Inverter State"
unique_id: "inverter_state"
state_topic: "victron/N/your-venus-id/system/0/SystemState/State"
value_template: >
{% if value_json.value == 0 %}
Off
{% elif value_json.value == 2 %}
VE.Bus Fault condition
{% elif value_json.value == 3 %}
Bulk
{% elif value_json.value == 4 %}
Absorption
{% elif value_json.value == 5 %}
Float
{% elif value_json.value == 6 %}
Storage
{% elif value_json.value == 7 %}
Equalize
{% elif value_json.value == 9 %}
Inverting
{% elif value_json.value == 10 %}
Assisting
{% elif value_json.value == 256 %}
Discharging
{% elif value_json.value == 257 %}
Sustain
{% else %}
Error - No Data
{% endif %}
# Current state of your charge controller
- name: "Solar Charger State"
unique_id: "solar_charger_state"
state_topic: "victron/N/your-venus-id/solarcharger/289/State"
value_template: >
{% if value_json.value == 0 %}
Off
{% elif value_json.value == 2 %}
Fault
{% elif value_json.value == 3 %}
Bulk
{% elif value_json.value == 4 %}
Absorption
{% elif value_json.value == 5 %}
Float
{% elif value_json.value == 6 %}
Storage
{% elif value_json.value == 7 %}
Equalize
{% else %}
Error - No Data
{% endif %}
# Estimated Time until battery is empty based on current load.
# These calculations were copied from victrons code to mimic how they display it
- name: "Battery Remaining"
unique_id: "battery_remaining"
icon: mdi:timer-sand
state_topic: "victron/N/your-venus-id/system/0/Dc/Battery/TimeToGo"
value_template: >
{% set battery_load = states('sensor.battery_load') | int(0) %}
{% if value is not defined %}
Error
{% elif value == '{"value": null}' or battery_load > 0 %}
∞
{% else %}
{% set seconds = value_json.value | round(0) | int %}
{% set days = (seconds / 86400) | round(0, 'floor') | int %}
{% set hours = ((seconds - days * 86400) / 3600) | round(0, 'floor') | int %}
{% set minutes = ((seconds - hours * 3600) / 60) | round(0, 'floor') | int %}
{% if 2 > days >= 1 %}
{{days}} Day
{% elif days >= 2 %}
{{days}} Days
{% elif hours > 0 %}
{{hours}} Hours
{% elif minutes > 0 %}
{{minutes}} Minutes
{% endif %}
{% endif %}
Restart your HA for the sensors to be loaded.
You can now add sensors to your Dashboards! Even better are to start writing automations based on your power. How you organize them is up to you, if you're intersted in my exact layout let me know and I can share more
I hope this tutorial was helpful, and enjoy!
HomeAssistant requires Integral sensors in order to properly track power usage. In my setup I have AC + DC Loads (consuming), Solar Loads (producing), and a Generator. I also have a battery system which requires Battery In + Battery out. I'll go over creating all of those now.
Please see my note higher up in this doc about how I organize my configuration.yaml
file. You will need to create sensor.yaml
and template.yaml
files if you want to use the organization I have.
This one is easy, just use sensor.net_solar_production
. This is the value of ALL your production, even if you have multiple charge controllers. In your sensors.yaml
add the follow integral sensor:
- platform: integration
unique_id: "total_solar_kwh"
source: sensor.net_solar_production
unit_prefix: k
round: 3
If you only have AC loads, just add the following in your sensors.yaml
:
- platform: integration
unique_id: "total_power_consumed"
source: sensor.ac_loads
unit_prefix: k
round: 3
If you have both AC & DC loads, you'll need to first create a Template sensor that combines them both. In template.yaml
add:
- name: total_power_consuming
unique_id: "total_power_consuming"
unit_of_measurement: "W"
state_class: measurement
device_class: power
state: >
{% set dc_loads = states('sensor.dc_loads') | int(0) %}
{% set ac_loads = states('sensor.ac_loads') | int(0) %}
{{ dc_loads + ac_loads }}
Then add the following in your sensors.yaml
:
- platform: integration
unique_id: "total_power_consumed"
source: sensor.total_power_consuming
unit_prefix: k
round: 3
You'll first need to create two template sensors that differentiate between power going to the battery and power coming from the battery. Add these to your template.yaml
:
- name: total_battery_out
unique_id: "total_battery_out"
unit_of_measurement: "W"
state_class: measurement
device_class: power
state: > # Only returns a value when load on battery is negative (consuming)
{% set battery_load = states('sensor.battery_load') | int(0) %}
{% if battery_load < 0 %}
{{ battery_load | abs }}
{% else %}
0
{% endif %}
- name: total_battery_in
unique_id: "total_battery_in"
unit_of_measurement: "W"
state_class: measurement
device_class: power
state: > # Only returns a value when load on battery is positive (charging)
{% set battery_load = states('sensor.battery_load') | int(0) %}
{% if battery_load >= 0 %}
{{ battery_load }}
{% else %}
0
{% endif %}
Now you can add the following to sensors.yaml
:
- platform: integration
unique_id: "total_battery_in_kwh"
source: sensor.total_battery_in
unit_prefix: k
round: 3
- platform: integration
unique_id: "total_battery_out_kwh"
source: sensor.total_battery_out
unit_prefix: k
round: 3
Skip this unless you have some sort of external AC Input you want to capture. I have a generator that I mark as "grid power". This comes from the AC Input of my multiplus. Depending on your AC Input you can name it whatever you want. In my MQTT.yaml
I have this sensor which pulls the numbers from the AC Input of the multiplus:
- name: "Generator"
unique_id: "Generator Load"
device_class: power
state_topic: "victron/N/your-venus-id/system/0/Ac/Genset/L1/Power"
value_template: '{{ value_json.value|float(0)|round(0) }}'
unit_of_measurement: "W"
icon: mdi:engine
Then in sensors.yaml
I add the following:
- platform: integration
unique_id: "total_generator_kwh"
source: sensor.generator
unit_prefix: k
round: 3
In HomeAssistant go to Settings>Dashboards>Energy or click here.
Add the integral sensors we just created:
This dashboard will take at least two-hours to start collecting and showing data, so be patient. Enjoy!