Submodules
This article describes how the submodules should be coded
Framework
Each submodule should extend the Submodule class
from submodules.submodule import Submodule
class Telemetry(Submodule):The Submodule class defines the following methods:
__init__defines
self.name,self.modules,self.config,self.logger,self.processesself.nameandself.configshould be passed through the constructorself.modulesandself.processesare initialized as empty and can be overriddenSubmodule.__init__(self,name,config)should be called in eachsubmodulesconstructorA
submodule's constructor should initialize any and all variables and processes, but it should NOT start any processes.The constructor basically "arms" the
submoduleand makes it ready tostart
startgeneric start method
The start method should initialize any runtime objects and start all processes
Basically tells the submodule to begin working
this method can, and is meant to be, overridden
set_modulesAccessor method for
self.modulesAssigns dependencies to the
submodule
has_moduleChecks if a
submoduleis inself.modulesand returnsTrueif presentDoes not
raise RuntimeError
get_object_or_raise_errorChecks if a
submoduleis inself.modulesand returns the module if presentraise RuntimeError(f"[{self.name}]:[{module_name}] not found")The
submoduleshould use this method when it needs to access an instance of one of its dependencies modules.
enter_normal_modeNot implemented in
Submodule
enter_low_power_modeNot implemented in
Submodule
The Submodule class is below. View this file on GitHub.
import logging
class Submodule:
"""
Abstract class for all submodule, regardless of job
"""
def __init__(self, name: str, config: dict):
"""
Instantiates a new Submodule instance
:param name: name of submodule
:param config: dictionary of configuration data
"""
self.name = name
self.config = config
self.logger = logging.getLogger(self.name)
self.modules = dict()
self.processes = dict()
def start(self) -> None:
"""
Iterates through self.processes and starts all processes.
This method is meant to be overridden
"""
for process in self.processes:
self.processes[process].start()
def enter_low_power_mode(self) -> None:
"""
Immediately puts the submodule into a low power state. Different for each submodule.
It is safe to assume that if this method is called, the previous state was NORMAL_MODE
"""
raise NotImplementedError
def enter_normal_mode(self) -> None:
"""
Immediately puts the submodule into a normal power state. Different for each submodule.
It is safe to assume that if this method is called, the previous state was LOW_POWER_MODE
:return:
"""
raise NotImplementedError
def set_modules(self, dependencies: dict) -> None:
"""
Accessor method for self.modules. self.modules shall be populated will any dependencies a submodule needs
:param dependencies: Dictionary of references to other submodules that are required by the submodule
:return: None
"""
self.modules = dependencies
def has_module(self, module_name: str) -> bool:
"""
Returns True if module_name is in self.modules and its value is not None
:param module_name: name of dependency module
:return: bool
"""
return module_name in self.modules and self.modules[module_name] is not None
def get_module_or_raise_error(self, module_name: str):
"""
Tries to access a reference to a dependency module and throws a RuntimeError otherwise
:param module_name: name of dependency module
:return: Reference to dependency module or None with RuntimeError raised
"""
if module_name in self.modules and self.modules[module_name] is not None:
return self.modules[module_name]
else:
raise RuntimeError(f"[{self.name}]:[{module_name}] not found")Last updated
Was this helpful?