From dd7071e0211c7bfabae40bbf68abbb5ed9cd527b Mon Sep 17 00:00:00 2001 From: Lucas Hicks Date: Tue, 17 Oct 2023 22:44:09 +1000 Subject: [PATCH 1/3] Makes general improvements to microcontroller script with imports, error handling and some comments. --- build/figurines/microcontroller_comms.py | 66 +++++++++++++++++++----- 1 file changed, 53 insertions(+), 13 deletions(-) diff --git a/build/figurines/microcontroller_comms.py b/build/figurines/microcontroller_comms.py index 05636a7..c532d9a 100644 --- a/build/figurines/microcontroller_comms.py +++ b/build/figurines/microcontroller_comms.py @@ -9,19 +9,22 @@ # =========================== IMPORTS ================================== # -import serial.tools.list_ports import threading import time from time import sleep -import requests -import socket +from json import JSONDecodeError import json import logging +import serial.tools.list_ports +import requests +from serial import SerialException, SerialTimeoutException # =========================== GLOBAL VALUES ================================== # POLL_DELAY = 15 COM_PORT_PREFIX = "cu.usbmodem" # usbmodem1101 and usbmodem2101 +MAX_CONNECTION_COUNT = 10 + global connect_status, read_state, port, serialPort global serial_count # Optimized counter, used to clear the serial input buffer serial_count = 0 @@ -106,8 +109,11 @@ def check_presence(port, interval=0.01): def start_thread(): + """Starts a thread that checks serial port presence""" global port, connect_status _LOGGER.info("Starting thread at port %s", port) + # target - callable object invoked by the start() or run() command + # args - arguments passed to check_presence command port_controller = threading.Thread(target=check_presence, args=(port, 0.1)) port_controller.daemon = True port_controller.start() @@ -120,28 +126,62 @@ def main(): global port, connect_status figurine_status = {} + connection_count = 0 + while True: + if connection_count >= MAX_CONNECTION_COUNT: + _LOGGER.error("Could not find valid serial connection and timed out, try again") + return + if not connect_status: - port_device = None + port_device = None ports = serial.tools.list_ports.comports() for port in ports: - if COM_PORT_PREFIX in port.name: + _LOGGER.info("Trying port - %s", port.device) + if port.name is not None and COM_PORT_PREFIX in port.name: port_device = port[0] break + connection_count += 1 if port_device is not None: - initialise_serial(port_device) - start_thread() + try: + initialise_serial(port_device) + except ValueError as e: + _LOGGER.error("Parameter given is out of range") + _LOGGER.debug(e) + except SerialException as e: + # SerialException derives from IOError + _LOGGER.error("Device can not be found or configured") + _LOGGER.debug(e) + + try: + start_thread() + except RuntimeError as e: + _LOGGER.error("start() method called more than once for same thread object") + _LOGGER.debug(e) + else: connect_status = False continue if serialPort.is_open: try: - response = json.loads( - requests.get('http://127.0.0.1:8000/figurines', timeout=5).text - ) - if response != figurine_status: - figurine_status = response - send_to_controller(figurine_status) + response_body = requests.get('http://127.0.0.1:8000/figurines', timeout=5).text + if response_body is not None: + try: + response = json.loads(response_body) + except JSONDecodeError as e: + _LOGGER.error("Not valid JSON document") + _LOGGER.debug(e) + else: + _LOGGER.Error("Got nothing from the api") + continue + try: + send_to_controller(response) + except SerialTimeoutException as e: + _LOGGER.error("Write timeout") + _LOGGER.debug(e) + # if response != figurine_status: + # figurine_status = response + # send_to_controller(figurine_status) sleep(POLL_DELAY) except requests.exceptions.ConnectionError as e: _LOGGER.info("Error making HTTP request") From 9184ed19b2bcf3ad85870cce2629ea2a13c3c837 Mon Sep 17 00:00:00 2001 From: Lucas Hicks Date: Tue, 17 Oct 2023 22:46:23 +1000 Subject: [PATCH 2/3] misc --- build/figurines/microcontroller_comms.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/build/figurines/microcontroller_comms.py b/build/figurines/microcontroller_comms.py index c532d9a..7ecd54f 100644 --- a/build/figurines/microcontroller_comms.py +++ b/build/figurines/microcontroller_comms.py @@ -123,8 +123,12 @@ def start_thread(): def main(): + """Main script loop that will attempt to connect to the microcontroller. + If so, it will send data via serial to move the servo motors + """ + global port, connect_status - figurine_status = {} + # figurine_status = {} connection_count = 0 From f0486171aea432d41f1598f6a69417699dce76e3 Mon Sep 17 00:00:00 2001 From: Lucas Hicks Date: Tue, 17 Oct 2023 22:48:40 +1000 Subject: [PATCH 3/3] Better config of logger messages. --- build/figurines/microcontroller_comms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/figurines/microcontroller_comms.py b/build/figurines/microcontroller_comms.py index 7ecd54f..8f5127f 100644 --- a/build/figurines/microcontroller_comms.py +++ b/build/figurines/microcontroller_comms.py @@ -33,8 +33,8 @@ # =========================== SERIAL HANDLING ================================== # +logging.basicConfig(level=logging.DEBUG, format="%(asctime)s %(levelname)s %(message)s") _LOGGER = logging.getLogger(__name__) -_LOGGER.setLevel(logging.DEBUG) def initialise_serial(port): global serialPort, connect_status