python-e3dc
python-e3dc copied to clipboard
Web connection seems not to work anymore
I have been using python-e3dc with the web connection to get some data out of e3dc reliable for ca 1.5 year. suddently, in the last few months, the webconnection functionalities is not working for me anymore, and my test script always fails:
Traceback (most recent call last): File "/home/ntesser/workspaces/private/python-e3dc/e3dc/_e3dc.py", line 225, in sendRequest self.rscp.connect() File "/home/ntesser/workspaces/private/python-e3dc/e3dc/_e3dc_rscp_web.py", line 427, in connect raise RequestTimeoutError e3dc._e3dc_rscp_web.RequestTimeoutError
I wonder if this is due to the new portal of e3dc and others are expiencing this problem or if it´s something off with my setup?
Which version of python-e3dc are you using?
Since 0.8.3
the websocket is consistently used. Before that change, for poll()
parsing of the website was used.
I was using commit of Jan 24, 2022 of e3dc_rscp_web: https://github.com/fsantini/python-e3dc/commits/master/e3dc/_e3dc_rscp_web.py
so I guess it was a version 7.X.
However it does not seem that any major changes from WSS to website parsing happens in the meantime.
I tryed with the newest version and a bunch of versions between 7.x and current version, and always getting the same error. My impression is that at least for my credentials then endpoint "wss://s10.e3dc.com/ws/" is not working as expected.
Any tip on how to debug that endpoint?
The older versions did used to call https://s10.e3dc.com/s10/phpcmd/cmd.php
for poll()
.
https://github.com/fsantini/python-e3dc/blob/bff23bbded99f08e2a2d56503dcd45b51e87df37/e3dc/_e3dc.py#L204
Please try again with the latest release and share the full exception.
Hi, sorry, I missed following up on this:
Here is the full stacktrace (I´ve updated python-e3dc to the last update of 4th of dec).
python e3dc.py
web connection
Traceback (most recent call last):
File "/home/ntesser/workspaces/private/python-e3dc/e3dc/_e3dc.py", line 225, in sendRequest
self.rscp.connect()
File "/home/ntesser/workspaces/private/python-e3dc/e3dc/_e3dc_rscp_web.py", line 417, in connect
raise RequestTimeoutError
e3dc._e3dc_rscp_web.RequestTimeoutError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/ntesser/workspaces/private/python-e3dc/e3dc.py", line 10, in <module>
e3dc_obj = E3DC(E3DC.CONNECT_WEB, username=USERNAME, password=PASS, serialNumber = SERIALNUMBER, isPasswordMd5=False, configuration = CONFIG)
File "/home/ntesser/workspaces/private/python-e3dc/e3dc/_e3dc.py", line 140, in __init__
self.get_system_info_static(keepAlive=True)
File "/home/ntesser/workspaces/private/python-e3dc/e3dc/_e3dc.py", line 820, in get_system_info_static
self.sendRequestTag(RscpTag.EMS_REQ_DERATE_AT_PERCENT_VALUE, keepAlive=True)
File "/home/ntesser/workspaces/private/python-e3dc/e3dc/_e3dc.py", line 263, in sendRequestTag
return self.sendRequest(
File "/home/ntesser/workspaces/private/python-e3dc/e3dc/_e3dc.py", line 237, in sendRequest
raise SendError("Max retries reached")
e3dc._e3dc.SendError: Max retries reached
I am using Ubuntu 22.04, python 3.9.12.
The test script I am using is the same as the example one in the readme.md and I double checked the value a few times and tried a few variations. e.g. serialnumber with or without 'S10-' in front. but always with the same issue. (connection timeout).
from e3dc import E3DC
USERNAME = 'yyy @gmail.com'
PASS = 'yyy'
SERIALNUMBER = 'yyy'
CONFIG = {"powermeters": [{"index": 6}]}
print("web connection")
e3dc_obj = E3DC(E3DC.CONNECT_WEB, username=USERNAME, password=PASS, serialNumber = SERIALNUMBER, isPasswordMd5=False, configuration = CONFIG)
# connect to the portal and poll the status. This might raise an exception in case of failed login. This operation is performed with Ajax
print(e3dc_obj.poll(keepAlive=True))
print(e3dc_obj.get_pvi_data(keepAlive=True))
e3dc_obj.disconnect()
I have the same issue. Python3.11 and latest commit. Connection via local works, ie user + password are correct.
...: e3dc_obj = E3DC(
...: E3DC.CONNECT_LOCAL,
...: username=USERNAME,
...: password=PASS,
...: ipAddress=IP,
...: key=KEY,
...: configuration = {},
...: )
...: # The following connections are performed through the RSCP interface
...: print(e3dc_obj.poll(keepAlive=True))
...: print(e3dc_obj.get_pvi_data(keepAlive=True))
...: e3dc_obj.disconnect()
local connection
{'autarky': 98.90287780761719, 'consumption': {'battery': 345, 'house': 730, 'wallbox': 0}, 'production': {'solar': 1061, 'add': 0, 'grid': 14}, 'selfConsumption': 99.07200622558594, 'stateOfCharge': 6, 'time': datetime.datetime(2024, 1, 21, 14, 21, 40, 853, tzinfo=datetime.timezone.utc)}
{'acMaxApparentPower': 4000.0, 'cosPhi': {'active': None, 'value': None, 'excited': None}, 'deviceState': {'connected': True, 'working': True, 'inService': False}, 'frequency': {'under': None, 'over': None}, 'index': 0, 'lastError': '3 0x0', 'maxPhaseCount': 3, 'maxStringCount': 2, 'onGrid': True, 'phases': {0: {'power': 643.0, 'voltage': 225.5, 'current': 2.950000047683716, 'apparentPower': 665.0, 'reactivePower': 0.0, 'energyAll': 14756097.0, 'energyGridConsumption': 6566.0}, 1: {'power': 0.0, 'voltage': 227.10000610351562, 'current': 0.0, 'apparentPower': 0.0, 'reactivePower': 0.0, 'energyAll': 9516854.0, 'energyGridConsumption': 550.0}, 2: {'power': 0.0, 'voltage': 225.6999969482422, 'current': 0.0, 'apparentPower': 0.0, 'reactivePower': 0.0, 'energyAll': 9996090.0, 'energyGridConsumption': 585.0}}, 'powerMode': 1, 'serialNumber': '<DELETED>', 'state': '0xb32315', 'strings': {0: {'power': 627.0, 'voltage': 584.0, 'current': 1.0700000524520874, 'energyAll': 21601691.0}, 1: {'power': 434.0, 'voltage': 422.0, 'current': 1.0199999809265137, 'energyAll': 15285519.0}}, 'systemMode': 2, 'temperature': {'max': 130.0, 'min': -30.0, 'values': [33.900001525878906, 33.900001525878906, 43.20000076293945, 36.099998474121094]}, 'type': 3, 'version': ' MAIN HW06 2.060', 'voltageMonitoring': {'thresholdTop': None, 'thresholdBottom': None, 'slopeUp': None, 'slopeDown': None}}
Remote:
In [17]: print("web connection")
...: e3dc_obj = E3DC(
...: E3DC.CONNECT_WEB,
...: username=USERNAME,
...: password=PASS,
...: serialNumber=SERIALNUMBER,
...: isPasswordMd5=False,
...: configuration = CONFIG
...: )
...: # connect to the portal and poll the status. This might raise an exception in case of failed login. This operation is performed with Ajax
...: print(e3dc_obj.poll(keepAlive=True))
...: print(e3dc_obj.get_pvi_data(keepAlive=True))
...: e3dc_obj.disconnect()
web connection
---------------------------------------------------------------------------
RequestTimeoutError Traceback (most recent call last)
File ~/e3dc-data/python-e3dc/e3dc/_e3dc.py:225, in E3DC.sendRequest(self, request, retries, keepAlive)
224 if not self.rscp.isConnected():
--> 225 self.rscp.connect()
226 result = self.rscp.sendRequest(request)
File ~/e3dc-data/python-e3dc/e3dc/_e3dc_rscp_web.py:417, in E3DC_RSCP_web.connect(self)
416 if not self.isConnected():
--> 417 raise RequestTimeoutError
RequestTimeoutError:
During handling of the above exception, another exception occurred:
SendError Traceback (most recent call last)
Cell In[17], line 2
1 print("web connection")
----> 2 e3dc_obj = E3DC(
3 E3DC.CONNECT_WEB,
4 username=USERNAME,
5 password=PASS,
6 serialNumber=SERIALNUMBER,
7 isPasswordMd5=False,
8 configuration = CONFIG
9 )
10 # connect to the portal and poll the status. This might raise an exception in case of failed login. This operation is performed with Ajax
11 print(e3dc_obj.poll(keepAlive=True))
File ~/e3dc-data/python-e3dc/e3dc/_e3dc.py:140, in E3DC.__init__(self, connectType, **kwargs)
131 self.password = hashlib.md5(
132 kwargs["password"].encode("utf-8")
133 ).hexdigest()
134 self.rscp = E3DC_RSCP_web(
135 self.username,
136 self.password,
137 "{}{}".format(self.serialNumberPrefix, self.serialNumber),
138 )
--> 140 self.get_system_info_static(keepAlive=True)
File ~/e3dc-data/python-e3dc/e3dc/_e3dc.py:820, in E3DC.get_system_info_static(self, keepAlive)
813 def get_system_info_static(self, keepAlive: bool = False):
814 """Polls the static system info via rscp protocol.
815
816 Args:
817 keepAlive (bool): True to keep connection alive. Defaults to False.
818 """
819 self.deratePercent = (
--> 820 self.sendRequestTag(RscpTag.EMS_REQ_DERATE_AT_PERCENT_VALUE, keepAlive=True)
821 * 100
822 )
824 self.deratePower = self.sendRequestTag(
825 RscpTag.EMS_REQ_DERATE_AT_POWER_VALUE, keepAlive=True
826 )
827 self.installedPeakPower = self.sendRequestTag(
828 RscpTag.EMS_REQ_INSTALLED_PEAK_POWER, keepAlive=True
829 )
File ~/e3dc-data/python-e3dc/e3dc/_e3dc.py:263, in E3DC.sendRequestTag(self, tag, retries, keepAlive)
244 def sendRequestTag(
245 self, tag: str | int | RscpTag, retries: int = 3, keepAlive: bool = False
246 ):
247 """This function uses the RSCP interface to make a request for a single tag.
248
249 Does make retries in case of exceptions like Socket.Error
(...)
261 e3dc.SendError: if retries are reached
262 """
--> 263 return self.sendRequest(
264 (tag, RscpType.NoneType, None), retries=retries, keepAlive=keepAlive
265 )[2]
File ~/e3dc-data/python-e3dc/e3dc/_e3dc.py:237, in E3DC.sendRequest(self, request, retries, keepAlive)
235 retry += 1
236 if retry > retries:
--> 237 raise SendError("Max retries reached")
239 if not keepAlive:
240 self.rscp.disconnect()
SendError: Max retries reached
Serial number +- "S10-" makes no difference.
It looks like E3DC changed their websocket endpoint configuration.
We are using wss://s10.e3dc.com/ws/
which is not working anymore but wss://s10.e3dc.com/ws
is. I'll update the code.