Files
homeassistant/integrations/modbus_sungrow.yaml
2024-12-18 13:26:06 +01:00

3184 lines
107 KiB
YAML

# Home Assistant Sungrow inverter integration
# https://github.com/mkaiser/Sungrow-SHx-Inverter-Modbus-Home-Assistant
# by Martin Kaiser
# last update: 2024-10-01 (2)
#
# Note: This YAML file will only work with Home Assistant >= 2023.10
modbus:
- name: SungrowSHx
type: tcp
host: !secret sungrow_modbus_host_ip
port: !secret sungrow_modbus_port
delay: 5
timeout: 10
sensors:
- name: Sungrow inverter serial
unique_id: sg_inverter_serial
device_address: !secret sungrow_modbus_slave
address: 4989 # reg 4990
input_type: input
data_type: string
count: 10
scan_interval: 600
# for Sungrow batteries only
# - name: Sungrow battery serial
# unique_id: sg_battery_serial
# device_address: !secret sbr_modbus_slave # Usually 200, only modbus-port, not via Winet-S
# address: 10710 # reg 10711
# input_type: input
# data_type: string
# count: 10
# scan_interval: 86400
- name: Sungrow device type code
unique_id: sg_dev_code
device_address: !secret sungrow_modbus_slave
address: 4999 # reg 5000
input_type: input
data_type: uint16
scan_interval: 600
- name: Daily PV generation & battery discharge
unique_id: sg_daily_pv_gen_battery_discharge
device_address: !secret sungrow_modbus_slave
address: 5002 # reg 5003
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Total PV generation & battery discharge
unique_id: sg_total_pv_gen_battery_discharge
device_address: !secret sungrow_modbus_slave
address: 5003 # reg 5004
input_type: input
data_type: uint32
swap: word
unit_of_measurement: kWh
precision: 1
device_class: energy
state_class: total
scale: 0.1
scan_interval: 600
- name: Inverter temperature
unique_id: sg_inverter_temperature
device_address: !secret sungrow_modbus_slave
address: 5007 # reg 5008
input_type: input
data_type: int16
precision: 1
unit_of_measurement: °C
device_class: Temperature
state_class: measurement
scale: 0.1
scan_interval: 10
- name: MPPT1 voltage
unique_id: sg_mppt1_voltage
device_address: !secret sungrow_modbus_slave
address: 5010 # reg 5011
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: V
device_class: Voltage
state_class: measurement
scale: 0.1
scan_interval: 10
- name: MPPT1 current
unique_id: sg_mppt1_current
device_address: !secret sungrow_modbus_slave
address: 5011 # reg 5012
input_type: input
data_type: uint16
precision: 2
unit_of_measurement: A
device_class: Current
state_class: measurement
scale: 0.1
scan_interval: 10
- name: MPPT2 voltage
unique_id: sg_mppt2_voltage
device_address: !secret sungrow_modbus_slave
address: 5012 # reg 5013
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: V
device_class: Voltage
state_class: measurement
scale: 0.1
scan_interval: 10
- name: MPPT2 current
unique_id: sg_mppt2_current
device_address: !secret sungrow_modbus_slave
address: 5013 # reg 5014
input_type: input
data_type: uint16
precision: 2
unit_of_measurement: A
device_class: Current
state_class: measurement
scale: 0.1
scan_interval: 10
- name: Total DC power
unique_id: sg_total_dc_power
device_address: !secret sungrow_modbus_slave
address: 5016 # reg 5017
input_type: input
data_type: uint32
swap: word
precision: 0
unit_of_measurement: W
device_class: power
state_class: measurement
scale: 1
scan_interval: 10
- name: Phase A voltage
unique_id: sg_phase_a_voltage
device_address: !secret sungrow_modbus_slave
address: 5018 # reg: 5019
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: V
device_class: Voltage
state_class: measurement
scale: 0.1
scan_interval: 10
- name: Phase B voltage
unique_id: sg_phase_b_voltage
device_address: !secret sungrow_modbus_slave
address: 5019 # reg: 5020
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: V
device_class: Voltage
state_class: measurement
scale: 0.1
scan_interval: 10
- name: Phase C voltage
unique_id: sg_phase_c_voltage
device_address: !secret sungrow_modbus_slave
address: 5020 # reg: 5021
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: V
device_class: Voltage
state_class: measurement
scale: 0.1
scan_interval: 10
- name: Grid frequency
unique_id: sg_grid_frequency
device_address: !secret sungrow_modbus_slave
address: 5035 # reg 5036
input_type: input
data_type: uint16
precision: 2
unit_of_measurement: "Hz"
device_class: frequency
state_class: measurement
scale: 0.1
scan_interval: 10
- name: Reactive power
unique_id: sg_reactive_power
device_address: !secret sungrow_modbus_slave
address: 5032 # reg 5033
input_type: input
data_type: int32
swap: word
precision: 0
unit_of_measurement: W
device_class: power
state_class: measurement
scale: 1
scan_interval: 10
- name: Power factor
unique_id: sg_power_factor
device_address: !secret sungrow_modbus_slave
address: 5034 # reg 5035
input_type: input
data_type: int16
precision: 3
unit_of_measurement: "%"
device_class: power_factor
state_class: measurement
scale: 0.001
scan_interval: 10
#https://www.photovoltaikforum.com/thread/166134-daten-lesen-vom-sungrow-wechselrichtern-modbus/?pageNo=13
#Meter Active Power: 5601-5602 S32 W (Energiezähler Wirkleistung)
#Meter Phase A Active Power: 5603-5604 S32 W (Stromzähler Phase A Wirkleistung)
#Meter Phase B Active Power: 5605-5606 S32 W (Stromzähler Phase B Wirkleistung)
#Meter Phase C Active Power: 5607-5608 S32 W (Stromzähler Phase C Wirkleistung)
- name: Meter active power raw
unique_id: sg_meter_active_power_raw
device_address: !secret sungrow_modbus_slave
address: 5600 # reg 5601
input_type: input
data_type: int32
swap: word
precision: 0
unit_of_measurement: W
device_class: power
state_class: measurement
scale: 1
scan_interval: 10
- name: Meter phase A active power raw
unique_id: sg_meter_phase_a_active_power_raw
device_address: !secret sungrow_modbus_slave
address: 5602 # reg 5603
input_type: input
data_type: int32
swap: word
precision: 0
unit_of_measurement: W
device_class: power
state_class: measurement
scale: 1
scan_interval: 10
- name: Meter phase B active power raw
unique_id: sg_meter_phase_b_active_power_raw
device_address: !secret sungrow_modbus_slave
address: 5604 # reg 5605
input_type: input
data_type: int32
swap: word
precision: 0
unit_of_measurement: W
device_class: power
state_class: measurement
scale: 1
scan_interval: 10
- name: Meter phase C active power raw
unique_id: sg_meter_phase_c_active_power_raw
device_address: !secret sungrow_modbus_slave
address: 5606 # reg 5607
input_type: input
data_type: int32
swap: word
precision: 0
unit_of_measurement: W
device_class: power
state_class: measurement
scale: 1
scan_interval: 10
- name: BDC rated power
unique_id: sg_bdc_rated_power
device_address: !secret sungrow_modbus_slave
address: 5627 # reg 5628
input_type: input
data_type: uint16
unit_of_measurement: "W"
device_class: power
state_class: measurement
scale: 100
scan_interval: 600
- name: BMS max. charging current
unique_id: sg_bms_max_charging_current
device_address: !secret sungrow_modbus_slave
address: 5634 # reg 5635
input_type: input
data_type: uint16
precision: 0
unit_of_measurement: A
device_class: Current
state_class: measurement
scale: 1
scan_interval: 60
- name: BMS max. discharging current
unique_id: sg_bms_max_discharging_current
device_address: !secret sungrow_modbus_slave
address: 5635 # reg 5636
input_type: input
data_type: uint16
precision: 0
unit_of_measurement: A
device_class: Current
state_class: measurement
scale: 1
scan_interval: 60
#https://www.photovoltaikforum.com/thread/166134-daten-lesen-vom-sungrow-wechselrichtern-modbus/?pageNo=13
#Phase A Backup Power: 5723 S16 W (Backup Leistung Phase A)
#Phase B Backup Power: 5724 S16 W (Backup Leistung Phase B)
#Phase C Backup Power: 5725 S16 W (Backup Leistung Phase C)
- name: Total backup power
device_address: !secret sungrow_modbus_slave
unique_id: sg_total_backup_power
address: 5725 # reg 5726
input_type: input
data_type: int16
precision: 0
unit_of_measurement: W
device_class: power
state_class: measurement
scale: 1
scan_interval: 10
- name: Backup phase A power
unique_id: sg_backup_phase_a_power
device_address: !secret sungrow_modbus_slave
address: 5722 # reg 5723
input_type: input
data_type: int16
precision: 0
unit_of_measurement: W
device_class: power
state_class: measurement
scale: 1
scan_interval: 10
- name: Backup phase B power
unique_id: sg_backup_phase_b_power
device_address: !secret sungrow_modbus_slave
address: 5723 # reg 5724
input_type: input
data_type: int16
precision: 0
unit_of_measurement: W
device_class: power
state_class: measurement
scale: 1
scan_interval: 10
- name: Backup phase C power
unique_id: sg_backup_phase_c_power
device_address: !secret sungrow_modbus_slave
address: 5724 # reg 5725
input_type: input
data_type: int16
precision: 0
unit_of_measurement: W
device_class: power
state_class: measurement
scale: 1
scan_interval: 10
# https://www.photovoltaikforum.com/thread/166134-daten-lesen-vom-sungrow-wechselrichtern-modbus/?postID=3324464#post3324464
- name: Meter phase A voltage
unique_id: sg_meter_phase_a_voltage
device_address: !secret sungrow_modbus_slave
address: 5740 # reg 5741
input_type: input
data_type: int16
precision: 1
unit_of_measurement: V
device_class: voltage
state_class: measurement
scale: 0.1
scan_interval: 10
- name: Meter phase B voltage
unique_id: sg_meter_phase_b_voltage
device_address: !secret sungrow_modbus_slave
address: 5741 # reg 5742
input_type: input
data_type: int16
precision: 1
unit_of_measurement: V
device_class: voltage
state_class: measurement
scale: 0.1
scan_interval: 10
- name: Meter phase C voltage
unique_id: sg_meter_phase_c_voltage
device_address: !secret sungrow_modbus_slave
address: 5742 # reg 5743
input_type: input
data_type: int16
precision: 1
unit_of_measurement: V
device_class: voltage
state_class: measurement
scale: 0.1
scan_interval: 10
- name: Meter phase A current
unique_id: sg_meter_phase_a_current
device_address: !secret sungrow_modbus_slave
address: 5743 # reg 5744
input_type: input
data_type: uint16
precision: 0
unit_of_measurement: A
device_class: current
state_class: measurement
scale: 0.01
scan_interval: 10
- name: Meter phase B current
unique_id: sg_meter_phase_b_current
device_address: !secret sungrow_modbus_slave
address: 5744 # reg 5745
input_type: input
data_type: uint16
precision: 0
unit_of_measurement: A
device_class: current
state_class: measurement
scale: 0.01
scan_interval: 10
- name: Meter phase C current
unique_id: sg_meter_phase_c_current
device_address: !secret sungrow_modbus_slave
address: 5745 # reg 5746
input_type: input
data_type: uint16
precision: 0
unit_of_measurement: A
device_class: current
state_class: measurement
scale: 0.01
scan_interval: 10
# Start monthly PV generation
- name: Monthly PV generation (01 January)
unique_id: sg_monthly_pv_generation_01_january
device_address: !secret sungrow_modbus_slave
address: 6226 # reg 6227
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Monthly PV generation (02 February)
unique_id: sg_monthly_pv_generation_02_february
device_address: !secret sungrow_modbus_slave
address: 6227 # reg 6228
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Monthly PV generation (03 March)
unique_id: sg_monthly_pv_generation_03_march
device_address: !secret sungrow_modbus_slave
address: 6228 # reg 6229
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Monthly PV generation (04 April)
unique_id: sg_monthly_pv_generation_04_april
device_address: !secret sungrow_modbus_slave
address: 6229 # reg 6230
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Monthly PV generation (05 May)
unique_id: sg_monthly_pv_generation_05_may
device_address: !secret sungrow_modbus_slave
address: 6230 # reg 6231
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Monthly PV generation (06 June)
unique_id: sg_monthly_pv_generation_06_june
device_address: !secret sungrow_modbus_slave
address: 6231 # reg 6232
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Monthly PV generation (07 July)
unique_id: sg_monthly_pv_generation_07_july
device_address: !secret sungrow_modbus_slave
address: 6232 # reg 6233
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Monthly PV generation (08 August)
unique_id: sg_monthly_pv_generation_08_august
device_address: !secret sungrow_modbus_slave
address: 6233 # reg 6234
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Monthly PV generation (09 September)
unique_id: sg_monthly_pv_generation_09_september
device_address: !secret sungrow_modbus_slave
address: 6234 # reg 6235
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Monthly PV generation (10 October)
unique_id: sg_monthly_pv_generation_10_october
device_address: !secret sungrow_modbus_slave
address: 6235 # reg 6236
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Monthly PV generation (11 November)
unique_id: sg_monthly_pv_generation_11_november
device_address: !secret sungrow_modbus_slave
address: 6236 # reg 6237
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Monthly PV generation (12 December)
unique_id: sg_monthly_pv_generation_12_december
device_address: !secret sungrow_modbus_slave
address: 6237 # reg 6238
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
# End monthly PV generation
# Start yearly pv generation
- name: Yearly PV generation (2019)
unique_id: sg_yearly_pv_generation_2019
device_address: !secret sungrow_modbus_slave
address: 6257 # reg 6258
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Yearly PV generation (2020)
unique_id: sg_yearly_pv_generation_2020
device_address: !secret sungrow_modbus_slave
address: 6259 # reg 6260
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Yearly PV generation (2021)
unique_id: sg_yearly_pv_generation_2021
device_address: !secret sungrow_modbus_slave
address: 6261 # reg 6262
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Yearly PV generation (2022)
unique_id: sg_yearly_pv_generation_2022
device_address: !secret sungrow_modbus_slave
address: 6263 # reg 6264
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Yearly PV generation (2023)
unique_id: sg_yearly_pv_generation_2023
device_address: !secret sungrow_modbus_slave
address: 6265 # reg 6266
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Yearly PV generation (2024)
unique_id: sg_yearly_pv_generation_2024
device_address: !secret sungrow_modbus_slave
address: 6267 # reg 6268
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Yearly PV generation (2025)
unique_id: sg_yearly_pv_generation_2025
device_address: !secret sungrow_modbus_slave
address: 6269 # reg 6270
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Yearly PV generation (2026)
unique_id: sg_yearly_pv_generation_2026
device_address: !secret sungrow_modbus_slave
address: 6271 # reg 6272
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Yearly PV generation (2027)
unique_id: sg_yearly_pv_generation_2027
device_address: !secret sungrow_modbus_slave
address: 6273 # reg 6274
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Yearly PV generation (2028)
unique_id: sg_yearly_pv_generation_2028
device_address: !secret sungrow_modbus_slave
address: 6275 # reg 6276
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Yearly PV generation (2029)
unique_id: sg_yearly_pv_generation_2029
device_address: !secret sungrow_modbus_slave
address: 6277 # reg 6278
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
# End yearly pv generation
# Start monthly export
- name: Monthly export (01 January)
unique_id: sg_monthly_export_01_january
device_address: !secret sungrow_modbus_slave
address: 6595 # reg 6596
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Monthly export (02 February)
unique_id: sg_monthly_export_02_february
device_address: !secret sungrow_modbus_slave
address: 6596 # reg 6597
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Monthly export (03 March)
unique_id: sg_monthly_export_03_march
device_address: !secret sungrow_modbus_slave
address: 6597 # reg 6598
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Monthly export (04 April)
unique_id: sg_monthly_export_04_april
device_address: !secret sungrow_modbus_slave
address: 6598 # reg 6599
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Monthly export (05 May)
unique_id: sg_monthly_export_05_may
device_address: !secret sungrow_modbus_slave
address: 6599 # reg 6600
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Monthly export (06 June)
unique_id: sg_monthly_export_06_june
device_address: !secret sungrow_modbus_slave
address: 6600 # reg 6601
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Monthly export (07 July)
unique_id: sg_monthly_export_07_july
device_address: !secret sungrow_modbus_slave
address: 6601 # reg 6602
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Monthly export (08 August)
unique_id: sg_monthly_export_08_august
device_address: !secret sungrow_modbus_slave
address: 6602 # reg 6603
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Monthly export (09 September)
unique_id: sg_monthly_export_09_september
device_address: !secret sungrow_modbus_slave
address: 6603 # reg 6604
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Monthly export (10 October)
unique_id: sg_monthly_export_10_october
device_address: !secret sungrow_modbus_slave
address: 6604 # reg 6605
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Monthly export (11 November)
unique_id: sg_monthly_export_11_november
device_address: !secret sungrow_modbus_slave
address: 6605 # reg 6606
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Monthly export (12 December)
unique_id: sg_monthly_export_12_december
device_address: !secret sungrow_modbus_slave
address: 6606 # reg 6607
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
# End monthly export
# Start yearly export energy from PV
- name: Yearly Export (2019)
unique_id: sg_yearly_export_2019
device_address: !secret sungrow_modbus_slave
address: 6615 # reg 6616
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total
scale: 0.1
scan_interval: 600
- name: Yearly Export (2020)
unique_id: sg_yearly_export_2020
device_address: !secret sungrow_modbus_slave
address: 6617 # reg 6618
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total
scale: 0.1
scan_interval: 600
- name: Yearly Export (2021)
unique_id: sg_yearly_export_2021
device_address: !secret sungrow_modbus_slave
address: 6619 # reg 6620
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total
scale: 0.1
scan_interval: 600
- name: Yearly Export (2022)
unique_id: sg_yearly_export_2022
device_address: !secret sungrow_modbus_slave
address: 6621 # reg 6622
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total
scale: 0.1
scan_interval: 600
- name: Yearly Export (2023)
unique_id: sg_yearly_export_2023
device_address: !secret sungrow_modbus_slave
address: 6623 # reg 6624
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total
scale: 0.1
scan_interval: 600
- name: Yearly Export (2024)
unique_id: sg_yearly_export_2024
device_address: !secret sungrow_modbus_slave
address: 6625 # reg 6626
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total
scale: 0.1
scan_interval: 600
- name: Yearly Export (2025)
unique_id: sg_yearly_export_2025
device_address: !secret sungrow_modbus_slave
address: 6627 # reg 6628
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total
scale: 0.1
scan_interval: 600
- name: Yearly Export (2026)
unique_id: sg_yearly_export_2026
device_address: !secret sungrow_modbus_slave
address: 6629 # reg 6630
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total
scale: 0.1
scan_interval: 600
- name: Yearly Export (2027)
unique_id: sg_yearly_export_2027
device_address: !secret sungrow_modbus_slave
address: 6631 # reg 6632
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total
scale: 0.1
scan_interval: 600
- name: Yearly Export (2028)
unique_id: sg_yearly_export_2028
device_address: !secret sungrow_modbus_slave
address: 6633 # reg 6634
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total
scale: 0.1
scan_interval: 600
# End yearly export energy from PV
- name: System state
unique_id: sg_system_state
device_address: !secret sungrow_modbus_slave
address: 12999 # reg 13000
input_type: input
data_type: uint16
precision: 0
scale: 1
state_class: measurement
scan_interval: 10
# register running state is not available for certain SH*RS inverters
# template sensors are used to determine the states based on other sensors
- name: Running state
unique_id: sg_running_state
device_address: !secret sungrow_modbus_slave
address: 13000 # reg 13001
input_type: input
data_type: uint16
precision: 0
state_class: measurement
scale: 1
scan_interval: 10
- name: Daily PV generation
unique_id: sg_daily_pv_generation
device_address: !secret sungrow_modbus_slave
address: 13001 # reg 13002
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Total PV generation
unique_id: sg_total_pv_generation
device_address: !secret sungrow_modbus_slave
address: 13002 # reg 13003
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total
scale: 0.1
scan_interval: 600
- name: Daily exported energy from PV
unique_id: sg_daily_exported_energy_from_PV
device_address: !secret sungrow_modbus_slave
address: 13004 # reg 13005
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Total exported energy from PV
unique_id: sg_total_exported_energy_from_pv
device_address: !secret sungrow_modbus_slave
address: 13005 # reg 13006
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total
scale: 0.1
scan_interval: 600
- name: Load power
unique_id: sg_load_power
device_address: !secret sungrow_modbus_slave
address: 13007 # reg 13008
input_type: input
data_type: int32
swap: word
precision: 0
unit_of_measurement: W
device_class: power
state_class: measurement
scale: 1
scan_interval: 10
# this value returns a positive value when exporting and a negative value when importing power
- name: Export power raw
unique_id: sg_battery_export_power_raw
device_address: !secret sungrow_modbus_slave
address: 13009 # reg 13010
input_type: input
data_type: int32
swap: word
precision: 0
unit_of_measurement: W
device_class: power
state_class: measurement
scale: 1
scan_interval: 10
- name: Daily battery charge from PV
unique_id: sg_daily_battery_charge_from_pv
device_address: !secret sungrow_modbus_slave
address: 13011 # reg 13012
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Total battery charge from PV
unique_id: sg_total_battery_charge_from_pv
device_address: !secret sungrow_modbus_slave
address: 13012 # reg 13013
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total
scale: 0.1
scan_interval: 600
- name: Daily direct energy consumption
unique_id: sg_daily_direct_energy_consumption
device_address: !secret sungrow_modbus_slave
address: 13016 # reg 13017
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Total direct energy consumption
unique_id: sg_total_direct_energy_consumption
device_address: !secret sungrow_modbus_slave
address: 13017 # reg 13018
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total
scale: 0.1
scan_interval: 600
- name: Battery voltage
unique_id: sg_battery_voltage
device_address: !secret sungrow_modbus_slave
address: 13019 # reg 13020
input_type: input
data_type: uint16
precision: 0
unit_of_measurement: V
device_class: Voltage
state_class: measurement
scale: 0.1
scan_interval: 10
# note: datasheet states that this value is unsigned, but it is acually signed:
# https://github.com/mkaiser/Sungrow-SHx-Inverter-Modbus-Home-Assistant/issues/304
- name: Battery current
unique_id: sg_battery_current
device_address: !secret sungrow_modbus_slave
address: 13020 # reg 13021
input_type: input
data_type: int16
precision: 1
unit_of_measurement: A
state_class: measurement
device_class: Current
scale: 0.1
scan_interval: 10
# always positive battery power
# use binary_sensor.battery_charging | discharging to retrieve the direction of the energy flow
- name: Battery power raw
unique_id: sg_battery_power_raw
device_address: !secret sungrow_modbus_slave
address: 13021 # reg 13022
input_type: input
data_type: uint16
precision: 0
unit_of_measurement: W
device_class: power
state_class: measurement
scale: 1
scan_interval: 10
- name: Battery level
unique_id: sg_battery_level
device_address: !secret sungrow_modbus_slave
address: 13022 # reg 13023
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: "%"
device_class: battery
state_class: measurement
scale: 0.1
scan_interval: 60
- name: Battery state of health
unique_id: sg_battery_state_of_health
device_address: !secret sungrow_modbus_slave
address: 13023 # reg 13024
input_type: input
data_type: uint16
precision: 0
unit_of_measurement: "%"
state_class: measurement
scale: 0.1
scan_interval: 600
- name: Battery temperature
unique_id: sg_battery_temperature
device_address: !secret sungrow_modbus_slave
address: 13024 # reg 13025
input_type: input
data_type: int16
precision: 1
unit_of_measurement: °C
device_class: Temperature
state_class: measurement
scale: 0.1
scan_interval: 60
- name: Daily battery discharge
unique_id: sg_daily_battery_discharge
device_address: !secret sungrow_modbus_slave
address: 13025 # reg 13026
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Total battery discharge
unique_id: sg_total_battery_discharge
device_address: !secret sungrow_modbus_slave
address: 13026 # reg 13027
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total
scale: 0.1
scan_interval: 600
- name: Phase A current
unique_id: sg_phase_a_current
device_address: !secret sungrow_modbus_slave
address: 13030 # reg 13031
input_type: input
data_type: int16
precision: 1
unit_of_measurement: A
device_class: current
state_class: measurement
scale: 0.1
scan_interval: 10
- name: Phase B current
unique_id: sg_phase_b_current
device_address: !secret sungrow_modbus_slave
address: 13031 # reg 13032
input_type: input
data_type: int16
precision: 1
unit_of_measurement: A
device_class: current
state_class: measurement
scale: 0.1
scan_interval: 10
- name: Phase C current
unique_id: sg_phase_c_current
device_address: !secret sungrow_modbus_slave
address: 13032 # reg 13033
input_type: input
data_type: int16
precision: 1
unit_of_measurement: A
device_class: current
state_class: measurement
scale: 0.1
scan_interval: 10
- name: Total active power
unique_id: sg_total_active_power
device_address: !secret sungrow_modbus_slave
address: 13033 # reg 13034
input_type: input
data_type: int32
swap: word
precision: 0
unit_of_measurement: W
device_class: power
state_class: measurement
scale: 1
scan_interval: 10
- name: Daily imported energy
unique_id: sg_daily_imported_energy
device_address: !secret sungrow_modbus_slave
address: 13035 # reg 13036
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Total imported energy
unique_id: sg_total_imported_energy
device_address: !secret sungrow_modbus_slave
address: 13036 # reg 13037
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total
scale: 0.1
scan_interval: 600
- name: Daily battery charge
unique_id: sg_daily_battery_charge
device_address: !secret sungrow_modbus_slave
address: 13039 # reg 13040
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Total battery charge
unique_id: sg_total_battery_charge
device_address: !secret sungrow_modbus_slave
address: 13040 # reg 13041
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total
scale: 0.1
scan_interval: 600
- name: Daily exported energy
unique_id: sg_daily_exported_energy
device_address: !secret sungrow_modbus_slave
address: 13044 # reg 13045
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: Total exported energy
unique_id: sg_total_exported_energy
device_address: !secret sungrow_modbus_slave
address: 13045 # reg 13046
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total
scale: 0.1
scan_interval: 600
#####################
# holding registers
#####################
- name: Inverter start stop
unique_id: sg_inverter_start_stop
device_address: !secret sungrow_modbus_slave
address: 12999 # reg 13000
input_type: holding
data_type: uint16
precision: 0
state_class: measurement
scan_interval: 10
- name: EMS mode selection raw
unique_id: sg_ems_mode_selection_raw
device_address: !secret sungrow_modbus_slave
address: 13049 # reg 13050
input_type: holding
data_type: uint16
state_class: measurement
scan_interval: 10
- name: Battery forced charge discharge cmd raw
unique_id: sg_battery_forced_charge_discharge_cmd_raw
device_address: !secret sungrow_modbus_slave
address: 13050 # reg 13051
input_type: holding
data_type: uint16
precision: 0
state_class: measurement
scan_interval: 10
- name: Battery forced charge discharge power
unique_id: sg_battery_forced_charge_discharge_power
device_address: !secret sungrow_modbus_slave
address: 13051 # reg 13052
input_type: holding
data_type: uint16
precision: 0
# datasheet says:
# 0 to 5000 W for SH*K-*
# 0 to 100 % for SH*.0RT
# for my SH10RT it is set in Watt, not in %
unit_of_measurement: W
device_class: power
state_class: measurement
scan_interval: 10
- name: Max SoC
unique_id: sg_max_soc
device_address: !secret sungrow_modbus_slave
address: 13057 # reg 13058
input_type: holding
data_type: uint16
precision: 1
unit_of_measurement: "%"
device_class: battery
state_class: measurement
scale: 0.1
scan_interval: 10
- name: Min SoC
unique_id: sg_min_soc
device_address: !secret sungrow_modbus_slave
address: 13058 # reg 13059
input_type: holding
data_type: uint16
precision: 1
unit_of_measurement: "%"
device_class: battery
state_class: measurement
scale: 0.1
scan_interval: 10
- name: Export power limit
unique_id: sg_export_power_limit
device_address: !secret sungrow_modbus_slave
address: 13073 # reg 13074
input_type: holding
data_type: uint16
precision: 0
unit_of_measurement: "W"
device_class: power
state_class: measurement
scale: 1
scan_interval: 10
- name: Export power limit mode raw
unique_id: sg_export_power_limit_mode_raw
device_address: !secret sungrow_modbus_slave
address: 13086 # reg 13087
input_type: holding
data_type: uint16
precision: 0
state_class: measurement
scan_interval: 10
#undocumented sensor (reverse engineered by some guys of photovoltaikforum.com and forum.iobroker.net )
- name: Reserved SoC for backup
unique_id: sg_reserved_soc_for_backup
device_address: !secret sungrow_modbus_slave
address: 13099 # reg 13100
input_type: holding
data_type: uint16
unit_of_measurement: "%"
device_class: battery
state_class: measurement
scale: 1
scan_interval: 10
- name: Battery max charge power
unique_id: sg_battery_max_charge_power
device_address: !secret sungrow_modbus_slave
address: 33046 # reg 33047
input_type: holding
data_type: uint16
precision: 0
unit_of_measurement: W
device_class: power
state_class: measurement
scale: 10
scan_interval: 10
- name: Battery max discharge power
unique_id: sg_battery_max_discharge_power
device_address: !secret sungrow_modbus_slave
address: 33047 # reg 33048
input_type: holding
data_type: uint16
precision: 0
unit_of_measurement: W
device_class: power
state_class: measurement
scale: 10
scan_interval: 10
# was reg 33048 before as an undocumented sensor (reverse engineered by some guys of photovoltaikforum.com and forum.iobroker.net )
# but now it is in sungrow's datasheet
- name: Battery capacity
unique_id: sg_battery_capacity
device_address: !secret sungrow_modbus_slave
address: 13038 # reg 13039
input_type: holding
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy_storage
scale: 0.01
scan_interval: 600
#undocumented sensor (reverse engineered by some guys of photovoltaikforum.com and forum.iobroker.net )
- name: Battery charging start power
unique_id: sg_battery_charging_start_power
device_address: !secret sungrow_modbus_slave
address: 33148 # reg 33149
input_type: holding
data_type: uint16
precision: 0
unit_of_measurement: W
device_class: power
state_class: measurement
scale: 10
scan_interval: 10
#undocumented sensor (reverse engineered by some guys of photovoltaikforum.com and forum.iobroker.net )
- name: Battery discharging start power
unique_id: sg_battery_discharging_start_power
device_address: !secret sungrow_modbus_slave
address: 33149 # reg 33150
input_type: holding
data_type: uint16
precision: 0
unit_of_measurement: W
device_class: power
state_class: measurement
scale: 10
scan_interval: 10
- name: Global mpp scan manual raw
unique_id: sg_global_mpp_scan_manual_raw
device_address: !secret sungrow_modbus_slave
address: 30229 # reg 30230
input_type: holding
data_type: uint16
precision: 0
state_class: measurement
scan_interval: 10
sensor:
- platform: filter
name: "Daily consumed energy (filtered)"
entity_id: sensor.daily_consumed_energy
# commented following line, due to: 'device_class' is an invalid option for 'sensor.filter', check: device_class
# device_class: energy
# commented following line, due to: 'state_class' is an invalid option for 'sensor.filter', check: state_class
# state_class: total_increasing
filters:
- filter: time_simple_moving_average
window_size: "00:05"
precision: 2
# 'virtual' template sensors for better readability
template:
- binary_sensor:
- name: PV generating
unique_id: sg_pv_generating
# TODO: test more with these parameters for template binary sensors
# device_class: none / power
# state_class: measurement
availability: >-
{{
not is_state('sensor.running_state', 'unavailable')
and not is_state('sensor.total_dc_power', 'unavailable')
}}
state: >-
{% if states('sensor.running_state')|is_number and states('sensor.running_state')|float > 0 %}
{# use available sensor running_state #}
{{ states('sensor.running_state')|int |bitwise_and(0x1) }}
{% else %}
{# workaround for SH*RS inverters without working running_state #}
{% if states('sensor.total_dc_power')|int > 0 %}
1
{% else %}
0
{% endif %}
{% endif %}
- name: PV generating (delay)
unique_id: sg_pv_generating_delay
# TODO: test more with these parameters for template binary sensors
# device_class: none / power
# state_class: measurement
availability: "{{ not is_state('binary_sensor.pv_generating', 'unavailable') }}"
delay_on:
seconds: 60
state: "{{ states('binary_sensor.pv_generating') }}"
- name: Battery charging
unique_id: sg_battery_charging
# TODO: test more with these parameters for template binary sensors
# device_class: none / power
# state_class: measurement
availability: >-
{{
not is_state('sensor.running_state', 'unavailable')
or
( not is_state('sensor.ems_mode_selection_raw', 'unavailable')
and not is_state('sensor.battery_forced_charge_discharge_cmd_raw', 'unavailable')
and not is_state('sensor.battery_power_raw', 'unavailable')
and not is_state('sensor.total_dc_power', 'unavailable')
and not is_state('sensor.load_power', 'unavailable')
)
}}
state: >-
{% if states('sensor.running_state')|is_number and states('sensor.running_state')|float > 0 %}
{# use available sensor running_state #}
{% if states('sensor.running_state')|int|bitwise_and(0x2) > 0 %}
on
{% else %}
off
{% endif %}
{% else %}
{# workaround for SH*RS inverters without working running_state #}
{% if (states('sensor.ems_mode_selection') ) == "Forced mode" %}
{# EMS forced mode #}
{% if (states('sensor.battery_forced_charge_discharge_cmd') == "Forced charge") %}
{# in mode Forced charge #}
{% if (states('sensor.battery_power_raw')|int > 0 ) %}
{# power flow from/to battery #}
on
{% else %}
{# no power flow from/to battery #}
off
{% endif %}
{% else %}
{# in EMS mode, but not in mode Forced charge #}
off
{% endif %}
{% else %}
{# not in EMS forced mode, assuming self consumption mode #}
{% if states('sensor.total_dc_power')|int > states('sensor.load_power')|int %}
{# more power generated than consumed. assuming battery charging #}
on
{% else %}
off
{% endif %}
{% endif %}
{% endif %}
- name: Battery charging (delay)
unique_id: sg_battery_charging_delay
# TODO: test more with these parameters for template binary sensors
# device_class: none / power
# state_class: measurement
availability: "{{ not is_state('binary_sensor.battery_charging', 'unavailable') }}"
delay_on:
seconds: 60
state: "{{ states('binary_sensor.battery_charging') }}"
- name: Battery discharging
unique_id: sg_battery_discharging
# TODO: test more with these parameters for template binary sensors
# device_class: none / power
# state_class: measurement
availability: >-
{{
not is_state('sensor.running_state', 'unavailable')
or
( not is_state('sensor.ems_mode_selection_raw', 'unavailable')
and not is_state('sensor.battery_forced_charge_discharge_cmd_raw', 'unavailable')
and not is_state('sensor.battery_power_raw', 'unavailable')
and not is_state('sensor.total_dc_power', 'unavailable')
and not is_state('sensor.load_power', 'unavailable')
)
}}
state: >-
{% if states('sensor.running_state')|is_number and states('sensor.running_state')|float > 0 %}
{# use available sensor running_state #}
{% if states('sensor.running_state')|int|bitwise_and(0x4) > 0 %}
on
{% else %}
off
{% endif %}
{% else %}
{# workaround for SH*RS inverters without working running_state #}
{% if (states('sensor.ems_mode_selection') ) == "Forced mode" %}
{# EMS forced mode #}
{% if (states('sensor.battery_forced_charge_discharge_cmd') == "Forced discharge") %}
{# in mode Forced discharge #}
{% if (states('sensor.battery_power_raw')|int > 0 ) %}
{# power flow from/to battery #}
on
{% else %}
{# no power flow from/to battery #}
off
{% endif %}
{% else %}
{# in EMS mode, but not in mode Forced charge #}
off
{% endif %}
{% else %}
{# not in EMS forced mode, assuming self consumption mode #}
{% if ( ( states('sensor.total_dc_power')|int < states('sensor.load_power')|int ) ) and states('sensor.battery_power_raw')|int > 0 %}
{# more power consumed than generated and some battery power --> assuming battery discharging #}
on
{% else %}
off
{% endif %}
{% endif %}
{% endif %}
- name: Battery discharging (delay)
unique_id: sg_battery_discharging_delay
# TODO: test more with these parameters for template binary sensors
# device_class: none / power
# state_class: measurement
availability: "{{ not is_state('binary_sensor.battery_discharging', 'unavailable') }}"
delay_on:
seconds: 60
state: "{{ states('binary_sensor.battery_discharging') }}"
- name: Exporting power
unique_id: sg_exporting_power
# TODO: test more with these parameters for template binary sensors
# device_class: none / power
# state_class: measurement
availability: >-
{{
not is_state('sensor.running_state', 'unavailable')
and not is_state('sensor.export_power_raw', 'unavailable')
}}
state: >-
{% if states('sensor.running_state')|is_number and states('sensor.running_state')|float > 0 %}
{# use available sensor running_state #}
{{ states('sensor.running_state')|int|bitwise_and(0x10) > 0 }}
{% else %}
{# workaround for SH*RS inverters without working running_state #}
{% if states('sensor.export_power_raw')|int > 0 %}
1
{% else %}
0
{% endif %}
{% endif %}
- name: Exporting power (delay)
unique_id: sg_exporting_power_delay
# TODO: test more with these parameters for template binary sensors
# device_class: none / power
# state_class: measurement
availability: "{{ not is_state('binary_sensor.exporting_power', 'unavailable') }}"
delay_on:
seconds: 60
state: "{{ states('binary_sensor.exporting_power') }}"
- name: Importing power
unique_id: sg_importing_power
# TODO: test more with these parameters for template binary sensors
# device_class: none / power
# state_class: measurement
availability: >-
{{
not is_state('sensor.running_state', 'unavailable')
and not is_state('sensor.running_state', 'unavailable')
}}
state: >-
{% if states('sensor.running_state')|is_number and states('sensor.running_state')|float > 0 %}
{# use available sensor running_state #}
{{ states('sensor.running_state')|int|bitwise_and(0x20) > 0 }}
{% else %}
{# workaround for SH*RS inverters without working running_state #}
{% if states('sensor.export_power_raw')|int < 0 %}
1
{% else %}
0
{% endif %}
{% endif %}
- name: Importing power (delay)
unique_id: sg_importing_power_delay
# TODO: test more with these parameters for template binary sensors
# device_class: none / power
# state_class: measurement
availability: "{{ not is_state('binary_sensor.importing_power', 'unavailable') }}"
delay_on:
seconds: 60
state: "{{ states('binary_sensor.importing_power') }}"
- sensor:
- name: MPPT1 power
unique_id: sg_mppt1_power
unit_of_measurement: W
device_class: power
state_class: measurement
availability: >-
{{
not is_state('sensor.mppt1_voltage', 'unavailable')
and not is_state('sensor.mppt1_current', 'unavailable')
}}
state: "{{ (states('sensor.mppt1_voltage') | float * states('sensor.mppt1_current') | float) |int }}"
- name: MPPT2 power
unique_id: sg_mppt2_power
unit_of_measurement: W
device_class: power
state_class: measurement
availability: >-
{{
not is_state('sensor.mppt2_voltage', 'unavailable')
and not is_state('sensor.mppt2_current', 'unavailable' )
}}
state: "{{ (states('sensor.mppt2_voltage') | float * states('sensor.mppt2_current') | float) |int }}"
- name: Phase A power
unique_id: sg_phase_a_power
unit_of_measurement: W
device_class: power
state_class: measurement
availability: >-
{{
not is_state('sensor.phase_a_voltage', 'unavailable')
and not is_state('sensor.phase_a_current', 'unavailable')
}}
state: "{{ (states('sensor.phase_a_voltage') | float * states('sensor.phase_a_current') | float) |int }}"
- name: Phase B power
unique_id: sg_phase_b_power
unit_of_measurement: W
device_class: power
state_class: measurement
availability: >-
{{
not is_state('sensor.phase_b_voltage', 'unavailable')
and not is_state('sensor.phase_b_current', 'unavailable')
}}
state: "{{ (states('sensor.phase_b_voltage') | float * states('sensor.phase_b_current') | float) |int }}"
- name: Phase C power
unique_id: sg_phase_c_power
unit_of_measurement: W
device_class: power
state_class: measurement
availability: >-
{{
not is_state('sensor.phase_c_voltage', 'unavailable')
and not is_state('sensor.phase_c_current', 'unavailable')
}}
state: "{{ (states('sensor.phase_c_voltage') | float * states('sensor.phase_c_current') | float) |int }}"
# template sensor in case the meter is not available (grid is off) and returns 0x7FFFFF
- name: Meter active power
unique_id: sg_meter_active_power
unit_of_measurement: W
device_class: power
state_class: measurement
availability: >-
{{
not is_state('sensor.meter_active_power_raw', 'unavailable')
and states('sensor.meter_active_power_raw')|int != 0x7FFFFFFF
}}
state: "{{ states('sensor.meter_active_power_raw') }}"
# template sensor in case the meter is not available (grid is off) and returns 0x7FFFFF
- name: Meter phase A active power
unique_id: sg_meter_phase_a_active_power
unit_of_measurement: W
device_class: power
state_class: measurement
availability: >-
{{
not is_state('sensor.meter_phase_a_active_power_raw', 'unavailable')
and states('sensor.meter_phase_a_active_power_raw')|int != 0x7FFFFFFF
}}
state: "{{ states('sensor.meter_phase_a_active_power_raw') }}"
# template sensor in case the meter is not available (grid is off) and returns 0x7FFFFF
- name: Meter phase B active power
unique_id: sg_meter_phase_b_active_power
unit_of_measurement: W
device_class: power
state_class: measurement
availability: >-
{{
not is_state('sensor.meter_phase_b_active_power_raw', 'unavailable')
and states('sensor.meter_phase_b_active_power_raw')|int != 0x7FFFFFFF
}}
state: "{{ states('sensor.meter_phase_b_active_power_raw') }}"
# template sensor in case the meter is not available (grid is off) and returns 0x7FFFFF
- name: Meter phase C active power
unique_id: sg_meter_phase_c_active_power
unit_of_measurement: W
device_class: power
state_class: measurement
availability: >-
{{
not is_state('sensor.meter_phase_c_active_power_raw', 'unavailable')
and states('sensor.meter_phase_c_active_power_raw')|int != 0x7FFFFFFF
}}
state: "{{ states('sensor.meter_phase_c_active_power_raw') }}"
- name: Sungrow inverter state
unique_id: sg_inverter_state
device_class: enum
availability: "{{ not is_state('sensor.system_state', 'unavailable') }}"
state: >-
{% if ((states('sensor.system_state') |int) in [0x0000,0x0040]) %}
Running
{% elif ((states('sensor.system_state') |int) == 0x0410) %}
Off-grid Charge
{% elif ((states('sensor.system_state') |int) == 0x0200) %}
Update Failed
{% elif ((states('sensor.system_state') |int) == 0x0400) %}
Maintain mode
{% elif ((states('sensor.system_state') |int) == 0x0800) %}
Forced mode
{% elif ((states('sensor.system_state') |int) == 0x1000) %}
Off-grid mode
{% elif ((states('sensor.system_state') |int) == 0x1111) %}
Un-Initialized
{% elif ((states('sensor.system_state') |int) in [0x0010,0x12000]) %}
Initial Standby
{% elif ((states('sensor.system_state') |int) in [0x1300,0x0002]) %}
Shutdown
{% elif ((states('sensor.system_state') |int) in [0x1400,0x0008] ) %}
Standby
{% elif ((states('sensor.system_state') |int) in [0x1500,0x0004] ) %}
Emergency Stop
{% elif ((states('sensor.system_state') |int) in [0x1600,0x0020]) %}
Startup
{% elif ((states('sensor.system_state') |int) == 0x1700) %}
AFCI self test shutdown
{% elif ((states('sensor.system_state') |int) == 0x1800) %}
Intelligent Station Building Status
{% elif ((states('sensor.system_state') |int) == 0x1900) %}
Safe Mode
{% elif ((states('sensor.system_state') |int) == 0x2000) %}
Open Loop
{% elif ((states('sensor.system_state') |int) == 0x2501) %}
Restarting
{% elif ((states('sensor.system_state') |int) == 0x4000) %}
External EMS mode
{% elif ((states('sensor.system_state') |int) in [0x55000,0x0100]) %}
Fault
{% elif ((states('sensor.system_state') |int) in [0x8000,0x0001]) %}
Stop
{% elif ((states('sensor.system_state') |int) == 0x8100) %}
De-rating Running
{% elif ((states('sensor.system_state') |int) == 0x8200) %}
Dispatch Run
{% elif ((states('sensor.system_state') |int) == 0x9100) %}
Warn Running
{% else %}
Unknown - should not see me! {{ (states('sensor.system_state') |int) }}
{% endif %}
- name: Sungrow device type
unique_id: sg_device_type
availability: "{{ not is_state('sensor.sungrow_device_type_code', 'unavailable') }}"
device_class: enum
state: >-
{% if ((states('sensor.sungrow_device_type_code') |int) == 0x0D06) %}
SH3K6
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0D07) %}
SH4K6
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0D09) %}
SH5K-20
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0D03) %}
SH5K-V13
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0D0A) %}
SH3K6-30
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0D0B) %}
SH4K6-30
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0D0C) %}
SH5K-30
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0D17) %}
SH3.RS
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0D0D) %}
SH3.6RS
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0D18) %}
SH4.0RS
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0D0F) %}
SH5.0RS
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0D10) %}
SH6.0RS
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0D1A) %}
SH8.0RS
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0D1B) %}
SH10RS
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E00) %}
SH5.0RT
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E01) %}
SH6.0RT
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E02) %}
SH8.0RT
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E03) %}
SH10RT
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E10) %}
SH5.0RT-20
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E11) %}
SH6.0RT-20
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E12) %}
SH8.0RT-20
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E13) %}
SH10RT-20
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E0C) %}
SH5.0RT-V112
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E0D) %}
SH6.0RT-V112
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E0E) %}
SH8.0RT-V112
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E0F) %}
SH10RT-V112
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E08) %}
SH5.0RT-V122
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E09) %}
SH6.0RT-V122
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E0A) %}
SH8.0RT-V122
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E0B) %}
SH10RT-V122
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E20) %}
SH5T-V11
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E21) %}
SH6T-V11
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E22) %}
SH8T-V11
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E23) %}
SH10T-V11
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E24) %}
SH12T-V11
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E25) %}
SH15T-V11
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E26) %}
SH20T-V11
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E28) %}
SH25T-V11
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0D0E) %}
SH4.6RS
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E26) %}
SH20T
{% elif ((states('sensor.sungrow_device_type_code') |int) == 0x0E28) %}
SH25T
{% else %}
Unknown device code: {{ '%0x' % (states('sensor.sungrow_device_type_code') |int) }}
{% endif %}
# make the sensor battery_forced_charge_discharge_cmd more human readable
# Inverter States from modbus reference manual
# 0xAA forced charge
# 0xBB forced discharge
# 0xCC Stop (default)
- name: Battery forced charge discharge cmd
unique_id: sg_battery_forced_charge_discharge_cmd
availability: "{{ not is_state('sensor.battery_forced_charge_discharge_cmd_raw', 'unavailable') }}"
# TODO: test state_class with enum
# state_class: measurement
device_class: enum
state: >-
{% if ((states('sensor.battery_forced_charge_discharge_cmd_raw') |int) == 0x00AA) %}
Forced charge
{% elif ((states('sensor.battery_forced_charge_discharge_cmd_raw') |int) == 0x00BB) %}
Forced discharge
{% elif ((states('sensor.battery_forced_charge_discharge_cmd_raw') |int) == 0x00CC) %}
Stop (default)
{% else %}
Unknown - should not see me!
{% endif %}
- name: Export power limit mode
unique_id: sg_export_power_limit_mode
availability: "{{ not is_state('sensor.export_power_limit_mode_raw', 'unavailable') }}"
# TODO: test state_class with enum
# state_class: measurement
device_class: enum
state: >-
{% if ((states('sensor.export_power_limit_mode_raw') |int) == 0x00AA) %}
Enabled
{% elif ((states('sensor.export_power_limit_mode_raw') |int) == 0x0055) %}
Disabled
{% else %}
Unknown - should not see me!
{% endif %}
# make the sensor ems_selection_raw more human readable
- name: EMS mode selection
unique_id: sg_ems_mode_selection
availability: "{{ not is_state('sensor.ems_mode_selection_raw', 'unavailable') }}"
# TODO: test state_class with enum with enum
# state_class: measurement
device_class: enum
state: >-
{% if ((states('sensor.ems_mode_selection_raw') |int) == 0) %}
Self-consumption mode (default)
{% elif ((states('sensor.ems_mode_selection_raw') |int) == 2) %}
Forced mode
{% elif ((states('sensor.ems_mode_selection_raw') |int) == 3) %}
External EMS
{% elif ((states('sensor.ems_mode_selection_raw') |int) == 4) %}
VPP
{% elif ((states('sensor.ems_mode_selection_raw') |int) == 8) %}
MicroGrid
{% else %}
Unknown - should not see me!
{% endif %}
- name: Signed battery power # positive if charging and negative if discharging
unique_id: sg_signed_battery_power
unit_of_measurement: W
device_class: power
state_class: measurement
availability: >-
{{
not is_state('binary_sensor.battery_charging', 'unavailable')
and not is_state('binary_sensor.battery_discharging', 'unavailable')
and not is_state('sensor.battery_power_raw', 'unavailable')
}}
state: >-
{% if is_state('binary_sensor.battery_charging', 'on') %}
{{ (states('sensor.battery_power_raw') | float)}}
{% elif is_state('binary_sensor.battery_discharging', 'on') %}
{{ (states('sensor.battery_power_raw') | float * -1)}}
{% else %}
0
{% endif %}
- name: Battery charging power # positive if charging else zero
unique_id: sg_battery_charging_power
unit_of_measurement: W
device_class: power
state_class: measurement
availability: >-
{{
not is_state('binary_sensor.battery_charging', 'unavailable')
and not is_state('sensor.battery_power_raw', 'unavailable')
}}
state: >-
{% if is_state('binary_sensor.battery_charging', 'on') %}
{{ states('sensor.battery_power_raw') }}
{% else %}
0
{% endif %}
- name: Battery discharging power # positive if discharging else zero
unique_id: sg_battery_discharging_power
unit_of_measurement: W
device_class: power
state_class: measurement
availability: >-
{{
not is_state('binary_sensor.battery_discharging', 'unavailable')
and not is_state('sensor.battery_power_raw', 'unavailable')
}}
state: >-
{% if is_state('binary_sensor.battery_discharging', 'on') %}
{{ states('sensor.battery_power_raw') }}
{% else %}
0
{% endif %}
- name: Import power # power from grid: positive if importing, else zero
unique_id: sg_import_power
unit_of_measurement: W
device_class: power
state_class: measurement
availability: "{{ not is_state('sensor.export_power_raw', 'unavailable') }}"
state: >-
{% if states('sensor.export_power_raw')|int < 0 %}
{{ states('sensor.export_power_raw')|int *-1 }}
{% else %}
0
{% endif %}
- name: Export power # power to grid: positive if exporting, else zero
unique_id: sg_export_power
unit_of_measurement: W
device_class: power
state_class: measurement
availability: "{{states('sensor.export_power_raw')|is_number }}"
state: >-
{% if states('sensor.export_power_raw')|int > 0 %}
{{ states('sensor.export_power_raw') }}
{% else %}
0
{% endif %}
- name: "Monthly PV generation (current)"
unique_id: sg_monthly_pv_generation_current
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
availability: >-
{% set currMonth = 'monthly_pv_generation_' ~ '%0.2d' % now().month ~ '_' ~ now().timestamp() | timestamp_custom('%B') | lower %}
{{ states('sensor.' ~ currMonth)|is_number }}
state: >
{% set currMonth = 'monthly_pv_generation_' ~ '%0.2d' % now().month ~ '_' ~ now().timestamp() | timestamp_custom('%B') | lower %}
{{ states('sensor.' ~ currMonth) }}
- name: "Yearly PV generation (current)"
unique_id: sg_yearly_pv_generation_current
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
availability: >-
{% set currYear = 'yearly_pv_generation_' ~ now().year %}
{{ states('sensor.' ~ currYear)|is_number }}
state: >
{% set currYear = 'yearly_pv_generation_' ~ now().year %}
{{ states('sensor.' ~ currYear) }}
- name: "Monthly export (current)"
unique_id: sg_monthly_export_current
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
availability: >-
{% set currMonth = 'monthly_export_' ~ '%0.2d' % now().month ~ '_' ~ now().timestamp() | timestamp_custom('%B') | lower %}
{{ states('sensor.' ~ currMonth)|is_number }}
state: >
{% set currMonth = 'monthly_export_' ~ '%0.2d' % now().month ~ '_' ~ now().timestamp() | timestamp_custom('%B') | lower %}
{{ states('sensor.' ~ currMonth) }}
- name: "Yearly export (current)"
unique_id: sg_yearly_export_current
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
availability: >-
{% set currYear = 'yearly_export_' ~ now().year %}
{{ states('sensor.' ~ currYear)|is_number }}
state: >
{% set currYear = 'yearly_export_' ~ now().year %}
{{ states('sensor.' ~ currYear) }}
- name: "Battery level (nominal)"
unique_id: sg_battery_level_nom
unit_of_measurement: "%"
device_class: battery
state_class: measurement
availability: >-
{{
not is_state('sensor.battery_level', 'unavailable')
and not is_state('sensor.min_soc', 'unavailable')
and not is_state('sensor.max_soc', 'unavailable')
}}
state: >-
{% set soc_min = states('sensor.min_soc') | float %}
{% set soc_max = states('sensor.max_soc') | float %}
{% set soc_cur = states('sensor.battery_level') | float %}
{{
((soc_min) + ((soc_max - soc_min) * (soc_cur / 100))) | round(1)
}}
- name: "Battery charge (nominal)"
unique_id: sg_battery_charge_nom
unit_of_measurement: kWh
device_class: energy_storage
state_class: measurement
availability: >-
{{
not is_state('sensor.battery_capacity', 'unavailable')
and not is_state('sensor.battery_level_nominal', 'unavailable')
}}
state: >-
{{
( states('sensor.battery_capacity') | float *
states('sensor.battery_level_nominal') | float / 100 )| round(1)
}}
- name: "Battery charge"
unique_id: sg_battery_charge
unit_of_measurement: kWh
device_class: energy_storage
state_class: measurement
availability: >-
{{
not is_state('sensor.battery_capacity', 'unavailable')
and not is_state('sensor.battery_level', 'unavailable')
and not is_state('sensor.min_soc', 'unavailable')
and not is_state('sensor.max_soc', 'unavailable')
}}
state: >-
{{
( states('sensor.battery_capacity')|float
* ( states('sensor.max_soc')|float - states('sensor.min_soc')|float ) /100
* states('sensor.battery_level')|float /100
) |round(2)
}}
- name: Daily consumed energy
unique_id: uid_daily_consumed_energy
unit_of_measurement: kWh
device_class: energy
# the state class is not total_increasing, because sometimes the read value are read at different times,
# resulting in decreasing values.
# "measurement" does not work, because it is incompatible with "energy"
state_class: total
availability: >-
{{
not is_state('sensor.daily_pv_generation', 'unavailable')
and not is_state('sensor.daily_exported_energy', 'unavailable')
and not is_state('sensor.daily_imported_energy', 'unavailable')
and not is_state('sensor.daily_battery_charge', 'unavailable')
and not is_state('sensor.daily_battery_discharge', 'unavailable')
}}
state: >-
{{
(
states('sensor.daily_pv_generation')|float
- states('sensor.daily_exported_energy')|float
+ states('sensor.daily_imported_energy')|float
- states('sensor.daily_battery_charge')|float
+ states('sensor.daily_battery_discharge')|float
)
}}
- name: Total consumed energy
unique_id: uid_total_consumed_energy
unit_of_measurement: kWh
device_class: energy
state_class: total
availability: >-
{{
not is_state('sensor.total_pv_generation', 'unavailable')
and not is_state('sensor.total_exported_energy', 'unavailable')
and not is_state('sensor.total_imported_energy', 'unavailable')
and not is_state('sensor.total_battery_charge', 'unavailable')
and not is_state('sensor.total_battery_discharge', 'unavailable')
}}
state: >-
{{
(
states('sensor.total_pv_generation')|float
- states('sensor.total_exported_energy')|float
+ states('sensor.total_imported_energy')|float
- states('sensor.total_battery_charge')|float
+ states('sensor.total_battery_discharge')|float
)
}}
# getting input for Min and Max SoC
input_number:
set_sg_min_soc:
name: Set min SoC
min: 0
max: 50
step: 1
set_sg_max_soc:
name: Set max SoC
min: 50
max: 100
step: 1
set_sg_reserved_soc_for_backup:
name: Set reserved SoC for backup
min: 0
max: 100
step: 1
set_sg_forced_charge_discharge_power:
name: Set forced charge discharge power in W
min: 0
max: 10240 # change this value according to the capability of your battery
step: 100
set_sg_battery_max_charge_power:
name: Set max battery charge power in W
min: 100
max: 10240 # change this value according to the capability of your battery
step: 100
set_sg_battery_max_discharge_power:
name: Set max battery discharge power in W
min: 100
max: 10240 # change this value according to the capability of your battery
step: 100
# This threshold is compared against the currently achievable charging power, not just against the currently available surplus.
# If this is set higher than the maximum charging power of the battery, charging will not start.
# If currently achievable charging power drops below this threshold, charging will stop. Actual charging power (limited by register 33047) is ignored.
# Charging might stop before reaching 100% if set too close to the maximum charging power of the battery, due to achievable charging power naturally dropping at high state of charge.
set_sg_battery_charging_start_power:
name: Set battery charging start power in W
min: 0
max: 1000
step: 10
set_sg_battery_discharging_start_power:
name: Set battery discharging start power in W
min: 0
max: 1000
step: 10
set_sg_export_power_limit:
name: Set export power limit
min: 0
max: 10500 # Note: max for SH10.RT. It would be ncie to have this as a global variable /secret
step: 100
input_select:
set_sg_inverter_run_mode:
name: Inverter mode
options:
- "Enabled"
- "Shutdown"
# get input for battery mode (forced charge/discharge, stop (default) )
set_sg_ems_mode:
name: EMS mode
options:
- "Self-consumption mode (default)"
- "Forced mode"
- "External EMS" # required for multiple inverters main /follower?
# these are commented, because they are rarely used
# - "VPP"
# - "MicroGrid"
icon: mdi:battery-unknown
set_sg_battery_forced_charge_discharge_cmd:
name: Battery forced charge discharge cmd
options:
- "Stop (default)"
- "Forced charge"
- "Forced discharge"
icon: mdi:battery-unknown
set_sg_export_power_limit_mode:
name: Export power limit mode
options:
- "Enabled"
- "Disabled"
icon: mdi:export
set_sg_global_mpp_scan_manual:
name: Global mpp scan manual
options:
- "Enabled"
- "Disabled"
icon: mdi:export
# Automations: Write modbus registers on input changes via GUI
# note: If you change a value by the sliders, it will take up to 60 seconds until the state variables are updated
# Unfortunately, I could not find a way to "force update" modbus registers, yet...
automation:
- id: "automation_sungrow_inverter_state"
alias: "sungrow inverter state"
description: "Enables/ stops the inverter"
trigger:
- platform: state
entity_id:
- input_select.set_sg_inverter_run_mode
condition: []
variables:
sg_start: 0xCF
sg_stop: 0xCE
action:
- action: modbus.write_register
data_template:
hub: SungrowSHx
slave: !secret sungrow_modbus_slave
address: 12999 # reg 13000
value: >
{% if is_state('input_select.set_sg_inverter_run_mode', "Enabled") %}
{{sg_start}}
{% else %}
{{sg_stop}}
{% endif %}
mode: single
- id: "automation_sungrow_inverter_state_input_selector_update"
alias: "sungrow inverter enable/ stop input selector update"
description: "Updates enable/ stops input selector"
trigger:
- platform: state
entity_id:
- sensor.sungrow_inverter_state
condition:
- condition: template
value_template: "{{ not is_state('sensor.sungrow_inverter_state', 'unavailable') }}"
action:
- action: input_select.select_option
target:
entity_id: input_select.set_sg_inverter_run_mode
data:
option: >
{% if is_state('sensor.sungrow_inverter_state', "Stop") or is_state('sensor.sungrow_inverter_state', "Shutdown") %}
Shutdown
{% else %}
Enabled
{% endif %}
mode: single
- id: "automation_sungrow_inverter_update_max_soc"
alias: "sungrow inverter update max SoC"
description: "Updates Sungrow max Soc holding register"
trigger:
- platform: state
entity_id:
- input_number.set_sg_max_soc
condition: []
action:
- action: modbus.write_register
data_template:
hub: SungrowSHx
slave: !secret sungrow_modbus_slave
address: 13057 # reg 13058
value: "{{ states('input_number.set_sg_max_soc') | int *10}}"
mode: single
- id: "automation_sungrow_inverter_update_max_soc_input_slider_update"
alias: "sungrow inverter max SoC input slider update"
description: "Updates Sungrow max Soc input slider"
trigger:
- platform: state
entity_id:
- sensor.max_soc
condition: []
action:
- action: input_number.set_value
target:
entity_id: input_number.set_sg_max_soc
data:
value: "{{ states('sensor.max_soc') }}"
mode: single
- id: "automation_sungrow_inverter_update_min_soc"
alias: "sungrow inverter update min SoC"
description: "Updates Sungrow min Soc holding register"
trigger:
- platform: state
entity_id:
- input_number.set_sg_min_soc
condition: []
action:
- action: modbus.write_register
data_template:
hub: SungrowSHx
slave: !secret sungrow_modbus_slave
address: 13058 # reg 13059
value: "{{ states('input_number.set_sg_min_soc') | int *10}}"
mode: single
- id: "automation_sungrow_inverter_update_min_soc_input_slider_update"
alias: "sungrow inverter min SoC input slider update"
description: "Updates Sungrow min Soc input slider"
trigger:
- platform: state
entity_id:
- sensor.min_soc
condition: []
action:
- action: input_number.set_value
target:
entity_id: input_number.set_sg_min_soc
data:
value: "{{ states('sensor.min_soc') }}"
mode: single
- id: "automation_sungrow_inverter_update_reserved_soc_for_backup"
alias: "sungrow inverter update reserved soc for backup"
description: "Updates reserved SoC for backup register"
trigger:
- platform: state
entity_id:
- input_number.set_sg_reserved_soc_for_backup
condition: []
action:
- action: modbus.write_register
data_template:
hub: SungrowSHx
slave: !secret sungrow_modbus_slave
address: 13099 # reg 13100
value: "{{ states('input_number.set_sg_reserved_soc_for_backup') | int}}"
mode: single
- id: "automation_sungrow_inverter_update_reserved_backup_soc_input_slider_update"
alias: "sungrow inverter reserved backup SoC input slider update"
description: "Updates Sungrow reserved backup Soc input slider"
trigger:
- platform: state
entity_id:
- sensor.reserved_soc_for_backup
condition: []
action:
- action: input_number.set_value
target:
entity_id: input_number.set_sg_reserved_soc_for_backup
data:
value: "{{ states('sensor.reserved_soc_for_backup') }}"
mode: single
- id: "automation_sungrow_inverter_update_battery_forced_charge_discharge_cmd"
alias: "sungrow inverter update battery forced charge discharge cmd"
description: "Updates Sungrow holding register for battery forced charge discharge command"
trigger:
- platform: state
entity_id:
- input_select.set_sg_battery_forced_charge_discharge_cmd
condition: []
variables:
ems_forced_charge: 0xAA
ems_forced_discharge: 0xBB
ems_stop_default: 0xCC
action:
- action: modbus.write_register
data_template:
hub: SungrowSHx
slave: !secret sungrow_modbus_slave
address: 13050 # reg 13051
value: >
{% if is_state('input_select.set_sg_battery_forced_charge_discharge_cmd', "Stop (default)") %}
{{ems_stop_default}}
{% elif is_state('input_select.set_sg_battery_forced_charge_discharge_cmd', "Forced charge") %}
{{ems_forced_charge}}
{% elif is_state('input_select.set_sg_battery_forced_charge_discharge_cmd', "Forced discharge") %}
{{ems_forced_discharge}}
{% else %}
{{ems_stop_default}}
{% endif %}
mode: single
- id: "automation_sungrow_inverter_update_battery_forced_charge_discharge_cmd_input_select_update"
alias: "sungrow inverter update battery forced charge discharge cmd input select update"
description: "Updates Sungrow battery forced charge discharge cmd input select"
trigger:
- platform: state
entity_id:
- sensor.battery_forced_charge_discharge_cmd
condition:
- condition: template
value_template: "{{ not is_state('sensor.battery_forced_charge_discharge_cmd', 'unavailable') }}"
action:
- action: input_select.select_option
target:
entity_id: input_select.set_sg_battery_forced_charge_discharge_cmd
data:
option: "{{ states('sensor.battery_forced_charge_discharge_cmd') }}"
mode: single
- id: "automation_sungrow_inverter_update_ems_mode"
alias: "sungrow inverter update EMS mode"
description: "Updates EMS mode"
trigger:
- platform: state
entity_id:
- input_select.set_sg_ems_mode
condition: []
variables:
ems_mode_self_consume: 0
ems_mode_forced: 2
ems_mode_external: 3
ems_mode_vpp: 4
ems_mode_microgrid: 8
action:
- action: modbus.write_register
data_template:
hub: SungrowSHx
slave: !secret sungrow_modbus_slave
address: 13049 # reg 13050
value: >
{% if is_state('input_select.set_sg_ems_mode', "Self-consumption mode (default)") %}
{{ems_mode_self_consume}}
{% elif is_state('input_select.set_sg_ems_mode', "Forced mode") %}
{{ems_mode_forced}}
{% elif is_state('input_select.set_sg_ems_mode', "External EMS") %}
{{ems_mode_external}}
{% elif is_state('input_select.set_sg_ems_mode', "VPP") %}
{{ems_mode_vpp}}
{% elif is_state('input_select.set_sg_ems_mode', "MicroGrid") %}
{{ems_mode_microgrid}}
{% else %}
{{ems_mode_self_consume}}
{% endif %}
mode: single
- id: "automation_sungrow_inverter_export_power_limit_mode_update"
alias: "sungrow inverter export power limit mode update"
description: "Updates Enable/Disable for export power limit mode"
trigger:
- platform: state
entity_id:
- sensor.export_power_limit_mode_raw
condition:
- condition: template
value_template: "{{ not is_state('sensor.export_power_limit_mode_raw', 'unavailable') }}"
action:
- action: input_select.select_option
target:
entity_id: input_select.set_sg_export_power_limit_mode
data:
option: >
{% if ((states('sensor.export_power_limit_mode_raw') |int) == 0x00AA) %}
Enabled
{% elif ((states('sensor.export_power_limit_mode_raw') |int) == 0x0055) %}
Disabled
{% endif %}
mode: single
- id: "automation_sungrow_export_power_limit_mode"
alias: "sungrow inverter export power limit mode"
description: "Set export power limit mode"
trigger:
- platform: state
entity_id:
- input_select.set_sg_export_power_limit_mode
condition: []
variables:
export_limit_enable: 0xAA
export_limit_disable: 0x55
action:
- action: modbus.write_register
data_template:
hub: SungrowSHx
slave: !secret sungrow_modbus_slave
address: 13086 # reg 13087
value: >
{% if is_state('input_select.set_sg_export_power_limit_mode', "Enabled") %}
{{export_limit_enable}}
{% elif is_state('input_select.set_sg_export_power_limit_mode', "Disabled") %}
{{export_limit_disable}}
{% else %}
{{export_limit_disable}}
{% endif %}
mode: single
- id: "automation_sungrow_inverter_export_power_limit_update"
alias: "sungrow inverter export power limit update"
description: "Updates export power limit slider"
trigger:
- platform: state
entity_id:
- sensor.export_power_limit
condition: []
action:
- action: input_number.set_value
target:
entity_id: input_number.set_sg_export_power_limit
data:
value: "{{ states('sensor.export_power_limit') }}"
mode: single
- id: "automation_sungrow_inverter_set_export_power_limit"
alias: "sungrow inverter export power limit"
description: "Sets export power limit"
trigger:
- platform: state
entity_id:
- input_number.set_sg_export_power_limit
condition: []
action:
- action: modbus.write_register
data_template:
hub: SungrowSHx
slave: !secret sungrow_modbus_slave
address: 13073 # reg 13074
value: "{{ states('input_number.set_sg_export_power_limit') }}"
mode: single
- id: "automation_sungrow_inverter_update_ems_mode_input_select_update"
alias: "sungrow inverter update EMS mode input select update"
description: "Updates EMS mode input select"
trigger:
- platform: state
entity_id:
- sensor.ems_mode_selection
condition:
- condition: template
value_template: "{{ not is_state('sensor.ems_mode_selection', 'unavailable') }}"
action:
- action: input_select.select_option
target:
entity_id: input_select.set_sg_ems_mode
data:
option: "{{ states('sensor.ems_mode_selection') }}"
mode: single
- id: "automation_sungrow_inverter_update_battery_forced_charge_discharge_power"
alias: "sungrow inverter update battery forced charge discharge power"
description: "Sets battery forced charge discharge power"
trigger:
- platform: state
entity_id:
- input_number.set_sg_forced_charge_discharge_power
condition: []
action:
- action: modbus.write_register
data_template:
hub: SungrowSHx
slave: !secret sungrow_modbus_slave
address: 13051 # reg 13052
value: "{{ states('input_number.set_sg_forced_charge_discharge_power') | int}}"
mode: single
- id: "automation_sungrow_inverter_update_battery_forced_charge_discharge_power_input_slider_update"
alias: "sungrow inverter update battery forced charge discharge power input slider update"
description: "Updates battery forced charge discharge power input slider"
trigger:
- platform: state
entity_id:
- sensor.battery_forced_charge_discharge_power
condition: []
action:
- action: input_number.set_value
target:
entity_id: input_number.set_sg_forced_charge_discharge_power
data:
value: "{{ states('sensor.battery_forced_charge_discharge_power') }}"
mode: single
- id: "automation_sungrow_inverter_update_battery_max_charge_power"
alias: "sungrow inverter update battery max charge power"
description: "Sets battery max charge power"
trigger:
- platform: state
entity_id:
- input_number.set_sg_battery_max_charge_power
condition: []
action:
- action: modbus.write_register
data_template:
hub: SungrowSHx
slave: !secret sungrow_modbus_slave
address: 33046 # reg 33047
value: "{{ states('input_number.set_sg_battery_max_charge_power') |float /10 |int}}"
mode: single
- id: "automation_sungrow_inverter_update_battery_max_charge_power_input_slider_update"
alias: "sungrow inverter update battery max charge power input slider update"
description: "Updates battery max charge power input slider"
trigger:
- platform: state
entity_id:
- sensor.battery_max_charge_power
condition: []
action:
- action: input_number.set_value
target:
entity_id: input_number.set_sg_battery_max_charge_power
data:
value: "{{ states('sensor.battery_max_charge_power') }}"
mode: single
- id: "automation_sungrow_inverter_update_battery_max_discharge_power"
alias: "sungrow inverter update battery max discharge power"
description: "Sets battery max discharge power"
trigger:
- platform: state
entity_id:
- input_number.set_sg_battery_max_discharge_power
condition: []
action:
- action: modbus.write_register
data_template:
hub: SungrowSHx
slave: !secret sungrow_modbus_slave
address: 33047 # reg 33048
value: "{{ states('input_number.set_sg_battery_max_discharge_power') |float /10 |int}}"
mode: single
- id: "automation_sungrow_inverter_update_battery_max_discharge_power_input_slider_update"
alias: "sungrow inverter update battery max discharge power input slider update"
description: "Updates battery max discharge power input slider"
trigger:
- platform: state
entity_id:
- sensor.battery_max_discharge_power
condition: []
action:
- action: input_number.set_value
target:
entity_id: input_number.set_sg_battery_max_discharge_power
data:
value: "{{ states('sensor.battery_max_discharge_power') }}"
mode: single
- id: "automation_sungrow_inverter_update_battery_charging_start_power"
alias: "sungrow inverter update battery charging start power"
description: "Sets battery charging start power"
trigger:
- platform: state
entity_id:
- input_number.set_sg_battery_charging_start_power
condition: []
action:
- action: modbus.write_register
data_template:
hub: SungrowSHx
slave: !secret sungrow_modbus_slave
address: 33148 # reg 33149
value: "{{ states('input_number.set_sg_battery_charging_start_power') |float /10 |int}}"
mode: single
- id: "automation_sungrow_inverter_update_battery_charging_start_power_input_slider_update"
alias: "sungrow inverter update battery charging start power input slider update"
description: "Updates battery charging start power input slider"
trigger:
- platform: state
entity_id:
- sensor.battery_charging_start_power
condition: []
action:
- action: input_number.set_value
target:
entity_id: input_number.set_sg_battery_charging_start_power
data:
value: "{{ states('sensor.battery_charging_start_power') }}"
mode: single
- id: "automation_sungrow_inverter_update_battery_discharging_start_power"
alias: "sungrow inverter update battery discharging start power"
description: "Sets battery discharging start power"
trigger:
- platform: state
entity_id:
- input_number.set_sg_battery_discharging_start_power
condition: []
action:
- action: modbus.write_register
data_template:
hub: SungrowSHx
slave: !secret sungrow_modbus_slave
address: 33149 # reg 33150
value: "{{ states('input_number.set_sg_battery_discharging_start_power') |float /10 | int}}"
mode: single
- id: "automation_sungrow_inverter_update_battery_discharging_start_power_input_slider_update"
alias: "sungrow inverter update battery discharging start power input slider update"
description: "Updates battery discharging start power input slider"
trigger:
- platform: state
entity_id:
- sensor.battery_discharging_start_power
condition: []
action:
- action: input_number.set_value
target:
entity_id: input_number.set_sg_battery_discharging_start_power
data:
value: "{{ states('sensor.battery_discharging_start_power') }}"
mode: single
- id: "automation_sungrow_inverter_global_mpp_scan_manual_update"
alias: "sungrow inverter global mpp scan manual update"
description: "Updates Enable/Disable for global mpp scan manual"
trigger:
- platform: state
entity_id:
- sensor.global_mpp_scan_manual_raw
condition:
- condition: template
value_template: "{{ not is_state('sensor.global_mpp_scan_manual_raw', 'unavailable') }}"
action:
- action: input_select.select_option
target:
entity_id: input_select.set_sg_global_mpp_scan_manual
data:
option: >
{% if ((states('sensor.global_mpp_scan_manual_raw') | int(default=0)) == 0x00AA) %}
Enabled
{% elif ((states('sensor.global_mpp_scan_manual_raw') | int(default=0)) == 0x0055) %}
Disabled
{% endif %}
mode: single
- id: "automation_sungrow_global_mpp_scan_manual"
alias: "sungrow inverter global mpp scan manual"
description: "Set global mpp scan manual"
trigger:
- platform: state
entity_id:
- input_select.set_sg_global_mpp_scan_manual
condition: []
variables:
export_limit_enable: 0xAA
export_limit_disable: 0x55
action:
- action: modbus.write_register
data_template:
hub: SungrowSHx
slave: !secret sungrow_modbus_slave
address: 30229 # reg 30230
value: >
{% if is_state('input_select.set_sg_global_mpp_scan_manual', "Enabled") %}
{{export_limit_enable}}
{% elif is_state('input_select.set_sg_global_mpp_scan_manual', "Disabled") %}
{{export_limit_disable}}
{% else %}
{{export_limit_disable}}
{% endif %}
mode: single
# Usage: Use these scripts to simplify automations
# Example (Adjust to your needs with appropriate trigger):
- id: force_charging_during_cheapest_hours
alias: Forced Battery Charging Management
description: "Manages forced battery charging during cheapest hours."
trigger:
- platform: state
entity_id:
- binary_sensor.cheapest_hours_for_charging_timer
action:
- choose:
- conditions:
- condition: state
entity_id: binary_sensor.cheapest_hours_for_charging_timer
state: "on"
sequence:
- action: script.sg_forced_charge_battery_mode
- conditions:
- condition: state
entity_id: binary_sensor.cheapest_hours_for_charging_timer
state: "off"
sequence:
- action: script.sg_self_consumption_mode
script:
sg_set_forced_discharge_battery_mode:
sequence:
- action: input_select.select_option
data:
entity_id: input_select.set_sg_ems_mode
option: "Forced mode"
- action: input_select.select_option
data:
entity_id: input_select.set_sg_battery_forced_charge_discharge_cmd
option: "Forced discharge"
# Uncomment notify action lines below for push notifications to mobile devices
# - action: notify.notify
# data:
# title: "Forced Battery Discharge"
# message: "Switched to Forced Battery Discharge mode"
sg_set_forced_charge_battery_mode:
sequence:
- action: input_select.select_option
data:
entity_id: input_select.set_sg_ems_mode
option: "Forced mode"
- action: input_select.select_option
data:
entity_id: input_select.set_sg_battery_forced_charge_discharge_cmd
option: "Forced charge"
sg_set_battery_bypass_mode:
sequence:
- action: input_select.select_option
data:
entity_id: input_select.set_sg_ems_mode
option: "Forced mode"
- action: input_select.select_option
data:
entity_id: input_select.set_sg_battery_forced_charge_discharge_cmd
option: "Stop (default)"
sg_set_self_consumption_mode:
sequence:
- action: input_select.select_option
data:
entity_id: input_select.set_sg_ems_mode
option: "Self-consumption mode (default)"
- action: input_select.select_option
data:
entity_id: input_select.set_sg_battery_forced_charge_discharge_cmd
option: "Stop (default)"