plugwise 0.27.6__tar.gz → 0.27.7__tar.gz
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.
- {plugwise-0.27.6 → plugwise-0.27.7}/PKG-INFO +2 -1
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise/connections/socket.py +9 -11
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise/controller.py +152 -143
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise/helper.py +3 -4
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise/nodes/circle.py +52 -15
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise/nodes/sed.py +2 -1
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise.egg-info/PKG-INFO +2 -1
- {plugwise-0.27.6 → plugwise-0.27.7}/pyproject.toml +6 -6
- {plugwise-0.27.6 → plugwise-0.27.7}/LICENSE +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/README.md +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise/__init__.py +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise/connections/__init__.py +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise/connections/serial.py +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise/constants.py +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise/exceptions.py +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise/messages/__init__.py +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise/messages/requests.py +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise/messages/responses.py +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise/nodes/__init__.py +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise/nodes/circle_plus.py +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise/nodes/scan.py +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise/nodes/sense.py +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise/nodes/stealth.py +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise/nodes/switch.py +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise/parser.py +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise/smile.py +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise/stick.py +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise/util.py +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise.egg-info/SOURCES.txt +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise.egg-info/dependency_links.txt +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise.egg-info/requires.txt +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/plugwise.egg-info/top_level.txt +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/setup.cfg +0 -0
- {plugwise-0.27.6 → plugwise-0.27.7}/setup.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: plugwise
|
3
|
-
Version: 0.27.
|
3
|
+
Version: 0.27.7
|
4
4
|
Summary: Plugwise Smile (Adam/Anna/P1), Stretch and USB (Stick) module for Python 3.
|
5
5
|
Home-page: https://github.com/plugwise/python-plugwise
|
6
6
|
Author: Plugwise device owners
|
@@ -37,6 +37,7 @@ Classifier: License :: OSI Approved :: MIT License
|
|
37
37
|
Classifier: Operating System :: OS Independent
|
38
38
|
Classifier: Programming Language :: Python :: 3.9
|
39
39
|
Classifier: Programming Language :: Python :: 3.10
|
40
|
+
Classifier: Programming Language :: Python :: 3.11
|
40
41
|
Classifier: Topic :: Home Automation
|
41
42
|
Requires-Python: >=3.9.0
|
42
43
|
Description-Content-Type: text/markdown
|
@@ -39,15 +39,14 @@ class SocketConnection(StickConnection):
|
|
39
39
|
err,
|
40
40
|
)
|
41
41
|
raise PortError(err)
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
)
|
42
|
+
self._reader_start("socket_reader_thread")
|
43
|
+
self._writer_start("socket_writer_thread")
|
44
|
+
self._is_connected = True
|
45
|
+
_LOGGER.debug(
|
46
|
+
"Successfully connected to host '%s' at port %s",
|
47
|
+
self._socket_host,
|
48
|
+
str(self._socket_port),
|
49
|
+
)
|
51
50
|
|
52
51
|
def _close_connection(self):
|
53
52
|
"""Close the socket."""
|
@@ -76,8 +75,7 @@ class SocketConnection(StickConnection):
|
|
76
75
|
)
|
77
76
|
self._is_connected = False
|
78
77
|
raise PortError(err)
|
79
|
-
|
80
|
-
return socket_data
|
78
|
+
return socket_data
|
81
79
|
return None
|
82
80
|
|
83
81
|
def _write_data(self, data):
|
@@ -49,6 +49,7 @@ class StickMessageController:
|
|
49
49
|
self.connection = None
|
50
50
|
self.discovery_finished = False
|
51
51
|
self.expected_responses = {}
|
52
|
+
self.lock_expected_responses = threading.Lock()
|
52
53
|
self.init_callback = None
|
53
54
|
self.last_seq_id = None
|
54
55
|
self.message_processor = message_processor
|
@@ -151,66 +152,67 @@ class StickMessageController:
|
|
151
152
|
def resend(self, seq_id):
|
152
153
|
"""Resend message."""
|
153
154
|
_mac = "<unknown>"
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
155
|
+
with self.lock_expected_responses:
|
156
|
+
if not self.expected_responses.get(seq_id):
|
157
|
+
_LOGGER.warning(
|
158
|
+
"Cannot resend unknown request %s",
|
159
|
+
str(seq_id),
|
160
|
+
)
|
161
|
+
else:
|
162
|
+
if self.expected_responses[seq_id][0].mac:
|
163
|
+
_mac = self.expected_responses[seq_id][0].mac.decode(UTF8_DECODE)
|
164
|
+
_request = self.expected_responses[seq_id][0].__class__.__name__
|
163
165
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
166
|
+
if self.expected_responses[seq_id][2] == -1:
|
167
|
+
_LOGGER.debug("Drop single %s to %s ", _request, _mac)
|
168
|
+
elif self.expected_responses[seq_id][2] <= MESSAGE_RETRY:
|
169
|
+
if (
|
170
|
+
isinstance(self.expected_responses[seq_id][0], NodeInfoRequest)
|
171
|
+
and not self.discovery_finished
|
172
|
+
):
|
173
|
+
# Time out for node which is not discovered yet
|
174
|
+
# to speedup the initial discover phase skip retries and mark node as not discovered.
|
175
|
+
_LOGGER.debug(
|
176
|
+
"Skip retry %s to %s to speedup discover process",
|
177
|
+
_request,
|
178
|
+
_mac,
|
179
|
+
)
|
180
|
+
if self.expected_responses[seq_id][1]:
|
181
|
+
self.expected_responses[seq_id][1]()
|
182
|
+
else:
|
183
|
+
_LOGGER.info(
|
184
|
+
"Resend %s for %s, retry %s of %s",
|
185
|
+
_request,
|
186
|
+
_mac,
|
187
|
+
str(self.expected_responses[seq_id][2] + 1),
|
188
|
+
str(MESSAGE_RETRY + 1),
|
189
|
+
)
|
190
|
+
self.send(
|
191
|
+
self.expected_responses[seq_id][0],
|
192
|
+
self.expected_responses[seq_id][1],
|
193
|
+
self.expected_responses[seq_id][2] + 1,
|
194
|
+
)
|
180
195
|
else:
|
181
|
-
_LOGGER.
|
182
|
-
"
|
196
|
+
_LOGGER.warning(
|
197
|
+
"Drop %s to %s because max retries %s reached",
|
183
198
|
_request,
|
184
199
|
_mac,
|
185
|
-
str(self.expected_responses[seq_id][2] + 1),
|
186
200
|
str(MESSAGE_RETRY + 1),
|
187
201
|
)
|
188
|
-
|
189
|
-
|
190
|
-
self.
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
self.node_state(_mac, False)
|
203
|
-
else:
|
204
|
-
_LOGGER.debug(
|
205
|
-
"Do a single ping request to %s to validate if node is reachable",
|
206
|
-
_mac,
|
207
|
-
)
|
208
|
-
self.send(
|
209
|
-
NodePingRequest(self.expected_responses[seq_id][0].mac),
|
210
|
-
None,
|
211
|
-
MESSAGE_RETRY + 1,
|
212
|
-
)
|
213
|
-
del self.expected_responses[seq_id]
|
202
|
+
# Report node as unavailable for missing NodePingRequest
|
203
|
+
if isinstance(self.expected_responses[seq_id][0], NodePingRequest):
|
204
|
+
self.node_state(_mac, False)
|
205
|
+
else:
|
206
|
+
_LOGGER.debug(
|
207
|
+
"Do a single ping request to %s to validate if node is reachable",
|
208
|
+
_mac,
|
209
|
+
)
|
210
|
+
self.send(
|
211
|
+
NodePingRequest(self.expected_responses[seq_id][0].mac),
|
212
|
+
None,
|
213
|
+
MESSAGE_RETRY + 1,
|
214
|
+
)
|
215
|
+
del self.expected_responses[seq_id]
|
214
216
|
|
215
217
|
def _send_message_loop(self):
|
216
218
|
"""Daemon to send messages waiting in queue."""
|
@@ -225,28 +227,26 @@ class StickMessageController:
|
|
225
227
|
# Calc next seq_id based last received ack message
|
226
228
|
# if previous seq_id is unknown use fake b"0000"
|
227
229
|
seq_id = inc_seq_id(self.last_seq_id)
|
228
|
-
self.
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
# Send request
|
249
|
-
self.connection.send(self.expected_responses[seq_id][0])
|
230
|
+
with self.lock_expected_responses:
|
231
|
+
self.expected_responses[seq_id] = request_set
|
232
|
+
if self.expected_responses[seq_id][2] == 0:
|
233
|
+
_LOGGER.info(
|
234
|
+
"Send %s to %s using seq_id %s",
|
235
|
+
self.expected_responses[seq_id][0].__class__.__name__,
|
236
|
+
self.expected_responses[seq_id][0].mac,
|
237
|
+
str(seq_id),
|
238
|
+
)
|
239
|
+
else:
|
240
|
+
_LOGGER.info(
|
241
|
+
"Resend %s to %s using seq_id %s, retry %s",
|
242
|
+
self.expected_responses[seq_id][0].__class__.__name__,
|
243
|
+
self.expected_responses[seq_id][0].mac,
|
244
|
+
str(seq_id),
|
245
|
+
str(self.expected_responses[seq_id][2]),
|
246
|
+
)
|
247
|
+
self.expected_responses[seq_id][3] = datetime.now()
|
248
|
+
# Send request
|
249
|
+
self.connection.send(self.expected_responses[seq_id][0])
|
250
250
|
time.sleep(SLEEP_TIME)
|
251
251
|
timeout_counter = 0
|
252
252
|
# Wait max 1 second for acknowledge response from USB-stick
|
@@ -289,63 +289,71 @@ class StickMessageController:
|
|
289
289
|
)
|
290
290
|
|
291
291
|
def _post_message_action(self, seq_id, ack_response=None, request="unknown"):
|
292
|
-
"""Execute action if request has been successful
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
)
|
301
|
-
try:
|
302
|
-
self.expected_responses[seq_id][1]()
|
303
|
-
# TODO: narrow exception
|
304
|
-
except Exception as err: # pylint: disable=broad-except
|
305
|
-
_LOGGER.error(
|
306
|
-
"Execution of %s for request with seq_id %s failed: %s",
|
292
|
+
"""Execute action if request has been successful."""
|
293
|
+
resend_request = False
|
294
|
+
with self.lock_expected_responses:
|
295
|
+
if seq_id in self.expected_responses:
|
296
|
+
if ack_response in (*REQUEST_SUCCESS, None):
|
297
|
+
if self.expected_responses[seq_id][1]:
|
298
|
+
_LOGGER.debug(
|
299
|
+
"Execute action %s of request with seq_id %s",
|
307
300
|
self.expected_responses[seq_id][1].__name__,
|
308
301
|
str(seq_id),
|
309
|
-
err,
|
310
302
|
)
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
303
|
+
try:
|
304
|
+
self.expected_responses[seq_id][1]()
|
305
|
+
# TODO: narrow exception
|
306
|
+
except Exception as err: # pylint: disable=broad-except
|
307
|
+
_LOGGER.error(
|
308
|
+
"Execution of %s for request with seq_id %s failed: %s",
|
309
|
+
self.expected_responses[seq_id][1].__name__,
|
310
|
+
str(seq_id),
|
311
|
+
err,
|
312
|
+
)
|
313
|
+
del self.expected_responses[seq_id]
|
314
|
+
elif ack_response in REQUEST_FAILED:
|
315
|
+
resend_request = True
|
320
316
|
else:
|
321
|
-
|
322
|
-
"
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
317
|
+
if not self.last_seq_id:
|
318
|
+
if b"0000" in self.expected_responses:
|
319
|
+
self.expected_responses[seq_id] = self.expected_responses[
|
320
|
+
b"0000"
|
321
|
+
]
|
322
|
+
del self.expected_responses[b"0000"]
|
323
|
+
self.last_seq_id = seq_id
|
324
|
+
else:
|
325
|
+
_LOGGER.info(
|
326
|
+
"Drop unexpected %s%s using seq_id %s",
|
327
|
+
STATUS_RESPONSES.get(ack_response, "") + " ",
|
328
|
+
request,
|
329
|
+
str(seq_id),
|
330
|
+
)
|
331
|
+
if resend_request:
|
332
|
+
self.resend(seq_id)
|
327
333
|
|
328
334
|
def _receive_timeout_loop(self):
|
329
335
|
"""Daemon to time out open requests without any (n)ack response message."""
|
330
336
|
while self._receive_timeout_thread_state:
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
_mac =
|
339
|
-
|
337
|
+
resend_list = []
|
338
|
+
with self.lock_expected_responses:
|
339
|
+
for seq_id in list(self.expected_responses.keys()):
|
340
|
+
if self.expected_responses[seq_id][3] is not None:
|
341
|
+
if self.expected_responses[seq_id][3] < (
|
342
|
+
datetime.now() - timedelta(seconds=MESSAGE_TIME_OUT)
|
343
|
+
):
|
344
|
+
_mac = "<unknown>"
|
345
|
+
if self.expected_responses[seq_id][0].mac:
|
346
|
+
_mac = self.expected_responses[seq_id][0].mac
|
347
|
+
_LOGGER.info(
|
348
|
+
"No response within %s seconds timeout for %s to %s with sequence ID %s",
|
349
|
+
str(MESSAGE_TIME_OUT),
|
350
|
+
self.expected_responses[seq_id][0].__class__.__name__,
|
351
|
+
_mac,
|
352
|
+
str(seq_id),
|
340
353
|
)
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
self.expected_responses[seq_id][0].__class__.__name__,
|
345
|
-
_mac,
|
346
|
-
str(seq_id),
|
347
|
-
)
|
348
|
-
self.resend(seq_id)
|
354
|
+
resend_list.append(seq_id)
|
355
|
+
for seq_id in resend_list:
|
356
|
+
self.resend(seq_id)
|
349
357
|
receive_timeout_checker = 0
|
350
358
|
while (
|
351
359
|
receive_timeout_checker < MESSAGE_TIME_OUT
|
@@ -366,25 +374,26 @@ class StickMessageController:
|
|
366
374
|
str(message.seq_id),
|
367
375
|
)
|
368
376
|
else:
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
377
|
+
with self.lock_expected_responses:
|
378
|
+
if self.expected_responses.get(message.seq_id):
|
379
|
+
_LOGGER.warning(
|
380
|
+
"Received unmanaged (%s) %s in response to %s with seq_id %s",
|
381
|
+
str(status),
|
382
|
+
message.__class__.__name__,
|
383
|
+
str(
|
384
|
+
self.expected_responses[message.seq_id][
|
385
|
+
1
|
386
|
+
].__class__.__name__
|
387
|
+
),
|
388
|
+
str(message.seq_id),
|
389
|
+
)
|
390
|
+
else:
|
391
|
+
_LOGGER.warning(
|
392
|
+
"Received unmanaged (%s) %s for unknown request with seq_id %s",
|
393
|
+
str(status),
|
394
|
+
message.__class__.__name__,
|
395
|
+
str(message.seq_id),
|
396
|
+
)
|
388
397
|
else:
|
389
398
|
_LOGGER.info(
|
390
399
|
"Received %s from %s with sequence id %s",
|
@@ -225,7 +225,6 @@ class SmileComm:
|
|
225
225
|
):
|
226
226
|
"""Set the constructor for this class."""
|
227
227
|
if not websession:
|
228
|
-
|
229
228
|
aio_timeout = ClientTimeout(total=timeout)
|
230
229
|
|
231
230
|
async def _create_session() -> ClientSession:
|
@@ -303,7 +302,9 @@ class SmileComm:
|
|
303
302
|
data=data,
|
304
303
|
auth=self._auth,
|
305
304
|
)
|
306
|
-
except
|
305
|
+
except (
|
306
|
+
ClientError
|
307
|
+
) as err: # ClientError is an ancestor class of ServerTimeoutError
|
307
308
|
if retry < 1:
|
308
309
|
LOGGER.warning(
|
309
310
|
"Failed sending %s %s to Plugwise Smile, error: %s",
|
@@ -1014,7 +1015,6 @@ class SmileHelper:
|
|
1014
1015
|
if (
|
1015
1016
|
appliance := self._appliances.find(f'./appliance[@id="{d_id}"]')
|
1016
1017
|
) is not None:
|
1017
|
-
|
1018
1018
|
self._appliance_measurements(appliance, data, measurements)
|
1019
1019
|
self._get_lock_state(appliance, data)
|
1020
1020
|
|
@@ -1082,7 +1082,6 @@ class SmileHelper:
|
|
1082
1082
|
appl_class = appliance_details["dev_class"]
|
1083
1083
|
appl_d_loc = appliance_details["location"]
|
1084
1084
|
if loc_id == appl_d_loc and appl_class in thermo_matching:
|
1085
|
-
|
1086
1085
|
# Pre-elect new master
|
1087
1086
|
if thermo_matching[appl_class] > self._thermo_locs[loc_id]["master_prio"]:
|
1088
1087
|
# Demote former master
|
@@ -66,7 +66,9 @@ class PlugwiseCircle(PlugwiseNode):
|
|
66
66
|
self._energy_consumption_today_reset = datetime.now().replace(
|
67
67
|
hour=0, minute=0, second=0, microsecond=0
|
68
68
|
)
|
69
|
+
self._energy_memory = {}
|
69
70
|
self._energy_history_collecting = False
|
71
|
+
self._energy_history_collecting_timestamp = datetime.now()
|
70
72
|
self._energy_history = {}
|
71
73
|
self._energy_last_collected_timestamp = datetime(2000, 1, 1)
|
72
74
|
self._energy_last_rollover_timestamp = datetime(2000, 1, 1)
|
@@ -613,7 +615,16 @@ class PlugwiseCircle(PlugwiseNode):
|
|
613
615
|
if log_address is None:
|
614
616
|
log_address = self._last_log_address
|
615
617
|
if log_address is not None:
|
616
|
-
if
|
618
|
+
if self._energy_history_collecting and (
|
619
|
+
self._energy_history_collecting_timestamp
|
620
|
+
< datetime.now() - timedelta(minutes=15)
|
621
|
+
):
|
622
|
+
_LOGGER.debug(
|
623
|
+
"Skip request_energy_counters for %s of address %s",
|
624
|
+
self.mac,
|
625
|
+
str(log_address),
|
626
|
+
)
|
627
|
+
elif len(self._energy_history) > 48:
|
617
628
|
# Energy history already collected
|
618
629
|
if (
|
619
630
|
log_address == self._last_log_address
|
@@ -624,31 +635,53 @@ class PlugwiseCircle(PlugwiseNode):
|
|
624
635
|
self._request_info(self.request_energy_counters)
|
625
636
|
else:
|
626
637
|
# Request new energy counters
|
627
|
-
self.
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
638
|
+
if self._energy_memory.get(log_address, 0) < 4:
|
639
|
+
self.message_sender(
|
640
|
+
CircleEnergyCountersRequest(self._mac, log_address),
|
641
|
+
None,
|
642
|
+
0,
|
643
|
+
PRIORITY_LOW,
|
644
|
+
)
|
645
|
+
else:
|
646
|
+
_LOGGER.info(
|
647
|
+
"Drop known request_energy_counters for %s of address %s",
|
648
|
+
self.mac,
|
649
|
+
str(log_address),
|
650
|
+
)
|
633
651
|
else:
|
634
652
|
# Collect energy counters of today and yesterday
|
635
653
|
# Each request contains will return 4 hours, except last request
|
636
654
|
|
637
655
|
# TODO: validate range of log_addresses
|
638
656
|
self._energy_history_collecting = True
|
657
|
+
self._energy_history_collecting_timestamp = datetime.now()
|
639
658
|
for req_log_address in range(log_address - 13, log_address):
|
659
|
+
if self._energy_memory.get(req_log_address, 0) < 4:
|
660
|
+
self.message_sender(
|
661
|
+
CircleEnergyCountersRequest(self._mac, req_log_address),
|
662
|
+
None,
|
663
|
+
0,
|
664
|
+
PRIORITY_LOW,
|
665
|
+
)
|
666
|
+
else:
|
667
|
+
_LOGGER.info(
|
668
|
+
"Drop known request_energy_counters at collecting for %s of address %s",
|
669
|
+
self.mac,
|
670
|
+
str(log_address),
|
671
|
+
)
|
672
|
+
if self._energy_memory.get(log_address, 0) < 4:
|
640
673
|
self.message_sender(
|
641
|
-
CircleEnergyCountersRequest(self._mac,
|
642
|
-
|
674
|
+
CircleEnergyCountersRequest(self._mac, log_address),
|
675
|
+
callback,
|
643
676
|
0,
|
644
677
|
PRIORITY_LOW,
|
645
678
|
)
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
679
|
+
else:
|
680
|
+
_LOGGER.info(
|
681
|
+
"Drop known request_energy_counters at collecting end for %s of address %s",
|
682
|
+
self.mac,
|
683
|
+
str(log_address),
|
684
|
+
)
|
652
685
|
|
653
686
|
def _response_energy_counters(self, message: CircleEnergyCountersResponse):
|
654
687
|
"""
|
@@ -677,6 +710,10 @@ class PlugwiseCircle(PlugwiseNode):
|
|
677
710
|
_log_timestamp := getattr(message, "logdate%d" % (_slot,)).value
|
678
711
|
) is None:
|
679
712
|
break
|
713
|
+
# Register collected history memory
|
714
|
+
if _slot > self._energy_memory.get(message.logaddr.value, 0):
|
715
|
+
self._energy_memory[message.logaddr.value] = _slot
|
716
|
+
|
680
717
|
self._energy_history[_log_timestamp] = getattr(
|
681
718
|
message, "pulses%d" % (_slot,)
|
682
719
|
).value
|
@@ -81,7 +81,8 @@ class NodeSED(PlugwiseNode):
|
|
81
81
|
SED_AWAKE_STARTUP,
|
82
82
|
SED_AWAKE_BUTTON,
|
83
83
|
]:
|
84
|
-
for
|
84
|
+
for pending_request in self._sed_requests.values():
|
85
|
+
request_message, callback = pending_request
|
85
86
|
_LOGGER.info(
|
86
87
|
"Send queued %s message to SED node %s",
|
87
88
|
request_message.__class__.__name__,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: plugwise
|
3
|
-
Version: 0.27.
|
3
|
+
Version: 0.27.7
|
4
4
|
Summary: Plugwise Smile (Adam/Anna/P1), Stretch and USB (Stick) module for Python 3.
|
5
5
|
Home-page: https://github.com/plugwise/python-plugwise
|
6
6
|
Author: Plugwise device owners
|
@@ -37,6 +37,7 @@ Classifier: License :: OSI Approved :: MIT License
|
|
37
37
|
Classifier: Operating System :: OS Independent
|
38
38
|
Classifier: Programming Language :: Python :: 3.9
|
39
39
|
Classifier: Programming Language :: Python :: 3.10
|
40
|
+
Classifier: Programming Language :: Python :: 3.11
|
40
41
|
Classifier: Topic :: Home Automation
|
41
42
|
Requires-Python: >=3.9.0
|
42
43
|
Description-Content-Type: text/markdown
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "plugwise"
|
7
|
-
version = "0.27.
|
7
|
+
version = "0.27.7"
|
8
8
|
license = {file = "LICENSE"}
|
9
9
|
description = "Plugwise Smile (Adam/Anna/P1), Stretch and USB (Stick) module for Python 3."
|
10
10
|
readme = "README.md"
|
@@ -16,6 +16,7 @@ classifiers = [
|
|
16
16
|
"Operating System :: OS Independent",
|
17
17
|
"Programming Language :: Python :: 3.9",
|
18
18
|
"Programming Language :: Python :: 3.10",
|
19
|
+
"Programming Language :: Python :: 3.11",
|
19
20
|
"Topic :: Home Automation",
|
20
21
|
]
|
21
22
|
authors = [
|
@@ -50,7 +51,7 @@ include-package-data = true
|
|
50
51
|
include = ["plugwise*"]
|
51
52
|
|
52
53
|
[tool.black]
|
53
|
-
target-version = ["py39", "py310"]
|
54
|
+
target-version = ["py39", "py310", "py311"]
|
54
55
|
exclude = 'generated'
|
55
56
|
|
56
57
|
[tool.isort]
|
@@ -166,9 +167,8 @@ expected-line-ending-format = "LF"
|
|
166
167
|
|
167
168
|
[tool.pylint.EXCEPTIONS]
|
168
169
|
overgeneral-exceptions = [
|
169
|
-
"BaseException",
|
170
|
-
"Exception",
|
171
|
-
"HomeAssistantError",
|
170
|
+
"builtins.BaseException",
|
171
|
+
"builtins.Exception",
|
172
172
|
]
|
173
173
|
|
174
174
|
[tool.pytest.ini_options]
|
@@ -187,7 +187,7 @@ norecursedirs = [
|
|
187
187
|
]
|
188
188
|
|
189
189
|
[tool.mypy]
|
190
|
-
python_version = "3.
|
190
|
+
python_version = "3.11"
|
191
191
|
show_error_codes = true
|
192
192
|
follow_imports = "silent"
|
193
193
|
ignore_missing_imports = true
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|