Does anyone know whether it is possible to change the ESS state from, for example, “Optimised (with BatteryLife)” to “Keep Batteries Charged” using ModBus? Thanks for @ebendl HA code, I was able to implement a few things I needed, so I would like to continue using the ModBus service as far as possible…
Yes. Change whatever register corresponds with /Settings/CGwacs/BatteryLife/State
, to:
1 = Optimised with battery life
9 = Keep Batteries Charged
10 = Optimised without battery life.
Amazing! I saw that, but I wasn’t sure (because there were many other states in the description as well).
It’s three state machines cobbled together. States 1-8 are used by batterylife, state 9 is to keep charged, and state 10 and up is used by no-batterylife. If you set it to any number inside the range, the state machine will react within the next second and change it to what it should be.
Hey, thanks for the example. Under which node would I place this snippet? Or do you have a link to a complete snippet? Thanks.
Hi Jarettj,
I should really put it up somewhere! Here’s the previous snippets again, with the “main” node for each:
#Modbus sensors for Victron sensors
sensor:
- platform: modbus
registers:
- name: "Victron Battery" #Battery SOC
hub: victron
data_type: uint
unit_of_measurement: "%"
slave: 100
register: 843
scale: 1
- name: "Victron Current Power Usage"
hub: victron
data_type: uint
unit_of_measurement: "W"
slave: 100
register: 817
scale: 1
- name: "Victron Grid Power"
hub: victron
data_type: int
unit_of_measurement: "W"
slave: 100
register: 820
scale: 1
- name: "Victron Battery Power"
hub: victron
data_type: int
unit_of_measurement: "W"
slave: 100
register: 842
scale: 1
- name: "Victron Battery State"
hub: victron
data_type: uint
slave: 100
register: 844
scale: 1
- name: "Victron PV power"
hub: victron
data_type: uint
unit_of_measurement: "W"
slave: 100
register: 850
scale: 1
- name: "Victron ESS BatteryLife state"
hub: victron
data_type: uint
slave: 100
register: 2900
scale: 1
- name: "Victron ESS Minimum SOC"
hub: victron
data_type: uint
slave: 100
register: 2901
scale: 0.1
#VEBus devices = Multiplus = UnitID 242 = Device Instance 261
- name: "Victron Grid voltage"
hub: victron
data_type: uint
slave: 242
register: 3
scale: 0.1
unit_of_measurement: "V"
- name: "Victron Essential usage"
hub: victron
data_type: int
slave: 242
register: 23
scale: 10
unit_of_measurement: "W"
- name: "Victron VEBus Input Power 1"
hub: victron
data_type: int
slave: 242
register: 12
scale: 10
unit_of_measurement: "W"
- name: "Victron VEBus State"
hub: victron
data_type: uint
slave: 242
register: 31
scale: 1
- name: "Victron VEBus Error"
hub: victron
data_type: uint
slave: 242
register: 32
scale: 1
- name: "Victron energy meter"
hub: victron
data_type: int
slave: 30
register: 2600
unit_of_measurement: "W"
- name: "Victron Grid Setpoint"
hub: victron
data_type: int
slave: 100
register: 2700
unit_of_measurement: "W"
- platform: template
sensors:
#Victron template sensors
victron_non_essential_usage:
friendly_name: 'None essential usage'
value_template: >
{{ (states("sensor.victron_energy_meter") | float - states("sensor.victron_vebus_input_power_1") | float ) | abs }}
unit_of_measurement: 'W'
victron_grid_usage:
friendly_name: 'Grid usage'
value_template: >
{% if float(states("sensor.victron_grid_power")) > 0 %}
{{ (states("sensor.victron_grid_power") | float | round (0) ) }}
{% else %}
0
{% endif %}
unit_of_measurement: 'W'
victron_batterylife_status:
friendly_name: "BatteryLife Status"
value_template: >-
{% if is_state('sensor.victron_ess_batterylife_state', '0') %}
Unused, BL disabled
{% elif is_state('sensor.victron_ess_batterylife_state', '1') %}
Restarting
{% elif is_state('sensor.victron_ess_batterylife_state', '2') %}
Self-consumption
{% elif is_state('sensor.victron_ess_batterylife_state', '3') %}
Self-consumption
{% elif is_state('sensor.victron_ess_batterylife_state', '4') %}
Self-consumption
{% elif is_state('sensor.victron_ess_batterylife_state', '5') %}
Discharge disabled
{% elif is_state('sensor.victron_ess_batterylife_state', '6') %}
Force charge
{% elif is_state('sensor.victron_ess_batterylife_state', '7') %}
Sustain
{% elif is_state('sensor.victron_ess_batterylife_state', '9') %}
Keep batteries charged
{% elif is_state('sensor.victron_ess_batterylife_state', '10') %}
BL Disabled
{% elif is_state('sensor.victron_ess_batterylife_state', '11') %}
BL Disabled (Low SoC)
{% else %}
Unknown - {{ states("sensor.victron_ess_batterylife_state") }}
{% endif %}
victron_inverter_state:
friendly_name: "Inverter State"
value_template: >-
{% if is_state('sensor.victron_vebus_state', '0') %}
Off
{% elif is_state('sensor.victron_vebus_state', '1') %}
Low Power
{% elif is_state('sensor.victron_vebus_state', '2') %}
Fault
{% elif is_state('sensor.victron_vebus_state', '3') %}
Bulk
{% elif is_state('sensor.victron_vebus_state', '4') %}
Absorption
{% elif is_state('sensor.victron_vebus_state', '5') %}
Float
{% elif is_state('sensor.victron_vebus_state', '6') %}
Storage
{% elif is_state('sensor.victron_vebus_state', '7') %}
Equalize
{% elif is_state('sensor.victron_vebus_state', '8') %}
Passthru
{% elif is_state('sensor.victron_vebus_state', '9') %}
Inverting
{% elif is_state('sensor.victron_vebus_state', '10') %}
Power assist
{% elif is_state('sensor.victron_vebus_state', '11') %}
Power supply
{% elif is_state('sensor.victron_vebus_state', '252') %}
Bulk protection
{% else %}
Unknown - {{ states('sensor.victron_vebus_state') }}
{% endif %}
victron_inverter_error:
friendly_name: "Inverter Error"
value_template: >-
{% if is_state('sensor.victron_vebus_error', '0') %}
No error
{% elif is_state('sensor.victron_vebus_error', '1') %}
Device is switched off because one of the other phases in the system has switched off
{% elif is_state('sensor.victron_vebus_error', '2') %}
New and old types MK2 are mixed in the system
{% elif is_state('sensor.victron_vebus_error', '3') %}
Not all- or more than- the expected devices were found in the system
{% elif is_state('sensor.victron_vebus_error', '4') %}
No other device whatsoever detected
{% elif is_state('sensor.victron_vebus_error', '5') %}
Overvoltage on AC-ou
{% elif is_state('sensor.victron_vebus_error', '6') %}
Error in DDC Program
{% elif is_state('sensor.victron_vebus_error', '7') %}
VE.Bus BMS connected- which requires an Assistant- but no assistant found
{% elif is_state('sensor.victron_vebus_error', '10') %}
System time synchronisation problem occurred
{% elif is_state('sensor.victron_vebus_error', '14') %}
Device cannot transmit data
{% elif is_state('sensor.victron_vebus_error', '16') %}
Dongle missing
{% elif is_state('sensor.victron_vebus_error', '17') %}
One of the devices assumed master status because the original master failed
{% elif is_state('sensor.victron_vebus_error', '18') %}
AC Overvoltage on the output of a slave has occurred while aready switched off
{% elif is_state('sensor.victron_vebus_error', '22') %}
This device cannot function as a slave
{% elif is_state('sensor.victron_vebus_error', '24') %}
Switch-over system protection initiated
{% elif is_state('sensor.victron_vebus_error', '25') %}
Firmware incompatibility
{% elif is_state('sensor.victron_vebus_error', '25') %}
Internal error
{% else %}
Unknown - {{ states('sensor.victron_vebus_error') }}
{% endif %}
#Victron energy sensors (from instant W to energy)
- platform: integration
source: sensor.victron_pv_power
name: 'Victron PV energy'
unit_prefix: k
round: 2
- platform: integration
source: sensor.victron_grid_power
name: 'Victron Grid energy'
unit_prefix: k
round: 2
- platform: integration
source: sensor.victron_current_power_usage
name: 'Victron total home energy'
unit_prefix: k
round: 2
utility_meter:
victron_pv_energy_daily:
source: sensor.victron_pv_energy
cycle: daily
victron_pv_energy_monthly:
source: sensor.victron_pv_energy
cycle: monthly
victron_home_energy_monthly:
source: sensor.victron_total_home_energy
cycle: monthly
victron_home_energy_daily:
source: sensor.victron_total_home_energy
cycle: daily
victron_grid_energy_monthly:
source: sensor.victron_grid_energy
cycle: monthly
victron_grid_energy_daily:
source: sensor.victron_grid_energy
cycle: daily
Wow! Thanks for the quick response. Best place would be github.com. You can create a snippet for all to see and mod/comment/star/like etc.
Might even evolve into a project
Cool dashboard @MongooseMan especially with the Rand savings addition
I presume you’re using tariffs in the HA utility meter…mind sharing your config
It’s a lot more manual than that
I basically track monthly kWh (both solar and grid) and have a template sensor I use to convert those into a monthly cost (without solar) and a monthly cost (with solar) and therefore a saving (formulae below using CT tariffs).
monthly_solar_saving:
friendly_name: "Monthly Solar Saving"
value_template: >-
{{
(([states('sensor.solar_energy_monthly')|float * 0.98 + states('sensor.grid_energy_monthly')|float, 600000]|min * 2.11 / 1000)
+ ([states('sensor.solar_energy_monthly')|float * 0.98 + states('sensor.grid_energy_monthly')|float - 600000, 0]|max * 2.9 / 1000)
- ([states('sensor.grid_energy_monthly')|float, 600000]|min * 2.11 / 1000)
- ([states('sensor.grid_energy_monthly')|float - 600000, 0]|max * 2.9 / 1000))
}}
I then do a monthly “true-up” using the VRM portal, and update the Total kWh and savings for each.
Another template sensor then uses that to calculate running total costs and savings
total_solar_saving_current:
friendly_name: "Total Solar Saving"
value_template: >-
R {{ ((states('input_number.total_solar_saving')| float + states('sensor.monthly_solar_saving')| float)) | round(2) }}
It’s something I keep meaning to update (it’ll break the next time tariffs change, for example) but it’s working well enough for now.
It’s not a source of truth, VRM fulfills that purpose, but it is a nice headsup monitor of what’s going on, more or less.
Thanks, definitely quite a process you have there…might give it a bash also not looking for perfection just some ball park estimates will do.
Also stumbled upon the power-wheel-card on GitHub power-wheel-card/README.md at f3e34e1aa263bf48b40e5557528733e247528787 · gurbyz/power-wheel-card · GitHub
You can plug in tariffs e.t.c. it has a couple of views for power, energy and money you can configure but not 100% sure if it’s suited for non-net metering environments like we have in SA, also not particularly keen on the overall appearance and battery support is still in beta
@ebendl am i mistaking or the value you have are onlye for one phase from the Victron ?
Sorry for the late reply! Yes, I have a single-phase system…
Ok thx, i was hoping you had a solution how to see the total power usage from all phases coz that is not availble from modbus, i guess i have to calculate it myself.
@ebendl Did you integrate your Victron data into the new energy dashboard if so how ? Do you have the sensors you used for that ?
Hi @donnib - I started but still need to do the battery in/battery out sensors. Still my aim to do it somewhere over the weekend or so - will post when I have everything set up.
So I did end up doing the Energy dashboard last night:
Doesn’t quite match what’s in VRM - at least in terms of consumption:
I think the numbers don’t match cause HA adds any excess solar to consumption but ignores efficiency. 10kWh solar is 8.5kWh on the ac side.
You got some YAML examples? I know @Sarel.Wagner was looking to see how to add the battery.
These are the modbus sensors:
modbus:
name: victron
host: <IP>
type: tcp
port: 502
switches:
- name: Force Charge
slave: 100
address: 2700
command_on: 5000
command_off: 20
verify:
sensors:
- name: "Victron Current Power Usage"
data_type: uint
unit_of_measurement: "W"
device_class: power
slave: 100
address: 817
scale: 1
- name: "Victron Grid Power"
data_type: int
unit_of_measurement: "W"
device_class: power
slave: 100
address: 820
scale: 1
- name: "Victron Battery Power"
data_type: int
unit_of_measurement: "W"
device_class: power
slave: 100
address: 842
scale: 1
- name: "Victron PV power"
data_type: uint
unit_of_measurement: "W"
device_class: power
slave: 100
address: 850
scale: 1
- name: "Victron Essential usage"
data_type: int
slave: 242
address: 23
scale: 10
unit_of_measurement: "W"
device_class: power
- name: "Victron VEBus Input Power 1"
data_type: int
slave: 242
address: 12
scale: 10
unit_of_measurement: "W"
device_class: power
Then I split the battery power into two using a template sensor, and isolate the power coming in from the grid:
- platform: template
sensors:
victron_battery_in:
friendly_name: 'Victron battery in'
value_template: >
{% if float(states("sensor.victron_battery_power")) > 0 %}
{{ (states("sensor.victron_battery_power") | float | round(0) ) }}
{% else %}
0
{% endif %}
unit_of_measurement: 'W'
device_class: power
victron_battery_out:
friendly_name: 'Victron battery out'
value_template: >
{% if float(states("sensor.victron_battery_power")) < 0 %}
{{ (states("sensor.victron_battery_power") | float | round(0) ) | abs }}
{% else %}
0
{% endif %}
unit_of_measurement: 'W'
device_class: power
victron_grid_usage:
friendly_name: 'Grid usage'
value_template: >
{% if float(states("sensor.victron_grid_power")) > 0 %}
{{ (states("sensor.victron_grid_power") | float | round (0) ) }}
{% else %}
0
{% endif %}
unit_of_measurement: 'W'
device_class: power
Do note the device_class:power – doing this makes sure that the integration sensor is set to device_class: energy which you need to be able to use them in the Energy settings.
Next I integrate the instantaneous power (W) usage into energy (kWh) using the integration sensors:
#Victron energy sensors (from instant W to energy)
- platform: integration
source: sensor.victron_pv_power
name: 'Victron PV energy'
unit_prefix: k
round: 2
- platform: integration
source: sensor.victron_grid_power
name: 'Victron Grid energy'
unit_prefix: k
round: 2
- platform: integration
source: sensor.victron_current_power_usage
name: 'Victron total home energy'
unit_prefix: k
round: 2
- platform: integration
source: sensor.victron_battery_in
name: 'Victron battery in energy'
unit_prefix: k
round: 2
- platform: integration
source: sensor.victron_battery_out
name: 'Victron battery out energy'
unit_prefix: k
round: 2
This is what you get:
That being said, there’s still a big difference between VRM and what HA calculates, especially for the battery part.
(if I take “consumed battery” - “battery in energy”, I get 0.51 kWh which is a far cry from 0.04kWh in VRM.
VRM does a lot of fudging. Well, not VRM so much as vrmlogger. Every 15 minutes it gets a bunch of values from energy counters, and it has to decide how much of that PV went to loads, and how much went into the battery, and it may well decide that all of it went to loads, because for 5 minutes there was a big load, even though for the other 10 minutes there wasn’t a big load and most of it really went into the batteries (and was taken out again for said big load).
It is not perfect, but in general it is good enough.