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.processes
self.name
andself.config
should be passed through the constructorself.modules
andself.processes
are initialized as empty and can be overriddenSubmodule.__init__(self,name,config)
should be called in eachsubmodules
constructorA
submodule
's constructor should initialize any and all variables and processes, but it should NOT start any processes.The constructor basically "arms" the
submodule
and makes it ready tostart
start
generic 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_modules
Accessor method for
self.modules
Assigns dependencies to the
submodule
has_module
Checks if a
submodule
is inself.modules
and returnsTrue
if presentDoes not
raise RuntimeError
get_object_or_raise_error
Checks if a
submodule
is inself.modules
and returns the module if presentraise RuntimeError(f"[{self.name}]:[{module_name}] not found")
The
submodule
should use this method when it needs to access an instance of one of its dependencies modules.
enter_normal_mode
Not implemented in
Submodule
enter_low_power_mode
Not 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?