goodwe 0.4.3__py3-none-any.whl → 0.4.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- goodwe/modbus.py +7 -6
- goodwe/protocol.py +21 -20
- {goodwe-0.4.3.dist-info → goodwe-0.4.4.dist-info}/METADATA +1 -1
- {goodwe-0.4.3.dist-info → goodwe-0.4.4.dist-info}/RECORD +7 -7
- {goodwe-0.4.3.dist-info → goodwe-0.4.4.dist-info}/LICENSE +0 -0
- {goodwe-0.4.3.dist-info → goodwe-0.4.4.dist-info}/WHEEL +0 -0
- {goodwe-0.4.3.dist-info → goodwe-0.4.4.dist-info}/top_level.txt +0 -0
goodwe/modbus.py
CHANGED
|
@@ -221,10 +221,11 @@ def validate_modbus_tcp_response(data: bytes, cmd: int, offset: int, value: int)
|
|
|
221
221
|
if len(data) <= 8:
|
|
222
222
|
logger.debug("Response is too short.")
|
|
223
223
|
return False
|
|
224
|
-
|
|
225
|
-
# The
|
|
226
|
-
|
|
227
|
-
|
|
224
|
+
|
|
225
|
+
# The Modbus/TCP message length check is completely ignore due to Goodwe bugs
|
|
226
|
+
# expected_length = int.from_bytes(data[4:6], byteorder='big', signed=False) + 6
|
|
227
|
+
# if len(data) < expected_length:
|
|
228
|
+
# raise PartialResponseException(len(data), expected_length)
|
|
228
229
|
|
|
229
230
|
if data[7] == MODBUS_READ_CMD:
|
|
230
231
|
expected_length = data[8] + 9
|
|
@@ -235,8 +236,8 @@ def validate_modbus_tcp_response(data: bytes, cmd: int, offset: int, value: int)
|
|
|
235
236
|
return False
|
|
236
237
|
elif data[7] in (MODBUS_WRITE_CMD, MODBUS_WRITE_MULTI_CMD):
|
|
237
238
|
if len(data) < 12:
|
|
238
|
-
logger.debug("Response has unexpected length: %d, expected %d.", len(data),
|
|
239
|
-
|
|
239
|
+
logger.debug("Response has unexpected length: %d, expected %d.", len(data), 12)
|
|
240
|
+
return False
|
|
240
241
|
response_offset = int.from_bytes(data[8:10], byteorder='big', signed=False)
|
|
241
242
|
if response_offset != offset:
|
|
242
243
|
logger.debug("Response has wrong offset: %X, expected %X.", response_offset, offset)
|
goodwe/protocol.py
CHANGED
|
@@ -42,6 +42,7 @@ class InverterProtocol:
|
|
|
42
42
|
self.response_future: Future | None = None
|
|
43
43
|
self.command: ProtocolCommand | None = None
|
|
44
44
|
self._partial_data: bytes | None = None
|
|
45
|
+
self._partial_missing: int = 0
|
|
45
46
|
|
|
46
47
|
def _ensure_lock(self) -> asyncio.Lock:
|
|
47
48
|
"""Validate (or create) asyncio Lock.
|
|
@@ -125,23 +126,21 @@ class UdpInverterProtocol(InverterProtocol, asyncio.DatagramProtocol):
|
|
|
125
126
|
self._timer.cancel()
|
|
126
127
|
self._timer = None
|
|
127
128
|
try:
|
|
128
|
-
if self._partial_data:
|
|
129
|
-
logger.debug("
|
|
129
|
+
if self._partial_data and self._partial_missing == len(data):
|
|
130
|
+
logger.debug("Composed fragmented response: %s + %s", self._partial_data.hex(), data.hex())
|
|
130
131
|
data = self._partial_data + data
|
|
131
|
-
if self.command.validator(data):
|
|
132
|
-
if self._partial_data:
|
|
133
|
-
logger.debug("Composed fragmented response: %s", data.hex())
|
|
134
|
-
else:
|
|
135
|
-
logger.debug("Received: %s", data.hex())
|
|
136
132
|
self._partial_data = None
|
|
133
|
+
self._partial_missing = 0
|
|
134
|
+
if self.command.validator(data):
|
|
135
|
+
logger.debug("Received: %s", data.hex())
|
|
137
136
|
self.response_future.set_result(data)
|
|
138
137
|
else:
|
|
139
138
|
logger.debug("Received invalid response: %s", data.hex())
|
|
140
139
|
asyncio.get_running_loop().call_soon(self._retry_mechanism)
|
|
141
|
-
except PartialResponseException:
|
|
142
|
-
logger.debug("Received response fragment: %s", data.hex())
|
|
140
|
+
except PartialResponseException as ex:
|
|
141
|
+
logger.debug("Received response fragment (%d of %d): %s", ex.length, ex.expected, data.hex())
|
|
143
142
|
self._partial_data = data
|
|
144
|
-
|
|
143
|
+
self._partial_missing = ex.expected - ex.length
|
|
145
144
|
except asyncio.InvalidStateError:
|
|
146
145
|
logger.debug("Response already handled: %s", data.hex())
|
|
147
146
|
except RequestRejectedException as ex:
|
|
@@ -169,6 +168,8 @@ class UdpInverterProtocol(InverterProtocol, asyncio.DatagramProtocol):
|
|
|
169
168
|
"""Send message via transport"""
|
|
170
169
|
self.command = command
|
|
171
170
|
self.response_future = response_future
|
|
171
|
+
self._partial_data = None
|
|
172
|
+
self._partial_missing = 0
|
|
172
173
|
payload = command.request_bytes()
|
|
173
174
|
if self._retry > 0:
|
|
174
175
|
logger.debug("Sending: %s - retry #%s/%s", self.command, self._retry, self.retries)
|
|
@@ -266,25 +267,23 @@ class TcpInverterProtocol(InverterProtocol, asyncio.Protocol):
|
|
|
266
267
|
if self._timer:
|
|
267
268
|
self._timer.cancel()
|
|
268
269
|
try:
|
|
269
|
-
if self._partial_data:
|
|
270
|
-
logger.debug("
|
|
270
|
+
if self._partial_data and self._partial_missing == len(data):
|
|
271
|
+
logger.debug("Composed fragmented response: %s + %s", self._partial_data.hex(), data.hex())
|
|
271
272
|
data = self._partial_data + data
|
|
273
|
+
self._partial_data = None
|
|
274
|
+
self._partial_missing = 0
|
|
272
275
|
if self.command.validator(data):
|
|
273
|
-
|
|
274
|
-
logger.debug("Composed fragmented response: %s", data.hex())
|
|
275
|
-
else:
|
|
276
|
-
logger.debug("Received: %s", data.hex())
|
|
276
|
+
logger.debug("Received: %s", data.hex())
|
|
277
277
|
self._retry = 0
|
|
278
|
-
self._partial_data = None
|
|
279
278
|
self.response_future.set_result(data)
|
|
280
279
|
else:
|
|
281
280
|
logger.debug("Received invalid response: %s", data.hex())
|
|
282
281
|
self.response_future.set_exception(RequestRejectedException())
|
|
283
282
|
self._close_transport()
|
|
284
|
-
except PartialResponseException:
|
|
285
|
-
logger.debug("Received response fragment: %s", data.hex())
|
|
283
|
+
except PartialResponseException as ex:
|
|
284
|
+
logger.debug("Received response fragment (%d of %d): %s", ex.length, ex.expected, data.hex())
|
|
286
285
|
self._partial_data = data
|
|
287
|
-
|
|
286
|
+
self._partial_missing = ex.expected - ex.length
|
|
288
287
|
except asyncio.InvalidStateError:
|
|
289
288
|
logger.debug("Response already handled: %s", data.hex())
|
|
290
289
|
except RequestRejectedException as ex:
|
|
@@ -335,6 +334,8 @@ class TcpInverterProtocol(InverterProtocol, asyncio.Protocol):
|
|
|
335
334
|
"""Send message via transport"""
|
|
336
335
|
self.command = command
|
|
337
336
|
self.response_future = response_future
|
|
337
|
+
self._partial_data = None
|
|
338
|
+
self._partial_missing = 0
|
|
338
339
|
payload = command.request_bytes()
|
|
339
340
|
if self._retry > 0:
|
|
340
341
|
logger.debug("Sending: %s - retry #%s/%s", self.command, self._retry, self.retries)
|
|
@@ -5,12 +5,12 @@ goodwe/es.py,sha256=iVK8EMCaAJJFihZLntJZ_Eu4sQWoZTVtTROp9mHFG6o,22730
|
|
|
5
5
|
goodwe/et.py,sha256=CiX-PE7wouDnj1RnPnOyqiNE4FELhOGdyPUOm9VCzUw,43890
|
|
6
6
|
goodwe/exceptions.py,sha256=dKMLxotjoR1ic8OVlw1joIJ4mKWD6oFtUMZ86fNM5ZE,1403
|
|
7
7
|
goodwe/inverter.py,sha256=86aMJzJjNOr1I_tCF5H6mBwzDTjLbGDKUL2hbi0XSxg,10459
|
|
8
|
-
goodwe/modbus.py,sha256=
|
|
8
|
+
goodwe/modbus.py,sha256=Mg_s_v8kbZgqXZM6ZUUxkZx2boAG8LkuDG5OiFKK2X4,8402
|
|
9
9
|
goodwe/model.py,sha256=dWBjMFJMnhZoUdDd9fGT54DERDANz4TirK0Wy8kWMbk,2068
|
|
10
|
-
goodwe/protocol.py,sha256=
|
|
10
|
+
goodwe/protocol.py,sha256=bOieJx6jbgSPYvwk8tSGkmRE586HgeCUGKezAkzNSsA,28563
|
|
11
11
|
goodwe/sensor.py,sha256=buPG8BcgZmRDqaMrLQUACLHB85U134qG6qo_ggsu48A,37679
|
|
12
|
-
goodwe-0.4.
|
|
13
|
-
goodwe-0.4.
|
|
14
|
-
goodwe-0.4.
|
|
15
|
-
goodwe-0.4.
|
|
16
|
-
goodwe-0.4.
|
|
12
|
+
goodwe-0.4.4.dist-info/LICENSE,sha256=aZAhk3lRdYT1YZV-IKRHISEcc_KNUmgfuNO3QhRamNM,1073
|
|
13
|
+
goodwe-0.4.4.dist-info/METADATA,sha256=QQS2Kydn9eELSDLYpWLzibdXB1x9WON9wmLJXCT7KYw,3376
|
|
14
|
+
goodwe-0.4.4.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
15
|
+
goodwe-0.4.4.dist-info/top_level.txt,sha256=kKoiqiVvAxDaDJYMZZQLgHQj9cuWT1MXLfXElTDuf8s,7
|
|
16
|
+
goodwe-0.4.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|