bohdan-s / SunGather

GNU General Public License v3.0
146 stars 60 forks source link

Support for SG8K-D Inverter #8

Closed rianbk closed 2 years ago

rianbk commented 2 years ago

Hey,

Firstly thanks for this, been working on something like this personally but found yours on whirlpool. The script seems to be working in some capacity but I don't think you directly support this model.

Traceback (most recent call last):
File "/usr/local/lib/python3.10/threading.py", line 1009, in _bootstrap_inner
self.run()
File "/usr/local/lib/python3.10/threading.py", line 946, in run
self._target(*self._args, **self._kwargs)
File "/usr/src/sungather/exports/mqtt.py", line 38, in publish
self.sensor_topic = self.sensor_topic.replace('{model}', inverter.get('device_type_code', 'unknown').replace('.',''))
AttributeError: 'int' object has no attribute 'replace'
Exception in thread Thread-72 (publish):

I have sent a request to sungrowpower for the modbus register

rianbk commented 2 years ago

Looking into it, it looks like im not getting total_active_power

bohdan-s commented 2 years ago

Can you confirm you are on 0.1.1? (It shows version on startup). also what do you get for total_aparent_power?

rianbk commented 2 years ago

I can't see it pushing a version to the logs. But it is the latest docker image.

Register | Value -- | -- device_type_code | 9219 nominal_active_power | 8.0 output_type | 2P daily_power_yields | 43.4 total_power_yields | 1624.7 total_running_time | 11796 internal_temperature | 59.4 total_apparent_power | 65535 mppt_1_voltage | 378.2 mppt_1_current | 2.1 mppt_2_voltage | 314.6 mppt_2_current | 4.1 mppt_3_voltage | 0.0 mppt_3_current | 0.0 total_dc_power | 2117 phase_a_voltage | 240.0 phase_b_voltage | 0.0 phase_c_voltage | 0.0 phase_a_current | 8.7 phase_b_current | 6553.5 phase_c_current | 6553.5 total_active_power | 2063 total_reactive_power | 165 power_factor | 1.0 grid_frequency | 50.23 work_state_1 | Run alarm_time_year | 2021 alarm_time_month | 11 alarm_time_day | 14 alarm_time_hour | 17 alarm_time_minute | 27 alarm_time_second | 0 alarm_code_1 | 0 nominal_reactive_power | 2.4 array_insulation_resistance | 925 active_power_regulation_setpoint | 65535 reactive_power_regulation_setpoint | 0 work_state_2 | Stop meter_power | -151 meter_a_phase_power | 0 meter_b_phase_power | 0 meter_c_phase_power | 0 load_power | 1965 daily_export_energy | 268 total_export_energy | 30460 daily_import_energy | 73 total_import_energy | 5876 daily_direct_energy_consumption | 166 total_direct_energy_consumption | 51323 mppt_4_voltage | 0.0 mppt_4_current | 0.0 mppt_5_voltage | 0.0 mppt_5_current | 0.0 mppt_6_voltage | 0.0 mppt_6_current | 0.0 mppt_7_voltage | 0.0 mppt_7_current | 0.0 mppt_8_voltage | 0.0 mppt_8_current | 0.0 monthly_power_yields | 6553.5 mppt_9_voltage | 0.0 mppt_9_current | 0.0 mppt_10_voltage | 0.0 mppt_10_current | 0.0 mppt_11_voltage | 0.0 mppt_11_current | 0.0 mppt_12_voltage | 0.0 mppt_12_current | 0.0 negative_voltage_to_the_ground | 6553.5 bus_voltage | 0.0 pid_work_state | 0 pid_alarm_code | 0

Total 72 registers

rianbk commented 2 years ago

logs.txt Here is a logs output for a few runs.

rianbk commented 2 years ago

chrome_EO8gOpMSjo

bohdan-s commented 2 years ago

I can see total_active_power listed. Yay so it means the inverter supports it. Could you email info@sungrowpower.com.au and ask them for a copy of the modbus register for your model? They will only provide it for devices registers to your account. If you manage to get it I can update the registers list with registers supported. otherwise you can run with level 3 (which returns everything) The other option is I can manually add the supported registers, but the offical map would be better.

rianbk commented 2 years ago

I can see total_active_power listed. Yay so it means the inverter supports it. Could you email info@sungrowpower.com.au and ask them for a copy of the modbus register for your model? They will only provide it for devices registers to your account. If you manage to get it I can update the registers list with registers supported. otherwise you can run with level 3 (which returns everything) The other option is I can manually add the supported registers, but the offical map would be better.

Email has been sent, i'll let you know if I get a response.

rianbk commented 2 years ago

@bohdan-s its failing on the export for mqtt, due to there being no model detected, is there a way i can supply this manually without breaking anything? ie: just override the topic:tele/inverter_SG8K-D/SENSOR

bohdan-s commented 2 years ago

Ahhh yes. The hyphen in the model is the issue. I’ll fix that tonight for you.

bohdan-s commented 2 years ago

I can see a few things in the log to fix up and improve the error checking. If they supply the registers it will be easier. Otherwise I’ll have a look at the logs and make some “educated guesses” for your model.

rianbk commented 2 years ago

I can see a few things in the log to fix up and improve the error checking. If they supply the registers it will be easier. Otherwise I’ll have a look at the logs and make some “educated guesses” for your model.

No problem, i'll let you know and I'm around for testing.

dbonnell commented 2 years ago

I have an SG8K-D too, and I just started working on adding support today. To add recognition of the model, simply add the following two lines to registesr.yaml at line# 118-119: - response: 0x2403 value: "SG8K-D"

I then inspected the level 3 regsister dump to see what was/n't supported, checked the values against what I see in the Sungrow app and then updated the model map for the main ones so they show at the correct level.

image

registers.zip

rianbk commented 2 years ago

I have an SG8K-D too, and I just started working on adding support today. To add recognition of the model, simply add the following two lines to registesr.yaml at line# 118-119: - response: 0x2403 value: "SG8K-D"

I then inspected the level 3 regsister dump to see what was/n't supported, checked the values against what I see in the Sungrow app and then updated the model map for the main ones so they show at the correct level.

image

registers.zip

Might be worth putting in a pull request if you have the time.

rianbk commented 2 years ago

Note sure if there is something wrong with the export but getting repeating energy values on the export to PVoutput. image

bohdan-s commented 2 years ago

The energy is a calculated value. I also have the same issue yesterday, but not today or previous days.

I'll do some troubleshooting with a few days of logs and see if I can find the cause.

bohdan-s commented 2 years ago

I should have a massive bunch of fixes and improved error support next week. I will add the registers above and hopefully we will get an official list back and I can add the whole series of inverters.

dbonnell commented 2 years ago

Looked ok for me in influxdb (via mqqt export).

image

I just enabled PVoutput export to test. I'm using the default scan interval in SunGather (30s) and default metric interval in PVoutput (5min), and it all seems ok there, too.

image

The Energy (v1) metric in PVoutput is daily_power_yields * 1000. I quickly checked the code in the pvoutput export module and can't see any issue.

I did notice that if SunGather loses connection to the inverter that it seems to just spit out the same metrics again??

bohdan-s commented 2 years ago

Thanks @dbonnell that confirms what I am seeing as well. I have started adding some failsafe code so if no / invalid data is detected to skip export and log it. It also seems some registers (like temperature) only work in running state, so need to 0 or not upload to the exports. I'm currently thinking 0 for invalid values.

rianbk commented 2 years ago

I can't see any errors in the log log.txt

Still getting something weird with power generated image

inverter:
  host: 2.2.2.2
  # port: 502             # Default for modbus is 502, for http is 8082
  # slave: 0x01           # Default is 0x01
  # timeout: 10           # Default is 10
  # scan_interval: 30     # Default is 30
  connection: sungrow     # options: modbus, sungrow, http
  # model: "SG7.0RT"      # This is autodetected on startup, only needed if detection issues or for testing
                          # See model list here: https://github.com/bohdan-s/SunGather#supported
  smart_meter: True     # Default is False, Set to true if inverter supports reading grind / house consumption
  #use_local_time: True # Default False, Uses Inventer time, if try uses PC time when updating timestamps (e.g. PVOutput)
  # hybrid: False         # Default false, if you have a Hybrid (battery) set to True
  # manual_load: False    # Manually calculate load total_active_power + meter_power if the inverter does not supply it
  #logging: 10           # 10 = Debug, 20 = Info, 30 = Warning (default), 40 = Error
  level: 1              # 0 = Model and Solar Generation, 
                          # 1 (default) = Useful data, all required for exports, 
                          # 2 everything your Inverter supports, 
                          # 3 Everything from every register 

exports:
  - name: console   # Print Registers to console, good for debugging / troubleshooting
    enabled: True

  - name: http
    enabled: True   # Access at http://localhost:8080 or http://[serverip]:8080
    # port: 8080    # Default port is 8080

  - name: mqtt      # Publish Registers to MQTT / Home Assistant
    host: homeassistant
    # port: 1883
    topic: "tele/inverter_{model}/SENSOR" # Variable {model} will be replaced with model number
    username: mqtt
    password: mqtt
    ha_discovery: True                    # Home Assistant Discovery, False by default
    ha_topics:                            # Name in HA, from Register
      - name: "Daily Generation"
        register: daily_power_yields
        unit: kWh
        dev_class: energy
        state_class: total_increasing
      - name: "Active Power"
        register: total_active_power
        unit: W
        dev_class: power
        state_class: measurement
      - name: "Load Power"
        register: load_power
        unit: W
        dev_class: power
        state_class: measurement
      - name: "Meter Power"
        register: meter_power
        unit: W
        dev_class: power
        state_class: measurement
      - name: "Export to Grid"
        register: export_to_grid
        unit: W
        dev_class: power
        state_class: measurement
      - name: "Import from Grid"
        register: import_from_grid
        unit: W
        dev_class: power
        state_class: measurement
      - name: "Temperature"
        register: internal_temperature
        unit: °C
        dev_class: temperature
        state_class: measurement

  - name: pvoutput      # Publish Registers to PVOutput
    api: "222"
    sid: "222"
    # 60 for regular accounts, 300 for donation accounts
    rate_limit: 300
    enabled: True
    parameters:
      - name: v1    # Energy Generation
        register: daily_power_yields    # Solar Generated Today (Energy)
        multiple: 1000
      - name: v2    # Power Generation
        register: total_active_power    # Current Generation (Power)
#     - name: v3    # Energy Consumption
#       register: 
      - name: v4    # Power Consumption
        register: load_power            # Current Home usage (Power)
#      - name: v5    # Temperature
#        register: internal_temperature  # Inverter internal temperature
#     - name: v6    # Voltage
#       register: total_active_power
      - name: c1    # Cumulative Flag, 
        value: 1    # If using v2/v4 set to 1
#      - name: "n"   # Net Flag
#        value: 1
#     - name: "v7"  # Extended Value v7 - Donation Only
#       register:
#     - name: "v8"  # Extended Value v8 - Donation Only
#       register:
#     - name: "v9"  # Extended Value v9 - Donation Only
#       register:
#     - name: "v10" # Extended Value v10 - Donation Only
#       register:
#     - name: "v11" # Extended Value v11 - Donation Only
#       register:
#     - name: "v12" # Extended Value v12 - Donation Only
#       register:
#     - name: "m1"  # Text Message 1 - Donation Only
#       register:
rianbk commented 2 years ago

I've deleted the outputs for today in PVoutput, lets see what that does

bohdan-s commented 2 years ago

Yea, I am going to clear the payload each time now. Rather than leave old values. It leaves me a few issues to resolve, currently it doesn't "force" any registers it just loads what it can and skips the others. So if it fails to read temp overnight the old value never gets cleared.

rianbk commented 2 years ago

I was having an issue in PVoutput where energy wasn't being calculated. image

I have stopped exporting v1 and this has resolved that image


  - name: pvoutput      # Publish Registers to PVOutput
    api: "222"
    sid: "222"
    # 60 for regular accounts, 300 for donation accounts
    rate_limit: 300
    enabled: True
    parameters:
#      - name: v1    # Energy Generation
#        register: daily_power_yields    # Solar Generated Today (Energy)
#        multiple: 1000
      - name: v2    # Power Generation
        register: total_active_power    # Current Generation (Power)
#     - name: v3    # Energy Consumption
#       register: 
      - name: v4    # Power Consumption
        register: load_power            # Current Home usage (Power)
#      - name: v5    # Temperature
#        register: internal_temperature  # Inverter internal temperature
#     - name: v6    # Voltage
#       register: total_active_power
      - name: c1    # Cumulative Flag, 
        value: 1    # If using v2/v4 set to 1
#      - name: "n"   # Net Flag
#        value: 1
#     - name: "v7"  # Extended Value v7 - Donation Only
#       register:
#     - name: "v8"  # Extended Value v8 - Donation Only
#       register:
#     - name: "v9"  # Extended Value v9 - Donation Only
#       register:
#     - name: "v10" # Extended Value v10 - Donation Only
#       register:
#     - name: "v11" # Extended Value v11 - Donation Only
#       register:
#     - name: "v12" # Extended Value v12 - Donation Only
#       register:
#     - name: "m1"  # Text Message 1 - Donation Only
#       register:
dbonnell commented 2 years ago

I have no issues with pvoutput

image

    parameters:
      - name: v1    # Energy Generation
        register: daily_power_yields    # Solar Generated Today (Energy)
        multiple: 1000
      - name: v2    # Power Generation
        register: total_active_power    # Current Generation (Power)
#     - name: v3    # Energy Consumption
#       register: 
      - name: v4    # Power Consumption
        register: load_power            # Current Home usage (Power)
      - name: v5    # Temperature
        register: internal_temperature  # Inverter internal temperature
      - name: v6    # Voltage
        register: phase_a_voltage
      - name: c1    # Cumulative Flag, 
        value: 1    # If using v2/v4 set to 1
dbonnell commented 2 years ago

Having just read the pvoutput API docs for the Add Status Service, only one pair of v2+v4 or v1+v3 are required for power and energy calculations. The other pair are automatically calculated from the provided pair of measurements.

    # provide either v1/v3 or v2/v4 
    parameters:
#     - name: v1    # Energy Generation
#       register: daily_power_yields    # Solar Generated Today (Energy)
#       multiple: 1000
      - name: v2    # Power Generation
        register: total_active_power    # Current Generation (Power)
#     - name: v3    # Energy Consumption
#       register: 
      - name: v4    # Power Consumption
        register: load_power            # Current Home usage (Power)
      - name: v5    # Temperature
        register: internal_temperature  # Inverter internal temperature
      - name: v6    # Voltage
        register: phase_a_voltage
      - name: c1    # Cumulative Flag, 
        value: 1    # If using v2/v4 or if v1/v3 are daily/lifetime totals, set to 1
#      - name: "n"   # Net Flag
#        value: 1
#     - name: "v7"  # Extended Value v7 - Donation Only
#       register:
#     - name: "v8"  # Extended Value v8 - Donation Only
#       register:
#     - name: "v9"  # Extended Value v9 - Donation Only
#       register:
#     - name: "v10" # Extended Value v10 - Donation Only
#       register:
#     - name: "v11" # Extended Value v11 - Donation Only
#       register:
#     - name: "v12" # Extended Value v12 - Donation Only
#       register:
#     - name: "m1"  # Text Message 1 - Donation Only
#       register:
dbonnell commented 2 years ago

P.S. I've emailed Sungrow Australia to see if they'll provide an official register map. I'll add the full list if/when I receive it.

rianbk commented 2 years ago

Noticed today that talking to the system failed at midnight and kept failing

daily_power_yields 0.0
total_power_yields 1706.0
internal_temperature 39.6
total_dc_power 0
total_active_power 0
work_state_1 Initial Stanby
meter_power 1295
load_power 1295
daily_export_energy 0
total_export_energy 30991
daily_import_energy 1
total_import_energy 6315
daily_direct_energy_consumption 0
total_direct_energy_consumption 51605
start_stop Start
export_to_grid 0
import_from_grid 1295
is_running True
timestamp 2021-12-29 0:03:44
Logged 20 registers to Console
Publish HTTP
Register Value
device_type_code SG8K-D
daily_power_yields 0.0
total_power_yields 1706.0
internal_temperature 39.6
total_dc_power 0
total_active_power 0
work_state_1 Initial Stanby
meter_power 1295
load_power 1295
daily_export_energy 0
total_export_energy 30991
daily_import_energy 1
total_import_energy 6315
daily_direct_energy_consumption 0
total_direct_energy_consumption 51605
start_stop Start
export_to_grid 0
import_from_grid 1295
is_running True
timestamp 2021-12-29 0:03:44
Logged 20 registers to Console
Publish HTTP
Register Value
device_type_code SG8K-D
daily_power_yields 0.0
total_power_yields 1706.0
internal_temperature 39.6
total_dc_power 0
total_active_power 0
work_state_1 Initial Stanby
meter_power 1295
load_power 1295
daily_export_energy 0
total_export_energy 30991
daily_import_energy 1
total_import_energy 6315
daily_direct_energy_consumption 0
total_direct_energy_consumption 51605
start_stop Start
export_to_grid 0
import_from_grid 1295
is_running True
timestamp 2021-12-29 0:03:44
Logged 20 registers to Console
Publish HTTP
Register Value
device_type_code SG8K-D
daily_power_yields 0.0
total_power_yields 1706.0
internal_temperature 39.6
total_dc_power 0
total_active_power 0
work_state_1 Initial Stanby
meter_power 1295
load_power 1295
daily_export_energy 0
total_export_energy 30991
daily_import_energy 1
2021-12-29 12:43:43 WARNING Modbus connection failed: Modbus Error: [Input/Output] No Response received from the remote unit/Unable to decode response

2021-12-29 12:44:23 WARNING Modbus connection failed: Modbus Error: [Input/Output] No Response received from the remote unit/Unable to decode response

2021-12-29 12:45:03 WARNING Modbus connection failed: Modbus Error: [Input/Output] No Response received from the remote unit/Unable to decode response

2021-12-29 12:45:43 WARNING Modbus connection failed: Modbus Error: [Input/Output] No Response received from the remote unit/Unable to decode response

2021-12-29 12:46:23 WARNING Modbus connection failed: Modbus Error: [Input/Output] No Response received from the remote unit/Unable to decode response

2021-12-29 12:47:03 WARNING Modbus connection failed: Modbus Error: [Input/Output] No Response received from the remote unit/Unable to decode response

total_import_energy 6315
daily_direct_energy_consumption 0
total_direct_energy_consumption 51605
start_stop Start
export_to_grid 0
import_from_grid 1295
is_running True
timestamp 2021-12-29 0:03:44
Logged 20 registers to Console
Publish HTTP
Register Value
device_type_code SG8K-D
daily_power_yields 0.0
total_power_yields 1706.0
internal_temperature 39.6
total_dc_power 0
total_active_power 0
work_state_1 Initial Stanby
meter_power 1295
load_power 1295
daily_export_energy 0
total_export_energy 30991
daily_import_energy 1
total_import_energy 6315
daily_direct_energy_consumption 0
total_direct_energy_consumption 51605
start_stop Start
export_to_grid 0
import_from_grid 1295
is_running True
timestamp 2021-12-29 0:03:44
Logged 20 registers to Console
Publish HTTP
Register Value
device_type_code SG8K-D
daily_power_yields 0.0
total_power_yields 1706.0
internal_temperature 39.6
total_dc_power 0
total_active_power 0
work_state_1 Initial Stanby
meter_power 1295
load_power 1295
daily_export_energy 0
total_export_energy 30991
daily_import_energy 1
total_import_energy 6315
daily_direct_energy_consumption 0
total_direct_energy_consumption 51605
start_stop Start
export_to_grid 0
import_from_grid 1295
is_running True
timestamp 2021-12-29 0:03:44
Logged 20 registers to Console
Publish HTTP
Register Value
device_type_code SG8K-D
daily_power_yields 0.0
total_power_yields 1706.0
internal_temperature 39.6
total_dc_power 0
total_active_power 0
work_state_1 Initial Stanby
meter_power 1295
load_power 1295
daily_export_energy 0
total_export_energy 30991
daily_import_energy 1
total_import_energy 6315
daily_direct_energy_consumption 0
total_direct_energy_consumption 51605
start_stop Start
export_to_grid 0
import_from_grid 1295
is_running True
timestamp 2021-12-29 0:03:44
Logged 20 registers to Console
Publish HTTP
Register Value
device_type_code SG8K-D
daily_power_yields 0.0
total_power_yields 1706.0
internal_temperature 39.6
total_dc_power 0
total_active_power 0
work_state_1 Initial Stanby
meter_power 1295
load_power 1295
daily_export_energy 0
total_export_energy 30991
daily_import_energy 1
total_import_energy 6315
daily_direct_energy_consumption 0
total_direct_energy_consumption 51605
start_stop Start
export_to_grid 0
import_from_grid 1295
is_running True
timestamp 2021-12-29 0:03:44
Logged 20 registers to Console
Publish HTTP
Register Value
device_type_code SG8K-D
daily_power_yields 0.0
total_power_yields 1706.0
internal_temperature 39.6
total_dc_power 0
total_active_power 0
work_state_1 Initial Stanby
meter_power 1295
load_power 1295
daily_export_energy 0
total_export_energy 30991
daily_import_energy 1
total_import_energy 6315
daily_direct_energy_consumption 0
total_direct_energy_consumption 51605
start_stop Start
export_to_grid 0
import_from_grid 1295
is_running True
timestamp 2021-12-29 0:03:44
Logged 20 registers to Console
Publish HTTP
Register Value
device_type_code SG8K-D
daily_power_yields 0.0
total_power_yields 1706.0
internal_temperature 39.6
total_dc_power 0
2021-12-29 12:47:43 WARNING Modbus connection failed: Modbus Error: [Input/Output] No Response received from the remote unit/Unable to decode response

2021-12-29 12:48:23 WARNING Modbus connection failed: Modbus Error: [Input/Output] No Response received from the remote unit/Unable to decode response

2021-12-29 12:49:03 WARNING Modbus connection failed: Modbus Error: [Input/Output] No Response received from the remote unit/Unable to decode response

2021-12-29 12:49:43 WARNING Modbus connection failed: Modbus Error: [Input/Output] No Response received from the remote unit/Unable to decode response

2021-12-29 12:50:23 WARNING Modbus connection failed: Modbus Error: [Input/Output] No Response received from the remote unit/Unable to decode response

total_active_power 0
work_state_1 Initial Stanby
meter_power 1295
load_power 1295
daily_export_energy 0
total_export_energy 30991
daily_import_energy 1
total_import_energy 6315
daily_direct_energy_consumption 0
total_direct_energy_consumption 51605
start_stop Start
export_to_grid 0
import_from_grid 1295
is_running True
timestamp 2021-12-29 0:03:44
Logged 20 registers to Console
Register Value
device_type_code SG8K-D
daily_power_yields 0.0
total_power_yields 1706.0
internal_temperature 39.6
total_dc_power 0
total_active_power 0
work_state_1 Initial Stanby
meter_power 1295
load_power 1295
daily_export_energy 0
total_export_energy 30991
daily_import_energy 1
total_import_energy 6315
daily_direct_energy_consumption 0
total_direct_energy_consumption 51605
start_stop Start
export_to_grid 0
import_from_grid 1295
is_running True
timestamp 2021-12-29 0:03:44
Logged 20 registers to Console
Publish HTTP
Register Value
device_type_code SG8K-D
daily_power_yields 0.0
total_power_yields 1706.0
internal_temperature 39.6
total_dc_power 0
total_active_power 0
work_state_1 Initial Stanby
meter_power 1295
load_power 1295
daily_export_energy 0
total_export_energy 30991
daily_import_energy 1
total_import_energy 6315
daily_direct_energy_consumption 0
total_direct_energy_consumption 51605
start_stop Start
export_to_grid 0
import_from_grid 1295
is_running True
timestamp 2021-12-29 0:03:44
Logged 20 registers to Console
Publish HTTP
Register Value
device_type_code SG8K-D
daily_power_yields 0.0
total_power_yields 1706.0
internal_temperature 39.6
total_dc_power 0
total_active_power 0
work_state_1 Initial Stanby
meter_power 1295
load_power 1295
daily_export_energy 0
total_export_energy 30991
daily_import_energy 1
total_import_energy 6315
daily_direct_energy_consumption 0
total_direct_energy_consumption 51605
start_stop Start
export_to_grid 0
import_from_grid 1295
is_running True
timestamp 2021-12-29 0:03:44
Logged 20 registers to Console
Publish HTTP
Register Value
device_type_code SG8K-D
daily_power_yields 0.0
total_power_yields 1706.0
internal_temperature 39.6
total_dc_power 0
total_active_power 0
work_state_1 Initial Stanby
meter_power 1295
load_power 1295
daily_export_energy 0
total_export_energy 30991
daily_import_energy 1
total_import_energy 6315
daily_direct_energy_consumption 0
total_direct_energy_consumption 51605
start_stop Start
export_to_grid 0
import_from_grid 1295
is_running True
timestamp 2021-12-29 0:03:44
Logged 20 registers to Console
Publish HTTP
Register Value
device_type_code SG8K-D
daily_power_yields 0.0
total_power_yields 1706.0
internal_temperature 39.6
total_dc_power 0
total_active_power 0
work_state_1 Initial Stanby
meter_power 1295
load_power 1295
daily_export_energy 0
total_export_energy 30991
daily_import_energy 1
total_import_energy 6315
daily_direct_energy_consumption 0
total_direct_energy_consumption 51605
start_stop Start
export_to_grid 0
import_from_grid 1295
is_running True

Restarting the container fixed it.

dbonnell commented 2 years ago

A couple of typos in registers.yaml: "Initial Stanby" should be "Initial Standby" at line# 331 and #429

dbonnell commented 2 years ago

I've adapted the iammeter Grafana dashboard template to work with the Sungrow data. The MQTT export from SunGather is pushed into InfluxDB using Telegraf, and the dashboard queries the Sungrow measurements in the telegraf database in InfluxDB.

The biggest pain was the "This Month" panel at the far right. To be able to calculate the month-to-date figures I used the Telegraph date processor to add a "month" tag to the data. Flux can do monthly aggregation, InfluxQL cannot. The dashboard has a "current_month" variable that queries the "month" tag of the most recent measurement. The "Month" panel's queries filter by month=$current_month$ AND time >= now()-31d to get the spread of the total_XXXX measurements.

The data looks whacky because the month tag was added midday today, so data before then is missing the month tag and this morning's measurements are therefore not included in the monthly totals.

Yesterday I got some whacky figures and it turned out that MQTT export had sent values of 64k during one of its exports, which the InfluxQL queries picked up in the spreads. It may have happened when I restarted SunGather after making a change (I added a debug switch to the pvoutput and mqtt exports, to temporarily change the log level to debug so they emit just the data they're pushing out, not the full debug stuff they would if the global logging level was set to debug).

The biggest problem I have though is my PC keeps dropping the WiFi connection to the SG8K-D, even though it has Auto Connect enabled and Power Management disabled. Now that everything is working, I think I'm going to move everything to a Raspberry Pi4, which will hopefully be able to keep connected to the Sungrow WiFi dongle.

image

dbonnell commented 2 years ago

I noticed my Monthly panel in Grafana was out of whack and when I investigated, I found the total_* registers values aren't right. Not sure why.

Metric                                                 SunGather         iSolarCloud
total_import_energy                           25016                9.02MWh
total_export_energy                           23042                15.234MWh
total_direct_energy_consumption      26917                9.234MWh
total_power_yields                             4995.9                24.468MWh

The daily_* registers are fine.

Metric                                                 SunGather         iSolarCloud
daily_import_energy                           152                    15.1kWh
daily_export_energy                           1                         0.1kWh
daily_direct_energy_consumption      16                      1.5kWh
daily_power_yields                             1.8                      1.6kWh

No response from Sungrow as yet (other than automated reply) to my request for the official modbus map :-(

rianbk commented 2 years ago

I got a response but it wasn’t helpful

“ Unfortunately, SG8K-D doesn't have spare RS485 ports to connect to other devices.”

bohdan-s commented 2 years ago

Ok, a few things to answer here :)

@dbonnell looking at your totals they seems to be multiples 65535 off the expected value, or Int16 instead of int32. They should now be read as int32 (values higher than 65535). I have also fixed the code so 65535 values (in modbus 0xFF or no response) will now be 0, this will be easier to graph. I'll publish 0.1.2 with a heap of fixes today, just finishing off some of the HomeAssistant discovery code.

bohdan-s commented 2 years ago

I have published v0.1.2 to git and Docker. @rianbk @dbonnell can you let me know if you see any issues? The Home Assistance Discovery is a bigger job, that requires breaking changes to config file, so I'll publish that later this week hopefully. @dbonnell any change of sharing your template? I'll upload it here and add some instructions to README on usage if thats ok?

dbonnell commented 2 years ago

I have published v0.1.2 to git and Docker. @rianbk @dbonnell can you let me know if you see any issues? The Home Assistance Discovery is a bigger job, that requires breaking changes to config file, so I'll publish that later this week hopefully. @dbonnell any change of sharing your template? I'll upload it here and add some instructions to README on usage if thats ok?

Will pull it down and let you know how it goes. Thanks very much (again) for your work.

More than happy to share the Grafana template. I was planning to do that once I fixed the "Monthly" panel, but if anyone wants to play around with it, here it is. Note that I've disabled all of the bar charts in the "Monthly" panel, as they currently don't work. SunGather.zip

Before using it, you'll need to add a data source for InfluxDB, which I called "InfluxDB". Just set the HTTP URL and any Auth settings required for influxdb, then under InfluxDB Details set the Database to telegraf. Click Save & Test to verify the connection.

After that you should be good to import the dashboard template above.

To get the data into InfluxDB I use Telegraf. Here's my Telegraf config file (/etc/telegraf/telegraf.d/mqtt.conf) which throws the tele/inverter_SG8K-D/SENSOR topics from MQTT into the "Sungrow" measurement in the "telegraf" database in influxdb. Note that I didn't include the HA topics. mqtt.zip

Note that the mqtt export in sungrow currently publishes ALL of the metrics that show at the set inverter.level, so if you have it set to 2 or 3, you'll get a ton of stuff in influxdb that you may not want/need.

To check if it is working:

influx -database telegraf -precision s
> select * from Sungrow limit 1

I think that's pretty much it but feel free to holler if I've missed something, or it doesn't work. (I'm new to InfluxDB and Grafana, so this was all a learning experience for me!)

bohdan-s commented 2 years ago

Thanks @dbonnell I am currently putting together a InfluxDB export, so that should make it a bit simpler going forward.

dbonnell commented 2 years ago

Awesome.  I was thinking of working on that after I finished the Grafana dashboard but you're a step ahead of me! -------- Original message --------From: bohdan-s @.> Date: 5/1/22 5:53 pm (GMT+10:00) To: bohdan-s/SunGather @.> Cc: David Bonnell @.>, Mention @.> Subject: Re: [bohdan-s/SunGather] Support for SG8K-D Inverter (Issue #8) Thanks @dbonnell I am currently putting together a InfluxDB export, so that should make it a bit simpler going forward.

—Reply to this email directly, view it on GitHub, or unsubscribe.Triage notifications on the go with GitHub Mobile for iOS or Android. You are receiving this because you were mentioned.Message ID: @.***>

rianbk commented 2 years ago

Allright, i'm updated and testing

dbonnell commented 2 years ago

I've updated and merged my changes. My Grafana dashboard stopped working right afterwards. Telegraf is reporting the following error:

Error in plugin: JSON time key could not be found

I can see in the mqtt export debug output that it is emitting a timestamp field, which is what I have configured in Telegraf as the json_time_key on the [[inputs.mqtt_consumer]]

2022-01-06 14:32:12 DEBUG    MQTTOutput: {"device_type_code": "SG8K-D", "daily_power_yields": 47.0, "total_power_yields": 5103.6, "internal_temperature": 73.3, "total_active_power": 7112, "work_state_1": "Run", "meter_power": -1004, "load_power": 6107, "daily_export_energy": 183, "total_export_energy": 23526, "daily_import_energy": 170, "total_import_energy": 25298, "daily_direct_energy_consumption": 287, "total_direct_energy_consumption": 27510, "start_stop": "Start", "export_to_grid": 1004, "import_from_grid": 0, "is_running": true, "timestamp": "2022-1-6 14:32:21"}

I restarted Telegraf and that error went away but nothing going to influx. Checked with mosquitto_sub and the topic has changed ... was tele/inverter_SG-8KD/SENSOR but is now tele/inverter_SG8KD/SENSOR, so my Telegraf config wasn't forwarding anything to influxdb. Back working again.

Other than that, I haven't seen any other issue. Export to pvoutput is fine.

dbonnell commented 2 years ago

The inverter wifi network disappears once there's no solar input, but the wifi auto reconnects when its available again in the morning. I got disconnect errors from SunGather, which I expect, but once the network was back up, I started getting these errors and it never recovered.

2022-01-07 06:41:44 DEBUG    MQTTOutput: {"device_type_code": "SG8K-D"}
    self._target(*self._args, **self._kwargs)
2022-01-07 06:41:44 INFO     Published to MQTT
  File "/mnt/d/work/sungrow/sungather/SunGather/exports/pvoutput.py", line 68, in publish
    now = datetime.datetime.strptime(inverter.get('timestamp'), "%Y-%m-%d %H:%M:%S")
TypeError: strptime() argument 1 must be str, not None
2022-01-07 06:42:15 ERROR    Unable to decode response Modbus Error: Unknown response 10
2022-01-07 06:42:15 ERROR    Modbus Error: [Input/Output] Unable to decode request
Traceback (most recent call last):
  File "/home/dbonnell/.local/lib/python3.8/site-packages/pymodbus/transaction.py", line 208, in execute
    self.client.framer.processIncomingPacket(response,
  File "/home/dbonnell/.local/lib/python3.8/site-packages/pymodbus/framer/socket_framer.py", line 165, in processIncomingPacket
    self._process(callback, error=True)
  File "/home/dbonnell/.local/lib/python3.8/site-packages/pymodbus/framer/socket_framer.py", line 175, in _process
    raise ModbusIOException("Unable to decode request")
pymodbus.exceptions.ModbusIOException: Modbus Error: [Input/Output] Unable to decode request

I had to restart SunGather this morning to get it working again. It shows the correct device_type_code so either it was able to connect and read that, or it never cleared that when the connection failed and is showing the old value?

If I manually disconnect the wifi connection, I get the same timestamp error but not the MODBUS decode error and after reconnecting the wifi, it recovers and starts logging again.

2022-01-07 12:47:52 ERROR    Connection to (11.11.11.1, 502) failed: timed out
2022-01-07 12:48:02 ERROR    Connection to (11.11.11.1, 502) failed: timed out
2022-01-07 12:48:02 WARNING  No data returned for read, 5000:100
                                Modbus Error: [Connection] Failed to connect[ModbusTcpClient(11.11.11.1:502)]
Exception in thread Thread-946:
Traceback (most recent call last):
  File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.8/threading.py", line 870, in run
2022-01-07 12:48:02 DEBUG    MQTTOutput: {"device_type_code": "SG8K-D"}
    self._target(*self._args, **self._kwargs)
  File "/mnt/d/work/sungrow/sungather/SunGather/exports/pvoutput.py", line 68, in publish
2022-01-07 12:48:02 INFO     Published to MQTT
    now = datetime.datetime.strptime(inverter.get('timestamp'), "%Y-%m-%d %H:%M:%S")
TypeError: strptime() argument 1 must be str, not None
2022-01-07 12:48:35 DEBUG    PVOutput Request: https://pvoutput.org/service/r2/addstatus.jsp, {'X-Pvoutput-Apikey': '8d0ec84de6d8ca062020ba30161a0212d9da1135', 'X-Pvoutput-SystemId': '87887', 'Content-Type': 'application/x-www-form-urlencoded', 'cache-control': 'no-cache'} : {'d': '20220107', 't': '12:48', 'v1': '31800.0', 'v2': '7705', 'v4': '1763', 'v5': '70.6', 'v6': 'None', 'c1': 1}
2022-01-07 12:48:35 DEBUG    MQTTOutput: {"device_type_code": "SG8K-D", "daily_power_yields": 31.8, "total_power_yields": 5149.3, "internal_temperature": 70.6, "total_active_power": 7705, "work_state_1": "Run", "meter_power": -5941, "load_power": 1763, "daily_export_energy": 170, "total_export_energy": 23712, "daily_import_energy": 208, "total_import_energy": 25606, "daily_direct_energy_consumption": 148, "total_direct_energy_consumption": 27781, "start_stop": "Start", "export_to_grid": 5941, "import_from_grid": 0, "is_running": true, "timestamp": "2022-1-7 12:48:50"}
2022-01-07 12:48:35 INFO     Published to MQTT
2022-01-07 12:48:36 INFO     Published to PVOutput
bohdan-s commented 2 years ago

@dbonnell I have pushed v0.1.3 that should better handle a connection being dropped, and cleaner reconnections. Thank you for all your testing, it has been a huge help.

bohdan-s commented 2 years ago

V0.1.3 also has a influxDB export now. Check the example config file for options. I'm pushing to a cloud insurance at the moment, but having never used influxdb before this is all new to me :) Let me know how it goes. You can pick and choose what to export in the config.

dbonnell commented 2 years ago

@dbonnell I have pushed v0.1.3 that should better handle a connection being dropped, and cleaner reconnections. Thank you for all your testing, it has been a huge help.

Seems to have done the trick .. reconnected without issue this morning. Great job!

I'll test the influxdb export tomorrow.

rianbk commented 2 years ago

Things are looking pretty good for me. The connection handling seems to be working good. Mine used to disconnect nearly everyday at midnight. Its now continued on for a few days now no issues. seamless export to pvoutput.

dbonnell commented 2 years ago

I've fixed the Monthly panel and a few other issues such as wrong unit conversion in the Last 1 month Yield and Consumption charts.

image

Grafana_SolarSystem.zip

The connection has been rock solid since upgrading to v0.1.3. Thank you @bohdan-s

I still haven't tested the influxdb export. I hope to get to that tonight or tomorrow morning.

bohdan-s commented 2 years ago

@rianbk @dbonnell I have pushed a huge update to v0.2.0. Re-writen most the PVOutput and MQTT code, as well as the way registers are read. Should be significantly faster (each scan went from 4s+ to 1.5s on my machine) and much more robust.

Interesting thing with PVOutput is it only accepts 1 update per 5 minutes. I have now re-writen the code to take every inverter scan over the 5 min window and average it then upload, you can also set it to do batch uploads (say hourly). This massively reduces the overhead and gives "smoother" results in my testing. It is also impossible to hit the rate limit now :)

I have set up influxDB and Grafana cloud instances, so i'll try out your dashboard @dbonnell and put some instructions on how to use it in the readme if thats ok :)

rianbk commented 2 years ago

Amazing, I’ll update and test.

dbonnell commented 2 years ago

Thanks @bohdan-s

I've updated and all seems to be working, but noticed this warning:

2022-01-14 08:40:16 WARNING  PVOutput: v6 configured to use phase_a_voltage but inverter is not returning this register

In registers.yaml (line# 258) I've changed phase_a_voltage) to level 1. Not sure if this makes sense as a default or perhaps it the defined level for registers should be ignored for all registers configured explicitly for active exports?

bohdan-s commented 2 years ago

Thanks, that was a typo :/ i set MPPT_1_voltage to level 1 instead of phase_a_voltage. I republished 0.2.2 with the correct register, no big deal if you already did it manually.

dbonnell commented 2 years ago

Thanks, that was a typo :/ i set MPPT_1_voltage to level 1 instead of phase_a_voltage. I republished 0.2.2 with the correct register, no big deal if you already did it manually.

Perfect, thank you

daloser commented 2 years ago

Thanks for all your work @bohdan-s! I had it working for my SG8K-D and it was reporting over mqtt into home assisstant. However I was having issues with it overnight failing and sometimes wouldn't reconnect. I have updated to 0.2.2 and redone the config file, but now i have issues with it reporting in mqtt; the web server report is coming out correctly.

Here is a snippet of the console if you can see any issues that i may have caused or have any suggestions to fix.

`2022-01-16 15:20:07 INFO Starting SunGather 0.2.2 2022-01-16 15:20:07 INFO Loaded config: config.yaml 2022-01-16 15:20:08 INFO Loaded registers: /home/pi/SunGather/SunGather/registers.yaml 2022-01-16 15:20:08 ERROR Failed loading export: [Errno 111] Connection refused Please make sure mqtt.py exists in the exports folder Exception in thread Thread-3: Traceback (most recent call last): File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner self.run() File "/usr/lib/python3.7/threading.py", line 865, in run self._target(*self._args, **self._kwargs) File "/home/pi/SunGather/SunGather/exports/mqtt.py", line 43, in publish self.mqtt_client.reconnect() File "/home/pi/.local/lib/python3.7/site-packages/paho/mqtt/client.py", line 1044, in reconnect sock = self._create_socket_connection() File "/home/pi/.local/lib/python3.7/site-packages/paho/mqtt/client.py", line 3685, in _create_socket_connection return socket.create_connection(addr, timeout=self._connect_timeout, source_address=source) File "/usr/lib/python3.7/socket.py", line 727, in create_connection raise err File "/usr/lib/python3.7/socket.py", line 716, in create_connection sock.connect(sa) ConnectionRefusedError: [Errno 111] Connection refused

Exception in thread Thread-5: Traceback (most recent call last): File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner self.run() File "/usr/lib/python3.7/threading.py", line 865, in run self._target(*self._args, **self._kwargs) File "/home/pi/SunGather/SunGather/exports/mqtt.py", line 43, in publish self.mqtt_client.reconnect() File "/home/pi/.local/lib/python3.7/site-packages/paho/mqtt/client.py", line 1044, in reconnect sock = self._create_socket_connection() File "/home/pi/.local/lib/python3.7/site-packages/paho/mqtt/client.py", line 3685, in _create_socket_connection return socket.create_connection(addr, timeout=self._connect_timeout, source_address=source) File "/usr/lib/python3.7/socket.py", line 727, in create_connection raise err File "/usr/lib/python3.7/socket.py", line 716, in create_connection sock.connect(sa) ConnectionRefusedError: [Errno 111] Connection refused

bohdan-s commented 2 years ago

Can you double check the IP for the MQTT server is correct? If you are using the Mosquito one built into HA then it will be same IP as HA.