Last active
August 24, 2025 11:42
-
-
Save nickw444/9a048bc5b6d36f00c869458121c19e86 to your computer and use it in GitHub Desktop.
Sungrow SG5.0RS-ADA Home Assistant modbus config
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| modbus: | |
| - name: Sungrow SG5.0RS | |
| type: tcp | |
| host: !secret sungrow_modbus_host_ip | |
| port: !secret sungrow_modbus_port | |
| sensors: | |
| - name: Inverter Device Type Code | |
| unique_id: inverter_device_type_code | |
| device_address: !secret sungrow_modbus_slave | |
| address: 4999 # reg 5000 | |
| input_type: input | |
| data_type: uint16 | |
| scan_interval: 1200 | |
| - name: Inverter Nominal Active Power | |
| unique_id: inverter_nominal_active_power | |
| device_address: !secret sungrow_modbus_slave | |
| address: 5000 # reg 5001 | |
| input_type: input | |
| data_type: uint16 | |
| precision: 1 | |
| unit_of_measurement: kW | |
| device_class: power | |
| state_class: measurement | |
| scale: 0.1 | |
| scan_interval: 1200 | |
| - name: Inverter Work State Code | |
| unique_id: inverter_work_state_code | |
| device_address: !secret sungrow_modbus_slave | |
| address: 5037 # reg 5038 | |
| input_type: input | |
| data_type: uint16 | |
| scan_interval: 60 | |
| - name: Inverter Daily Power Yield (Raw) # << Use this for production tracking (60s precision) | |
| unique_id: inverter_daily_power_yield_raw | |
| 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: 60 | |
| - name: Inverter Total Power Yield | |
| unique_id: inverter_total_power_yield | |
| device_address: !secret sungrow_modbus_slave | |
| address: 5003 # reg 5004-5005 | |
| input_type: input | |
| data_type: uint32 | |
| swap: word | |
| unit_of_measurement: kWh | |
| precision: 1 | |
| device_class: energy | |
| state_class: total_increasing | |
| scale: 1 | |
| scan_interval: 600 | |
| ## Disabled: Gives same as 5004-5005, but with additional precision - risk overflow after large yields. | |
| # - name: Inverter Total Power Yield (85) | |
| # unique_id: inverter_total_power_yield_85 | |
| # device_address: !secret sungrow_modbus_slave | |
| # address: 5143 # reg 5144-5145 | |
| # input_type: input | |
| # data_type: uint32 | |
| # swap: word | |
| # unit_of_measurement: kWh | |
| # precision: 1 | |
| # device_class: energy | |
| # state_class: total_increasing | |
| # scale: 0.1 | |
| # scan_interval: 600 | |
| - name: Inverter temperature | |
| unique_id: inverter_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: 600 | |
| - name: Inverter Total Running Time | |
| unique_id: inverter_total_running_time | |
| device_address: !secret sungrow_modbus_slave | |
| address: 5005 # reg 5006-5007 | |
| input_type: input | |
| data_type: uint32 | |
| swap: word | |
| precision: 0 | |
| unit_of_measurement: h | |
| device_class: duration | |
| state_class: measurement | |
| scale: 1 | |
| scan_interval: 600 | |
| - name: Inverter Daily Running Time | |
| unique_id: inverter_daily_running_time | |
| device_address: !secret sungrow_modbus_slave | |
| address: 5112 # reg 5113 | |
| input_type: input | |
| data_type: uint16 | |
| precision: 0 | |
| unit_of_measurement: min | |
| device_class: duration | |
| state_class: measurement | |
| scan_interval: 600 | |
| ## === MPPTs / DC Power === | |
| - name: Inverter MPPT1 voltage | |
| unique_id: inverter_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: 15 | |
| - name: Inverter MPPT1 current | |
| unique_id: inverter_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: 15 | |
| - name: Inverter MPPT2 voltage | |
| unique_id: inverter_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: 15 | |
| - name: Inverter MPPT2 current | |
| unique_id: inverter_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: 15 | |
| - name: Inverter Total DC power | |
| unique_id: inverter_total_dc_power | |
| device_address: !secret sungrow_modbus_slave | |
| address: 5016 # reg 5017-5018 | |
| input_type: input | |
| data_type: uint32 | |
| swap: word | |
| precision: 0 | |
| unit_of_measurement: W | |
| device_class: power | |
| state_class: measurement | |
| scale: 1 | |
| scan_interval: 5 | |
| ## === End MPPTs / DC Power === | |
| ## === Apparent Power === | |
| - name: Inverter Total Apparent Power | |
| unique_id: inverter_total_apparent_power | |
| device_address: !secret sungrow_modbus_slave | |
| address: 5008 # reg 5009-5010 | |
| input_type: input | |
| data_type: uint32 | |
| swap: word | |
| unit_of_measurement: VA | |
| precision: 0 | |
| device_class: apparent_power | |
| state_class: measurement | |
| scale: 1 | |
| scan_interval: 60 | |
| - name: Inverter Total Active Power | |
| unique_id: inverter_total_active_power | |
| device_address: !secret sungrow_modbus_slave | |
| address: 5030 # reg 5031-5032 | |
| input_type: input | |
| data_type: uint32 | |
| swap: word | |
| unit_of_measurement: W | |
| precision: 0 | |
| device_class: power | |
| state_class: measurement | |
| scale: 1 | |
| scan_interval: 5 | |
| - name: Inverter Total Reactive Power | |
| unique_id: inverter_total_reactive_power | |
| device_address: !secret sungrow_modbus_slave | |
| address: 5032 # reg 5033-5034 | |
| input_type: input | |
| data_type: int32 | |
| swap: word | |
| unit_of_measurement: var | |
| precision: 0 | |
| device_class: reactive_power | |
| state_class: measurement | |
| scale: 1 | |
| scan_interval: 60 | |
| - name: Inverter Power Factor | |
| unique_id: inverter_power_factor | |
| device_address: !secret sungrow_modbus_slave | |
| address: 5034 # reg 5035 | |
| input_type: input | |
| data_type: int16 | |
| unit_of_measurement: "%" | |
| precision: 3 | |
| device_class: power_factor | |
| state_class: measurement | |
| scale: 0.001 | |
| scan_interval: 60 | |
| ## Disabled: Same as 5148 - but 5148 has additional precision. | |
| # - name: Inverter Grid frequency | |
| # unique_id: inverter_grid_frequency | |
| # device_address: !secret sungrow_modbus_slave | |
| # address: 5035 # reg 5036 | |
| # input_type: input | |
| # data_type: uint16 | |
| # unit_of_measurement: "Hz" | |
| # precision: 2 | |
| # device_class: frequency | |
| # state_class: measurement | |
| # scale: 0.1 | |
| # scan_interval: 600 | |
| - name: Inverter Grid frequency | |
| unique_id: inverter_grid_frequency | |
| device_address: !secret sungrow_modbus_slave | |
| address: 5147 # reg 5148 | |
| input_type: input | |
| data_type: uint16 | |
| unit_of_measurement: "Hz" | |
| precision: 2 | |
| device_class: frequency | |
| state_class: measurement | |
| scale: 0.01 | |
| scan_interval: 60 | |
| ## === End Apparent Power === | |
| ## === Consumption Meter === | |
| ## Disabled: Seems to always read at 0 | |
| # - name: Inverter Daily Exported Energy ## Note: Seems to always read at 0 | |
| # unique_id: inverter_daily_exported_energy | |
| # device_address: !secret sungrow_modbus_slave | |
| # address: 5092 # reg 5093-5094 | |
| # 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: Inverter Total Exported Energy Raw | |
| unique_id: inverter_total_exported_energy_raw | |
| device_address: !secret sungrow_modbus_slave | |
| address: 5094 # reg 5095-5096 | |
| 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: 60 | |
| ## Disabled: Seems to always read at 0 | |
| # - name: Inverter Daily Imported Energy | |
| # unique_id: inverter_daily_imported_energy | |
| # device_address: !secret sungrow_modbus_slave | |
| # address: 5096 # reg 5097-5098 | |
| # 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: Inverter Total Imported Energy Raw | |
| unique_id: inverter_total_imported_energy_raw | |
| device_address: !secret sungrow_modbus_slave | |
| address: 5098 # reg 5099-5100 | |
| 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: 60 | |
| ## Disabled: Seems to always read at 0 | |
| # - name: Inverter Daily Direct Consumption Energy ## Note: Seems to always read at 0 | |
| # unique_id: inverter_daily_direct_consumption_energy | |
| # device_address: !secret sungrow_modbus_slave | |
| # address: 5100 # reg 5101-5102 | |
| # 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 | |
| ## Disabled: Seems to always read at 0 | |
| # - name: Inverter Total Direct Consumption Energy ## Note: Seems to always read at 0 | |
| # unique_id: inverter_total_direct_consumption_energy | |
| # device_address: !secret sungrow_modbus_slave | |
| # address: 5102 # reg 5103-5104 | |
| # 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: Inverter Meter Power (Raw) | |
| unique_id: inverter_meter_power_raw | |
| device_address: !secret sungrow_modbus_slave | |
| address: 5082 # reg 5083-5084 | |
| input_type: input | |
| data_type: int32 | |
| swap: word | |
| precision: 0 | |
| unit_of_measurement: W | |
| device_class: power | |
| state_class: measurement | |
| scale: 1 | |
| scan_interval: 5 | |
| ## Disabled: Seems to always read at 0 | |
| # - name: Inverter Load Power | |
| # unique_id: inverter_load_power | |
| # device_address: !secret sungrow_modbus_slave | |
| # address: 5090 # reg 5091-5092 | |
| # input_type: input | |
| # data_type: int32 | |
| # swap: word | |
| # precision: 0 | |
| # unit_of_measurement: W | |
| # device_class: power | |
| # state_class: measurement | |
| # scale: 1 | |
| # scan_interval: 600 | |
| # Disabled: Same as Reg 5083-5084. | |
| # - name: Inverter Meter Power (undocumented) | |
| # unique_id: inverter_meter_power_undocumented_1 | |
| # device_address: !secret sungrow_modbus_slave | |
| # address: 5600 # reg 5601-5602 | |
| # input_type: input | |
| # data_type: int32 | |
| # swap: word | |
| # precision: 0 | |
| # unit_of_measurement: W | |
| # device_class: power | |
| # state_class: measurement | |
| # scale: 1 | |
| # scan_interval: 5 | |
| template: | |
| - sensor: | |
| # Occasionally this sensor will spike, but with no specific pattern (maybe one bit flip?) | |
| # Because of this, we use a mean sensor to check for spikes and report unavailable. | |
| # The sensor reports every 60s. If the house is consuming at the highest rate possible (63A, ~15kW), | |
| # then the 3h mean would be ~22.5kW behind the current reading. | |
| # We use 40 as a buffer based on historical metrics. | |
| - name: Inverter Total Imported Energy | |
| unique_id: inverter_total_imported_energy | |
| unit_of_measurement: kWh | |
| device_class: energy | |
| state_class: total_increasing | |
| availability: >- | |
| {{ | |
| has_value('sensor.inverter_total_imported_energy_raw') | |
| and states('sensor.inverter_total_imported_energy_raw')|int(0) != 0 | |
| and states('sensor.inverter_total_imported_energy_raw')|int(0) < states('sensor.inverter_total_imported_energy_mean_3h')|int(0) + 40 | |
| }} | |
| state: "{{ states('sensor.inverter_total_imported_energy_raw') }}" | |
| - name: Inverter Total Exported Energy | |
| unique_id: inverter_total_exported_energy | |
| unit_of_measurement: kWh | |
| device_class: energy | |
| state_class: total_increasing | |
| availability: >- | |
| {{ | |
| has_value('sensor.inverter_total_exported_energy_raw') | |
| and states('sensor.inverter_total_exported_energy_raw')|int != 0 | |
| }} | |
| state: "{{ states('sensor.inverter_total_exported_energy_raw') }}" | |
| # Occasionally this register reports 512 and other large values, causing | |
| # it to throw the energy dashboard completely off. Omit 512 explicitly, and | |
| # any value greater than the theoretical daily yield (~50kWh) | |
| - name: Inverter Daily Power Yield | |
| unique_id: inverter_daily_power_yield | |
| unit_of_measurement: kWh | |
| device_class: energy | |
| state_class: total_increasing | |
| availability: >- | |
| {{ | |
| has_value('sensor.inverter_daily_power_yield_raw') | |
| and states('sensor.inverter_daily_power_yield_raw')|int != 512 | |
| and states('sensor.inverter_daily_power_yield_raw')|int < 60 | |
| }} | |
| state: "{{ states('sensor.inverter_daily_power_yield_raw') }}" | |
| - name: Inverter MPPT1 Power | |
| unique_id: inverter_mppt1_power | |
| unit_of_measurement: W | |
| device_class: power | |
| state_class: measurement | |
| availability: >- | |
| {{ | |
| has_value('sensor.inverter_mppt1_voltage') | |
| and has_value('sensor.inverter_mppt1_current') | |
| }} | |
| state: "{{ (states('sensor.inverter_mppt1_voltage') | float * states('sensor.inverter_mppt1_current') | float) |int }}" | |
| - name: Inverter MPPT2 Power | |
| unique_id: inverter_mppt2_power | |
| unit_of_measurement: W | |
| device_class: power | |
| state_class: measurement | |
| availability: >- | |
| {{ | |
| has_value('sensor.inverter_mppt2_voltage') | |
| and has_value('sensor.inverter_mppt2_current') | |
| }} | |
| state: "{{ (states('sensor.inverter_mppt2_voltage') | float * states('sensor.inverter_mppt2_current') | float) |int }}" | |
| - name: Inverter Meter Power | |
| unique_id: inverter_meter_power | |
| unit_of_measurement: W | |
| device_class: power | |
| state_class: measurement | |
| availability: >- | |
| {{ | |
| has_value('sensor.inverter_meter_power_raw') | |
| and states('sensor.inverter_meter_power_raw')|int != 0x7FFFFFFF | |
| }} | |
| state: "{{ states('sensor.inverter_meter_power_raw') }}" | |
| - name: Inverter Load Power | |
| unique_id: inverter_load_power | |
| unit_of_measurement: W | |
| device_class: power | |
| state_class: measurement | |
| availability: > | |
| {{ has_value('sensor.inverter_total_active_power') | |
| and has_value('sensor.inverter_meter_power') }} | |
| state: "{{ states('sensor.inverter_total_active_power')|float + states('sensor.inverter_meter_power')|float }}" | |
| - name: Inverter MPPT1 Power Per Panel | |
| unique_id: inverter_mppt1_power_per_panel | |
| availability: "{{ has_value('sensor.inverter_mppt1_power') }}" | |
| unit_of_measurement: W | |
| device_class: power | |
| state_class: measurement | |
| state: "{{ (states('sensor.inverter_mppt1_power')|float/5) | round(1) }}" | |
| - name: Inverter MPPT2 Power Per Panel | |
| unique_id: inverter_mppt2_power_per_panel | |
| availability: "{{ has_value('sensor.inverter_mppt2_power') }}" | |
| unit_of_measurement: W | |
| device_class: power | |
| state_class: measurement | |
| state: "{{ (states('sensor.inverter_mppt2_power')|float/9) | round(1) }}" | |
| - name: Inverter Work State | |
| unique_id: inverter_work_state | |
| device_class: enum | |
| availability: "{{ has_value('sensor.inverter_work_state_code') }}" | |
| state: >- | |
| {% if ((states('sensor.inverter_work_state_code') | int(default=0)) == 0x0) %} | |
| Run | |
| {% elif ((states('sensor.inverter_work_state_code') | int(default=0)) == 0x8000) %} | |
| Stop | |
| {% elif ((states('sensor.inverter_work_state_code') | int(default=0)) == 0x1300) %} | |
| Key Stop | |
| {% elif ((states('sensor.inverter_work_state_code') | int(default=0)) == 0x1500) %} | |
| Emergency Stop | |
| {% elif ((states('sensor.inverter_work_state_code') | int(default=0)) == 0x1400) %} | |
| Standby | |
| {% elif ((states('sensor.inverter_work_state_code') | int(default=0)) == 0x1200) %} | |
| Initial Standby | |
| {% elif ((states('sensor.inverter_work_state_code') | int(default=0)) == 0x1600) %} | |
| Starting | |
| {% elif ((states('sensor.inverter_work_state_code') | int(default=0)) == 0x9100) %} | |
| Alarm Run | |
| {% elif ((states('sensor.inverter_work_state_code') | int(default=0)) == 0x8100) %} | |
| Derating Run | |
| {% elif ((states('sensor.inverter_work_state_code') | int(default=0)) == 0x8200) %} | |
| Dispatch Run | |
| {% elif ((states('sensor.inverter_work_state_code') | int(default=0)) == 0x5500) %} | |
| Fault | |
| {% elif ((states('sensor.inverter_work_state_code') | int(default=0)) == 0x2500) %} | |
| Communicate Fault | |
| {% else %} | |
| Unhandled State | |
| {% endif %} | |
| - name: Inverter Device Type | |
| unique_id: inverter_device_type | |
| availability: "{{ has_value('sensor.inverter_device_type_code') }}" | |
| device_class: enum | |
| state: >- | |
| {% if ((states('sensor.inverter_device_type_code') | int(default=0)) == 0x260F) %} | |
| SG5.0RS | |
| {% else %} | |
| Unknown device code: {{ '%0x' % (states('sensor.sungrow_device_type_code') | int(default=0)) }} | |
| {% endif %} | |
| utility_meter: | |
| inverter_daily_imported_energy: | |
| source: sensor.inverter_total_imported_energy | |
| cycle: daily | |
| inverter_daily_exported_energy: | |
| source: sensor.inverter_total_exported_energy | |
| cycle: daily | |
| sensor: | |
| ## Used for filtering outliers. | |
| - platform: statistics | |
| name: "Inverter Total Imported Energy Mean 3h" | |
| entity_id: sensor.inverter_total_imported_energy_raw | |
| state_characteristic: mean | |
| max_age: | |
| hours: 3 | |
| ## Mean sensors | |
| - platform: statistics | |
| name: "Inverter Total Active Power (mean 1m)" | |
| entity_id: sensor.inverter_total_active_power | |
| state_characteristic: mean | |
| max_age: | |
| minutes: 1 | |
| - platform: statistics | |
| name: "Inverter Meter Power (mean 1m)" | |
| entity_id: sensor.inverter_meter_power | |
| state_characteristic: mean | |
| max_age: | |
| minutes: 1 | |
| ## Testing: Filter sensors | |
| - platform: filter | |
| name: "Inverter Total Imported Energy (Filtered SMA)" | |
| entity_id: sensor.inverter_total_imported_energy | |
| filters: | |
| - filter: time_simple_moving_average | |
| window_size: "00:05:00" | |
| precision: 2 | |
| - platform: filter | |
| name: "Inverter Total Imported Energy (Filtered Lowpass)" | |
| entity_id: sensor.inverter_total_imported_energy | |
| filters: | |
| - filter: lowpass | |
| time_constant: 10 | |
| - platform: filter | |
| name: "Inverter Total exported Energy (Filtered SMA)" | |
| entity_id: sensor.inverter_total_exported_energy | |
| filters: | |
| - filter: time_simple_moving_average | |
| window_size: "00:05:00" | |
| precision: 2 | |
| - platform: filter | |
| name: "Inverter Total exported Energy (Filtered Lowpass)" | |
| entity_id: sensor.inverter_total_exported_energy | |
| filters: | |
| - filter: lowpass | |
| time_constant: 10 | |
| - platform: filter | |
| name: "Inverter Daily Power Yield (Filtered Range)" | |
| entity_id: sensor.inverter_daily_power_yield | |
| filters: | |
| - filter: range | |
| lower_bound: 0 | |
| upper_bound: 60 | |
| - platform: filter | |
| name: "Inverter Daily Power Yield (Filtered SMA)" | |
| entity_id: sensor.inverter_daily_power_yield | |
| filters: | |
| - filter: range | |
| lower_bound: 0 | |
| upper_bound: 60 | |
| - filter: time_simple_moving_average | |
| window_size: "00:05:00" | |
| precision: 2 | |
| - platform: filter | |
| name: "Inverter Daily Power Yield (Filtered Lowpass)" | |
| entity_id: sensor.inverter_daily_power_yield | |
| filters: | |
| - filter: range | |
| lower_bound: 0 | |
| upper_bound: 60 | |
| - filter: lowpass | |
| time_constant: 10 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
thank you.