It’s been 2 years since I fell into the Renewable Energy Rabbit Hole and something this has been able to do, is to also spark my interest in IoT devices and hardware. Something I have realized over the years is that it is not only important for you to have a Solar Inverter setup, you also need data from your inverter setup. Now some inverters come with a manageable energy monitoring solution, the best I have seen so far has to be from Victron with their
I used to use an SRNE inverter and thanks to the good folks at
If you are someone like me who owns the same inverter and you are looking for a way to make it work locally on your Home Assistant network, this tutorial is for you. A basic overview of what we will be doing is taking the data from the Inverter’s
The Waveshare device comes with a power adapter too. You plug it into power, and plug it into the side that has the DC 5V port.
Then you take an Ethernet cable, plug one side to your home router or network switch’s LAN port, and plug the other side to the Waveshare device.
After that, you should observe to see if the Ethernet port has the usual still and blinking light to confirm the cable connection was successful.
When you check at the back of your Waveshare device, you would see the Default IP, Username and Password. Mine has 192.168.0.7
as the Default IP, admin
as the username and admin
as password.
When you visit the default IP, you should see the Waveshare homepage which looks like this.
For me, my router’s range is 192.168.8.x
, but the Waveshare was 192.168.0.7
, so my computer wasn’t able to communicate with it unless I temporarily changed my PC’s IP to match. \
Go to your Network & Internet under settings.
Click on the properties
Click on edit IP Assignment and choose Manual
Toggle IPv4 and you would see a drop-down of settings
Set IP Address to 192.168.0.10
(or any other 192.168.0.x
, except .7
)
Subnet Mask (from router’s LAN settings) to 255.255.255.0
Gateway to 192.168.0.1
(if required, or leave blank)
Then save.
192.168.0.7
192.168.8.15
Now we can see the Waveshare device on our network, we are halfway there. Next thing we need to do is to connect the inverter itself to the Waveshare device.
Then insert pin 1 into B- and pin 2 into A+ on the Waveshare device.
Now we are done with all physical connections, let’s go to the Waveshare IP. Click on the Serial Port tab. Change the Work Mode to TCP Server. Baud Rate to 9600, Data Size to 8, Parity to None, Stop Bits to 1, Local Port Number to 502. Then save and restart.
To confirm data is being transferred, look at the Current Status tab and see if the byte figures increase as it refreshes.
The Modbus data is currently being sent from the inverter to your home network. What’s left is to have Home Assistant decode that information and have them as entities. Luckily Home Assistant has a
configuration.yaml
file on your Home Assistant network.configuration.yaml
as lean as possible by having separate yaml files for things and then including them into the configuration.yaml
file, go ahead and create a new file called modbus.yaml
and a new file called templates.yaml
.modbus.yaml
into the configuration.yaml
by adding the code below.modbus: !include modbus.yaml
template: !include templates.yaml
#Modbus
- name: growatt
type: rtuovertcp
host: 192.168.8.15 # Waveshare RS485 adapter IP
port: 502 # Change if necessary
delay: 5
timeout: 5
message_wait_milliseconds: 500
sensors:
# System Status
- name: "Growatt System Status"
slave: 1
address: 0
input_type: input
data_type: uint16
# Solar PV Sensors
- name: "Growatt PV1 Voltage"
slave: 1
address: 1
input_type: input
data_type: uint16
scale: 0.1
unit_of_measurement: "V"
- name: "Growatt PV2 Voltage"
slave: 1
address: 2
input_type: input
data_type: uint16
scale: 0.1
unit_of_measurement: "V"
- name: "Growatt PV1 Current"
slave: 1
address: 7
input_type: input
data_type: uint16
scale: 0.1
unit_of_measurement: "A"
- name: "Growatt PV2 Current"
slave: 1
address: 8
input_type: input
data_type: uint16
scale: 0.1
unit_of_measurement: "A"
# PV Power (Read High & Low Registers)
- name: "Growatt PV1 Charge Power High"
slave: 1
address: 3
input_type: input
data_type: uint16
- name: "Growatt PV1 Charge Power Low"
slave: 1
address: 4
input_type: input
data_type: uint16
- name: "Growatt PV2 Charge Power High"
slave: 1
address: 5
input_type: input
data_type: uint16
- name: "Growatt PV2 Charge Power Low"
slave: 1
address: 6
input_type: input
data_type: uint16
# Inverter & System Temperature Sensors
- name: "Growatt Inverter Temperature"
slave: 1
address: 25
input_type: input
data_type: uint16
scale: 0.1
unit_of_measurement: "°C"
- name: "Growatt DC-DC Temperature"
slave: 1
address: 26
input_type: input
data_type: uint16
scale: 0.1
unit_of_measurement: "°C"
# Battery Sensors
- name: "Growatt Battery Voltage"
slave: 1
address: 17
input_type: input
data_type: uint16
scale: 0.01
unit_of_measurement: "V"
- name: "Growatt Battery SOC"
slave: 1
address: 18
input_type: input
data_type: uint16
unit_of_measurement: "%"
- name: "Growatt Battery Power High"
slave: 1
address: 77
input_type: input
data_type: int16
- name: "Growatt Battery Power Low"
slave: 1
address: 78
input_type: input
data_type: int16
# AC Output Sensors
- name: "Growatt AC Output Voltage"
slave: 1
address: 22
input_type: input
data_type: uint16
scale: 0.1
unit_of_measurement: "V"
- name: "Growatt AC Output Frequency"
slave: 1
address: 23
input_type: input
data_type: uint16
scale: 0.01
unit_of_measurement: "Hz"
# AC Charge Power (High & Low)
- name: "Growatt AC Charge Power High"
slave: 1
address: 13
input_type: input
data_type: uint16
- name: "Growatt AC Charge Power Low"
slave: 1
address: 14
input_type: input
data_type: uint16
# Grid Sensors
- name: "Growatt Grid Voltage"
slave: 1
address: 20
input_type: input
data_type: uint16
scale: 0.1
unit_of_measurement: "V"
- name: "Growatt Grid Frequency"
slave: 1
address: 21
input_type: input
data_type: uint16
scale: 0.01
unit_of_measurement: "Hz"
# Load Power
- name: "Growatt Load Power High"
slave: 1
address: 9
input_type: input
data_type: int16
- name: "Growatt Load Power Low"
slave: 1
address: 10
input_type: input
data_type: int16
# Load Percentage
- name: "Growatt Load Percentage"
slave: 1
address: 27
input_type: input
data_type: uint16
scale: 0.1
unit_of_measurement: "%"
# Fan Speeds
- name: "Growatt MPPT Fan Speed"
slave: 1
address: 81
input_type: input
data_type: uint16
unit_of_measurement: "%"
- name: "Growatt Inverter Fan Speed"
slave: 1
address: 82
input_type: input
data_type: uint16
unit_of_measurement: "%"
# Fault Codes
- name: "Growatt Fault Bit"
slave: 1
address: 40
input_type: input
data_type: uint16
- name: "Growatt Warning Bit"
slave: 1
address: 41
input_type: input
data_type: uint16
- name: "Growatt Fault Value"
slave: 1
address: 42
input_type: input
data_type: uint16
- name: "Growatt Warning Value"
slave: 1
address: 43
input_type: input
data_type: uint16
# Work Time Total (High & Low)
- name: "Growatt Work Time Total High"
slave: 1
address: 30
input_type: input
data_type: uint16
- name: "Growatt Work Time Total Low"
slave: 1
address: 31
input_type: input
data_type: uint16
# AC Input Power (High & Low)
- name: "Growatt AC Input Power High"
slave: 1
address: 36
input_type: input
data_type: uint16
- name: "Growatt AC Input Power Low"
slave: 1
address: 37
input_type: input
data_type: uint16
# PV Energy Today & Total
- name: "Growatt Solar Energy Today High"
slave: 1
address: 48
input_type: input
data_type: uint16
- name: "Growatt Solar Energy Today Low"
slave: 1
address: 49
input_type: input
data_type: uint16
- name: "Growatt Solar Energy Total High"
slave: 1
address: 50
input_type: input
data_type: uint16
- name: "Growatt Solar Energy Total Low"
slave: 1
address: 51
input_type: input
data_type: uint16
# AC Charge Energy
- name: "Growatt AC Charge Energy Today High"
slave: 1
address: 56
input_type: input
data_type: uint16
- name: "Growatt AC Charge Energy Today Low"
slave: 1
address: 57
input_type: input
data_type: uint16
- name: "Growatt AC Charge Energy Total High"
slave: 1
address: 58
input_type: input
data_type: uint16
- name: "Growatt AC Charge Energy Total Low"
slave: 1
address: 59
input_type: input
data_type: uint16
# Battery Discharge Energy
- name: "Growatt Battery Discharge Energy Today High"
slave: 1
address: 60
input_type: input
data_type: uint16
- name: "Growatt Battery Discharge Energy Today Low"
slave: 1
address: 61
input_type: input
data_type: uint16
- name: "Growatt Battery Discharge Energy Total High"
slave: 1
address: 62
input_type: input
data_type: uint16
- name: "Growatt Battery Discharge Energy Total Low"
slave: 1
address: 63
input_type: input
data_type: uint16
# AC Discharge Energy
- name: "Growatt AC Discharge Energy Today High"
slave: 1
address: 64
input_type: input
data_type: uint16
- name: "Growatt AC Discharge Energy Today Low"
slave: 1
address: 65
input_type: input
data_type: uint16
- name: "Growatt AC Discharge Energy Total High"
slave: 1
address: 66
input_type: input
data_type: uint16
- name: "Growatt AC Discharge Energy Total Low"
slave: 1
address: 67
input_type: input
data_type: uint16
# AC Charge Current & AC Discharge Power
- name: "Growatt AC Charge Battery Current"
slave: 1
address: 68
input_type: input
data_type: uint16
scale: 0.1
unit_of_measurement: "A"
- name: "Growatt AC Discharge Power High"
slave: 1
address: 69
input_type: input
data_type: uint16
- name: "Growatt AC Discharge Power Low"
slave: 1
address: 70
input_type: input
data_type: uint16
templates.yaml
and paste this code inside it.- sensor:
# Growatt Output Power
- name: "Growatt Output Power"
unit_of_measurement: "W"
state_class: measurement
device_class: power
state: >
{% set high = states('sensor.growatt_output_power_high') | int(0) %}
{% set low = states('sensor.growatt_output_power_low') | int(0) %}
{{ ((high * 65536) + low) * 0.1 }}
# Growatt Battery Power
- name: "Growatt Battery Power"
unit_of_measurement: "W"
state_class: measurement
device_class: power
state: >
{% set high = states('sensor.growatt_battery_power_high') | int(0) %}
{% set low = states('sensor.growatt_battery_power_low') | int(0) %}
{{ ((high * 65536) + low) * 0.1 }}
# Growatt PV1 Charge Power
- name: "Growatt PV1 Charge Power"
unit_of_measurement: "W"
state_class: measurement
device_class: power
state: >
{% set high = states('sensor.growatt_pv1_charge_power_high') | int(0) %}
{% set low = states('sensor.growatt_pv1_charge_power_low') | int(0) %}
{{ ((high * 65536) + low) * 0.1 }}
# Growatt PV2 Charge Power
- name: "Growatt PV2 Charge Power"
unit_of_measurement: "W"
state_class: measurement
device_class: power
state: >
{% set high = states('sensor.growatt_pv2_charge_power_high') | int(0) %}
{% set low = states('sensor.growatt_pv2_charge_power_low') | int(0) %}
{{ ((high * 65536) + low) * 0.1 }}
# Growatt Load Power
- name: "Growatt Load Power"
unit_of_measurement: "W"
state_class: measurement
device_class: power
state: >
{% set high = states('sensor.growatt_load_power_high') | int(0) %}
{% set low = states('sensor.growatt_load_power_low') | int(0) %}
{{ ((high * 65536) + low) * 0.1 }}
# Growatt Load Power Alternative (Handles Negative Power)
- name: "Growatt Load Power Signed"
unit_of_measurement: "W"
state_class: measurement
device_class: power
state: >
{% set high = states('sensor.growatt_load_power_high') | int(0) %}
{% set low = states('sensor.growatt_load_power_low') | int(0) %}
{% if high > 32767 %} # Handle negative values (Two's complement)
{% set high = high - 65536 %}
{% endif %}
{{ ((high * 65536) + low) * 0.1 }}
# Growatt AC Charge Power
- name: "Growatt AC Charge Power"
unit_of_measurement: "W"
state_class: measurement
device_class: power
state: >
{% set high = states('sensor.growatt_ac_charge_power_high') | int(0) %}
{% set low = states('sensor.growatt_ac_charge_power_low') | int(0) %}
{{ ((high * 65536) + low) * 0.1 }}
# Growatt Work Time Total
- name: "Growatt Work Time Total"
unit_of_measurement: "Hours"
state_class: measurement
state: >
{% set high = states('sensor.growatt_work_time_total_high') | int(0) %}
{% set low = states('sensor.growatt_work_time_total_low') | int(0) %}
{% set total_seconds = ((high * 65536) + low) * 0.5 %}
{{ (total_seconds / 3600) | round(2) }} # Convert seconds to hours
# Growatt AC Input Power
- name: "Growatt AC Input Power"
unit_of_measurement: "W"
state_class: measurement
device_class: power
state: >
{% set high = states('sensor.growatt_ac_input_power_high') | int(0) %}
{% set low = states('sensor.growatt_ac_input_power_low') | int(0) %}
{{ ((high * 65536) + low) * 0.1 }}
# Growatt Solar Energy Today
- name: "Growatt Solar Energy Today"
unit_of_measurement: "kWh"
state_class: total_increasing
state: >
{% set high = states('sensor.growatt_solar_energy_today_high') | int(0) %}
{% set low = states('sensor.growatt_solar_energy_today_low') | int(0) %}
{{ ((high * 65536) + low) * 0.1 }}
# Growatt Solar Energy Total
- name: "Growatt Solar Energy Total"
unit_of_measurement: "kWh"
state_class: total_increasing
state: >
{% set high = states('sensor.growatt_solar_energy_total_high') | int(0) %}
{% set low = states('sensor.growatt_solar_energy_total_low') | int(0) %}
{{ ((high * 65536) + low) * 0.1 }}
# Growatt AC Charge Energy Today
- name: "Growatt AC Charge Energy Today"
unit_of_measurement: "kWh"
state_class: total_increasing
state: >
{% set high = states('sensor.growatt_ac_charge_energy_today_high') | int(0) %}
{% set low = states('sensor.growatt_ac_charge_energy_today_low') | int(0) %}
{{ ((high * 65536) + low) * 0.1 }}
# Growatt AC Charge Energy Total
- name: "Growatt AC Charge Energy Total"
unit_of_measurement: "kWh"
state_class: total_increasing
state: >
{% set high = states('sensor.growatt_ac_charge_energy_total_high') | int(0) %}
{% set low = states('sensor.growatt_ac_charge_energy_total_low') | int(0) %}
{{ ((high * 65536) + low) * 0.1 }}
# Growatt AC Discharge Power
- name: "Growatt AC Discharge Power"
unit_of_measurement: "W"
state_class: measurement
device_class: power
state: >
{% set high = states('sensor.growatt_ac_discharge_power_high') | int(0) %}
{% set low = states('sensor.growatt_ac_discharge_power_low') | int(0) %}
{{ ((high * 65536) + low) * 0.1 }}
# Growatt AC Discharge Energy Today
- name: "Growatt AC Discharge Energy Today"
unit_of_measurement: "kWh"
state_class: total_increasing
state: >
{% set high = states('sensor.growatt_ac_discharge_energy_today_high') | int(0) %}
{% set low = states('sensor.growatt_ac_discharge_energy_today_low') | int(0) %}
{{ ((high * 65536) + low) * 0.1 }}
# Growatt AC Discharge Energy Total
- name: "Growatt AC Discharge Energy Total"
unit_of_measurement: "kWh"
state_class: total_increasing
state: >
{% set high = states('sensor.growatt_ac_discharge_energy_total_high') | int(0) %}
{% set low = states('sensor.growatt_ac_discharge_energy_total_low') | int(0) %}
{{ ((high * 65536) + low) * 0.1 }}
# Growatt Battery Discharge Energy Today
- name: "Growatt Battery Discharge Energy Today"
unit_of_measurement: "kWh"
state_class: total_increasing
state: >
{% set high = states('sensor.growatt_battery_discharge_energy_today_high') | int(0) %}
{% set low = states('sensor.growatt_battery_discharge_energy_today_low') | int(0) %}
{{ ((high * 65536) + low) * 0.1 }}
# Growatt Battery Discharge Energy Total
- name: "Growatt Battery Discharge Energy Total"
unit_of_measurement: "kWh"
state_class: total_increasing
state: >
{% set high = states('sensor.growatt_battery_discharge_energy_total_high') | int(0) %}
{% set low = states('sensor.growatt_battery_discharge_energy_total_low') | int(0) %}
{{ ((high * 65536) + low) * 0.1 }}
# Growatt System Status (Human-Readable)
- name: "Growatt System Status Description"
state: >
{% set status = states('sensor.growatt_system_status') | int(0) %}
{% if status == 0 %} Standby
{% elif status == 1 %} No Use
{% elif status == 2 %} Discharge
{% elif status == 3 %} Fault
{% elif status == 4 %} Flash
{% elif status == 5 %} PV charge
{% elif status == 6 %} AC charge
{% elif status == 7 %} Combine charge
{% elif status == 8 %} Combine charge and Bypass
{% elif status == 9 %} PV charge and Bypass
{% elif status == 10 %} AC charge and Bypass
{% elif status == 11 %} Bypass
{% elif status == 12 %} PV charge and Discharge
{% else %} Unknown Status ({{ status }})
{% endif %}
Now the Modbus sensor entities we created should be showing up in Home Assistant. You can confirm by going to the Entities tab in Home Assistant and filtering by Modbus integration or you search “Growatt” there.
Also for some context, you would observe in the modbus.yaml
file, there are High and Low of some values. Those values are stored as two registers (high and low bytes), so they need to be combined correctly. Since Home Assistant doesn’t support direct bit-shifting in Modbus, we use template sensors in the templates.yaml
file to combine the values.
Thanks for reading and feel free to share your experience in the comment section.