Solution: Reading Solax SK-SU5000(E) inverters & SDM630V2 Modbus Power Meters

I m just on a Normal Fixed Tariff ( USwitch Octopus 12M Fixed )
I have yet to look into any of the emon stuff yet. As I wanted to wait till I got battery control working, which I have now.

If you are using emonCMS, install the ‘App’ and do a comparison. I have no PV/Battery etc and my effective rate for the last 4 months would have been 10p/kWh as opposed to the 14p I am paying.

I did install emonCMS on a PI4 when trying the original Power Scraper on this thread.

I will look at installing the Docker version on my main server tonight save having the PI powered on.

I have started reading through the Octopus Agile emoncms thread.

2 posts were split to a new topic: Battery appears not to be charging

How I can read values from SMD630V2 smart meter when it is connected directly via Modbus wires to Solax X3 Hybrid inverter? I can easily read values from the inverter via the Modbus TCP connection. I’m using Loxone Miniserver with the Modbus server instance. This is not a problem, register numbers converted from hex to decimal are working. But I don’t understand how I can read values from SMD630V2 smart meter via inverter over Modbus TCP connection.

That’s because the 630 uses Modbus RTU which is raw serial data. i.e. it’s not encapsulated
in a TCP frame like Modbus TCP.

In fact, that’s essentially what Modbus TCP is. i.e. a Modbus RTU packet in a TCP frame.
A Modbus RTU to Modbus TCP gateway attached to the 630 should enable you to poll the 630 from your Modbus TCP connection.

Eastron_SDM630Modbus_V2_user_manual_2016_V1_3.pdf (1.7 MB)

https://www.ebay.com/itm/USR-K7-Industrial-Super-Port-UART-Ethernet-Module-Modbus-RTU-to-TCP-IP-Module/274441506664?hash=item3fe5fd0f68%3Ag%3AFHgAAOSwrTBfH8ux&LH_BIN=1

The SDM630v2 is not supported directly by the Solax inverters. It needs to be connected via RS485 to the machine running the scraper.

Hi @Pukka,
how did you get Solax running with node-red? May be could you share a flow?

Sam

I dont have the orignal node-red stuff as I moved over to this config a few years ago. If I remember correctly you just add the node red modbus and then you can read the registers.
Paul

I have just updated to the latest code and I am getting an error when trying to launch the program

sudo ./power_scraper.py
:0: UserWarning: You do not have a working installation of the service_identity module: 'cannot import name 'verify_ip_address' from 'service_identity.pyopenssl' (/usr/lib/python3/dist-packages/service_identity/pyopenssl.py)'.  Please install it from <https://pypi.python.org/pypi/service_identity> and make sure all of its dependencies are satisfied.  Without the service_identity module, Twisted can perform only rudimentary TLS client hostname verification.  Many valid certificate/hostname mappings may be rejected.
Setting up EmonCMS
not connected
not connected
err [Failure instance: Traceback: <class 'KeyError'>: 'max-power'
/usr/local/lib/python3.7/dist-packages/pymodbus/framer/socket_framer.py:181:_process
/usr/local/lib/python3.7/dist-packages/pymodbus/client/asynchronous/twisted/__init__.py:126:_handleResponse
/usr/local/lib/python3.7/dist-packages/twisted/internet/defer.py:460:callback
/usr/local/lib/python3.7/dist-packages/twisted/internet/defer.py:568:_startRunCallbacks
--- <exception caught here> ---
/usr/local/lib/python3.7/dist-packages/twisted/internet/defer.py:654:_runCallbacks
/home/pi/PowerScraper/Inputs/SolaxModbus.py:198:solaxRegisterCallback
./power_scraper.py:58:outputActions
/home/pi/PowerScraper/Outputs/SolaxBatteryControl.py:135:send
/home/pi/PowerScraper/Outputs/SolaxBatteryControl.py:62:setInverterPower
]
err [Failure instance: Traceback: <class 'KeyError'>: 'max-power'
/usr/local/lib/python3.7/dist-packages/pymodbus/framer/socket_framer.py:181:_process
/usr/local/lib/python3.7/dist-packages/pymodbus/client/asynchronous/twisted/__init__.py:126:_handleResponse
/usr/local/lib/python3.7/dist-packages/twisted/internet/defer.py:460:callback
/usr/local/lib/python3.7/dist-packages/twisted/internet/defer.py:568:_startRunCallbacks
--- <exception caught here> ---
/usr/local/lib/python3.7/dist-packages/twisted/internet/defer.py:654:_runCallbacks
/home/pi/PowerScraper/Inputs/SolaxModbus.py:198:solaxRegisterCallback
./power_scraper.py:58:outputActions
/home/pi/PowerScraper/Outputs/SolaxBatteryControl.py:135:send
/home/pi/PowerScraper/Outputs/SolaxBatteryControl.py:62:setInverterPower
]
^CShutdown

Fixed text formattting - BT, Moderator

Whoops, I forgot to add that to the sample config. Add a max-power = 5000 to you inverter definitions. I’ll update the sample config now.

Just a heads up, I had 2 of my inverters fail recently with “Inv EEPROM fault”. Solax didn’t have replacements or engineers, so they sent me 2 of the new X1 hybrids + approximately equivalent hybrid batteries to replace my LG Chems which were not compatible (48V vs high voltage for the new inverters).

The latest patches reduce the number of writes to EEPROM to try and avoid this.

If you do get the fault, Solax will tell you to update the firmware on the inverter. This failed on both of mine, and bricked the units, which is why they replaced them.

If they do send out new hardware, great, if not, this is how I was able to repair my failed units:

Bad manager flash

  • Shut down the inverter & remove the cover
  • Remove the manager board, it’s the bottom one with the ethernet ports on it
  • Use an SWD programmer with ST-Util to flash the firmware manually. The SWD programmer should be connected to the JTAG port next to the display connector.

Bad Master Inverter Flash

  • Remove the inverter control board directly above the manager board.
  • There are 2 JTAG ports in the lower left. The horizontal one is for the slave controller (you don’t need to touch this), and the vertical one is for the master.
  • Connect an XDS100V2 or V3 programmer (cheap clones available from China) to the master port, and flash the inverter master firmware.

Fix INV EEPROM fault

  • You should be confident with SMD soldering to attempt this
  • Remove the inverter control board directly above the manager board.
  • Remove the failed EEPROM chip U1 next to the JTAG connectors
  • Replace it with a new Atmel AT24C08C chip
  • Reinstall the board & bring the inverter up
  • Reset Manager EEROM & Inverter EEROM in the settings
  • Restart the inverter

This should allow you to bring the inverter back online in the event of a failure.

Shipping from China can be slow, so I would recommend ordering a few cheap pieces in advance & keeping them aside in case something bad does happen:
https://www.aliexpress.com/item/32719963657.html

Thats sorted it :slight_smile:

Did you try and flash the inverter without switching it off? :wink:

If the inverter was working and now getting “Inv EEPROM fault” can you just replace the Atmel AT24C08C without needing to reflash the boards?

Paul

next error :frowning:

sudo ./power_scraper.py
:0: UserWarning: You do not have a working installation of the service_identity module: ‘cannot import name ‘verify_ip_address’ from ‘service_identity.pyopenssl’ (/usr/lib/python3/dist-packages/service_identity/pyopenssl.py)’. Please install it from https://pypi.python.org/pypi/service_identity and make sure all of its dependencies are satisfied. Without the service_identity module, Twisted can perform only rudimentary TLS client hostname verification. Many valid certificate/hostname mappings may be rejected.
Setting up EmonCMS
not connected
not connected
err [Failure instance: Traceback: <class ‘KeyError’>: ‘linked-batteries’
/usr/local/lib/python3.7/dist-packages/pymodbus/framer/socket_framer.py:181:_process
/usr/local/lib/python3.7/dist-packages/pymodbus/client/asynchronous/twisted/init.py:126:_handleResponse
/usr/local/lib/python3.7/dist-packages/twisted/internet/defer.py:460:callback
/usr/local/lib/python3.7/dist-packages/twisted/internet/defer.py:568:_startRunCallbacks
— —
/usr/local/lib/python3.7/dist-packages/twisted/internet/defer.py:654:_runCallbacks
/home/pi/PowerScraper/Inputs/SolaxModbus.py:198:solaxRegisterCallback
./power_scraper.py:58:outputActions
/home/pi/PowerScraper/Outputs/SolaxBatteryControl.py:209:send

Nope, it happened on all 3 machines. They were all running Manager 2.27 - so maybe it was a firmware bug? They did reflash properly over the network once upgraded to 2.31.

If the inverter is working, and getting “Inv EEPROM Fault”, you can follow the procedure I outlined to get the machine back online without having to reflash it.

I did notice that in the previous set of firmware, the inverter mis-reported “Inverter Power” when charging the batteries from the grid, reporting twice as much power draw than it should have. This is fixed in the latest set of firmware.

Hmm, you’re missing linked-batteries from the config, it should be in the sample.

I have listed in the config

[Solax-BatteryControl]
#source = “MainsMeter” # The data source for power consumption
linked-batteries = true # If set, all batteries charge/discharge at the same rate when trying to zero total power
timezone = “AEDT-10” # If set, always use this timezone for period calculations. This may be useful if your machine tracks daylight savings, but your energy provider does not

Odd, I didn’t make any changes in that area, your config does look correct though.

Did you keep a copy of your previous config? It might be worth doing a diff and seeing if any extraneous changes may be throwing off the parser.

I am not sure what is going on, I have removed the PowerScraper folder and git cloned a new copy from the server, created a new config file, If when i change the file to only have 1 inverter battery is currently at 95% I cannot get it to suppy the house load.

> # Enable this section to scrape the Wifi interface of Solax inverters
> #[Solax-Wifi]
> #poll_period = 10 # seconds
> #timeout = 5 # seconds
> #inverters = ['solax1-wifi', 'solax2-wifi', 'solax3-wifi']
> 
> # Enable this section to scrape the Modbus/TCP (Ethernet port) of Solax inverters
> [Solax-Modbus]
> poll_period = 10 # seconds
> timeout = 5 # seconds
> power_budget_avg_samples = 30 # The maximum number of samples to average power budget over
> installer_password = **12345** # The installer password for the inverter (same as used on the front panel), required if you want to use battery control
> inverter_power = 5000 # Limit the inverter power to this amount, required if you want to use battery control
> inverters = ['solax1']
> 
> # Enable this section to scrape Modbus/RTU (RS485) connected SDM630v2 energy meters
> #[SDM630Modbusv2]
> #poll_period = 1 # seconds
> #timeout = 1 # seconds
> #baud = 38400
> #parity = 'E'
> #stopbits = 1
> #ports = ["/dev/ttyMainsMeter"]
> 
> # Enable this section to output to EmonCMS
> [emoncms]
> timeout = 5 # seconds
> server = "**http://12345/emoncms**"
> api_key = "**12345**"
> 
> 
> # Enable these sections to control battery charge/discharge on Solax SK-SU5000E inverters
> # This does a number of things:
> # 1. Allows more than 2 time periods through the day
> # 2. Allows excess generation on 1 inverter to charge an inverter on another phase instead
> #    of feeding that energy back to the grid (requires your billing meter to simply sum
> #    usage across phases)
> # 3. Allows inverters to share loads larger than what a single battery can discharge at
> # 4. Allow grid charge up to a certain level (to allow enough energy stored to see you through
> #    peak times)
> 
> #[Solax-BatteryControl]
> #source = "MainsMeter"     # The data source for power consumption
> #linked-batteries = true   # If set, all batteries charge/discharge at the same rate when trying to zero total power
> #timezone = "AEDT-10" # If set, always use this timezone for period calculations. This may be useful if your machine tracks daylight savings, but your energy provider does not
> 
> # Defines the inverters that will participate
> [Solax-BatteryControl.Inverter.solax1] # First inverter
> phase = 1                          # Which phase the inverter is connected to, as seen by the power consumption meter
> single-phase-charge-limit = 2000   # If the charge rate is below this, aim to zero our own phase, if it's above, aim to zero total power
> single-phase-discharge-limit = 2000   # If the discharge rate is below this, aim to zero our own phase, if it's above, aim to zero total power
> max-power = 5000                   # Limit the inverter output to this value
> max-charge = 2000                  # Maximum battery charge rate in Watts
> max-discharge = 2000               # Maximum battery discharge rate in Watts
> grace-capacity = 5                # Percentage of total capacity at which to stop charging to reserve for absorbing power greater than inverter output
> grace-power-threshold = 4500       # Ignore the grace capacity if PV power is greater than this
> grace-charge-power = 500           # The amount of power to charge the battery at when in the grace period
> #[Solax-BatteryControl.Inverter.solax2]
> #phase = 2
> #single-phase-charge-limit = 1000
> #single-phase-discharge-limit = 1000
> #max-charge = 2000
> #max-discharge = 2000
> #[Solax-BatteryControl.Inverter.solax3]
> #phase = 3
> #single-phase-charge-limit = 1000
> #single-phase-discharge-limit = 1000
> #max-charge = 2000
> #max-discharge = 2000
> #grace-capacity = 0
> 
> # Define the time periods
> # Suitable for ActewAGL Time of Use plans in Canberra, Australia
> # Peak times are widened in case the time on the meter drifts
> #[Solax-BatteryControl.Period.MorningPeak]
> #start = "6:55:00"      # The start time of the period
> #end = "9:05:00"        # The end time of the period
> #min-charge = 20        # The minimum % charge left in the batteries. The inverter will not discharge lower than this in this period
> #grid-charge = false    # True to charge from the grid if the charge is less than min-charge
> #force-discharge = 2000 # If set, will force the battery to discharge at this rate
> #
> [Solax-BatteryControl.Period.DayShoulderGracePeriod] # Reserve grace capacity in this period
> start = "00:00:00"
> end = "23:59:00"
> min-charge = 10        # Once charged, we don't want the battery to drop below this to give us enough to get through the following peak period
> grid-charge = false
> grace = false
> prefer-battery = false   # Solar power should go to charging the battery if battery is below mininmum
> #
> #[Solax-BatteryControl.Period.DayShoulder] # No grace capacity, aim to have the batteries fully charged
> #start = "14:00:00"
> #end = "15:55:00"
> #min-charge = 30        # Once charged, we don't want the battery to drop below this to give us enough to get through the following peak period
> #grid-charge = false
> #grace = false
> #
> # Allow charging near the end of the shoulder period (if the batteries are less than 30%)
> #[Solax-BatteryControl.Period.DayShoulderGridCharge]
> #start = "15:55:00"
> #end = "16:55:00"
> #min-charge = 30
> #grid-charge = true
> #grace = false
> #
> #[Solax-BatteryControl.Period.EveningPeak]
> #start = "16:55:00"
> #end = "20:05:00"
> #min-charge = 20
> #grid-charge = false
> #grace = false
> #
> #[Solax-BatteryControl.Period.EveningShoulder]
> #start = "20:05:00"
> #end = "22:05:00"
> #min-charge = 20
> #grid-charge = false
> #grace = false
> #
> #[Solax-BatteryControl.Period.Offpeak]
> #start = "22:05:00"
> #end = "6:55:00"
> #min-charge = 30
> #grid-charge = true
> #grace = false

Formatted text. BT - Moderator