Skip to content

Commit e2a3e47

Browse files
authored
Hub general exception (#167)
* Restart on general exception and log error better * Bump version to 0.16.2 * Improve IM closing process * Send ACK and Direct ACk to complete processing
1 parent 5beea5e commit e2a3e47

File tree

4 files changed

+41
-11
lines changed

4 files changed

+41
-11
lines changed

insteonplm/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -485,8 +485,8 @@ async def _ensure_reader(self):
485485
_LOGGER.error('Reconnect to Hub (TimeoutError)')
486486
await self._stop_reader(True)
487487
except Exception as e:
488-
_LOGGER.debug('Stop reading due to %s', str(e))
489-
await self._stop_reader(False)
488+
_LOGGER.debug('Restarting reading due to %s', str(e))
489+
await self._stop_reader(True)
490490
_LOGGER.info('Insteon Hub reader stopped')
491491
return
492492

insteonplm/plm.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -315,10 +315,8 @@ async def pause_writing(self):
315315
"""Pause writing."""
316316
self._restart_writer = False
317317
if self._writer_task:
318-
self._writer_task.remove_done_callback(self.restart_writing)
319-
self._writer_task.cancel()
320-
await self._writer_task
321-
await asyncio.sleep(0, loop=self._loop)
318+
self._send_queue.put_nowait(None)
319+
await asyncio.sleep(.1)
322320

323321
# pylint: disable=unused-argument
324322
def restart_writing(self, task=None):
@@ -412,9 +410,12 @@ async def _get_message_from_send_queue(self):
412410
await self._write_transport_lock.acquire()
413411
while self._restart_writer:
414412
# wait for an item from the queue
413+
msg_info = await self._send_queue.get()
414+
if msg_info is None:
415+
self._restart_writer = False
416+
return
417+
message_sent = False
415418
try:
416-
msg_info = await self._send_queue.get()
417-
message_sent = False
418419
while not message_sent:
419420
message_sent = await self._write_message(msg_info)
420421
await asyncio.sleep(msg_info.wait_timeout, loop=self._loop)
@@ -429,6 +430,7 @@ async def _get_message_from_send_queue(self):
429430
except Exception as e:
430431
_LOGGER.error('Restarting Insteon Modem writer due to %s',
431432
str(e))
433+
_LOGGER.error('MSG: %s', str(msg_info.msg))
432434
self._restart_writer = True
433435
if self._write_transport_lock.locked():
434436
self._write_transport_lock.release()

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def readme():
1111

1212
setup(
1313
name='insteonplm',
14-
version='0.16.1',
14+
version='0.16.2',
1515
author='David McNett',
1616
author_email='nugget@macnugget.org',
1717
url='https://github.com/nugget/python-insteonplm',

tests/test_plm.py

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from insteonplm.constants import (COMMAND_LIGHT_ON_0X11_NONE,
77
COMMAND_LIGHT_OFF_0X13_0X00,
88
MESSAGE_FLAG_BROADCAST_0X80,
9+
MESSAGE_FLAG_DIRECT_MESSAGE_ACK_0X20,
910
COMMAND_ID_REQUEST_0X10_0X00,
1011
COMMAND_LIGHT_STATUS_REQUEST_0X19_0X00,
1112
MESSAGE_NAK,
@@ -195,15 +196,34 @@ def async_light_on_level_callback(device_id, state, value):
195196
acknak=MESSAGE_ACK)
196197
plm.data_received(msg.bytes)
197198

199+
# Direct ACK of off message
200+
msg = StandardReceive(
201+
address='4d5e6f', target='010b00',
202+
commandtuple=COMMAND_LIGHT_OFF_0X13_0X00,
203+
flags=MESSAGE_FLAG_DIRECT_MESSAGE_ACK_0X20)
204+
plm.data_received(msg.bytes)
205+
198206
# Test that the second SET_LEVEL command is sent
199207
msg = StandardSend('4d5e6f', COMMAND_LIGHT_ON_0X11_NONE, cmd2=0xbb)
200208
cmd_sent = await wait_for_plm_command(plm, msg, loop)
201209
if not cmd_sent:
202210
assert False
203211

212+
# ACK the SET_LEVEL command and let the Direct ACK message expire
213+
msg = StandardSend('4d5e6f', COMMAND_LIGHT_ON_0X11_NONE, cmd2=0xbb,
214+
acknak=MESSAGE_ACK)
215+
plm.data_received(msg.bytes)
216+
217+
msg = StandardReceive(
218+
address='4d5e6f', target='010b00',
219+
commandtuple=COMMAND_LIGHT_ON_0X11_NONE,
220+
cmd2=0xbb,
221+
flags=MESSAGE_FLAG_DIRECT_MESSAGE_ACK_0X20)
222+
plm.data_received(msg.bytes)
223+
204224
await plm.close()
205225
_LOGGER.error('PLM closed in test_plm')
206-
await asyncio.sleep(0, loop=loop)
226+
await asyncio.sleep(.1, loop=loop)
207227
open_tasks = asyncio.Task.all_tasks(loop=loop)
208228
for task in open_tasks:
209229
if hasattr(task, 'name'):
@@ -215,6 +235,7 @@ def async_light_on_level_callback(device_id, state, value):
215235
# pylint: disable=too-many-statements
216236
async def do_plm_x10(loop):
217237
"""Asyncio coroutine to test the PLM X10 message handling."""
238+
_LOGGER.setLevel(logging.DEBUG)
218239
_LOGGER.info('Connecting to Insteon PLM')
219240

220241
# pylint: disable=not-an-iterable
@@ -269,9 +290,12 @@ async def do_plm_x10(loop):
269290
await asyncio.sleep(.1, loop=loop)
270291
assert cb.callbackvalue1 == 0x00
271292

293+
_LOGGER.info('Close PLM')
294+
_LOGGER.info('_________')
295+
272296
await plm.close()
273297
_LOGGER.error('PLM closed in test_x10')
274-
await asyncio.sleep(0, loop=loop)
298+
await asyncio.sleep(.1, loop=loop)
275299
open_tasks = asyncio.Task.all_tasks(loop=loop)
276300
for task in open_tasks:
277301
if hasattr(task, 'name'):
@@ -310,3 +334,7 @@ def test_plm_x10():
310334
_LOGGER.error('Task: %s', task)
311335
if not task.done():
312336
loop.run_until_complete(task)
337+
338+
339+
if __name__ == '__main__':
340+
test_plm()

0 commit comments

Comments
 (0)