GithubHelp home page GithubHelp logo

nmakel / solaredge_modbus Goto Github PK

View Code? Open in Web Editor NEW
136.0 136.0 33.0 7.7 MB

SolarEdge Modbus data collection library

License: MIT License

Python 99.20% Makefile 0.51% Dockerfile 0.29%
influxdb inverter modbus modbus-rtu modbus-tcp solaredge solaredge-api sunspec

solaredge_modbus's People

Contributors

capi avatar dragonq avatar jonespd avatar ljonka avatar nmakel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

solaredge_modbus's Issues

TCP Connection issues

Hello,

I've packaged this into a docker container, and using the influx script which has been working great for testing. I've noticed some weird things happening when connecting to an inverter at the TCP layer.

When I run the image on Ubuntu/RHEL, I get a TCP Socket error and the script crashes. But running on WSL ( still linux ) the script executes for a while, and then crashes. I think there's some optimizations needed at the TCP later.

Using wireshark/pfsense, I've observed;

  • WSL2/Windows10/Ubuntu/Docker - there's a lot of TCP retransmits, and TCP port number re-use
  • Linux there's a lot of FIN/ACKS is a row

Is there a way to TCP keepalive the connection? It looks very chatty and perhaps the modbus servers/inverters can't handle this? Just a hunch. This is the error received when running on plain linux, some googling found there may be async methods?

File "/usr/local/lib/python3.9/site-packages/pymodbus-2.5.0rc2-py3.9.egg/pymodbus/client/sync.py", line 108, in execute
raise ConnectionException("Failed to connect[%s]" % (self.str()))
pymodbus.exceptions.ConnectionException: Modbus Error: [Connection] Failed to connect[ModbusTcpClient(10.5.90.2:1502)]

Meter registers

Hi,

I would like to read connected Meter registers. Is it possible?

Field type conflict Field Power_Apparent in Measurement Meter

Inverter gives back different datatypes for Power_Apparent. Sometimes INT sometimes Float.

Is it possible to convert it to a float always before sending JSON to Inlflux?

Error:
input field "power_apparent" on measurement "meter" is type integer, already exists as type float dropped=1"

No example on PyPi package

Hello,

I think the package on PyPi does not contain the example.py

(solaredge_modbus) rd@home:/virtualenv/solaredge_modbus$ find -name example*
(solaredge_modbus) rd@home:
/virtualenv/solaredge_modbus$

If I download it from github it works flawless though.

Thanks
Rainer

Timeout when trying to connect...

Hi!

I have tried to establish contact with my SolarEdge inverter but sofar I always get a timeout when trying:

Inverter(192.168.10.243:502, connectionType.TCP: timeout=1, retries=3, unit=0x1):

I can see at the inverter display that Modbus over TCP is active and ready.
The inverter SW is 3.2537.

I have tried increasing the timeout but that does not help.

Anybody else with this problem?

Best regards / Leif, Sweden

Incomplete information example.py

Hello,
I used example.py script and get only below information:
`
python3 example.py 192.168.1.80 1502
Inverter(192.168.1.80:1502, connectionType.TCP: timeout=1, retries=3, unit=0x1):

Registers:
Manufacturer: SolarEdge
Model: SE6K-RW0TEBNN4
Type: Three Phase Inverter
Version: 0004.0014.0107
Serial: ######
Status: Producing
Temperature: 19.79°C
Current: 2.71A
Traceback (most recent call last):
File "/home/pi/solaredge_modbus/example.py", line 57, in
print(f"\tPhase 1 Current: {(values['l1_current'] * (10 ** values['current_scale'])):.2f}{inverter.registers['l1_current'][6]}")
KeyError: 'l1_current'
`

Showstopper on importing solaredge_modbus __init__.py

Hi nmakel,

installed newest version using pip3 today, having issues in python 3.8. Looks like a syntax error on line 184 of init.py:

jack@acer:/dev/solar$ pip3 install solaredge_modbus
Collecting solaredge_modbus
Using cached solaredge_modbus-0.6.3-py3-none-any.whl (10 kB)
Requirement already satisfied: pymodbus>=2.3.0 in /usr/local/lib/python3.8/dist-packages (from solaredge_modbus) (2.4.0)
Requirement already satisfied: pyserial>=3.4 in /usr/lib/python3/dist-packages (from pymodbus>=2.3.0->solaredge_modbus) (3.4)
Requirement already satisfied: six>=1.15.0 in /home/jack/.local/lib/python3.8/site-packages (from pymodbus>=2.3.0->solaredge_modbus) (1.15.0)
Installing collected packages: solaredge-modbus
Successfully installed solaredge-modbus-0.6.3
jack@acer:
/dev/solar$ python3
Python 3.8.5 (default, Jul 28 2020, 12:59:40)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

import solaredge_modbus
Traceback (most recent call last):
File "", line 1, in
File "/home/jack/.local/lib/python3.8/site-packages/solaredge_modbus/init.py", line 184
else
^
SyntaxError: invalid syntax

----- Lines 181-185, looks like a missing colon on "else". edited source, works ok now.

        if (parity
                and parity.upper() in ["N", "E", "O"]):
            self.parity = parity.upper()
        else
            self.parity = False

Error: ValueError: Not a valid parity: False

I just run a fresh copy following instructions and the error ValueError: Not a valid parity: False is raised. What can be the issue? Many thanks. Sorry if this is not the forum to post this issue.

Python 3.8.11 (default, Jul 22 2021, 15:32:17) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import solaredge_modbus
>>> inverter = solaredge_modbus.Inverter("192.168.86.156", 1502, 10, 1)

>>> inverter.read_all()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.8/site-packages/solaredge_modbus/__init__.py", line 354, in read_all
    results.update(self._read_all(register_batch, rtype))
  File "/usr/local/lib/python3.8/site-packages/solaredge_modbus/__init__.py", line 307, in _read_all
    data = self._read_holding_registers(offset, length)
  File "/usr/local/lib/python3.8/site-packages/solaredge_modbus/__init__.py", line 225, in _read_holding_registers
    self.connect()
  File "/usr/local/lib/python3.8/site-packages/solaredge_modbus/__init__.py", line 330, in connect
    return self.client.connect()
  File "/usr/local/lib/python3.8/site-packages/pymodbus/client/sync.py", line 652, in connect
    self.socket = serial.serial_for_url(self.port,
  File "/usr/local/lib/python3.8/site-packages/serial/__init__.py", line 87, in serial_for_url
    instance = klass(None, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/serial/serialutil.py", line 225, in __init__
    self.parity = parity
  File "/usr/local/lib/python3.8/site-packages/serial/serialutil.py", line 336, in parity
    raise ValueError("Not a valid parity: {!r}".format(parity))
ValueError: Not a valid parity: False


>>> inverter.read("c_manufacturer")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.8/site-packages/solaredge_modbus/__init__.py", line 342, in read
    return {key: self._read(self.registers[key])}
  File "/usr/local/lib/python3.8/site-packages/solaredge_modbus/__init__.py", line 273, in _read
    return self._decode_value(self._read_holding_registers(address, length), length, dtype, vtype)
  File "/usr/local/lib/python3.8/site-packages/solaredge_modbus/__init__.py", line 225, in _read_holding_registers
    self.connect()
  File "/usr/local/lib/python3.8/site-packages/solaredge_modbus/__init__.py", line 330, in connect
    return self.client.connect()
  File "/usr/local/lib/python3.8/site-packages/pymodbus/client/sync.py", line 652, in connect
    self.socket = serial.serial_for_url(self.port,
  File "/usr/local/lib/python3.8/site-packages/serial/__init__.py", line 87, in serial_for_url
    instance = klass(None, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/serial/serialutil.py", line 225, in __init__
    self.parity = parity
  File "/usr/local/lib/python3.8/site-packages/serial/serialutil.py", line 336, in parity
    raise ValueError("Not a valid parity: {!r}".format(parity))
ValueError: Not a valid parity: False

Tested with python 3.8, 3.7 and 3.9

Not working setup

I tried the modbus library for the first time. The example generates data but when i try to use the read_all i get the following.

`>>> inverter.connect()
True

inverter.connected()
True
inverter.read_all()
Traceback (most recent call last):
File "", line 1, in
File "/usr/local/lib/python3.7/dist-packages/solaredge_modbus/init.py", li ne 343, in read_all
results.update(self._read_all(register_batch, rtype))
File "/usr/local/lib/python3.7/dist-packages/solaredge_modbus/init.py", li ne 296, in _read_all
data = self._read_holding_registers(offset, length)
File "/usr/local/lib/python3.7/dist-packages/solaredge_modbus/init.py", li ne 218, in _read_holding_registers
result = self.client.read_holding_registers(address=address, count=length, u nit=self.unit)
File "/usr/local/lib/python3.7/dist-packages/pymodbus/client/common.py", line 114, in read_holding_registers
return self.execute(request)
File "/usr/local/lib/python3.7/dist-packages/pymodbus/client/sync.py", line 10 8, in execute
raise ConnectionException("Failed to connect[%s]" % (self.str()))
pymodbus.exceptions.ConnectionException: Modbus Error: [Connection] Failed to co nnect[ModbusTcpClient(192.168.2.8:1502)]
inverter.read("current")
{'current': 95}
`

Does anyone have a idea how to fix?

Strange values for energy_total

Hi Niels,

I have created a plugin for Domoticz using your library (https://github.com/addiejanssen/domoticz-solaredge-modbustcp-plugin).
It's working great for most users, but there is one user that reports strange values for the energy_total values.
Initially, we thought it was a Domoticz topic or something related to the plugin, but I think there is an issue with the values returned by either the inverter itself or your library.
Here's a dump of what comes back from Inverter.read_all() (I removed the serial number of the inverter):

{
    "c_model": "SE5K-RW0TEBNN4",
    "c_version": "0004.0010.0025",
    "c_deviceaddress": 1,
    "c_sunspec_did": 103,
    "current": 222,
    "p1_current": 67,
    "p2_current": 73,
    "p3_current": 81,
    "current_scale": -2,
    "p1_voltage": 3961,
    "p2_voltage": 3961,
    "p3_voltage": 4001,
    "p1n_voltage": 2319,
    "p2n_voltage": 2273,
    "p3n_voltage": 2291,
    "voltage_scale": -1,
    "power_ac": 18500,
    "power_ac_scale": -2,
    "frequency": 4999,
    "frequency_scale": -2,
    "power_apparent": 5078,
    "power_apparent_scale": -1,
    "power_reactive": -4730,
    "power_reactive_scale": -1,
    "power_factor": -3611,
    "power_factor_scale": -2,
    "energy_total": 1059323905,
    "energy_total_scale": 0,
    "current_dc": 25118,
    "current_dc_scale": -5,
    "voltage_dc": 7477,
    "voltage_dc_scale": -1,
    "power_dc": 18781,
    "power_dc_scale": -2,
    "temperature": 2735,
    "temperature_scale": -2,
    "status": 4,
    "vendor_status": 0
}

Looks ok, but the funny bit is the value of energy_total.
We have seen the following values comming back:

2020-10-11 15:00:00    57160500
2020-10-11 16:00:00    65182104
2020-10-11 17:00:00    20984628
2020-10-11 18:00:00     1350042

2020-10-12 08:00:00     1795686
2020-10-12 09:00:00    13434880
2020-10-12 10:00:00    27761050
2020-10-12 11:00:00    40317748
2020-10-12 12:00:00    65470464
2020-10-12 13:00:00   151807584
2020-10-12 14:00:00   127231592

2020-10-15 17:44:10  3128439603
2020-10-15 17:45:10  3128714854
2020-10-15 17:47:11  3129265356
2020-10-15 17:48:11  3129527500
2020-10-15 17:49:11  3129763430
2020-10-15 17:50:11  3129986252
2020-10-15 17:51:11  3130195968

2020-10-16 14:19:22  3658350592
2020-10-16 14:28:22  3691970560

2020-10-18 08:27:51   264896513

2020-10-20 12:21:02  1059323905

The inverter and panels are new and have been installed a few weeks ago.
According to the SolarEdge monitoring site and app, the installation produced just over 70 kWh in total so far.

All the other values are making perfect sense and seem to align with what SolarEdge is reporting as well.
It is just the energy_total that is all over the place and going up and down.

Can you help us out?

Thanks,

Addie

Is it known which models are supported?

Hi,

can you tell if the SolarEdge SE5K inverter supports modbus TCP? I only saw modbus on RS485 in the documentation, but I may have missed something.

Thanks
Rainer

NO ISSUE but QUESTION: Writing to the inverters

Hi,

Would it be possible to write data to the inverter?
I got a smart meter which gives me data about my actual import/export. It would be nice if we can send that over modbus to the interver instead of buying a compatible meter. This would save me/us money.

incomplete install output

I'm assuming the result I have is because things are not yet fully configured - but I get

./example.py --json 10.10.10.146 1502
{
    "meters": {},
    "batteries": {
        "Battery1": {},
        "Battery2": {}
    }
}

and

./example.py 10.10.10.146 1502
Inverter(10.10.10.146:1502, connectionType.TCP: timeout=1, retries=3, unit=0x1):

Registers:
Traceback (most recent call last):
  File "/home/sven/src/github/solaredge_modbus/./example.py", line 46, in <module>
    print(f"\tManufacturer: {values['c_manufacturer']}")
KeyError: 'c_manufacturer'

If I'm right, it might be useful to add this info to the docs and for the non-json output to tell the user what's probably going on :)

Works perfectly!! I Sugget to add it to the PP-MANAGER

Hi Niels,
you plugins is really very good and well documented.
I just suggest you to add it to the PP-MANAGER and Domoticz Plugins Manager:
Check https://www.domoticz.com/wiki/Plugins .
These two plugins are commonly used to install other plugins automatically, using git.
Adding your plugin to the list of plugins supported by PP-MANAGER and Domoticz Plugins Manager requires just few minutes.
Thanks a lot again for your good plugin.
Paolo

Unidecode error on Windows connecting to SE4000 inverter

Hello,

Thanks for all your good work on this module. Just installed it in Windows 10 Python 3.8.7 (64 bits) and connected to my SolarEdge inverter.

At start an error was received:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 12: invalid start byte
Changed line 247 in init.py and added the "ignore" parameter base don this link
https://stackoverflow.com/questions/42339876/error-unicodedecodeerror-utf-8-codec-cant-decode-byte-0xff-in-position-0-in
decoded = data.decode_string(length * 2).decode("utf-8", "ignore").replace("\x00", "").rstrip()

This resolved my issue and data is received from the SE4000 inverter. Will continue with uploading to influxdb and create a panel.
Hope this helps improving a future release

it seems that decoding the parameter for
"current_dc_scale": -32768,
shows incorrect value (should be -1 in stead of -32768). Will test tomorrow when system is producing if it is OK then.
GWS65

Meter data no longer working?

From last night, the meter data in my dashboards is no longer working, I have no idea if this is influx, or the python scripts, or solaredge have changed anything.

My python/docker container is still connecting to the inverter. The scripts are writing data successfully to InfluxDB. Any data such as the below no longer work and return no data, but queries referencing inverter not meter return data.

SELECT mean("power_selfconsumption") FROM "meter" WHERE ("c_serialnumber" = '606540544') AND $timeFilter GROUP BY time($__interval) fill(null)

Connection showing true regardless of Unit # and possible RTS issue?

Hey Niels,

First off great work on this library, this is saving me a ton of work and this is a somewhat new world for me (MODBUS). So this helps get me off on a great start.

I modified your example script for RS485 RTU implementation. I am connecting to a SolarEdge SE 3800H. I am on the RS485-2 and using the app I have everything configured correctly as according to technical notes document you have referenced in prior post. I added the connect method and got it to reply true. The device ID is set to 1 (via the app), I have changed it to 2 and changed the command line argument to see if it ever returns false. Regardless, it always returns true (this might happen regardless if the unit is wrong or right). From what I can tell its similar to this gentlemen's post.

I am on beaglebone (dont think it matters) and am using a PMOD RS485 to UART adapter, link here. I think I might be having RTS/flow control issues since this chip requires me to toggle the flow control. And since I can only go low on RTS (via a GPIO toggle) after the inverter read call, I think I need to get a chip that controls this automatically. like this Otherwise, I would have to hack the modbus library to handle this (to my knowledge). Since I can not toggle the pin low until after the read call returns, I think this is something period that needs to be changed.

Here is the log output below, take note the first line (connection status) and last line (the false return on a single register read).

debian@beaglebone:~$ python3 example.py /dev/ttyO4 --baud 115200 --stopbits 1 --parity N --timeout 2 --unit 2
Is inverter connected: True
2021-02-09 15:27:13 DEBUG: Current transaction state - IDLE
2021-02-09 15:27:13 DEBUG: Running transaction 1
2021-02-09 15:27:13 DEBUG: SEND: 0x2 0x3 0x9c 0x54 0x0 0x10 0x2b 0xb5
2021-02-09 15:27:13 DEBUG: New Transaction state 'SENDING'
2021-02-09 15:27:13 DEBUG: Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
2021-02-09 15:27:15 DEBUG: Transaction failed. (Modbus Error: [Invalid Message] Incomplete message received, expected at least 2 bytes (0 received))
2021-02-09 15:27:15 DEBUG: Frame - [b''] not ready
2021-02-09 15:27:15 DEBUG: Getting transaction 2
2021-02-09 15:27:15 DEBUG: Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
2021-02-09 15:27:15 DEBUG: Current transaction state - TRANSACTION_COMPLETE
2021-02-09 15:27:15 DEBUG: Running transaction 2
2021-02-09 15:27:15 DEBUG: SEND: 0x2 0x3 0x9c 0x54 0x0 0x10 0x2b 0xb5
2021-02-09 15:27:15 DEBUG: Changing state to IDLE - Last Frame End - None, Current Time stamp - 1612906035.144507
2021-02-09 15:27:15 DEBUG: New Transaction state 'SENDING'
2021-02-09 15:27:15 DEBUG: Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
2021-02-09 15:27:17 DEBUG: Incomplete message received, Expected 37 bytes Recieved 0 bytes !!!!
2021-02-09 15:27:17 DEBUG: Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
2021-02-09 15:27:17 DEBUG: RECV:
2021-02-09 15:27:17 DEBUG: Frame - [b''] not ready
2021-02-09 15:27:17 DEBUG: Getting transaction 2
2021-02-09 15:27:17 DEBUG: Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
2021-02-09 15:27:17 DEBUG: Current transaction state - TRANSACTION_COMPLETE
2021-02-09 15:27:17 DEBUG: Running transaction 3
2021-02-09 15:27:17 DEBUG: SEND: 0x2 0x3 0x9c 0x54 0x0 0x10 0x2b 0xb5
2021-02-09 15:27:17 DEBUG: Changing state to IDLE - Last Frame End - 1612906037.156145, Current Time stamp - 1612906037.177895
2021-02-09 15:27:17 DEBUG: New Transaction state 'SENDING'
2021-02-09 15:27:17 DEBUG: Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
2021-02-09 15:27:19 DEBUG: Incomplete message received, Expected 37 bytes Recieved 0 bytes !!!!
2021-02-09 15:27:19 DEBUG: Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
2021-02-09 15:27:19 DEBUG: RECV:
2021-02-09 15:27:19 DEBUG: Frame - [b''] not ready
2021-02-09 15:27:19 DEBUG: Getting transaction 2
2021-02-09 15:27:19 DEBUG: Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
{'c_model': False}

Any help or guidance be appreciated.

Thank you in advance.

Battery data in InfluxDB

Hi Niels.

Sincere thanks for the awesome work on solaredge_modbus. Within 2 hours of configuring the RS485 connection to my Pi4, your project had me displaying real-time data in Grafana - Outstanding!

I have however hit an issue with the Battery data being added to InfluxDB using your "example_influxdb.py" utility.

If I run "example.py --json" I get the following output with full details of my currently connected LG Battery (Battery1) :

pi@powerlog:~/solaredge $ ./example.py --json
{
    "c_manufacturer": "SolarEdge",
    "c_model": "SE6000",
    "c_version": "0003.2724",
    "c_serialnumber": "7F??????",
    "c_deviceaddress": 126,
    "c_sunspec_did": 101,
    "current": 5773,
    "p1_current": 5773,
    "p2_current": 0,
    "p3_current": 0,
    "current_scale": -3,
    "p1_voltage": 2390,
    "p2_voltage": 0,
    "p3_voltage": 0,
    "p1n_voltage": 0,
    "p2n_voltage": 0,
    "p3n_voltage": 0,
    "voltage_scale": -1,
    "power_ac": 13730,
    "power_ac_scale": -1,
    "frequency": 49979,
    "frequency_scale": -3,
    "power_apparent": 13755,
    "power_apparent_scale": -1,
    "power_reactive": -8300,
    "power_reactive_scale": -2,
    "power_factor": 9981,
    "power_factor_scale": -2,
    "energy_total": 19552816,
    "energy_total_scale": 0,
    "current_dc": 3341,
    "current_dc_scale": -3,
    "voltage_dc": 4172,
    "voltage_dc_scale": -1,
    "power_dc": 13939,
    "power_dc_scale": -1,
    "temperature": 2496,
    "temperature_scale": -2,
    "status": 4,
    "vendor_status": 0,
    "rrcr_state": 0,
    "active_power_limit": 100,
    "cosphi": 0,
    "meters": {
        "Meter1": {
            "c_manufacturer": "WattNode",
            "c_model": "WND-3Y-400-MB",
            "c_option": "Export+Import",
            "c_version": "31",
            "c_serialnumber": "50?????",
            "c_deviceaddress": 2,
            "c_sunspec_did": 203,
            "current": 11,
            "p1_current": 0,
            "p2_current": 0,
            "p3_current": 11,
            "current_scale": -1,
            "voltage_ln": 23918,
            "p1n_voltage": 23918,
            "p2n_voltage": 23927,
            "p3n_voltage": 23724,
            "voltage_ll": -24216,
            "p12_voltage": -24161,
            "p23_voltage": -24171,
            "p31_voltage": -24317,
            "voltage_scale": -2,
            "frequency": 4996,
            "frequency_scale": -2,
            "power": 36,
            "p1_power": 0,
            "p2_power": 0,
            "p3_power": 36,
            "power_scale": 0,
            "power_apparent": 41,
            "p1_power_apparent": 0,
            "p2_power_apparent": 0,
            "p3_power_apparent": 41,
            "power_apparent_scale": 0,
            "power_reactive": -19,
            "p1_power_reactive": 0,
            "p2_power_reactive": 0,
            "p3_power_reactive": -19,
            "power_reactive_scale": 0,
            "power_factor": 6945,
            "p1_power_factor": 10000,
            "p2_power_factor": 10000,
            "p3_power_factor": 835,
            "power_factor_scale": -2,
            "export_energy_active": 7629117,
            "p1_export_energy_active": 0,
            "p2_export_energy_active": 1689533,
            "p3_export_energy_active": 6030760,
            "import_energy_active": 16422941,
            "p1_import_energy_active": 0,
            "p2_import_energy_active": 2831511,
            "p3_import_energy_active": 13682604,
            "energy_active_scale": 0,
            "export_energy_apparent": 0,
            "p1_export_energy_apparent": 0,
            "p2_export_energy_apparent": 0,
            "p3_export_energy_apparent": 0,
            "import_energy_apparent": 0,
            "p1_import_energy_apparent": 0,
            "p2_import_energy_apparent": 0,
            "p3_import_energy_apparent": 0,
            "energy_apparent_scale": -32768,
            "import_energy_reactive_q1": 0,
            "p1_import_energy_reactive_q1": 0,
            "p2_import_energy_reactive_q1": 0,
            "p3_import_energy_reactive_q1": 0,
            "import_energy_reactive_q2": 0,
            "p1_import_energy_reactive_q2": 0,
            "p2_import_energy_reactive_q2": 0,
            "p3_import_energy_reactive_q2": 0,
            "export_energy_reactive_q3": 0,
            "p1_export_energy_reactive_q3": 0,
            "p2_export_energy_reactive_q3": 0,
            "p3_export_energy_reactive_q3": 0,
            "export_energy_reactive_q4": 0,
            "p1_export_energy_reactive_q4": 0,
            "p2_export_energy_reactive_q4": 0,
            "p3_export_energy_reactive_q4": 0,
            "energy_reactive_scale": -32768
        }
    },
    "batteries": {
        "Battery1": {
            "c_manufacturer": "LG\u0001\u0018\u00021807057059",
            "c_model": "R15563P3SSEG11807057059",
            "c_version": "DCDC 7.4.7 BMS 1.4.6.0",
            "c_serialnumber": "18????????",
            "c_deviceaddress": 15,
            "c_sunspec_did": 0,
            "rated_energy": 9800.0,
            "maximum_charge_continuous_power": 5000.0,
            "maximum_discharge_continuous_power": 5000.0,
            "maximum_charge_peak_power": 5000.0,
            "maximum_discharge_peak_power": 5000.0,
            "average_temperature": 18.600000381469727,
            "maximum_temperature": 0.0,
            "instantaneous_voltage": 417.1000061035156,
            "instantaneous_current": -3.3996644020080566,
            "instantaneous_power": -1418.0,
            "lifetime_export_energy_counter": 2051,
            "lifetime_import_energy_counter": 129,
            "maximum_energy": 9800.0,
            "available_energy": 8239.0,
            "soh": 88.5,
            "soe": 46.49835968017578,
            "status": 4,
            "status_internal": 3,
            "event_log": 0,
            "event_log_internal": 0
        },
        "Battery2": {
            "c_manufacturer": "\u0002",
            "c_model": "False",
            "c_version": "False",
            "c_serialnumber": "False",
            "c_deviceaddress": 14,
            "c_sunspec_did": 0,
            "rated_energy": -3.4028234663852886e+38,
            "maximum_charge_continuous_power": -3.4028234663852886e+38,
            "maximum_discharge_continuous_power": -3.4028234663852886e+38,
            "maximum_charge_peak_power": -3.4028234663852886e+38,
            "maximum_discharge_peak_power": -3.4028234663852886e+38,
            "average_temperature": -3.4028234663852886e+38,
            "maximum_temperature": 0.0,
            "instantaneous_voltage": -3.4028234663852886e+38,
            "instantaneous_current": -3.4028234663852886e+38,
            "instantaneous_power": 0.0,
            "lifetime_export_energy_counter": 0,
            "lifetime_import_energy_counter": 0,
            "maximum_energy": -3.4028234663852886e+38,
            "available_energy": -3.4028234663852886e+38,
            "soh": -3.4028234663852886e+38,
            "soe": -3.4028234663852886e+38,
            "status": 7,
            "status_internal": 0,
            "event_log": 0,
            "event_log_internal": 0
        }
    }
}

Note that although my SE6000 inverter can support a second Battery, "Battery2" shown in the above output does not currently exist.

On checking the contents of my InfluxDB database, it appears that the metrics from the non-existent "Battery2" are the only ones that have been added by the "example_influxdb.py" utility. Also note that the manufacturer, model, etc. of the inverter itself have been associated with the Battery data :

> select * from battery
name: battery
time                available_energy        average_temperature     c_deviceaddress c_deviceaddress_1 c_manufacturer c_model c_serialnumber c_sunspec_did c_sunspec_did_1 c_version event_log event_log_internal instantaneous_current   instantaneous_power instantaneous_voltage   lifetime_export_energy_counter lifetime_import_energy_counter maximum_charge_continuous_power maximum_charge_peak_power maximum_discharge_continuous_power maximum_discharge_peak_power maximum_energy          maximum_temperature rated_energy            soe                     soh                     status status_internal
----                ----------------        -------------------     --------------- ----------------- -------------- ------- -------------- ------------- --------------- --------- --------- ------------------ ---------------------   ------------------- ---------------------   ------------------------------ ------------------------------ ------------------------------- ------------------------- ---------------------------------- ---------------------------- --------------          ------------------- ------------            ---                     ---                     ------ ---------------
1633513058000000000 -3.4028234663852886e+38 -3.4028234663852886e+38 14              126               SolarEdge      SE6000  7F??????       0             101             0003.2724 0         0                  -3.4028234663852886e+38 0                   -3.4028234663852886e+38 0                              0                              -3.4028234663852886e+38         -3.4028234663852886e+38   -3.4028234663852886e+38            -3.4028234663852886e+38      -3.4028234663852886e+38 0                   -3.4028234663852886e+38 -3.4028234663852886e+38 -3.4028234663852886e+38 7      0
1633513069000000000 -3.4028234663852886e+38 -3.4028234663852886e+38 14              126               SolarEdge      SE6000  7F??????       0             101             0003.2724 0         0                  -3.4028234663852886e+38 0                   -3.4028234663852886e+38 0                              0                              -3.4028234663852886e+38         -3.4028234663852886e+38   -3.4028234663852886e+38            -3.4028234663852886e+38      -3.4028234663852886e+38 0                   -3.4028234663852886e+38 -3.4028234663852886e+38 -3.4028234663852886e+38 7      0

Could you please provide some guidance on what changes I would need to make to the "example_influxdb.py" utility to allow the metrics for "Battery1" to be successfully added to InfluxDB ?

Many thanks in advance.
Darren

Reading different units through same (master) inverter

Hi,
I'm the creator of a home-assistant integration for solaredge through modbus. Based on some issues created in my repo, I went to search a better native library than my own... One of the issues talked about in my repo is about connecting multiple slave units through one master unit. The slaves are accessed through IP/Port of the master, and I strongly doubt if for this case multiple connections would be allowed as it's also not the case for eg. meters/batteries . At this time you are already supporting a parent in order to share the modbus client and use a single TCP connection. But at the moment the unit of the parent is always taken over by the child. Do you think it would be an option that another Inverter, which acts as a modbus slave, can be instantiated with a parent (Master) Inverter argument, but without defacto sharing the unitId? I add the setup picture of the solaredge manual to make the situation a bit more clear:
solareedge_modbus

Unable to connect to TCP Modbus after upgrade to 4.14.107

Hi, for starters great project, I'm using this Python module for primary monitoring of my PV installation. This is maybe not an issue for module itself, but more like a question. whether anyone else experience same issue as I did just now, when I upgraded my SolarEdge SE7K-RW0TEBNN4 inverter via SetApp from version for CPU 4.13.x to 4.14.107. After that I get connection refused errors when trying to connect to 1502 port, tried to disable TCP Modbus or change the port number, but nothing helps. Anyone else with same issue, or better - any solution?

generalized sunspec

Hi,

Is there anything that is actually SolarEdge specific in here?
SunSpec is not Solaredge specific, so as long as all is SunSpec, would you consider renaming your SolarEdge class to e.g. SunSpec and the project?

PS: can you also add a disconnect/close function, or would you prefer me to make a PR?

Thanks for your work!

Modbus RTU 32-bit Floats Not decoded in correct order

I'm talking to a SolarEdge SE7600 on a Modbus RTU connection. When I read the CosPhi register using this library (register address 0xF002) which has a default value of 1.0 (0x3F800000) and which is reported in the RTU Modbus device reply packet as 0x010304 00003F80 EA63 the decode_32bit_float isn't correctly interpreting this as a 1.0 (probably due to inconsistencies in Modbus 32bit float conventions), but it's interpreting it 16-bitwise backwards as best I can tell. I also tried this for other registers (the handling for which haven't yet been implemented here) in the "Technical Note – Power Control Protocol for SolarEdge Inverters" document and the results are consistent in that it appears that the 32bit floats are decoded out of order (16-bitwise backwards).

Connection lost after 24h

hi,

when running your script i get a disconnect every 24h. cant find out what the problem ist.
Attached ist the error code:

Traceback (most recent call last):
File "read_PV_modbus.py", line 51, in
values = inverter.read_all()
File "/usr/local/lib/python3.7/dist-packages/solaredge_modbus/init.py", line 354, in read_all
results.update(self._read_all(register_batch, rtype))
File "/usr/local/lib/python3.7/dist-packages/solaredge_modbus/init.py", line 307, in _read_all
data = self._read_holding_registers(offset, length)
File "/usr/local/lib/python3.7/dist-packages/solaredge_modbus/init.py", line 229, in _read_holding_registers
result = self.client.read_holding_registers(address, length, unit=self.unit)
File "/usr/local/lib/python3.7/dist-packages/pymodbus/client/common.py", line 114, in read_holding_registers
return self.execute(request)
File "/usr/local/lib/python3.7/dist-packages/pymodbus/client/sync.py", line 109, in execute
return self.transaction.execute(request)
File "/usr/local/lib/python3.7/dist-packages/pymodbus/transaction.py", line 177, in execute
broadcast=broadcast
File "/usr/local/lib/python3.7/dist-packages/pymodbus/transaction.py", line 290, in _transact
result = self._recv(response_length, full)
File "/usr/local/lib/python3.7/dist-packages/pymodbus/transaction.py", line 321, in _recv
read_min = self.client.framer.recvPacket(min_size)
File "/usr/local/lib/python3.7/dist-packages/pymodbus/framer/init.py", line 49, in recvPacket
return self.client.recv(size)
File "/usr/local/lib/python3.7/dist-packages/pymodbus/client/sync.py", line 89, in recv
return self._recv(size)
File "/usr/local/lib/python3.7/dist-packages/pymodbus/client/sync.py", line 299, in recv
size, data, time.time() - time
)
File "/usr/local/lib/python3.7/dist-packages/pymodbus/client/sync.py", line 343, in _handle_abrupt_socket_close
raise ConnectionException(msg)
pymodbus.exceptions.ConnectionException: Modbus Error: [Connection] ModbusTcpClient(192.168.0.60:1502): Connection unexpectedly closed 0.000085 seconds into read of 8 bytes without response from unit before it closed connection
Traceback (most recent call last):
File "read_PV_modbus.py", line 61, in
"c_manufacturer": values["c_manufacturer"],
KeyError: 'c_manufacturer'

Dont' see battery or meters information

Hi,

I have three inverts (and 1 meter) and 1 battery. But I don't see that back in the JSON export. I see this data in the solaredge app, but not in this script. Any idea what I need to do? Below the output and the last two arrays are empty.

2022-09-30_10-58-10

active_power_limit

Does anybody understand how to use/interpret the value "active_power_limit" field that is returned in the json data? It is an integer between 1 and 100. It seems to be related to setting an Export Limit. eg I have a 10kw inverter, and the export limit is set to 5kw. If it is (probably) generating 10kw and exporting 5kw, it will have a value of 50, if it is generating under 5kw, it will have a value of 100. If it is between 5 and 10kw, but it is all being used, ie none is being curtailed, then it will also show 100. I would have thought dividing the AC Power value by this number would show the uncurtailed value, but it doesnt seem to quite work that way. It isnt in the Sunspec documentation either.

Connection problem

Hi,

When I run the example file with my IP and port of my solaredge main convert (have in total 3 + battery) I get this error directly:

pymodbus.exceptions.ConnectionException: Modbus Error: [Connection] ModbusTcpClient(192.168.1.246:502): Connection unexpectedly closed 0.000037 seconds into read of 8 bytes without response from unit before it closed connection

I know for sure that I can connect to this IP and port, becasue with NodeRed I can read the modbus via the modbus module there. Any thoughts?

Unable to communicate with the inververter

Thank you, your examples and codes helped me a lot.
I have 3 units in my system, and I tried to test communication with each of them using different unit values 1, 2 and 3. But only got respond for two inverters, I couldn't receive response from second inverter. usage: example.py [-h] [--timeout TIMEOUT] [--unit UNIT] [--json] host port
Also I couldn't grasp how and when to use multiple inverters part. Shall I all these commands as they are

Master inverter over Modbus TCP >>> master = solaredge_modbusinverter(host="10.0.0.123", port=1502, unit=1)

Second inverter using master's connection >>> second = solaredge_modbusinverter(parent=master, unit=2)

Third inverter >>> third = solaredge_modbus.lnverter(parent=master, unit=3)

Or shall I modify other commands in the example.py to see all there inverter data in one query.

current_scale glitch

Hi,

I just reviewed example.py and found that

print(f"\tCurrent: {(values['current'] * (10 ** values['temperature_scale'])):.2f}{inverter.registers['current'][6]}")

should probably be

print(f"\tCurrent: {(values['current'] * (10 ** values['current_scale'])):.2f}{inverter.registers['current'][6]}")

Both are reported by my inverter as -2, so this does not make a functional difference for me right now.

How tp change configuration?

I am fairly new to HASS and learn about all the "quirks".
One thing that is very frustrating is the missing (easy) ability to change settings on "integrations".
If I want to add a meter to the SolarEdge Modbus configuration after the initial configuration, how can I do this? I would expect somewhere to get to the dialog that was showing during the first installation of the integration. Do I miss something?

Also, I do have two inverters setup as Leader and Follower via RS485. I do not see an option to configure this anywhere. I can set my second inverter to use Modbus TCP as well but there is no way to install "two" integrations of the same type (IP Address of the second inverter is different).

Again, might be me as a HASS newbee ;)

Sample dashboards / grafana

Hi, thanks a tonne for this project, it's quite awesome!

I've used your sample influx script to dump the data to influxdb, and have Grafana plugged in over the top and been able to create a few graphs such as power usage, production, temp monitors, and wondering if you have anything built or what you use to visualize the data.

The few metrics I have are great, but its a bit funky trying to match some of the data to mirror the solaredge cloud, ie total kWh per day, or what sort of voltages I should be looking at.

solardasg

Power of Meter and Inverter not matching

Hi,

i try to use the module on an SE82.8K, (on an SE10 it works perfect) and i get this data:
{'c_manufacturer': 'SolarEdge',
'c_model': 'SE82.8K-RW0P0BNA4',
'c_version': '0004.0015.0119',
'c_serialnumber': '7E08B1DA',
'c_deviceaddress': 1,
'c_sunspec_did': 103,
'current': 11017,
'l1_current': 3665,
'l2_current': 3678,
'l3_current': 3672,
'current_scale': -2,
'l1_voltage': 4065,
'l2_voltage': 4062,
'l3_voltage': 4056,
'l1n_voltage': 2341,
'l2n_voltage': 2339,
'l3n_voltage': 2351,
'voltage_scale': -1,
'power_ac': 25859,
'power_ac_scale': 0,
'frequency': 5000,
'frequency_scale': -2,
'power_apparent': 25892,
'power_apparent_scale': 0,
'power_reactive': -13130,
'power_reactive_scale': -1,
'power_factor': -9986,
'power_factor_scale': -2,
'energy_total': 172573312,
'energy_total_scale': 0,
'current_dc': 35090,
'current_dc_scale': -3,
'voltage_dc': 0,
'voltage_dc_scale': -32768,
'power_dc': 26252,
'power_dc_scale': 0,
'temperature': 5405,
'temperature_scale': -2,
'status': 4,
'vendor_status': 0,
'rrcr_state': 0,
'active_power_limit': 100,
'cosphi': 0}

{'c_manufacturer': '&P\x02\x7f\x02%[l\x02P\x03P:\x16\x01R0 \x05',

'c_model': 'False',
'c_option': 'False',
'c_version': 'False',
'c_serialnumber': 'False',
'c_deviceaddress': 0,
'c_sunspec_did': 32768,
'current': 0,
'l1_current': 701,
'l2_current': 153,
'l3_current': 2,
'current_scale': 1,
'voltage_ln': -1,
'l1n_voltage': 1,
'l2n_voltage': 0,
'l3n_voltage': 0,
'voltage_ll': -1,
'l12_voltage': -1,
'l23_voltage': 2823,
'l31_voltage': 2826,
'voltage_scale': -126,
'frequency': 99,
'frequency_scale': -32768,
'power': 4069,
'l1_power': 2349,
'l2_power': 0,
'l3_power': -15562,
'power_scale': -1,
'power_apparent': -1,
'l1_power_apparent': -1,
'l2_power_apparent': -1,
'l3_power_apparent': -1,
'power_apparent_scale': -1,
'power_reactive': -1,
'l1_power_reactive': -1,
'l2_power_reactive': -1,
'l3_power_reactive': -1,
'power_reactive_scale': -1,
'power_factor': -1,
'l1_power_factor': -1,
'l2_power_factor': -1,
'l3_power_factor': -1,
'power_factor_scale': -1,
'export_energy_active': 2147516416,
'l1_export_energy_active': 2147516416,
'l2_export_energy_active': 2147516416,
'l3_export_energy_active': 2147516416,
'import_energy_active': 2147549183,
'l1_import_energy_active': 0,
'l2_import_energy_active': 154009599,
'l3_import_energy_active': 0,
'energy_active_scale': -1,
'export_energy_apparent': 0,
'l1_export_energy_apparent': 0,
'l2_export_energy_apparent': 0,
'l3_export_energy_apparent': 0,
'import_energy_apparent': 0,
'l1_import_energy_apparent': 0,
'l2_import_energy_apparent': 2147516416,
'l3_import_energy_apparent': 2147549183,
'energy_apparent_scale': -1,
'import_energy_reactive_q1': 4294904108,
'l1_import_energy_reactive_q1': 0,
'l2_import_energy_reactive_q1': 0,
'l3_import_energy_reactive_q1': 0,
'import_energy_reactive_q2': 0,
'l1_import_energy_reactive_q2': 0,
'l2_import_energy_reactive_q2': 0,
'l3_import_energy_reactive_q2': 0,
'export_energy_reactive_q3': 0,
'l1_export_energy_reactive_q3': 2147516416,
'l2_export_energy_reactive_q3': 2147549183,
'l3_export_energy_reactive_q3': 0,
'export_energy_reactive_q4': 154337279,
'l1_export_energy_reactive_q4': 0,
'l2_export_energy_reactive_q4': 0,
'l3_export_energy_reactive_q4': 0,
'energy_reactive_scale': -1}

There is an error in the power of the meter, the one from the inverter has 'power_ac': 25859, and the Meter has 'power': 4069, which is not true. it must be also around 24000 at this moment. i think there is something wrong.
How can this be fixed.

Is there a way to get import power, export power and used in home power?

Thanks
Alex

inverter.read_all() not returning some keys

Hi,
In version 0.6.5, example.py does not seem to want to return the following keys ''c_manufacturer': 'SolarEdge', 'c_model': 'SE5000', 'c_version': '0003.2312', 'c_serialnumber': '7F1718EA', 'c_deviceaddress': 1" all other keys are returned starting with 'c_sunspec_did'.

It works in version 0.6.3 which is where the keylist above was obtained from.

So in example.py, line 29 values = inverter.read_all()

returns this dictionary:
{'c_manufacturer': 'SolarEdge', 'c_model': 'SE5000', 'c_version': '0003.2312', 'c_serialnumber': '7F1718EA', 'c_deviceaddress': 1, 'c_sunspec_did': 101, 'current': 13351, 'p1_current': 13351, 'p2_current': 0, 'p3_current': 0, 'current_scale': -3, 'p1_voltage': 2492, 'p2_voltage': 0, 'p3_voltage': 0, 'p1n_voltage': 0, 'p2n_voltage': 0, 'p3n_voltage': 0, 'voltage_scale': -1, 'power_ac': 3318, 'power_ac_scale': 0, 'frequency': 50018, 'frequency_scale': -3, 'power_apparent': 3323, 'power_apparent_scale': 0, 'power_reactive': 19400, 'power_reactive_scale': -2, 'power_factor': -9983, 'power_factor_scale': -2, 'energy_total': 15334336, 'energy_total_scale': 0, 'current_dc': 7543, 'current_dc_scale': -3, 'voltage_dc': 4465, 'voltage_dc_scale': -1, 'power_dc': 3368, 'power_dc_scale': 0, 'temperature': 2647, 'temperature_scale': -2, 'status': 5, 'vendor_status': 0}

In version 0.6.5 it returns this:
{'c_sunspec_did': 101, 'current': 15000, 'p1_current': 15000, 'p2_current': 0, 'p3_current': 0, 'current_scale': -3, 'p1_voltage': 2492, 'p2_voltage': 0, 'p3_voltage': 0, 'p1n_voltage': 0, 'p2n_voltage': 0, 'p3n_voltage': 0, 'voltage_scale': -1, 'power_ac': 3732, 'power_ac_scale': 0, 'frequency': 49990, 'frequency_scale': -3, 'power_apparent': 3736, 'power_apparent_scale': 0, 'power_reactive': 17500, 'power_reactive_scale': -2, 'power_factor': -9984, 'power_factor_scale': -2, 'energy_total': 15334366, 'energy_total_scale': 0, 'current_dc': 8546, 'current_dc_scale': -3, 'voltage_dc': 4432, 'voltage_dc_scale': -1, 'power_dc': 3788, 'power_dc_scale': 0, 'temperature': 2682, 'temperature_scale': -2, 'status': 5, 'vendor_status': 0}

I tried version 0.6.4 but I get the error 'UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 12: invalid start byte'. I assume this is related to #21.

In version 0.6.5, if I comment out the printing of the above keys, I get:

Inverter(xxxxxxxxxxxx:502, connectionType.TCP: timeout=1, retries=3, unit=0x1):

Registers:
Type: Single Phase Inverter
Status: Producing (Throttled)
Temperature: 26.82°C
Current: 150.00A
Voltage: 249.20V
Frequency: 49.99Hz
Power: 3732.00W
Power (Apparent): 3736.00VA
Power (Reactive): 175.00VAr
Power Factor: -99.84%
Total Energy: 15334366Wh
DC Current: 8.55A
DC Voltage: 443.20V
DC Power: 3788.00W

Second battery returning invalid unicode

Hello all,

having issues reading via Modbus/TCP on a SolarEdge SE7600A-US inverter with two LG Chem RESU10H batteries. Inverter and first battery returning queries via Modbus/TCP just fine. Second battery... not so much. Looks to me like registers on battery 2 are overlapping with battery 1.

I've tried changing the decode at line 244 from UTF-8 to ISO-8859-1 and latin-1 to no resolution.

Attaching screenshots with serial numbers redacted for privacy. Glad to open up the modbus connection to you nmakel if you can provide an IP address.

inverter.read('c_model')
{'c_model': 'SE7600'}
inverter.read('c_version')
{'c_version': '0003.2618'}

batteries = inverter.batteries()
print(inverter.batteries())
{'Battery1': Battery1(172.26.7.155:502, connectionType.TCP: timeout=1, retries=3, unit=0x1), 'Battery2': Battery2(172.26.7.155:502, connectionType.TCP: timeout=1, retries=3, unit=0x1)}
battery1 = batteries['Battery1']
battery2 = batteries['Battery2']

values=batteries['Battery1'].read_all()
print(values)
{'c_manufacturer': 'LG\x01\x18\x029999999999', 'c_model': 'R15563P3SSEG19999999999', 'c_version': 'DCDC 7.4.8 BMS 1.7.0.1', 'c_serialnumber': '9999999999', 'c_deviceaddress': 15, 'c_sunspec_did': 0, 'rated_energy': 9800.0, 'maximum_charge_continuous_power': 5000.0, 'maximum_discharge_continuous_power': 5000.0, 'maximum_charge_peak_power': 5000.0, 'maximum_discharge_peak_power': 5000.0, 'average_temperature': 23.399999618530273, 'maximum_temperature': 0.0, 'instantaneous_voltage': 408.29998779296875, 'instantaneous_current': 1.8466814756393433, 'instantaneous_power': 754.0, 'lifetime_export_energy_counter': 0, 'lifetime_import_energy_counter': 5768, 'maximum_energy': 9800.0, 'available_energy': 9310.0, 'soh': 100.0, 'soe': 84.48979949951172, 'status': 3, 'status_internal': 3, 'event_log': 0, 'event_log_internal': 0}

values=batteries['Battery2'].read_all()
Traceback (most recent call last):
File "", line 1, in
File "/home/jack/.local/lib/python3.8/site-packages/solaredge_modbus/init.py", line 343, in read_all
results.update(self._read_all(register_batch, rtype))
File "/home/jack/.local/lib/python3.8/site-packages/solaredge_modbus/init.py", line 311, in _read_all
results[k] = self._decode_value(data, length, dtype, vtype)
File "/home/jack/.local/lib/python3.8/site-packages/solaredge_modbus/init.py", line 244, in _decode_value
decoded = data.decode_string(length * 2).decode("utf-8").replace("\x00", "").rstrip()
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbb in position 19: invalid start byte

Example.py, 3-phase voltages, correct?

In example.py all 3-phase voltages are the same (inverter.registers['p1_voltage']) ? Is this correct?

print(f"\tPhase 1 voltage: {(values['p1_voltage'] * (10 ** values['voltage_scale'])):.2f}{inverter.registers['p1_voltage'][6]}")
print(f"\tPhase 2 voltage: {(values['p1_voltage'] * (10 ** values['voltage_scale'])):.2f}{inverter.registers['p1_voltage'][6]}")
print(f"\tPhase 3 voltage: {(values['p1_voltage'] * (10 ** values['voltage_scale'])):.2f}{inverter.registers['p1_voltage'][6]}")

Thanks in advance, Thanks for writing this module.

Adding additional parameters

I'm not sure if this would work, but here is a list of ModBus parameters that include additional ones (for example related to the battery) which are currently not supported:
Power Control Open Protocol for SolarEdge Inverters.pdf
(from https://www.photovoltaikforum.com/core/attachment/157903-power-control-open-protocol-for-solaredge-inverters-pdf/)

I would specifically be interested in those from the Global StorEdge Control Block (starting from E004 onwards), if possible in both read and write mode. This could be used to implement a software-controlled charge management either consumption/time-based or with even more complex dependencies on other devices.

Would this be possible to implement?

Read data multiple times from Webserver

Hi,
I tried to get data over web server as JSON format.
I can get data the first time I load the page on my Browser, but the second call and all other get empty data.
I'm not a python dev then I think it's an error of my code.

Here is my web server

from http.server import BaseHTTPRequestHandler, HTTPServer
import time
import argparse
import json
import solaredge_modbus

hostName = "0.0.0.0"
serverPort = 8000

class MyServer(BaseHTTPRequestHandler):

    def do_GET(self):
        inverter = solaredge_modbus.Inverter(
            host="XX.XX.XX.XX",
            port=1502,
        )
        values = {}
        values = inverter.read_all()
        meters = inverter.meters()
        batteries = inverter.batteries()
        values["meters"] = {}
        values["batteries"] = {}

        for meter, params in meters.items():
            meter_values = params.read_all()
            values["meters"][meter] = meter_values

        for battery, params in batteries.items():
            battery_values = params.read_all()
            values["batteries"][battery] = battery_values

        #print(json.dumps(values, indent=4))


        self.send_response(200)
        self.send_header("Content-type", "application/json")
        self.end_headers()
        self.wfile.write(bytes(json.dumps(values, ensure_ascii=False), 'UTF-8'))

if __name__ == "__main__":
    webServer = HTTPServer((hostName, serverPort), MyServer)
    print("Server started http://%s:%s" % (hostName, serverPort))

    try:
        webServer.serve_forever()
    except KeyboardInterrupt:
        pass

    webServer.server_close()
    print("Server stopped.")

And the first load is

{
  "c_manufacturer": "SolarEdge",
  "c_model": "SE10K-RW0TEBEN4",
  "c_version": "0004.0015.0119",
  "c_serialnumber": "XXX",
  "c_deviceaddress": 1,
  "c_sunspec_did": 103,
  "current": 1274,
  "l1_current": 426,
  "l2_current": 426,
  "l3_current": 421,
  "current_scale": -2,
  "l1_voltage": 4140,
  "l2_voltage": 4116,
  "l3_voltage": 4126,
  "l1n_voltage": 2395,
  "l2n_voltage": 2380,
  "l3n_voltage": 2373,
  "voltage_scale": -1,
  "power_ac": 29082,
  "power_ac_scale": -1,
  "frequency": 5000,
  "frequency_scale": -2,
  "power_apparent": 3037,
  "power_apparent_scale": 0,
  "power_reactive": -8750,
  "power_reactive_scale": -1,
  "power_factor": -9575,
  "power_factor_scale": -2,
  "energy_total": 309673,
  "energy_total_scale": 0,
  "current_dc": 3936,
  "current_dc_scale": -3,
  "voltage_dc": 7500,
  "voltage_dc_scale": -1,
  "power_dc": 29525,
  "power_dc_scale": -1,
  "temperature": 4640,
  "temperature_scale": -2,
  "status": 4,
  "vendor_status": 0,
  "rrcr_state": 0,
  "active_power_limit": 100,
  "cosphi": 0,
  "meters": {
    "Meter1": {
      "c_manufacturer": "SolarEdge",
      "c_model": "SE-MTR-3Y-400V-A",
      "c_option": "Export+Import",
      "c_version": "75",
      "c_serialnumber": "XXX",
      "c_deviceaddress": 2,
      "c_sunspec_did": 203,
      "current": 91,
      "l1_current": 38,
      "l2_current": 33,
      "l3_current": 19,
      "current_scale": -1,
      "voltage_ln": 23863,
      "l1n_voltage": 23863,
      "l2n_voltage": 23844,
      "l3n_voltage": 23660,
      "voltage_ll": 0,
      "l12_voltage": 0,
      "l23_voltage": 0,
      "l31_voltage": 0,
      "voltage_scale": -2,
      "frequency": 5000,
      "frequency_scale": -2,
      "power": 1853,
      "l1_power": 879,
      "l2_power": 777,
      "l3_power": 196,
      "power_scale": 0,
      "power_apparent": 1977,
      "l1_power_apparent": 914,
      "l2_power_apparent": 779,
      "l3_power_apparent": 431,
      "power_apparent_scale": 0,
      "power_reactive": 687,
      "l1_power_reactive": 250,
      "l2_power_reactive": 53,
      "l3_power_reactive": 384,
      "power_reactive_scale": 0,
      "power_factor": -7903,
      "l1_power_factor": -9570,
      "l2_power_factor": -9909,
      "l3_power_factor": -4230,
      "power_factor_scale": -2,
      "export_energy_active": 201020,
      "l1_export_energy_active": 88102,
      "l2_export_energy_active": 85953,
      "l3_export_energy_active": 39579,
      "import_energy_active": 54273,
      "l1_import_energy_active": 14174,
      "l2_import_energy_active": 12512,
      "l3_import_energy_active": 40202,
      "energy_active_scale": 0,
      "export_energy_apparent": 0,
      "l1_export_energy_apparent": 0,
      "l2_export_energy_apparent": 0,
      "l3_export_energy_apparent": 0,
      "import_energy_apparent": 0,
      "l1_import_energy_apparent": 0,
      "l2_import_energy_apparent": 0,
      "l3_import_energy_apparent": 0,
      "energy_apparent_scale": -32768,
      "import_energy_reactive_q1": 0,
      "l1_import_energy_reactive_q1": 0,
      "l2_import_energy_reactive_q1": 0,
      "l3_import_energy_reactive_q1": 0,
      "import_energy_reactive_q2": 0,
      "l1_import_energy_reactive_q2": 0,
      "l2_import_energy_reactive_q2": 0,
      "l3_import_energy_reactive_q2": 0,
      "export_energy_reactive_q3": 0,
      "l1_export_energy_reactive_q3": 0,
      "l2_export_energy_reactive_q3": 0,
      "l3_export_energy_reactive_q3": 0,
      "export_energy_reactive_q4": 0,
      "l1_export_energy_reactive_q4": 0,
      "l2_export_energy_reactive_q4": 0,
      "l3_export_energy_reactive_q4": 0,
      "energy_reactive_scale": -32768
    }
  },
  "batteries": {
    
  }
}

And the second call get this and it's very slow

{
  "meters": {
    
  },
  "batteries": {
    "Battery1": {
      
    },
    "Battery2": {
      
    }
  }
}

The goal is just to have a mini web server serving data as JSON which I will call from a custom Dashboard.
Any help will be appreciate.

meters() not working

Hi, I am testing your code on an Raspberry Pi. I have a Solaredge inverter with a Solaredge meter.
This is working:
meter = solaredge_modbus.Meter(host="192.168.178.81", port=1502)

This is working and give a correct value:

>>> inverter.read("frequency")
{'frequency': 5003}

But this gives an error message:

>>> inverter.meters()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Inverter' object has no attribute 'meters'
>>>

With a different solution (ioBroker), I can sucessfully read the values of the meter. e.g. registers 40207, 40211
image

How to get "current solar energy" value

Hi Niels!

Thank you for creating and maintaining this library. I used it for some weeks now to collect the data of my SE7K to an influx DB. Which was very easy thanks to your documentation.

What I try to figure out for some time now is how to get the "current solar power" value from the inverter. See value "A" in the following screenshot from the SolarEdge app.

image

The value "power" in the following script output shows 259W which matches "B" in the screenshot. This is "I_AC_Power" register 40083. I searched the registers in the SolarEdige register documentation but found no other one that could contain "A".

Value "C" I can get from the meter. Value "D" probably from the battery. Did not yet investigate that. With B, C and D I could calculate A, but is this really the way?

Inverter(localhost:1502, connectionType.TCP: timeout=1, retries=3, unit=0x1):

Registers:
        Manufacturer: SolarEdge
        Model: SE7K-RWS48BEB4
        Type: Three Phase Inverter
        Version: 0004.0013.0040
        Serial: nnnnnnnnnn
        Status: Producing
        Temperature: 37.24°C
        Current: 2.63A
        Phase 1 Current: 0.85A
        Phase 2 Current: 0.89A
        Phase 3 Current: 0.88A
        Phase 1 voltage: 409.30V
        Phase 2 voltage: 409.50V
        Phase 3 voltage: 407.80V
        Phase 1-N voltage: 235.90V
        Phase 2-N voltage: 237.20V
        Phase 3-N voltage: 235.10V
        Frequency: 49.99Hz
        Power: 259.00W
        Power (Apparent): 621.50VA
        Power (Reactive): -565.00VAr
        Power Factor: 41.56%
        Total Energy: 454451Wh
        DC Current: 0.32A
        DC Voltage: 815.20V
        DC Power: 262.94W
Batteries found:
        Model: BYD Premium LVS 8.0
        SOE: 11.0
Meters found:
        Model: SE-MTR-3Y-400V-A
        Export Energy Active: 267017Wh
        Import Energy Active: 147045Wh

Note: Screenshot and script output were take at the same time (as fast as I could press the keys on my phone and on my keyboard).

Best wishes
Stefan

get error using example_influxdb

Hei
I'm getting this error..
example_influxdb.py", line 7, in
from influxdb import InfluxDBClient
ModuleNotFoundError: No module named 'influxdb'

is it something related to my influxdb configuration?

Export limit available?

Hello, can you tell me if export-limit is available to view using registers on the inverter? If yes, can it be changes on-the-fly? I would like to change export limit based on some other circumstances in the grid.

Monitoring individual PV modules?

This looks like an amazing Python package - thanks loads for sharing!

One quick question: Can this Python package monitor data for individual PV modules (if the modules are 'smart modules' or the PV modules have power optimizers installed)? Apparently the Solar Edge monitoring platform captures module-level data, but I don't know if module-level data is available over MODbus.

update: I've looked through the SolarEdge MODbus docs; and the SolarEdge web API specs and, as far as I can tell, neither exposes module-level data :(

readout data not correct?

hello, i am new to python and influx.
However i got everything running and setup a Chronograf chart to verify the readouts.

I wanted to check them against the API Data.

what i noticed is, that all data from the meter seems to be as expected and ok.
However i could not find the actual production of the solaredge PV in the meters section so i did look in the inverter section.
I think this should be power_ac. But i do not understand this. the values range between 3k and 30k. however i have a max 10,5 kW Peak Produktion and when the API says i have 7k Production power_ac shows. 3k. Even more when the API Production says 3k (less than the 7k) power_ac says 28k so more than before by the factor 10. Any hints? i did not modify your script at all.

able to connect, but cannot read any values

Hello Niels,

Thanks a ton for all the work you put into this library. Looks great. I am trying to use it to talk with my SolarEdge 7.6KW HD-Wave with EV Charger, SE7600H. I enabled Modbus TCP on port 502. I can ping the inverter's IP address and I'm able to use your library and also Simply TCP Client to 'connect' to the inverter.

However, when I send any of the 'read' commands using your library and also the Simply TCP Client I do not get any response. I've tried restarting the inverter -- no change.

I realize there's a lot to debug here to get this to work and I'm going to dive into that (upgrade firmware, etc.) but I wonder if you can offer any advice based on your experience with this equipment. Do you have any suggestions of what I should try first? I've been working on this for about 6 hours now and have run out of ideas short of upgrading the firmware and trying again.

By the way, current firmware is as follows. (Also see attached pic.)
DSP1/2:1.000/2.000
CPU: 3.2536

Do you recommend upgrading the firmware?

Thank you for any help or advice you can offer.

-Allan

2020-09-14 inverter firmware

Cannot use module, example not working.

Hello.

The system is Debian 9.13 x64, Python 3.5.3
I want to monitor my inverter with domoticz. The https://github.com/addiejanssen/domoticz-solaredge-modbustcp-plugin depend on your program. So I installed it with pip, but it is not working:

2021-01-25 16:50:04.732 Error: (SolarEdge_ModbusTCP) failed to load 'plugin.py', Python Path used was '/opt/domoticz/plugins/domoticz-solaredge-modbustcp-plugin/:/usr/lib/python35.zip:/usr/lib/python3.5:/usr/lib/python3.5/plat-x86_64-linux-gnu:/usr/lib/python3.5/lib-dynload'.
2021-01-25 16:50:04.732 Error: (SolarEdge Inverter) Module Import failed, exception: 'ImportError'
2021-01-25 16:50:04.732 Error: (SolarEdge Inverter) Module Import failed: ' Name: solaredge_modbus'
2021-01-25 16:50:04.732 Error: (SolarEdge Inverter) Error Line details not available.

To investigate what happening I followed instruction and installed it from your git repo. The problem is same, but now I have your example.py, so I tried to run that:

./example.py

File "./example.py", line 43
print(f"{inverter}:")
^
SyntaxError: invalid syntax

If I remove the "f" from there, there coming another message:

Traceback (most recent call last):
File "./example.py", line 6, in
import solaredge_modbus

So I think the problem is that solaredge_modbus not found.

pip3 list

acme (0.28.0)
ardexaplugin (0.2.3)
asn1crypto (0.24.0)
bitstring (3.1.7)
certbot (0.28.0)
certifi (2016.2.28)
chardet (3.0.4)
click (7.1.2)
ConfigArgParse (0.11.0)
configobj (5.0.6)
cryptography (2.3)
ecdsa (0.16.1)
esptool (3.0)
future (0.15.2)
idna (2.6)
iotop (0.6)
josepy (1.1.0)
lxml (3.7.1)
mock (2.0.0)
natsort (4.0.3)
netifaces (0.10.4)
parsedatetime (2.4)
pbr (4.2.0)
pip (9.0.1)
pymodbus (2.4.0)
pyModbusTCP (0.1.8)
pyOpenSSL (19.0.0)
pyRFC3339 (1.0)
pyserial (3.5)
python-apt (1.4.3)
pythondialog (3.4.0)
pytz (2016.7)
pyudev (0.21.0)
reedsolo (1.5.4)
requests (2.21.0)
requests-toolbelt (0.7.0)
setuptools (33.1.1)
six (1.15.0)
solaredge-modbus (0.6.4)
urllib3 (1.24.1)
zope.component (4.3.0)
zope.event (4.2.0)
zope.hookable (4.0.4)
zope.interface (4.3.2)

What can I do to use this program?

Thanks

example.py and serial connection to inverter

Hi Niels,

To test if the communication between SE3500H and RPI is working i want to test this script.

Im using a USB to RS485 dongle. its connected to /dev/ttyUSB1

Is example.py able to work with Modbus serial or only via TCP?
If working via serial, how should i run the script?

python3 example.py /dev/ttyUSB1/ 115200 doesnt work.
I think because in example.py we dont have the argparser stuff for the serial connection?

pi@raspberrypi4:~/solaredgemodbus $ python3 example.py /dev/ttyUSB1/ 115200
Traceback (most recent call last):
File "example.py", line 26, in
values = inverter.read_all()
File "/home/pi/solaredgemodbus/solaredge_modbus/init.py", line 343, in read_all
results.update(self._read_all(register_batch, rtype))
File "/home/pi/solaredgemodbus/solaredge_modbus/init.py", line 296, in _read_all
data = self._read_holding_registers(offset, length)
File "/home/pi/solaredgemodbus/solaredge_modbus/init.py", line 218, in _read_holding_registers
result = self.client.read_holding_registers(address=address, count=length, unit=self.unit)
File "/home/pi/.local/lib/python3.7/site-packages/pymodbus/client/common.py", line 114, in read_holding_registers
return self.execute(request)
File "/home/pi/.local/lib/python3.7/site-packages/pymodbus/client/sync.py", line 107, in execute
raise ConnectionException("Failed to connect[%s]" % (self.str()))
pymodbus.exceptions.ConnectionException: Modbus Error: [Connection] Failed to connect[ModbusTcpClient(/dev/ttyUSB1/:115200)]

Integration fails to read data during "Battery Backup" situation

I do have a power outage right now at my house and the solaredge_modbus integration does not show any values. After looking into the logs I see this:

2021-11-09 10:06:11 ERROR (MainThread) [custom_components.solaredge_modbus] Error reading modbus data
Traceback (most recent call last):
File "/config/custom_components/solaredge_modbus/init.py", line 187, in async_refresh_modbus_data
update_result = self.read_modbus_data()
File "/config/custom_components/solaredge_modbus/init.py", line 230, in read_modbus_data
and self.read_modbus_data_meter2()
File "/config/custom_components/solaredge_modbus/init.py", line 247, in read_modbus_data_meter2
return self.read_modbus_data_meter("m2_", 40364)
File "/config/custom_components/solaredge_modbus/init.py", line 405, in read_modbus_data_meter
exported = validate(self.calculate_value(exported, energywsf), ">", 0)
File "/config/custom_components/solaredge_modbus/init.py", line 124, in validate
raise ValueError(f"Value {value} failed validation ({comparison}{against})")
ValueError: Value 0 failed validation (>0)

I think in a battery backup case this value could be negative or at least 0 (zero).

Line 405 should be (409 probably as well):

exported = validate(self.calculate_value(exported, energywsf), ">=", 0)

(please excuse if python has a different way of saying "greater or equal" - I am a c# guy :))

EDIT: changing the validation does not remove the error

KeyError on example.py

When I run the example.py I get this error;

Registers:
Traceback (most recent call last):
  File "./example.py", line 46, in <module>
    print(f"\tManufacturer: {values['c_manufacturer']}")
KeyError: 'c_manufacturer'

Any ideas?

Alex

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.