changeset 5:696a46a1b239

logging and minor refactors
author drewp@bigasterisk.com
date Sun, 05 Feb 2023 14:26:04 -0800
parents 6182841fb92e
children ca63391a2214
files telemetrix_local.py
diffstat 1 files changed, 116 insertions(+), 86 deletions(-) [+]
line wrap: on
line diff
--- a/telemetrix_local.py	Sun Feb 05 14:14:01 2023 -0800
+++ b/telemetrix_local.py	Sun Feb 05 14:26:04 2023 -0800
@@ -20,6 +20,8 @@
 # import struct
 import sys
 import time
+import logging
+log = logging.getLogger('tele')
 
 # noinspection PyPackageRequirementscd
 from serial.serialutil import SerialException
@@ -31,8 +33,66 @@
 # noinspection PyUnresolvedReferences
 from telemetrix_aio.telemetrix_aio_socket import TelemetrixAioSocket
 # noinspection PyUnresolvedReferences
-from telemetrix_aio.telemtrix_aio_serial import TelemetrixAioSerial
-
+from telemetrix_local_serial import TelemetrixAioSerial
+
+# for debug logging. Should move to private_constants.py
+CommandName = {
+     0: 'LOOP_COMMAND',
+     1: 'SET_PIN_MODE',
+     2: 'DIGITAL_WRITE',
+     3: 'ANALOG_WRITE',
+     4: 'MODIFY_REPORTING',
+     5: 'GET_FIRMWARE_VERSION',
+     6: 'ARE_U_THERE',
+     7: 'SERVO_ATTACH',
+     8: 'SERVO_WRITE',
+     9: 'SERVO_DETACH',
+     10: 'I2C_BEGIN',
+     11: 'I2C_READ',
+     12: 'I2C_WRITE',
+     13: 'SONAR_NEW',
+     14: 'DHT_NEW',
+     15: 'STOP_ALL_REPORTS',
+     16: 'SET_ANALOG_SCANNING_INTERVAL',
+     17: 'ENABLE_ALL_REPORTS',
+     18: 'RESET',
+     19: 'SPI_INIT',
+     20: 'SPI_WRITE_BLOCKING',
+     21: 'SPI_READ_BLOCKING',
+     22: 'SPI_SET_FORMAT',
+     23: 'SPI_CS_CONTROL',
+     24: 'ONE_WIRE_INIT',
+     25: 'ONE_WIRE_RESET',
+     26: 'ONE_WIRE_SELECT',
+     27: 'ONE_WIRE_SKIP',
+     28: 'ONE_WIRE_WRITE',
+     29: 'ONE_WIRE_READ',
+     30: 'ONE_WIRE_RESET_SEARCH',
+     31: 'ONE_WIRE_SEARCH',
+     32: 'ONE_WIRE_CRC8',
+     33: 'SET_PIN_MODE_STEPPER',
+     34: 'STEPPER_MOVE_TO',
+     35: 'STEPPER_MOVE',
+     36: 'STEPPER_RUN',
+     37: 'STEPPER_RUN_SPEED',
+     38: 'STEPPER_SET_MAX_SPEED',
+     39: 'STEPPER_SET_ACCELERATION',
+     40: 'STEPPER_SET_SPEED',
+     41: 'STEPPER_SET_CURRENT_POSITION',
+     42: 'STEPPER_RUN_SPEED_TO_POSITION',
+     43: 'STEPPER_STOP',
+     44: 'STEPPER_DISABLE_OUTPUTS',
+     45: 'STEPPER_ENABLE_OUTPUTS',
+     46: 'STEPPER_SET_MINIMUM_PULSE_WIDTH',
+     47: 'STEPPER_SET_ENABLE_PIN',
+     48: 'STEPPER_SET_3_PINS_INVERTED',
+     49: 'STEPPER_SET_4_PINS_INVERTED',
+     50: 'STEPPER_IS_RUNNING',
+     51: 'STEPPER_GET_CURRENT_POSITION',
+     52: 'STEPPER_GET_DISTANCE_TO_GO',
+     53: 'STEPPER_GET_TARGET_POSITION',
+     54: 'GET_FEATURES',
+}
 
 # noinspection GrazieInspection,PyArgumentList,PyMethodMayBeStatic,PyRedundantParentheses
 class TelemetrixAIO:
@@ -82,13 +142,9 @@
         """
         # check to make sure that Python interpreter is version 3.8.3 or greater
         python_version = sys.version_info
-        if python_version[0] >= 3:
-            if python_version[1] >= 8:
-                if python_version[2] >= 3:
-                    pass
-            else:
-                raise RuntimeError("ERROR: Python 3.7 or greater is "
-                                   "required for use of this program.")
+        if python_version[:3] < (3, 8, 3):
+            raise RuntimeError("ERROR: Python 3.8.3 or greater is "
+                               "required for use of this program.")
 
         # save input parameters
         self.com_port = com_port
@@ -140,67 +196,39 @@
         self.dht_count = 0
 
         # serial port in use
-        self.serial_port = None
-
-        # generic asyncio task holder
+        self.serial_port: Optional[TelemetrixAioSerial] = None
+ 
         self.the_task = None
 
         # flag to indicate we are in shutdown mode
         self.shutdown_flag = False
 
-        self.report_dispatch = {}
-
         # reported features
         self.reported_features = 0
 
         # To add a command to the command dispatch table, append here.
-        self.report_dispatch.update(
-            {PrivateConstants.LOOP_COMMAND: self._report_loop_data})
-        self.report_dispatch.update(
-            {PrivateConstants.DEBUG_PRINT: self._report_debug_data})
-        self.report_dispatch.update(
-            {PrivateConstants.DIGITAL_REPORT: self._digital_message})
-        self.report_dispatch.update(
-            {PrivateConstants.ANALOG_REPORT: self._analog_message})
-        self.report_dispatch.update(
-            {PrivateConstants.SERVO_UNAVAILABLE: self._servo_unavailable})
-        self.report_dispatch.update(
-            {PrivateConstants.I2C_READ_REPORT: self._i2c_read_report})
-        self.report_dispatch.update(
-            {PrivateConstants.I2C_TOO_FEW_BYTES_RCVD: self._i2c_too_few})
-        self.report_dispatch.update(
-            {PrivateConstants.I2C_TOO_MANY_BYTES_RCVD: self._i2c_too_many})
-        self.report_dispatch.update(
-            {PrivateConstants.SONAR_DISTANCE: self._sonar_distance_report})
-        self.report_dispatch.update({PrivateConstants.DHT_REPORT: self._dht_report})
-        self.report_dispatch.update(
-            {PrivateConstants.SPI_REPORT: self._spi_report})
-        self.report_dispatch.update(
-            {PrivateConstants.ONE_WIRE_REPORT: self._onewire_report})
-        self.report_dispatch.update(
-            {PrivateConstants.STEPPER_DISTANCE_TO_GO:
-                 self._stepper_distance_to_go_report})
-        self.report_dispatch.update(
-            {PrivateConstants.STEPPER_TARGET_POSITION:
-                 self._stepper_target_position_report})
-        self.report_dispatch.update(
-            {PrivateConstants.STEPPER_CURRENT_POSITION:
-                 self._stepper_current_position_report})
-        self.report_dispatch.update(
-            {PrivateConstants.STEPPER_RUNNING_REPORT:
-                 self._stepper_is_running_report})
-        self.report_dispatch.update(
-            {PrivateConstants.STEPPER_RUN_COMPLETE_REPORT:
-                 self._stepper_run_complete_report})
-        self.report_dispatch.update(
-            {PrivateConstants.STEPPER_DISTANCE_TO_GO:
-                 self._stepper_distance_to_go_report})
-        self.report_dispatch.update(
-            {PrivateConstants.STEPPER_TARGET_POSITION:
-                 self._stepper_target_position_report})
-        self.report_dispatch.update(
-            {PrivateConstants.FEATURES:
-                 self._features_report})
+        self.report_dispatch = {
+            PrivateConstants.LOOP_COMMAND: self._report_loop_data,
+            PrivateConstants.DEBUG_PRINT: self._report_debug_data,
+            PrivateConstants.DIGITAL_REPORT: self._digital_message,
+            PrivateConstants.ANALOG_REPORT: self._analog_message,
+            PrivateConstants.SERVO_UNAVAILABLE: self._servo_unavailable,
+            PrivateConstants.I2C_READ_REPORT: self._i2c_read_report,
+            PrivateConstants.I2C_TOO_FEW_BYTES_RCVD: self._i2c_too_few,
+            PrivateConstants.I2C_TOO_MANY_BYTES_RCVD: self._i2c_too_many,
+            PrivateConstants.SONAR_DISTANCE: self._sonar_distance_report,
+            PrivateConstants.DHT_REPORT: self._dht_report,
+            PrivateConstants.SPI_REPORT: self._spi_report,
+            PrivateConstants.ONE_WIRE_REPORT: self._onewire_report,
+            PrivateConstants.STEPPER_DISTANCE_TO_GO: self._stepper_distance_to_go_report,
+            PrivateConstants.STEPPER_TARGET_POSITION: self._stepper_target_position_report,
+            PrivateConstants.STEPPER_CURRENT_POSITION: self._stepper_current_position_report,
+            PrivateConstants.STEPPER_RUNNING_REPORT: self._stepper_is_running_report,
+            PrivateConstants.STEPPER_RUN_COMPLETE_REPORT: self._stepper_run_complete_report,
+            PrivateConstants.STEPPER_DISTANCE_TO_GO: self._stepper_distance_to_go_report,
+            PrivateConstants.STEPPER_TARGET_POSITION: self._stepper_target_position_report,
+            PrivateConstants.FEATURES: self._features_report,
+        }
 
         # dictionaries to store the callbacks for each pin
         self.analog_callbacks = {}
@@ -281,7 +309,7 @@
         Use this method if you wish to start TelemetrixAIO manually from
         an asyncio function.
          """
-
+        log.debug('start_aio')
         if not self.ip_address:
             if not self.com_port:
                 # user did not specify a com_port
@@ -316,36 +344,45 @@
 
         # get arduino firmware version and print it
         firmware_version = await self._get_firmware_version()
+        log.debug(f'start_aio p2 {firmware_version=}')
         if not firmware_version:
-            print('*** Firmware Version retrieval timed out. ***')
-            print('\nDo you have Arduino connectivity and do you have the ')
-            print('Telemetrix4Arduino sketch uploaded to the board and are connected')
-            print('to the correct serial port.\n')
-            print('To see a list of serial ports, type: '
+            log.info('*** Firmware Version retrieval timed out. ***')
+            log.info('\nDo you have Arduino connectivity and do you have the ')
+            log.info('Telemetrix4Arduino sketch uploaded to the board and are connected')
+            log.info('to the correct serial port.\n')
+            log.info('To see a list of serial ports, type: '
                   '"list_serial_ports" in your console.')
             if self.shutdown_on_exception:
                 await self.shutdown()
             raise RuntimeError
         else:
             if firmware_version[2] < 5:
+            log.debug(f'p3')
                 raise RuntimeError('Please upgrade the server firmware to version 5.0.0 or greater')
-            print(f'Telemetrix4Arduino Version Number: {firmware_version[2]}.'
-                  f'{firmware_version[3]}.{firmware_version[4]}')
+            log.info(f'Telemetrix4Arduino Version Number: {firmware_version[1]}.'
+                     f'{firmware_version[2]}.{firmware_version[3]}')
             # start the command dispatcher loop
             command = [PrivateConstants.ENABLE_ALL_REPORTS]
+            log.debug('start_aio send ENABLE_ALL_REPORTS')
             await self._send_command(command)
             if not self.loop:
+                log.debug('start_aio new loop')
                 self.loop = asyncio.get_event_loop()
             self.the_task = self.loop.create_task(self._arduino_report_dispatcher())
+            log.debug('create task for _arduino_report_dispatcher')
+            log.debug(f'create task for _arduino_report_dispatcher done: {self.the_task}')
 
             # get the features list
             command = [PrivateConstants.GET_FEATURES]
+            log.debug('send get_features')
             await self._send_command(command)
             time.sleep(.5)
 
             # Have the server reset its data structures
             command = [PrivateConstants.RESET]
+            log.debug('send reset')
             await self._send_command(command)
+        log.debug(f'start_aio bye\n')
 
     async def get_event_loop(self):
         """
@@ -440,7 +477,8 @@
         if not i_am_here:
             print(f'ERROR: correct arduino_instance_id not found')
 
-        print('Correct arduino_instance_id found')
+
+        log.info('Correct arduino_instance_id found\n')
 
     async def _get_firmware_version(self):
         """
@@ -1389,21 +1427,17 @@
             raise RuntimeError('_set_pin_mode: A Callback must be specified')
         else:
             if pin_state == PrivateConstants.AT_INPUT:
-                command = [PrivateConstants.SET_PIN_MODE, pin_number,
-                           PrivateConstants.AT_INPUT, 1]
+                command = [PrivateConstants.SET_PIN_MODE, pin_number, pin_state, 1]
                 self.digital_callbacks[pin_number] = callback
             elif pin_state == PrivateConstants.AT_INPUT_PULLUP:
-                command = [PrivateConstants.SET_PIN_MODE, pin_number,
-                           PrivateConstants.AT_INPUT_PULLUP, 1]
+                command = [PrivateConstants.SET_PIN_MODE, pin_number, pin_state, 1]
+                log.debug(f'saving yuor cb for {pin_number=} to {callback}')
                 self.digital_callbacks[pin_number] = callback
             elif pin_state == PrivateConstants.AT_ANALOG:
-                command = [PrivateConstants.SET_PIN_MODE, pin_number,
-                           PrivateConstants.AT_ANALOG,
-                           differential >> 8, differential & 0xff, 1]
+                command = [PrivateConstants.SET_PIN_MODE, pin_number, pin_state, differential >> 8, differential & 0xff, 1]
                 self.analog_callbacks[pin_number] = callback
             elif pin_state == PrivateConstants.AT_OUTPUT:
-                command = [PrivateConstants.SET_PIN_MODE, pin_number,
-                           PrivateConstants.AT_OUTPUT, 1]
+                command = [PrivateConstants.SET_PIN_MODE, pin_number, pin_state, 1]
             else:
                 if self.shutdown_on_exception:
                     await self.shutdown()
@@ -2110,8 +2144,8 @@
         :param pin: Pin number.
         """
 
-        command = [PrivateConstants.MODIFY_REPORTING,
-                   PrivateConstants.REPORTING_DIGITAL_ENABLE, pin]
+        log.debug(f'enable_digital_reporting {pin=}')
+        command = [PrivateConstants.MODIFY_REPORTING, PrivateConstants.REPORTING_DIGITAL_ENABLE, pin]
         await self._send_command(command)
 
     async def _arduino_report_dispatcher(self):
@@ -2126,7 +2160,6 @@
 
         :returns: This method never returns
         """
-
         while True:
             if self.shutdown_flag:
                 break
@@ -2147,10 +2180,6 @@
                 packet = list(await self.sock.read(packet_length))
 
             report = packet[0]
-            # print(report)
-            # handle all other messages by looking them up in the
-            # command dictionary
-
             await self.report_dispatch[report](packet[1:])
             await asyncio.sleep(self.sleep_tune)
 
@@ -2270,6 +2299,7 @@
         value = data[1]
 
         time_stamp = time.time()
+        log.debug(f'digital_callbacks[{pin}] is {self.digital_callbacks.get(pin)}')
         if self.digital_callbacks[pin]:
             message = [PrivateConstants.DIGITAL_REPORT, pin, value, time_stamp]
             await self.digital_callbacks[pin](message)