nmakel / solaredge_modbus Goto Github PK
View Code? Open in Web Editor NEWSolarEdge Modbus data collection library
License: MIT License
SolarEdge Modbus data collection library
License: MIT License
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;
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)]
Hi,
I would like to read connected Meter registers. Is it possible?
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"
Hello,
I think the package on PyPi does not contain the example.py
(solaredge_modbus) rd@home:/virtualenv/solaredge_modbus$ find -name example*/virtualenv/solaredge_modbus$
(solaredge_modbus) rd@home:
If I download it from github it works flawless though.
Thanks
Rainer
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
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'
`
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/dev/solar$ python3
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:
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
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
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?
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
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
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.
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 :)
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
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
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)
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.
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
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:
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?
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!
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).
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'
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.
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?
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
Or shall I modify other commands in the example.py to see all there inverter data in one query.
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.
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 ;)
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.
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
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
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
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.
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?
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.
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
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.
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
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?
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.
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 :(
The line below in example.py doesnt work. Maybe convert the list of enumerations to key value like with C_SUNSPEC_DID_MAP
if values['c_sunspec_did'] is solaredge_modbus.sunspecDID.THREE_PHASE_INVERTER:
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.
hi,please can u add support for influxdb api v2?
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
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:
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.
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
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)]
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
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
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.