diff --git a/code/sys_shd/pyproject.toml b/code/sys_shd/pyproject.toml index 66081ae..44ca929 100644 --- a/code/sys_shd/pyproject.toml +++ b/code/sys_shd/pyproject.toml @@ -9,7 +9,7 @@ build-backend = "setuptools.build_meta" # users can install this project, e.g.: # # $ pip install -name = "system_shared_tool" +name = "system_shared_tool_rt" # Versions should comply with PEP 440: # https://www.python.org/dev/peps/pep-0440/ diff --git a/code/sys_shd/requirements.txt b/code/sys_shd/requirements.txt index 056410d..58bfddd 100644 --- a/code/sys_shd/requirements.txt +++ b/code/sys_shd/requirements.txt @@ -2,3 +2,4 @@ posix-ipc>=1.1.1 PyYAML>=6.0.1 system-config-tool>=0.0.7 system-logger-tool>=0.2.2 +RPi-GPIO>=0.7.1 \ No newline at end of file diff --git a/code/sys_shd/src/system_shared_tool/__init__.py b/code/sys_shd/src/system_shared_tool/__init__.py index e5e76de..3cbdffb 100644 --- a/code/sys_shd/src/system_shared_tool/__init__.py +++ b/code/sys_shd/src/system_shared_tool/__init__.py @@ -2,7 +2,8 @@ This file specifies what is going to be exported from this module. In this case is sys_shd. """ -from .sys_shd_common import SysShdErrorC, SysShdNodeParamsC, SysShdNodeC, SysShdNodeStatusE +from .sys_shd_common import (SysShdErrorC, SysShdNodeParamsC, SysShdNodeC, SysShdNodeStatusE, + SysShdPeripheralC) from .sys_shd_channels import SysShdIpcChanC, SysShdChanC from .sys_shd_objects import SysShdSharedObjC __all__= ['SysShdChanC', 'SysShdSharedObjC', 'SysShdErrorC', 'SysShdNodeStatusE', diff --git a/code/sys_shd/src/system_shared_tool/context.py b/code/sys_shd/src/system_shared_tool/context.py index bd64209..47ad90f 100644 --- a/code/sys_shd/src/system_shared_tool/context.py +++ b/code/sys_shd/src/system_shared_tool/context.py @@ -27,8 +27,10 @@ # For further information check out README.md DEFAULT_CHAN_NUM_MSG : int = 100 # Max number of allowed message per chan DEFAULT_IPC_MSG_SIZE : int = 100 # Size of message sent through IPC message queue -DEFAULT_CHAN_TIMEOUT : int = 1 +DEFAULT_CHAN_TIMEOUT : int|None = None +DEFAULT_GPIO_CONFIG_PATH : str = 'config_gpio.yaml' -CONSTANTS_NAMES = ('DEFAULT_CHAN_NUM_MSG', 'DEFAULT_IPC_MSG_SIZE', 'DEFAULT_CHAN_TIMEOUT') +CONSTANTS_NAMES = ('DEFAULT_CHAN_NUM_MSG', 'DEFAULT_IPC_MSG_SIZE', 'DEFAULT_CHAN_TIMEOUT', + 'DEFAULT_GPIO_CONFIG_PATH') sys_conf_update_config_params(context=globals(), constants_names=CONSTANTS_NAMES) diff --git a/code/sys_shd/src/system_shared_tool/sys_shd_channels.py b/code/sys_shd/src/system_shared_tool/sys_shd_channels.py index 44c00e6..d3bd46b 100644 --- a/code/sys_shd/src/system_shared_tool/sys_shd_channels.py +++ b/code/sys_shd/src/system_shared_tool/sys_shd_channels.py @@ -7,6 +7,7 @@ ####################### MANDATORY IMPORTS ####################### from __future__ import annotations +from typing import Any ####################### GENERIC IMPORTS ####################### from queue import Queue, Empty, Full from pickle import dumps, loads, HIGHEST_PROTOCOL @@ -59,7 +60,7 @@ def delete_until_last(self) -> None: while self.qsize() > 1: self.get() - def receive_data(self) -> object: + def receive_data(self) -> Any: ''' Pop the first element from the queue and return it. If queue is empty, wait until a new element is pushed to the queue. @@ -69,7 +70,7 @@ def receive_data(self) -> object: ''' return self.get() - def receive_data_unblocking(self) -> object: + def receive_data_unblocking(self) -> Any: ''' Receive data from the queue in unblocking mode. @@ -142,7 +143,7 @@ def delete_until_last(self) -> None: while self.current_messages > 0: self.receive(timeout = 0) - def receive_data(self, timeout: int = DEFAULT_CHAN_TIMEOUT) -> object: + def receive_data(self, timeout: int|None = DEFAULT_CHAN_TIMEOUT) -> Any: ''' Pop the first element from the queue and return it. If queue is empty, wait until a new element is pushed to the queue. @@ -162,7 +163,7 @@ def receive_data(self, timeout: int = DEFAULT_CHAN_TIMEOUT) -> object: self.block = False return msg_decoded - def receive_data_unblocking(self) -> object: + def receive_data_unblocking(self) -> Any: ''' Receive data from the queue in unblocking mode. Returns: diff --git a/code/sys_shd/src/system_shared_tool/sys_shd_common.py b/code/sys_shd/src/system_shared_tool/sys_shd_common.py index a80e84a..f65f363 100644 --- a/code/sys_shd/src/system_shared_tool/sys_shd_common.py +++ b/code/sys_shd/src/system_shared_tool/sys_shd_common.py @@ -11,22 +11,28 @@ from enum import Enum from time import time, sleep ####################### SYSTEM ABSTRACTION IMPORTS ####################### +from system_config_tool import sys_conf_read_config_params, SysConfSectionNotFoundErrorC from system_logger_tool import Logger, SysLogLoggerC, sys_log_logger_get_module_logger if __name__ == "__main__": cycler_logger = SysLogLoggerC() log: Logger = sys_log_logger_get_module_logger(__name__) ####################### THIRD PARTY IMPORTS ####################### +from RPi.GPIO.GPIO import setmode, BCM, BOARD, setup, output, HIGH, LOW, OUT ####################### MODULE IMPORTS ####################### ####################### PROJECT IMPORTS ####################### -####################### ENUMS ####################### - -####################### CLASSES ####################### +###################### CONSTANTS ###################### +from .context import DEFAULT_GPIO_CONFIG_PATH +gpio_mode = sys_conf_read_config_params(filename=DEFAULT_GPIO_CONFIG_PATH, section= 'GPIO_BOARD') +if gpio_mode == 'BOARD': + setmode(BOARD) +else: + setmode(BCM) _TO_MS = 1000 - +####################### ENUMS ####################### class SysShdNodeStatusE(Enum): ''' Enum class for the node state @@ -37,6 +43,7 @@ class SysShdNodeStatusE(Enum): INIT = 2 STOP = 3 +####################### CLASSES ####################### class SysShdNodeParamsC: ''' Class that contains the can parameters in order to create the thread correctly @@ -66,6 +73,13 @@ def __init__(self,name: str, cycle_period: int, working_flag : Event, working_flag (Event): [description] node_params (SysShdNodeParamsC, optional): .Defaults to SysShdNodeParamsC(). ''' + try: + port: int = sys_conf_read_config_params(filename=DEFAULT_GPIO_CONFIG_PATH, + section= name) + except SysConfSectionNotFoundErrorC as err: + log.warning(f"No port configurable {err}") + else: + self.gpio: SysShdPeripheralC = SysShdPeripheralC(port=port) super().__init__(group = None, target = node_params.target, name = name, args = node_params.args, kwargs = node_params.kwargs, daemon = node_params.daemon) @@ -102,7 +116,11 @@ def run(self) -> None: while self.working_flag.is_set(): try: next_time = time()+self.cycle_period/_TO_MS + if hasattr(self, 'gpio'): + self.gpio.set_gpio_up() self.process_iteration() + if hasattr(self, 'gpio'): + self.gpio.set_gpio_down() # Sleep the remaining time sleep_time = next_time-int(time()) # sleep_time is measure in miliseconds @@ -135,3 +153,24 @@ def __init__(self, message) -> None: message (str): explanation of the error ''' super().__init__(message) + +class SysShdPeripheralC: + ''' + Class that contains the common methods to toggle gpios. + ''' + def __init__(self, port: int) -> None: + self.port: int = port + setup(port, OUT) + def set_gpio_up(self) -> None: + """ + Sets the GPIO pin to a high state. + """ + log.debug(f"Setting GPIO {self.port} up") + output(self.port, HIGH) + + def set_gpio_down(self) -> None: + """ + Sets the GPIO pin to a low state. + """ + log.debug(f"Setting GPIO {self.port} down") + output(self.port, LOW)