# 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)"