From 3b5a1f67fef72e031505240011977fbfe849f400 Mon Sep 17 00:00:00 2001 From: Rodriguez Date: Tue, 17 Oct 2023 08:41:49 +0200 Subject: [PATCH] time lock implemented on serial connector (need testing) --- .../connectors/serial_base.py | 2 +- .../panduza_platform/connectors/serial_tty.py | 103 ++++++++---------- .../ammeter/drv_korad_ka3005p_ammeter.py | 4 +- .../drivers/bpc/drv_korad_ka3005p_bpc.py | 4 +- .../drivers/bpc/drv_tenma_722710_bpc.py | 4 +- .../voltmeter/drv_korad_ka3005p_voltmeter.py | 4 +- 6 files changed, 57 insertions(+), 64 deletions(-) diff --git a/platform/panduza_platform/connectors/serial_base.py b/platform/panduza_platform/connectors/serial_base.py index fe3b7d6..563fa7a 100644 --- a/platform/panduza_platform/connectors/serial_base.py +++ b/platform/panduza_platform/connectors/serial_base.py @@ -1,6 +1,6 @@ import abc -class ConnectorUartBase(metaclass=abc.ABCMeta): +class SerialBase(metaclass=abc.ABCMeta): """Base class for modbus client connectors It defines method to interact with the modbus client diff --git a/platform/panduza_platform/connectors/serial_tty.py b/platform/panduza_platform/connectors/serial_tty.py index 538b2e1..d26d1a9 100644 --- a/platform/panduza_platform/connectors/serial_tty.py +++ b/platform/panduza_platform/connectors/serial_tty.py @@ -1,14 +1,14 @@ -import logging +import time import asyncio -import serial +import logging import serial_asyncio -from .serial_base import ConnectorUartBase +from .serial_base import SerialBase from log.driver import driver_logger from .udev_tty import SerialPortFromUsbSetting -class ConnectorUartSerial(ConnectorUartBase): +class SerialTty(SerialBase): """ """ @@ -19,7 +19,7 @@ class ConnectorUartSerial(ConnectorUartBase): __INSTANCES = {} # Local logs - log = driver_logger("ConnectorUartSerial") + log = driver_logger("SerialTty") ########################################################################### ########################################################################### @@ -35,19 +35,19 @@ async def Get(loop,**kwargs): * *serial_baudrate* (``int``) -- serial baudrate - + * *usb_vendor* (``str``) -- ID_VENDOR_ID * *usb_model* (``str``) -- ID_MODEL_ID """ # Log - ConnectorUartSerial.log.debug(f"Get connector for {kwargs}") + SerialTty.log.debug(f"Get connector for {kwargs}") - async with ConnectorUartSerial.__MUTEX: + async with SerialTty.__MUTEX: # Log - ConnectorUartSerial.log.debug(f"Lock acquired !") + SerialTty.log.debug(f"Lock acquired !") # Get the serial port name @@ -63,20 +63,20 @@ async def Get(loop,**kwargs): raise Exception("no way to identify the serial port") # Create the new connector - if not (serial_port_name in ConnectorUartSerial.__INSTANCES): - ConnectorUartSerial.__INSTANCES[serial_port_name] = None + if not (serial_port_name in SerialTty.__INSTANCES): + SerialTty.__INSTANCES[serial_port_name] = None try: - new_instance = ConnectorUartSerial(loop,**kwargs) + new_instance = SerialTty(loop,**kwargs) await new_instance.connect() - ConnectorUartSerial.__INSTANCES[serial_port_name] = new_instance - ConnectorUartSerial.log.info("connector created") + SerialTty.__INSTANCES[serial_port_name] = new_instance + SerialTty.log.info("connector created") except Exception as e: - ConnectorUartSerial.__INSTANCES.pop(serial_port_name) + SerialTty.__INSTANCES.pop(serial_port_name) raise Exception('Error during initialization').with_traceback(e.__traceback__) # Return the previously created - return ConnectorUartSerial.__INSTANCES[serial_port_name] + return SerialTty.__INSTANCES[serial_port_name] ########################################################################### ########################################################################### @@ -84,14 +84,19 @@ async def Get(loop,**kwargs): def __init__(self, loop,**kwargs): """Constructor """ + # Init local mutex self._mutex = asyncio.Lock() + + # Init time lock + self._time_lock = None + key = kwargs["serial_port_name"] self.loop = loop - if not (key in ConnectorUartSerial.__INSTANCES): + if not (key in SerialTty.__INSTANCES): raise Exception("You need to pass through Get method to create an instance") else: self.log = logging.getLogger(key) @@ -114,16 +119,18 @@ async def connect(self): - ########################################################################### - ########################################################################### + # ============================================================================= + # OVERRIDE FROM SERIAL_BASE + + # --- async def read_uart(self, n_bytes = None): """Read from UART using asynchronous mode """ async with self._mutex: - #await asyncio.sleep(1) + try: if n_bytes is None: data = await asyncio.wait_for(self.reader.readline(), timeout=1.0) @@ -135,49 +142,35 @@ async def read_uart(self, n_bytes = None): except asyncio.TimeoutError as e: raise Exception('Error during reading uart').with_traceback(e.__traceback__) - ########################################################################### - ########################################################################### + # --- - async def write_uart(self,message): + async def write_uart(self, message, time_lock=None): """write to UART using asynchronous mode """ async with self._mutex: - #await asyncio.sleep(1) + try: + # Manage time lock by waiting for the remaining duration + if self._time_lock: + elapsed = time.time() - self._time_lock["t0"] + if elapsed < self._time_lock["duration"]: + await asyncio.sleep(elapsed) + self._time_lock = None + + # Start sending the message self.writer.write(message.encode()) - await self.writer.drain() - except Exception as e: - raise Exception('Error during writing to uart').with_traceback(e.__traceback__) - - - ########################################################################### - # SERIAL SYNCHRONOUS - ########################################################################### - - - - # async def connect(self): - # """Start the serial connection - # """ - - # self.uart = serial.Serial(self.port_name, baudrate=self.baudrate, timeout=1) - - + # Wait for the emittion completion + await self.writer.drain() - # async def read_uart(self): - # async with self._mutex: - - # data = self.uart.readline()[:-2] + # Set the time lock if requested by the user + if time_lock != None: + self._time_lock = { + "duration": time_lock, + "t0": time.time() + } - # decoded_data = data.decode('utf-8') - # if decoded_data : - # return decoded_data - + except Exception as e: + raise Exception('Error during writing to uart').with_traceback(e.__traceback__) - # async def write_uart(self,message): - # async with self._mutex: - # print(message.encode()) - - # self.uart.write(message.encode()) diff --git a/platform/panduza_platform/drivers/ammeter/drv_korad_ka3005p_ammeter.py b/platform/panduza_platform/drivers/ammeter/drv_korad_ka3005p_ammeter.py index 5ef7ef8..192b603 100644 --- a/platform/panduza_platform/drivers/ammeter/drv_korad_ka3005p_ammeter.py +++ b/platform/panduza_platform/drivers/ammeter/drv_korad_ka3005p_ammeter.py @@ -1,7 +1,7 @@ from hamcrest import assert_that, has_key, instance_of import asyncio from meta_drivers.ammeter import MetaDriverAmmeter -from connectors.serial_tty import ConnectorUartSerial +from connectors.serial_tty import SerialTty class DrvKoradKa3005pAmmeter(MetaDriverAmmeter): @@ -30,7 +30,7 @@ async def _PZA_DRV_loop_init(self, loop, tree): # Checks assert_that(settings, has_key("serial_baudrate")) - self.uart_connector = await ConnectorUartSerial.Get(loop,**settings) + self.uart_connector = await SerialTty.Get(loop,**settings) # Call meta class BPC ini await super()._PZA_DRV_loop_init(loop, tree) diff --git a/platform/panduza_platform/drivers/bpc/drv_korad_ka3005p_bpc.py b/platform/panduza_platform/drivers/bpc/drv_korad_ka3005p_bpc.py index 9f5a001..4df25bb 100644 --- a/platform/panduza_platform/drivers/bpc/drv_korad_ka3005p_bpc.py +++ b/platform/panduza_platform/drivers/bpc/drv_korad_ka3005p_bpc.py @@ -1,7 +1,7 @@ from hamcrest import assert_that, has_key, instance_of import asyncio from meta_drivers.bpc import MetaDriverBpc -from connectors.serial_tty import ConnectorUartSerial +from connectors.serial_tty import SerialTty VOLTAGE_BOUNDS = { "min": 0, "max": 30 } CURRENT_BOUNDS = { "min": 0, "max": 5 } @@ -40,7 +40,7 @@ async def _PZA_DRV_loop_init(self, loop, tree): # Checks assert_that(settings, has_key("serial_baudrate")) - self.uart_connector = await ConnectorUartSerial.Get(loop,**settings) + self.uart_connector = await SerialTty.Get(loop,**settings) # Call meta class BPC ini await super()._PZA_DRV_loop_init(loop, tree) diff --git a/platform/panduza_platform/drivers/bpc/drv_tenma_722710_bpc.py b/platform/panduza_platform/drivers/bpc/drv_tenma_722710_bpc.py index 0bf3c38..46e8b3c 100644 --- a/platform/panduza_platform/drivers/bpc/drv_tenma_722710_bpc.py +++ b/platform/panduza_platform/drivers/bpc/drv_tenma_722710_bpc.py @@ -1,6 +1,6 @@ from hamcrest import assert_that, has_key, instance_of from meta_drivers.bpc import MetaDriverBpc -from connectors.serial_tty import ConnectorUartSerial +from connectors.serial_tty import SerialTty STATE_VALUE_ENUM = { True : 1, False: 0 } VOLTAGE_BOUNDS = { "min": 0, "max": 30 } @@ -49,7 +49,7 @@ async def _PZA_DRV_loop_init(self, loop, tree): #self.modbus = await ConnectorModbusClientSerial.Get(**settings) # Get the gate connector - self.uart_connector = await ConnectorUartSerial.Get(loop,**settings) + self.uart_connector = await SerialTty.Get(loop,**settings) # #self.modbus_unit = 1 diff --git a/platform/panduza_platform/drivers/voltmeter/drv_korad_ka3005p_voltmeter.py b/platform/panduza_platform/drivers/voltmeter/drv_korad_ka3005p_voltmeter.py index 466d02d..c258fff 100644 --- a/platform/panduza_platform/drivers/voltmeter/drv_korad_ka3005p_voltmeter.py +++ b/platform/panduza_platform/drivers/voltmeter/drv_korad_ka3005p_voltmeter.py @@ -1,7 +1,7 @@ from hamcrest import assert_that, has_key, instance_of import asyncio from meta_drivers.voltmeter import MetaDriverVoltmeter -from connectors.serial_tty import ConnectorUartSerial +from connectors.serial_tty import SerialTty class DrvKoradKa3005pVoltmeter(MetaDriverVoltmeter): @@ -30,7 +30,7 @@ async def _PZA_DRV_loop_init(self, loop, tree): # Checks assert_that(settings, has_key("serial_baudrate")) - self.uart_connector = await ConnectorUartSerial.Get(loop,**settings) + self.uart_connector = await SerialTty.Get(loop,**settings) # Call meta class BPC ini await super()._PZA_DRV_loop_init(loop, tree)