Mercurial > code > home > repos > doorbell
comparison telemetrix_local.py @ 9:7e19dffb767b default tip
rm more unused code and logging
author | drewp@bigasterisk.com |
---|---|
date | Mon, 06 Feb 2023 11:53:42 -0800 |
parents | 5441581186f8 |
children |
comparison
equal
deleted
inserted
replaced
8:5441581186f8 | 9:7e19dffb767b |
---|---|
21 # import struct | 21 # import struct |
22 import sys | 22 import sys |
23 import time | 23 import time |
24 import logging | 24 import logging |
25 log = logging.getLogger('tele') | 25 log = logging.getLogger('tele') |
26 cmdlog = logging.getLogger('command') | |
26 | 27 |
27 # noinspection PyPackageRequirementscd | 28 # noinspection PyPackageRequirementscd |
28 from serial.serialutil import SerialException | 29 from serial.serialutil import SerialException |
29 # noinspection PyPackageRequirements | 30 # noinspection PyPackageRequirements |
30 from serial.tools import list_ports | 31 from serial.tools import list_ports |
104 | 105 |
105 """ | 106 """ |
106 | 107 |
107 # noinspection PyPep8,PyPep8 | 108 # noinspection PyPep8,PyPep8 |
108 def __init__(self, com_port=None, | 109 def __init__(self, com_port=None, |
109 arduino_instance_id=1, arduino_wait=4, | 110 arduino_instance_id=1, |
110 sleep_tune=0.0001, autostart=True, | 111 autostart=True, shutdown_on_exception=True, |
111 loop=None, shutdown_on_exception=True, | |
112 close_loop_on_shutdown=True, | |
113 ip_address=None, ip_port=31335): | 112 ip_address=None, ip_port=31335): |
114 | 113 |
115 """ | 114 """ |
116 If you have a single Arduino connected to your computer, | 115 If you have a single Arduino connected to your computer, |
117 then you may accept all the default values. | 116 then you may accept all the default values. |
120 | 119 |
121 :param com_port: e.g. COM3 or /dev/ttyACM0. | 120 :param com_port: e.g. COM3 or /dev/ttyACM0. |
122 | 121 |
123 :param arduino_instance_id: Must match value in the Telemetrix4Arduino sketch | 122 :param arduino_instance_id: Must match value in the Telemetrix4Arduino sketch |
124 | 123 |
125 :param arduino_wait: Amount of time to wait for an Arduino to | |
126 fully reset itself. | |
127 | |
128 :param sleep_tune: A tuning parameter (typically not changed by user) | |
129 | |
130 :param autostart: If you wish to call the start method within | 124 :param autostart: If you wish to call the start method within |
131 your application, then set this to False. | 125 your application, then set this to False. |
132 | |
133 :param loop: optional user provided event loop | |
134 | 126 |
135 :param shutdown_on_exception: call shutdown before raising | 127 :param shutdown_on_exception: call shutdown before raising |
136 a RunTimeError exception, or | 128 a RunTimeError exception, or |
137 receiving a KeyboardInterrupt exception | 129 receiving a KeyboardInterrupt exception |
138 | |
139 :param close_loop_on_shutdown: stop and close the event loop loop | |
140 when a shutdown is called or a serial | |
141 error occurs | |
142 | 130 |
143 """ | 131 """ |
144 # check to make sure that Python interpreter is version 3.8.3 or greater | 132 # check to make sure that Python interpreter is version 3.8.3 or greater |
145 python_version = sys.version_info | 133 python_version = sys.version_info |
146 if python_version[:3] < (3, 8, 3): | 134 if python_version[:3] < (3, 8, 3): |
148 "required for use of this program.") | 136 "required for use of this program.") |
149 | 137 |
150 # save input parameters | 138 # save input parameters |
151 self.com_port = com_port | 139 self.com_port = com_port |
152 self.arduino_instance_id = arduino_instance_id | 140 self.arduino_instance_id = arduino_instance_id |
153 self.arduino_wait = arduino_wait | |
154 self.sleep_tune = sleep_tune | |
155 self.autostart = autostart | 141 self.autostart = autostart |
156 self.ip_address = ip_address | 142 self.ip_address = ip_address |
157 self.ip_port = ip_port | 143 self.ip_port = ip_port |
158 | 144 |
159 # if tcp, this variable is set to the connected socket | 145 # if tcp, this variable is set to the connected socket |
160 self.sock = None | 146 self.sock = None |
161 | 147 |
162 # set the event loop | |
163 if loop is None: | |
164 self.loop = asyncio.get_event_loop() | |
165 else: | |
166 self.loop = loop | |
167 | |
168 self.shutdown_on_exception = shutdown_on_exception | 148 self.shutdown_on_exception = shutdown_on_exception |
169 self.close_loop_on_shutdown = close_loop_on_shutdown | |
170 | 149 |
171 # dictionaries to store the callbacks for each pin | 150 # dictionaries to store the callbacks for each pin |
172 self.analog_callbacks = {} | 151 self.analog_callbacks = {} |
173 | 152 |
174 self.digital_callbacks = {} | 153 self.digital_callbacks = {} |
197 self.dht_count = 0 | 176 self.dht_count = 0 |
198 | 177 |
199 # serial port in use | 178 # serial port in use |
200 self.serial_port: Optional[TelemetrixAioSerial] = None | 179 self.serial_port: Optional[TelemetrixAioSerial] = None |
201 | 180 |
202 self.the_task = None | 181 self.report_task = None |
203 | |
204 # flag to indicate we are in shutdown mode | |
205 self.shutdown_flag = False | |
206 | 182 |
207 # reported features | 183 # reported features |
208 self.reported_features = 0 | 184 self.reported_features = 0 |
209 | 185 |
210 # To add a command to the command dispatch table, append here. | 186 # To add a command to the command dispatch table, append here. |
294 | 270 |
295 print(f'TelemetrixAIO Version: {PrivateConstants.TELEMETRIX_AIO_VERSION}') | 271 print(f'TelemetrixAIO Version: {PrivateConstants.TELEMETRIX_AIO_VERSION}') |
296 print(f'Copyright (c) 2018-2021 Alan Yorinks All rights reserved.\n') | 272 print(f'Copyright (c) 2018-2021 Alan Yorinks All rights reserved.\n') |
297 | 273 |
298 if autostart: | 274 if autostart: |
299 self.loop.run_until_complete(self.start_aio()) | 275 raise NotImplementedError("you run start_aio") |
300 | 276 |
301 async def start_aio(self): | 277 async def start_aio(self): |
302 """ | 278 """ |
303 This method may be called directly, if the autostart | 279 This method may be called directly, if the autostart |
304 parameter in __init__ is set to false. | 280 parameter in __init__ is set to false. |
335 if self.shutdown_on_exception: | 311 if self.shutdown_on_exception: |
336 await self.shutdown() | 312 await self.shutdown() |
337 raise RuntimeError('No Arduino Found or User Aborted Program') | 313 raise RuntimeError('No Arduino Found or User Aborted Program') |
338 # using tcp/ip | 314 # using tcp/ip |
339 else: | 315 else: |
340 self.sock = TelemetrixAioSocket(self.ip_address, self.ip_port, self.loop) | 316 self.sock = TelemetrixAioSocket(self.ip_address, self.ip_port) |
341 await self.sock.start() | 317 await self.sock.start() |
342 # self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | 318 # self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
343 # self.sock.connect((self.ip_address, self.ip_port)) | 319 # self.sock.connect((self.ip_address, self.ip_port)) |
344 # print(f'Successfully connected to: {self.ip_address}:{self.ip_port}') | 320 # print(f'Successfully connected to: {self.ip_address}:{self.ip_port}') |
345 | 321 |
346 # get arduino firmware version and print it | 322 # get arduino firmware version and print it |
347 firmware_version = await self._get_firmware_version() | 323 firmware_version = await self._get_firmware_version() |
348 log.debug(f'start_aio p2 {firmware_version=}') | |
349 if not firmware_version: | 324 if not firmware_version: |
350 log.info('*** Firmware Version retrieval timed out. ***') | 325 log.info('*** Firmware Version retrieval timed out. ***') |
351 log.info('\nDo you have Arduino connectivity and do you have the ') | 326 log.info('\nDo you have Arduino connectivity and do you have the ') |
352 log.info('Telemetrix4Arduino sketch uploaded to the board and are connected') | 327 log.info('Telemetrix4Arduino sketch uploaded to the board and are connected') |
353 log.info('to the correct serial port.\n') | 328 log.info('to the correct serial port.\n') |
355 '"list_serial_ports" in your console.') | 330 '"list_serial_ports" in your console.') |
356 if self.shutdown_on_exception: | 331 if self.shutdown_on_exception: |
357 await self.shutdown() | 332 await self.shutdown() |
358 raise RuntimeError | 333 raise RuntimeError |
359 else: | 334 else: |
360 log.debug(f'p3') | |
361 if firmware_version[1] < 5: | 335 if firmware_version[1] < 5: |
362 raise RuntimeError('Please upgrade the server firmware to version 5.0.0 or greater') | 336 raise RuntimeError('Please upgrade the server firmware to version 5.0.0 or greater') |
363 log.info(f'Telemetrix4Arduino Version Number: {firmware_version[1]}.' | 337 log.info(f'Telemetrix4Arduino Version Number: {firmware_version[1]}.' |
364 f'{firmware_version[2]}.{firmware_version[3]}') | 338 f'{firmware_version[2]}.{firmware_version[3]}') |
365 # start the command dispatcher loop | 339 # start the command dispatcher loop |
366 command = [PrivateConstants.ENABLE_ALL_REPORTS] | 340 command = [PrivateConstants.ENABLE_ALL_REPORTS] |
367 log.debug('start_aio send ENABLE_ALL_REPORTS') | |
368 await self._send_command(command) | 341 await self._send_command(command) |
369 if not self.loop: | 342 self.report_task = asyncio.create_task(self._arduino_report_dispatcher()) |
370 log.debug('start_aio new loop') | 343 log.debug(f'create task for _arduino_report_dispatcher done: {self.report_task}') |
371 self.loop = asyncio.get_event_loop() | |
372 self.the_task = self.loop.create_task(self._arduino_report_dispatcher()) | |
373 log.debug('create task for _arduino_report_dispatcher') | |
374 log.debug(f'create task for _arduino_report_dispatcher done: {self.the_task}') | |
375 | 344 |
376 # get the features list | 345 # get the features list |
377 command = [PrivateConstants.GET_FEATURES] | 346 command = [PrivateConstants.GET_FEATURES] |
378 log.debug('send get_features') | |
379 await self._send_command(command) | 347 await self._send_command(command) |
380 # time.sleep(.5) | 348 # time.sleep(.5) |
381 | 349 |
382 # Have the server reset its data structures | 350 # Have the server reset its data structures |
383 command = [PrivateConstants.RESET] | 351 command = [PrivateConstants.RESET] |
384 log.debug('send reset') | |
385 await self._send_command(command) | 352 await self._send_command(command) |
386 log.debug(f'start_aio bye\n') | |
387 | |
388 async def get_event_loop(self): | |
389 """ | |
390 Return the currently active asyncio event loop | |
391 | |
392 :return: Active event loop | |
393 | |
394 """ | |
395 return self.loop | |
396 | 353 |
397 async def _find_arduino(self): | 354 async def _find_arduino(self): |
398 """ | 355 """ |
399 This method will search all potential serial ports for an Arduino | 356 This method will search all potential serial ports for an Arduino |
400 containing a sketch that has a matching arduino_instance_id as | 357 containing a sketch that has a matching arduino_instance_id as |
421 serial_ports.append(self.serial_port) | 378 serial_ports.append(self.serial_port) |
422 | 379 |
423 # display to the user | 380 # display to the user |
424 print('\t' + port.device) | 381 print('\t' + port.device) |
425 | 382 |
426 # wait for arduino to reset | |
427 print('\nWaiting {} seconds(arduino_wait) for Arduino devices to ' | |
428 'reset...'.format(self.arduino_wait)) | |
429 await asyncio.sleep(self.arduino_wait) | |
430 | |
431 print('\nSearching for an Arduino configured with an arduino_instance = ', | 383 print('\nSearching for an Arduino configured with an arduino_instance = ', |
432 self.arduino_instance_id) | 384 self.arduino_instance_id) |
433 | 385 |
434 for serial_port in serial_ports: | 386 for serial_port in serial_ports: |
435 self.serial_port = serial_port | 387 self.serial_port = serial_port |
455 log.info(f'Searching for correct arduino_instance_id: {self.arduino_instance_id}') | 407 log.info(f'Searching for correct arduino_instance_id: {self.arduino_instance_id}') |
456 while True: | 408 while True: |
457 # if port is not found, a serial exception will be thrown | 409 # if port is not found, a serial exception will be thrown |
458 log.info('Opening {} ...'.format(self.com_port)) | 410 log.info('Opening {} ...'.format(self.com_port)) |
459 self.serial_port = TelemetrixAioSerial(self.com_port, 115200) | 411 self.serial_port = TelemetrixAioSerial(self.com_port, 115200) |
460 # log.debug('await open') | |
461 await self.serial_port.open() | 412 await self.serial_port.open() |
462 | 413 |
463 # print('Waiting {} seconds for the Arduino To Reset.' | |
464 # .format(self.arduino_wait)) | |
465 # await asyncio.sleep(self.arduino_wait) | |
466 command = [PrivateConstants.ARE_U_THERE] | 414 command = [PrivateConstants.ARE_U_THERE] |
467 try: | 415 try: |
468 i_am_here = await asyncio.wait_for(self._send_command(command, has_response=True), timeout=0.5) | 416 i_am_here = await asyncio.wait_for(self._send_command(command, has_response=True), timeout=0.5) |
469 except asyncio.TimeoutError: | 417 except asyncio.TimeoutError: |
470 log.info(f'no answer- retrying') | 418 log.info(f'no answer- retrying') |
481 This method retrieves the Arduino4Telemetrix firmware version | 429 This method retrieves the Arduino4Telemetrix firmware version |
482 | 430 |
483 :returns: Firmata firmware version | 431 :returns: Firmata firmware version |
484 """ | 432 """ |
485 command = [PrivateConstants.GET_FIRMWARE_VERSION] | 433 command = [PrivateConstants.GET_FIRMWARE_VERSION] |
486 log.debug('GET_FIRMWARE_VERSION') | |
487 firmware_version = await self._send_command(command, has_response=True) | 434 firmware_version = await self._send_command(command, has_response=True) |
488 log.debug(f'{firmware_version=}\n') | |
489 | |
490 return firmware_version | 435 return firmware_version |
491 | 436 |
492 async def analog_write(self, pin, value): | 437 async def analog_write(self, pin, value): |
493 """ | 438 """ |
494 Set the specified pin to the specified value. | 439 Set the specified pin to the specified value. |
2054 """ | 1999 """ |
2055 This method attempts an orderly shutdown | 2000 This method attempts an orderly shutdown |
2056 If any exceptions are thrown, they are ignored. | 2001 If any exceptions are thrown, they are ignored. |
2057 | 2002 |
2058 """ | 2003 """ |
2059 self.shutdown_flag = True | |
2060 # stop all reporting - both analog and digital | 2004 # stop all reporting - both analog and digital |
2061 try: | 2005 try: |
2062 if self.serial_port: | 2006 if self.serial_port: |
2063 command = [PrivateConstants.STOP_ALL_REPORTS] | 2007 command = [PrivateConstants.STOP_ALL_REPORTS] |
2064 await self._send_command(command) | 2008 await self._send_command(command) |
2065 | |
2066 time.sleep(.5) | |
2067 | |
2068 if self.close_loop_on_shutdown: | |
2069 self.loop.stop() | |
2070 elif self.sock: | 2009 elif self.sock: |
2071 command = [PrivateConstants.STOP_ALL_REPORTS] | 2010 command = [PrivateConstants.STOP_ALL_REPORTS] |
2072 await self._send_command(command) | 2011 await self._send_command(command) |
2073 self.the_task.cancel() | 2012 self.report_task.cancel() |
2074 time.sleep(.5) | |
2075 if self.close_loop_on_shutdown: | |
2076 self.loop.stop() | |
2077 except (RuntimeError, SerialException): | 2013 except (RuntimeError, SerialException): |
2078 pass | 2014 pass |
2079 | 2015 |
2080 async def disable_all_reporting(self): | 2016 async def disable_all_reporting(self): |
2081 """ | 2017 """ |
2476 if command: | 2412 if command: |
2477 # the length of the list is added at the head | 2413 # the length of the list is added at the head |
2478 command.insert(0, len(command)) | 2414 command.insert(0, len(command)) |
2479 # print(command) | 2415 # print(command) |
2480 send_message = bytes(command) | 2416 send_message = bytes(command) |
2481 log.debug(f'sending {CommandName[command[1]]} {command[2:]}') | 2417 cmdlog.debug(f'sending {CommandName[command[1]]} {command[2:]}') |
2482 if not self.ip_address: | 2418 if not self.ip_address: |
2483 await self.serial_port.write(send_message) | 2419 await self.serial_port.write(send_message) |
2484 else: | 2420 else: |
2485 await self.sock.write(send_message) | 2421 await self.sock.write(send_message) |
2486 # await asyncio.sleep(.1) | 2422 # await asyncio.sleep(.1) |
2489 return None | 2425 return None |
2490 else: | 2426 else: |
2491 header = await self.serial_port.read(1) | 2427 header = await self.serial_port.read(1) |
2492 packet_length = header[0] | 2428 packet_length = header[0] |
2493 pkt = await self.serial_port.read(packet_length) | 2429 pkt = await self.serial_port.read(packet_length) |
2494 log.debug(f'got response {list(pkt)}') | 2430 cmdlog.debug(f'got response {list(pkt)}') |
2495 | 2431 |
2496 return pkt | 2432 return pkt |