Skip to content

Commit 396721b

Browse files
authored
Merge pull request #78 from plugwise/protected_member_fix_usb
Python 3.9 support and protected member fixes for Stick
2 parents 5a70306 + 0bd374a commit 396721b

File tree

15 files changed

+337
-561
lines changed

15 files changed

+337
-561
lines changed

.github/workflows/verify.yml

Lines changed: 188 additions & 188 deletions
Large diffs are not rendered by default.

CHANGELOG.md

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
## 0.9.4 - (alpha)
44

55
- Underlying code improvements (complexity, linting, amongst others)
6+
- Make stick code run at python 3.9 (fixes AttributeError: 'Thread' object has no attribute 'isAlive')
67

78
## 0.9.3 - Add lock-state switches
89

910
- Add support for getting and setting the lock-state of Plugs-, Circles-, Stealth-switches, for Adam and Stretch only. A set lock-state prevents a switch from being turned off.
1011
- There is no lock_state available for the following special Plugwise classes: `central heating pump` and `value actuator`
1112

12-
## 0.9.2 - Smile Optimize
13+
## 0.9.2 - Smile Optimize
1314

1415
- Functions not called by the plugwise(-beta) code have been moved to helper.py in which they are part of the subclass SmileHelper
1516
- All for-loops are now executed only once, the results are stored in self-parameters.
@@ -51,7 +52,7 @@
5152
- Scan devices
5253
- `motion` (boolean) - Current detection state of motion.
5354
- Sense devices
54-
- `humidity` (integer) - Last reported humidity value.
55+
- `humidity` (integer) - Last reported humidity value.
5556
- `temperature` (integer) - Last reported temperature value.
5657
- Circle/Circle+/Stealth devices
5758
- `current_power_usage` (float) - Current power usage (Watts) during the last second
@@ -63,7 +64,7 @@
6364
- `power_production_current_hour` (float) - Total power production (kWh) this hour
6465
- `relay_state` (boolean) - State of the output power relay. Setting this property will operate the relay
6566
- Switch devices
66-
- `switch` (boolean) - Last reported state of switch
67+
- `switch` (boolean) - Last reported state of switch
6768
- Stretch v2: fix failed connection by re-adding the aiohttp-workaround
6869

6970
## 0.8.6 - Code quality improvements for stick
@@ -72,14 +73,14 @@
7273
- Improvement: Validate message checksums
7374
- Improvement: Do a single ping request to validate if node is on-line
7475
- Improvement: Guard Scan sensitivity setting to medium
75-
- Improvement: Move general module code of messages, nodes, connection to the __init__.py files.
76+
- Improvement: Move general module code of messages, nodes, connection to the **init**.py files.
7677
- Improvement: Do proper timeout handling while sequence counter resets (once every 65532 messages)
7778
- Improvement: Better code separation. All logic is in their designated files:
78-
1. Connection (connection/*.py)
79+
1. Connection (connection/\*.py)
7980
2. Data parsing (parser.py)
80-
3. Data encoding/decoding of message (messages/*.py)
81+
3. Data encoding/decoding of message (messages/\*.py)
8182
4. Message handling - Initialization & transportation (controller.py)
82-
5. Message processing - Do the required stuff (stick.py & nodes/*.py)
83+
5. Message processing - Do the required stuff (stick.py & nodes/\*.py)
8384
- Improvement: Resolves all flake8 comments
8485

8586
## 0.8.5 - Fix sensor scaling
@@ -182,23 +183,23 @@ Changelogs below this line are separated in the former python-plugwise USB-only
182183
- Add exporter for fixtures to be used by HA-core for testing plugwise
183184
- Improve `error`-detection
184185
- Expose Plugwise System notifications (i.e. warnings or errors visible in the app)
185-
186+
186187
### 1.0.0 - Stable release
187188

188189
- Just `black`ened code (Python `black`)
189190

190191
### 0.2.15 - Code cleanup
191192

192193
- Just code improvements
193-
194+
194195
### 0.2.14 - Code cleanup
195196

196197
- Just code improvements
197-
198+
198199
### 0.2.13 - Final legacy fix
199200

200201
- Adjust `dwh` and `setpoint` handling
201-
202+
202203
### 0.2.12 - Fix available schema's
203204

204205
- Thanks to report from @fsaris
@@ -208,12 +209,12 @@ Changelogs below this line are separated in the former python-plugwise USB-only
208209

209210
- See [65](https://github.com/plugwise/plugwise-beta/issues/65)
210211
- Add return water temperature from Auxiliary
211-
212+
212213
### 0.2.10 - Core PR updates
213214

214215
- Add exception for InvalidAuthentication
215216
- Revert setting heating when None
216-
217+
217218
### 0.2.9 - Use intended state
218219

219220
- Change to `intended_central_heating_state`
@@ -225,17 +226,17 @@ Changelogs below this line are separated in the former python-plugwise USB-only
225226
- CI/CD improve pre-commit hooks
226227
- Remove useless water sensor
227228
- Improve testing guidelines README
228-
229+
229230
### 0.2.7 - CI/CD
230231

231232
- CI/CD Version number handling
232-
233+
233234
### 0.2.6 - New firmware support and XML handling
234235

235236
- Improvement by contributor @sbeukers (Smile P1 v4 support)
236237
- Legacy Anna fixes and test improvements
237238
- Favour `domain_objects` over `appliances` XML-data
238-
239+
239240
### 0.2.5 - Issuefix, cleanup and CI/CD
240241

241242
- Fix for HVAC idle issue [#57](https://github.com/plugwise/plugwise-beta/issues/57)
@@ -248,7 +249,7 @@ Changelogs below this line are separated in the former python-plugwise USB-only
248249
- `chs` and `dhw` determined from `boiler_state`
249250
- No `chs` or `dhw` on legacy Anna
250251
- More legacy anna fixes
251-
252+
252253
### 0.2.1 - Master thermostat fixes
253254

254255
- Legacy Anna fixes
@@ -270,12 +271,12 @@ Changelogs below this line are separated in the former python-plugwise USB-only
270271
- Prepare virtualenvs (travis etc.)
271272
- Code styling/wording fixes (lint/pep)
272273
- Improve READMEs
273-
274+
274275
### 0.1.25 - Domestic hot water and CI/CD improvements
275276

276277
- Testing improvements
277278
- `dhw`-handling
278-
279+
279280
### 0.1.24 - Add handling erroneous XML and/or timeouts
280281

281282
- Favour exception raises above returning `False`
@@ -293,7 +294,7 @@ Changelogs below this line are separated in the former python-plugwise USB-only
293294

294295
- Add heatpump-environment data and tests (thanks to @marcelveldt)
295296
- Improve `outdoor_temperature` accordingly (favour Auxiliary over Smile)
296-
297+
297298
### 0.1.20 - Fix thermostat count
298299

299300
### 0.1.19 - Add thermostat counting
@@ -307,7 +308,7 @@ Changelogs below this line are separated in the former python-plugwise USB-only
307308
### 0.1.16 - Fix central components
308309

309310
- Version skip to align with `-beta`-component
310-
311+
311312
### 0.1.12 - Introduce heatpump
312313

313314
- Thanks to @marcelveldt and his environment
@@ -316,7 +317,7 @@ Changelogs below this line are separated in the former python-plugwise USB-only
316317
### 0.1.11 - Add all options for P1 DSMR
317318

318319
- Thanks to @(tbd) and his environment
319-
320+
320321
### 0.1.9 - Set HVAC on legacy Anna
321322

322323
### 0.1.8 - Scheduled state on legacy Anna
@@ -333,7 +334,7 @@ Changelogs below this line are separated in the former python-plugwise USB-only
333334
- Improve/standardize public variables
334335
- Tests updated accordingly
335336
- Version skip to align with `-beta`-component
336-
337+
337338
### 0.1.0 - Public beta
338339

339340
### 0.0.57 - Review to public beta
@@ -376,7 +377,7 @@ Changelogs below this line are separated in the former python-plugwise USB-only
376377
- Improve handling Lisa thermostat
377378
- Improve relay (plugs) functionality
378379
- Add individual Smiles as 'hub'-components
379-
380+
380381
### 0.0.26 - Add relay (plugs) support and tests
381382

382383
### 0.0.x - Not individually release but left in [this repo](https://github.com/plugwise/Plugwise-HA)

plugwise/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Plugwise module."""
22

3-
__version__ = "0.9.4a9"
3+
__version__ = "0.9.4a10"
44

55
from plugwise.smile import Smile
66
from plugwise.stick import stick

plugwise/connections/__init__.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ def connect(self) -> bool:
3636
self._open_connection()
3737
return self._is_connected
3838

39+
def _open_connection(self):
40+
"""Placeholder."""
41+
3942
################################################
4043
### Reader ###
4144
################################################
@@ -55,6 +58,10 @@ def _reader_deamon(self):
5558
time.sleep(0.01)
5659
_LOGGER.debug("Reader daemon stopped")
5760

61+
def _read_data(self):
62+
"""placeholder."""
63+
return b"0000"
64+
5865
################################################
5966
### Writer ###
6067
################################################
@@ -86,6 +93,9 @@ def _writer_daemon(self):
8693
callback()
8794
_LOGGER.debug("Writer daemon stopped")
8895

96+
def _write_data(self, data):
97+
"""Placeholder."""
98+
8999
def send(self, message: NodeRequest, callback=None):
90100
"""Add message to write queue."""
91101
self._write_queue.put_nowait((message, callback))
@@ -100,11 +110,11 @@ def is_connected(self):
100110

101111
def read_thread_alive(self):
102112
"""Return state of write thread."""
103-
return self._reader_thread.isAlive() if self.run_reader_thread else False
113+
return self._reader_thread.is_alive() if self.run_reader_thread else False
104114

105115
def write_thread_alive(self):
106116
"""Return state of write thread."""
107-
return self._writer_thread.isAlive() if self.run_writer_thread else False
117+
return self._writer_thread.is_alive() if self.run_writer_thread else False
108118

109119
################################################
110120
### Close connection ###
@@ -117,7 +127,10 @@ def disconnect(self):
117127
self.run_writer_thread = False
118128
self.run_reader_thread = False
119129
max_wait = 5 * SLEEP_TIME
120-
while self._writer_thread.isAlive():
130+
while self._writer_thread.is_alive():
121131
time.sleep(SLEEP_TIME)
122132
max_wait -= SLEEP_TIME
123133
self._close_connection()
134+
135+
def _close_connection(self):
136+
"""Placeholder."""

plugwise/controller.py

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,28 @@ def __init__(self, port: str, message_processor, node_state):
5959
self._send_message_queue = None
6060
self._send_message_thread = None
6161
self._receive_timeout_thread = False
62-
self._run_receive_timeout_thread = False
63-
self._run_send_message_thread = False
62+
self._receive_timeout_thread_state = False
63+
self._send_message_thread_state = False
64+
65+
@property
66+
def receive_timeout_thread_state(self) -> bool:
67+
"""Required state of the receive timeout thread"""
68+
return self._receive_timeout_thread_state
69+
70+
@property
71+
def receive_timeout_thread_is_alive(self) -> bool:
72+
"""Current state of the receive timeout thread"""
73+
return self._send_message_thread.is_alive()
74+
75+
@property
76+
def send_message_thread_state(self) -> bool:
77+
"""Required state of the send message thread"""
78+
return self._send_message_thread_state
79+
80+
@property
81+
def send_message_thread_is_alive(self) -> bool:
82+
"""Current state of the send message thread"""
83+
return self._send_message_thread.is_alive()
6484

6585
def connect_to_stick(self, callback=None) -> bool:
6686
"""
@@ -82,14 +102,14 @@ def connect_to_stick(self, callback=None) -> bool:
82102
_LOGGER.debug("Starting message controller threads...")
83103
# send daemon
84104
self._send_message_queue = PriorityQueue()
85-
self._run_send_message_thread = True
105+
self._send_message_thread_state = True
86106
self._send_message_thread = threading.Thread(
87107
None, self._send_message_loop, "send_messages_thread", (), {}
88108
)
89109
self._send_message_thread.daemon = True
90110
self._send_message_thread.start()
91111
# receive timeout daemon
92-
self._run_receive_timeout_thread = True
112+
self._receive_timeout_thread_state = True
93113
self._receive_timeout_thread = threading.Thread(
94114
None, self._receive_timeout_loop, "receive_timeout_thread", (), {}
95115
)
@@ -194,7 +214,7 @@ def resend(self, seq_id):
194214

195215
def _send_message_loop(self):
196216
"""Daemon to send messages waiting in queue."""
197-
while self._run_send_message_thread:
217+
while self._send_message_thread_state:
198218
try:
199219
_prio, _retry, _dt, request_set = self._send_message_queue.get(
200220
block=True, timeout=1
@@ -235,7 +255,7 @@ def _send_message_loop(self):
235255
):
236256
time.sleep(0.1)
237257
timeout_counter += 1
238-
if timeout_counter >= 10 and self._run_send_message_thread:
258+
if timeout_counter >= 10 and self._send_message_thread_state:
239259
self.resend(seq_id)
240260
_LOGGER.debug("Send message loop stopped")
241261

@@ -308,7 +328,7 @@ def _post_message_action(self, seq_id, ack_response=None, request="unknown"):
308328

309329
def _receive_timeout_loop(self):
310330
"""Daemon to time out open requests without any (n)ack response message."""
311-
while self._run_receive_timeout_thread:
331+
while self._receive_timeout_thread_state:
312332
for seq_id in list(self.expected_responses.keys()):
313333
if self.expected_responses[seq_id][3] is not None:
314334
if self.expected_responses[seq_id][3] < (
@@ -330,7 +350,7 @@ def _receive_timeout_loop(self):
330350
receive_timeout_checker = 0
331351
while (
332352
receive_timeout_checker < MESSAGE_TIME_OUT
333-
and self._run_receive_timeout_thread
353+
and self._receive_timeout_thread_state
334354
):
335355
time.sleep(1)
336356
receive_timeout_checker += 1
@@ -376,6 +396,38 @@ def _log_status_message(self, message, status=None):
376396

377397
def disconnect_from_stick(self):
378398
"""Disconnect from stick and raise error if it fails"""
379-
self._run_send_message_thread = False
380-
self._run_receive_timeout_thread = False
399+
self._send_message_thread_state = False
400+
self._receive_timeout_thread_state = False
381401
self.connection.disconnect()
402+
403+
def restart_receive_timeout_thread(self):
404+
"""Restart the receive timeout thread if not running"""
405+
if not self._receive_timeout_thread.is_alive():
406+
_LOGGER.warning(
407+
"Unexpected halt of receive thread, restart thread",
408+
)
409+
self._receive_timeout_thread = threading.Thread(
410+
None,
411+
self._receive_timeout_loop,
412+
"receive_timeout_thread",
413+
(),
414+
{},
415+
)
416+
self._receive_timeout_thread.daemon = True
417+
self._receive_timeout_thread.start()
418+
419+
def restart_send_message_thread(self):
420+
"""Restart the message sender thread if not running"""
421+
if not self._send_message_thread.is_alive():
422+
_LOGGER.warning(
423+
"Unexpected halt of send thread, restart thread",
424+
)
425+
self._send_message_thread = threading.Thread(
426+
None,
427+
self._send_message_loop,
428+
"send_messages_thread",
429+
(),
430+
{},
431+
)
432+
self._send_message_thread.daemon = True
433+
self._send_message_thread.start()

plugwise/messages/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
class PlugwiseMessage:
88
"""Plugwise message base."""
99

10+
ID = b"0000"
11+
1012
def __init__(self):
1113
self.mac = ""
1214
self.checksum = None

0 commit comments

Comments
 (0)