From 9bb71b9e90ca9b3cbb17c0e123da1a58f16cc3e8 Mon Sep 17 00:00:00 2001 From: infeeeee Date: Fri, 22 Mar 2024 22:47:56 +0100 Subject: [PATCH 1/3] AppSettings, set update interval --- IoTuring/ClassManager/consts.py | 5 +- IoTuring/Configurator/Configuration.py | 8 ++-- IoTuring/Configurator/Configurator.py | 47 ++++++++++++++++--- IoTuring/Configurator/ConfiguratorLoader.py | 39 +++++++++++++-- IoTuring/Configurator/ConfiguratorObject.py | 15 ++++-- IoTuring/Entity/Entity.py | 17 +++++-- .../Deployments/AppSettings/AppSettings.py | 25 ++++++++++ IoTuring/Settings/Settings.py | 45 ++++++++++++++++++ IoTuring/Settings/SettingsManager.py | 32 +++++++++++++ IoTuring/Warehouse/Warehouse.py | 18 ++++--- IoTuring/__init__.py | 13 ++++- 11 files changed, 231 insertions(+), 33 deletions(-) create mode 100644 IoTuring/Settings/Deployments/AppSettings/AppSettings.py create mode 100644 IoTuring/Settings/Settings.py create mode 100644 IoTuring/Settings/SettingsManager.py diff --git a/IoTuring/ClassManager/consts.py b/IoTuring/ClassManager/consts.py index 9e073220..c2ebdcb4 100644 --- a/IoTuring/ClassManager/consts.py +++ b/IoTuring/ClassManager/consts.py @@ -1,7 +1,10 @@ +# Class keys: KEY_ENTITY = "entity" KEY_WAREHOUSE = "warehouse" +KEY_SETTINGS = "settings" CLASS_PATH = { KEY_ENTITY: "Entity/Deployments", - KEY_WAREHOUSE: "Warehouse/Deployments" + KEY_WAREHOUSE: "Warehouse/Deployments", + KEY_SETTINGS: "Settings/Deployments" } diff --git a/IoTuring/Configurator/Configuration.py b/IoTuring/Configurator/Configuration.py index 69fbb6a9..e6a354e0 100644 --- a/IoTuring/Configurator/Configuration.py +++ b/IoTuring/Configurator/Configuration.py @@ -1,15 +1,15 @@ from __future__ import annotations -from IoTuring.ClassManager.consts import KEY_ENTITY, KEY_WAREHOUSE +from IoTuring.ClassManager.consts import KEY_ENTITY, KEY_WAREHOUSE, KEY_SETTINGS CONFIG_CLASS = { KEY_ENTITY: "active_entities", - KEY_WAREHOUSE: "active_warehouses" + KEY_WAREHOUSE: "active_warehouses", + KEY_SETTINGS: "settings" } BLANK_CONFIGURATION = { - CONFIG_CLASS[KEY_ENTITY]: [{"type": "AppInfo"}], - CONFIG_CLASS[KEY_WAREHOUSE]: [] + CONFIG_CLASS[KEY_ENTITY]: [{"type": "AppInfo"}] } diff --git a/IoTuring/Configurator/Configurator.py b/IoTuring/Configurator/Configurator.py index c1fd1877..41c8bf72 100644 --- a/IoTuring/Configurator/Configurator.py +++ b/IoTuring/Configurator/Configurator.py @@ -5,15 +5,13 @@ from IoTuring.Configurator.MenuPreset import QuestionPreset from IoTuring.Configurator.Configuration import FullConfiguration, SingleConfiguration - -from IoTuring.Logger.LogObject import LogObject -from IoTuring.Exceptions.Exceptions import UserCancelledException - -from IoTuring.ClassManager.ClassManager import ClassManager, KEY_ENTITY, KEY_WAREHOUSE - from IoTuring.Configurator import ConfiguratorIO from IoTuring.Configurator import messages +from IoTuring.ClassManager.ClassManager import ClassManager, KEY_ENTITY, KEY_WAREHOUSE, KEY_SETTINGS + +from IoTuring.Logger.LogObject import LogObject +from IoTuring.Exceptions.Exceptions import UserCancelledException from IoTuring.MyApp.SystemConsts import OperatingSystemDetection as OsD from InquirerPy import inquirer @@ -88,6 +86,7 @@ def Menu(self) -> None: mainMenuChoices = [ {"name": "Manage entities", "value": self.ManageEntities}, {"name": "Manage warehouses", "value": self.ManageWarehouses}, + {"name": "Settings", "value": self.ManageSettings}, {"name": "Start IoTuring", "value": self.WriteConfigurations}, {"name": "Help", "value": self.DisplayHelp}, {"name": "Quit", "value": self.Quit}, @@ -167,6 +166,39 @@ def ManageWarehouses(self) -> None: else: self.AddNewWarehouse(choice) + def ManageSettings(self) -> None: + """ UI for App and other Settings """ + + scm = ClassManager(KEY_SETTINGS) + + choices = [] + + availableSettings = scm.ListAvailableClasses() + for sClass in availableSettings: + + choices.append( + {"name": sClass.NAME + " Settings", + "value": sClass}) + + choice = self.DisplayMenu( + choices=choices, + message=f"Select settings to edit" + ) + + if choice == CHOICE_GO_BACK: + self.Menu() + + else: + if not self.IsClassActive(choice): + self.config.configs.append(choice.GetDefaultConfigurations()) + + settings_config = self.config.GetConfigsOfType(choice.NAME)[0] + + self.EditActiveConfiguration( + choice, settings_config) + + self.ManageSettings() + def IsClassActive(self, typeClass) -> bool: """Check if class has an active configuration """ return bool(self.config.GetConfigsOfType(typeClass.NAME)) @@ -206,7 +238,8 @@ def AddNewWarehouse(self, whClass) -> None: def ManageActiveConfiguration(self, typeClass, single_config: SingleConfiguration) -> None: choices = [ - {"name": f"Edit the {typeClass.GetClassKey()} settings", "value": "Edit"}, + {"name": f"Edit the {typeClass.GetClassKey()} settings", + "value": "Edit"}, {"name": f"Remove the {typeClass.GetClassKey()}", "value": "Remove"} ] diff --git a/IoTuring/Configurator/ConfiguratorLoader.py b/IoTuring/Configurator/ConfiguratorLoader.py index 54f07d02..dbb9094b 100644 --- a/IoTuring/Configurator/ConfiguratorLoader.py +++ b/IoTuring/Configurator/ConfiguratorLoader.py @@ -1,15 +1,18 @@ from __future__ import annotations +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from IoTuring.Entity.Entity import Entity + from IoTuring.Warehouse.Warehouse import Warehouse + from IoTuring.Settings.Settings import Settings + import sys -from IoTuring.Entity.Entity import Entity from IoTuring.Logger.LogObject import LogObject from IoTuring.Configurator.Configurator import Configurator -from IoTuring.ClassManager.ClassManager import ClassManager, KEY_ENTITY, KEY_WAREHOUSE -from IoTuring.Warehouse.Warehouse import Warehouse +from IoTuring.ClassManager.ClassManager import ClassManager, KEY_ENTITY, KEY_WAREHOUSE, KEY_SETTINGS class ConfiguratorLoader(LogObject): - configurator = None def __init__(self, configurator: Configurator) -> None: self.configurations = configurator.config @@ -64,3 +67,31 @@ def LoadEntities(self) -> list[Entity]: # - for each one: # - pass the configuration to the warehouse function that uses the configuration to init the Warehouse # - append the Warehouse to the list + + def LoadSettings(self) -> list[Settings]: + settings = [] + scm = ClassManager(KEY_SETTINGS) + settingsClasses = scm.ListAvailableClasses() + + for sClass in settingsClasses: + + # Check if config was saved: + savedConfigs = self.configurations\ + .GetConfigsOfType(sClass.NAME) + + if savedConfigs: + sc = sClass(savedConfigs[0]) + + # Fallback to default: + else: + sc = sClass(sClass.GetDefaultConfigurations()) + + settings.append(sc) + return settings + + # How Settings configurations work: + # - Settings' configs are added to SettingsManager singleton on main __init__ + # - For advanced usage custom loading could be set up in the class' __init()__ + # - Setting classes has classmethods to get their configs from SettingsManager Singleton, + # SettingsManager shouldn't be called directly, e.g: + # AppSettings.GetFromSettingsConfigurations(CONFIG_KEY_UPDATE_INTERVAL) diff --git a/IoTuring/Configurator/ConfiguratorObject.py b/IoTuring/Configurator/ConfiguratorObject.py index a308cfa2..cccf8154 100644 --- a/IoTuring/Configurator/ConfiguratorObject.py +++ b/IoTuring/Configurator/ConfiguratorObject.py @@ -1,5 +1,5 @@ from IoTuring.Configurator.MenuPreset import BooleanAnswers, MenuPreset -from IoTuring.Configurator.Configuration import SingleConfiguration, CONFIG_CLASS +from IoTuring.Configurator.Configuration import SingleConfiguration, CONFIG_CLASS, CONFIG_KEY_TYPE class ConfiguratorObject: @@ -11,8 +11,7 @@ def __init__(self, single_configuration: SingleConfiguration) -> None: self.configurations = single_configuration # Add missing default values: - preset = self.ConfigurationPreset() - defaults = preset.GetDefaults() + defaults = self.ConfigurationPreset().GetDefaults() if defaults: for default_key, default_value in defaults.items(): @@ -59,3 +58,13 @@ def GetClassKey(cls) -> str: if class_key not in CONFIG_CLASS: raise Exception(f"Invalid class {class_key}") return class_key + + @classmethod + def GetDefaultConfigurations(cls) -> SingleConfiguration: + """Get the default configuration of this class""" + + # Get default configs as dict: + config_dict = cls.ConfigurationPreset().GetDefaults() + config_dict[CONFIG_KEY_TYPE] = cls.NAME + + return SingleConfiguration(cls.GetClassKey(), config_dict=config_dict) diff --git a/IoTuring/Entity/Entity.py b/IoTuring/Entity/Entity.py index 1ee44d46..3c420517 100644 --- a/IoTuring/Entity/Entity.py +++ b/IoTuring/Entity/Entity.py @@ -1,15 +1,20 @@ from __future__ import annotations +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from IoTuring.Configurator.Configuration import SingleConfiguration + from IoTuring.Entity.EntityData import EntityData, EntitySensor, EntityCommand, ExtraAttribute + + import time import subprocess from IoTuring.Configurator.ConfiguratorObject import ConfiguratorObject -from IoTuring.Configurator.Configuration import SingleConfiguration -from IoTuring.Exceptions.Exceptions import UnknownEntityKeyException from IoTuring.Logger.LogObject import LogObject -from IoTuring.Entity.EntityData import EntityData, EntitySensor, EntityCommand, ExtraAttribute +from IoTuring.Exceptions.Exceptions import UnknownEntityKeyException + from IoTuring.MyApp.SystemConsts import OperatingSystemDetection as OsD -DEFAULT_UPDATE_TIMEOUT = 10 +from IoTuring.Settings.Deployments.AppSettings.AppSettings import AppSettings, CONFIG_KEY_UPDATE_INTERVAL class Entity(ConfiguratorObject, LogObject): @@ -25,7 +30,9 @@ def __init__(self, single_configuration: SingleConfiguration) -> None: # When I update the values this number changes (randomly) so each warehouse knows I have updated self.valuesID = 0 - self.updateTimeout = DEFAULT_UPDATE_TIMEOUT + + self.updateTimeout = int( + AppSettings.GetFromSettingsConfigurations(CONFIG_KEY_UPDATE_INTERVAL)) def Initialize(self): """ Must be implemented in sub-classes, may be useful here to use the configuration """ diff --git a/IoTuring/Settings/Deployments/AppSettings/AppSettings.py b/IoTuring/Settings/Deployments/AppSettings/AppSettings.py new file mode 100644 index 00000000..98fb244c --- /dev/null +++ b/IoTuring/Settings/Deployments/AppSettings/AppSettings.py @@ -0,0 +1,25 @@ +from IoTuring.Configurator.MenuPreset import MenuPreset +from IoTuring.Settings.Settings import Settings + + +CONFIG_KEY_UPDATE_INTERVAL = "update_interval" +# CONFIG_KEY_SLOW_INTERVAL = "slow_interval" + + +class AppSettings(Settings): + """Singleton for storing AppSettings, not related to a specifuc Entity or Warehouse """ + NAME = "App" + + @classmethod + def ConfigurationPreset(cls): + preset = MenuPreset() + + preset.AddEntry(name="Main update interval in seconds", + key=CONFIG_KEY_UPDATE_INTERVAL, mandatory=True, + question_type="integer", default=10) + + # preset.AddEntry(name="Secondary update interval in minutes", + # key=CONFIG_KEY_SLOW_INTERVAL, mandatory=True, + # question_type="integer", default=10) + + return preset diff --git a/IoTuring/Settings/Settings.py b/IoTuring/Settings/Settings.py new file mode 100644 index 00000000..ffe85196 --- /dev/null +++ b/IoTuring/Settings/Settings.py @@ -0,0 +1,45 @@ +from IoTuring.Configurator.ConfiguratorObject import ConfiguratorObject +from IoTuring.Settings.SettingsManager import SettingsManager +from IoTuring.Configurator.MenuPreset import BooleanAnswers + + +class Settings(ConfiguratorObject): + """Base class for settings""" + NAME = "Settings" + + @classmethod + def GetFromSettingsConfigurations(cls, key: str): + """Get value from settings' saved configurations from SettingsManager + + Args: + key (str): The CONFIG_KEY of the configuration + + Raises: + Exception: If the key not found + + Returns: + Any: The config value + """ + + sM = SettingsManager() + saved_config = sM.GetConfigOfType(cls) + + if saved_config.HasConfigKey(key): + return saved_config.GetConfigValue(key) + else: + raise Exception( + f"Can't find key {key} in SettingsManager configurations") + + @classmethod + def GetTrueOrFalseFromSettingsConfigurations(cls, key: str) -> bool: + """Get boolean value from settings' saved configurations from SettingsManager + + Args: + key (str): The CONFIG_KEY of the configuration + + Returns: + bool: The config value + """ + + value = cls.GetFromSettingsConfigurations(key).lower() + return bool(value in BooleanAnswers.TRUE_ANSWERS) diff --git a/IoTuring/Settings/SettingsManager.py b/IoTuring/Settings/SettingsManager.py new file mode 100644 index 00000000..688be350 --- /dev/null +++ b/IoTuring/Settings/SettingsManager.py @@ -0,0 +1,32 @@ +from __future__ import annotations +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from IoTuring.Settings.Settings import Settings + from IoTuring.Configurator.Configuration import SingleConfiguration + +from IoTuring.Logger.Logger import Singleton +from IoTuring.Logger.LogObject import LogObject + + +class SettingsManager(LogObject, metaclass=Singleton): + """Singleton for storing configurations of Settings""" + + def __init__(self) -> None: + self.setting_configs = {} + + def AddSettings(self, setting_entities: list[Settings]) -> None: + """Add settings configuration + + Args: + setting_entities (list[Settings]): The loaded settings classes + """ + for setting_entity in setting_entities: + self.setting_configs[setting_entity.NAME] = setting_entity.configurations + + def GetConfigOfType(self, setting_class) -> SingleConfiguration: + """Get the configuration of a saved class. Raises exception if not found""" + + if setting_class.NAME in self.setting_configs: + return self.setting_configs[setting_class.NAME] + else: + raise Exception(f"No settings config for {setting_class.NAME}") diff --git a/IoTuring/Warehouse/Warehouse.py b/IoTuring/Warehouse/Warehouse.py index 1acd5bb1..8b3ccb15 100644 --- a/IoTuring/Warehouse/Warehouse.py +++ b/IoTuring/Warehouse/Warehouse.py @@ -1,14 +1,17 @@ from __future__ import annotations -from IoTuring.Entity.Entity import Entity -from IoTuring.Logger.LogObject import LogObject -from IoTuring.Configurator.ConfiguratorObject import ConfiguratorObject -from IoTuring.Configurator.Configuration import SingleConfiguration -from IoTuring.Entity.EntityManager import EntityManager +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from IoTuring.Entity.Entity import Entity + from IoTuring.Configurator.Configuration import SingleConfiguration from threading import Thread import time -DEFAULT_LOOP_TIMEOUT = 10 +from IoTuring.Logger.LogObject import LogObject +from IoTuring.Configurator.ConfiguratorObject import ConfiguratorObject +from IoTuring.Entity.EntityManager import EntityManager + +from IoTuring.Settings.Deployments.AppSettings.AppSettings import AppSettings, CONFIG_KEY_UPDATE_INTERVAL class Warehouse(ConfiguratorObject, LogObject): @@ -16,7 +19,8 @@ class Warehouse(ConfiguratorObject, LogObject): def __init__(self, single_configuration: SingleConfiguration) -> None: super().__init__(single_configuration) - self.loopTimeout = DEFAULT_LOOP_TIMEOUT + self.loopTimeout = int( + AppSettings.GetFromSettingsConfigurations(CONFIG_KEY_UPDATE_INTERVAL)) def Start(self) -> None: """ Initial configuration and start the thread that will loop the Warehouse.Loop() function""" diff --git a/IoTuring/__init__.py b/IoTuring/__init__.py index 6dfa3682..d90d7524 100644 --- a/IoTuring/__init__.py +++ b/IoTuring/__init__.py @@ -9,6 +9,7 @@ from IoTuring.Configurator.Configurator import Configurator from IoTuring.Configurator.ConfiguratorLoader import ConfiguratorLoader from IoTuring.Entity.EntityManager import EntityManager +from IoTuring.Settings.SettingsManager import SettingsManager from IoTuring.Logger.Logger import Logger from IoTuring.Logger.Colors import Colors @@ -72,9 +73,17 @@ def loop(): # This have to start after configurator.Menu(), otherwise won't work starting from the menu signal.signal(signal.SIGINT, Exit_SIGINT_handler) + # Load Settings: + settings = ConfiguratorLoader(configurator).LoadSettings() + sM = SettingsManager() + sM.AddSettings(settings) + logger.Log(Logger.LOG_INFO, "App", App()) # Print App info - logger.Log(Logger.LOG_INFO, "Configurator", - "Run the script with -c to enter configuration mode") + + # Add help if not started from Configurator + if not args.configurator: + logger.Log(Logger.LOG_INFO, "Configurator", + "Run the script with -c to enter configuration mode") eM = EntityManager() From 8afc49e072fee1b0ad3dfba8669e62c27b8ef72f Mon Sep 17 00:00:00 2001 From: infeeeee Date: Sat, 23 Mar 2024 05:20:43 +0100 Subject: [PATCH 2/3] Add retry interval setting --- .../Deployments/AppSettings/AppSettings.py | 7 +++++++ .../HomeAssistantWarehouse.py | 15 ++++++++++----- .../Deployments/MQTTWarehouse/MQTTWarehouse.py | 3 +-- IoTuring/Warehouse/Warehouse.py | 4 +++- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/IoTuring/Settings/Deployments/AppSettings/AppSettings.py b/IoTuring/Settings/Deployments/AppSettings/AppSettings.py index 98fb244c..b0eabe5d 100644 --- a/IoTuring/Settings/Deployments/AppSettings/AppSettings.py +++ b/IoTuring/Settings/Deployments/AppSettings/AppSettings.py @@ -3,6 +3,7 @@ CONFIG_KEY_UPDATE_INTERVAL = "update_interval" +CONFIG_KEY_RETRY_INTERVAL = "retry_interval" # CONFIG_KEY_SLOW_INTERVAL = "slow_interval" @@ -18,6 +19,12 @@ def ConfigurationPreset(cls): key=CONFIG_KEY_UPDATE_INTERVAL, mandatory=True, question_type="integer", default=10) + preset.AddEntry(name="Connection retry interval in seconds", + instruction="If broker is not available retry after this amount of time passed", + key=CONFIG_KEY_RETRY_INTERVAL, mandatory=True, + question_type="integer", default=1) + + # preset.AddEntry(name="Secondary update interval in minutes", # key=CONFIG_KEY_SLOW_INTERVAL, mandatory=True, # question_type="integer", default=10) diff --git a/IoTuring/Warehouse/Deployments/HomeAssistantWarehouse/HomeAssistantWarehouse.py b/IoTuring/Warehouse/Deployments/HomeAssistantWarehouse/HomeAssistantWarehouse.py index 5e34bbaa..dc011e6e 100644 --- a/IoTuring/Warehouse/Deployments/HomeAssistantWarehouse/HomeAssistantWarehouse.py +++ b/IoTuring/Warehouse/Deployments/HomeAssistantWarehouse/HomeAssistantWarehouse.py @@ -15,11 +15,12 @@ from IoTuring.Logger import consts from IoTuring.Entity.ValueFormat import ValueFormatter +from IoTuring.Settings.Deployments.AppSettings.AppSettings import AppSettings, CONFIG_KEY_UPDATE_INTERVAL + INCLUDE_UNITS_IN_SENSORS = False INCLUDE_UNITS_IN_EXTRA_ATTRIBUTES = True -SLEEP_TIME_NOT_CONNECTED_WHILE = 1 # That stands for: App name, Client name, EntityData Id TOPIC_DATA_FORMAT = "{}/{}HomeAssistant/{}" @@ -240,8 +241,12 @@ def __init__(self, entityData: EntitySensor, wh: "HomeAssistantWarehouse") -> N if self.supports_extra_attributes: self.AddTopic("json_attributes_topic") - # Extra payload for sensors: - self.discovery_payload['expire_after'] = 600 # TODO Improve + # Make sure expire_after is greater than the loop timeout: + loop_timeout = int(AppSettings.GetFromSettingsConfigurations( + CONFIG_KEY_UPDATE_INTERVAL)) + sensor_expire_seconds = 600 if loop_timeout < 600 else int( + loop_timeout * 1.5) + self.discovery_payload['expire_after'] = sensor_expire_seconds def SendValues(self): """ Send values of the sensor to the state topic """ @@ -404,7 +409,7 @@ def RegisterEntityCommands(self): def Loop(self): while (not self.client.IsConnected()): - time.sleep(SLEEP_TIME_NOT_CONNECTED_WHILE) + time.sleep(self.retry_interval) # Mechanism to call the function to send discovery data every CONFIGURATION_SEND_LOOP_SKIP_NUMBER loop if self.loopCounter == 0: @@ -434,7 +439,7 @@ def MakeValuesTopic(self, topic_suffix: str) -> str: def NormalizeTopic(topicstring: str) -> str: """ Home assistant requires stricter topic names """ # Remove non ascii characters: - topicstring=topicstring.encode("ascii", "ignore").decode() + topicstring = topicstring.encode("ascii", "ignore").decode() return MQTTClient.NormalizeTopic(topicstring).replace(" ", "_") @classmethod diff --git a/IoTuring/Warehouse/Deployments/MQTTWarehouse/MQTTWarehouse.py b/IoTuring/Warehouse/Deployments/MQTTWarehouse/MQTTWarehouse.py index 09eb2727..8530124f 100644 --- a/IoTuring/Warehouse/Deployments/MQTTWarehouse/MQTTWarehouse.py +++ b/IoTuring/Warehouse/Deployments/MQTTWarehouse/MQTTWarehouse.py @@ -9,7 +9,6 @@ import time -SLEEP_TIME_NOT_CONNECTED_WHILE = 1 TOPIC_FORMAT = "{}/{}/{}" # That stands for: App name, Client name, EntityData Id @@ -53,7 +52,7 @@ def RegisterEntityCommands(self): def Loop(self): while(not self.client.IsConnected()): - time.sleep(SLEEP_TIME_NOT_CONNECTED_WHILE) + time.sleep(self.retry_interval) # Here in Loop I send sensor's data (command callbacks are not managed here) for entity in self.GetEntities(): diff --git a/IoTuring/Warehouse/Warehouse.py b/IoTuring/Warehouse/Warehouse.py index 8b3ccb15..15e586dd 100644 --- a/IoTuring/Warehouse/Warehouse.py +++ b/IoTuring/Warehouse/Warehouse.py @@ -11,7 +11,7 @@ from IoTuring.Configurator.ConfiguratorObject import ConfiguratorObject from IoTuring.Entity.EntityManager import EntityManager -from IoTuring.Settings.Deployments.AppSettings.AppSettings import AppSettings, CONFIG_KEY_UPDATE_INTERVAL +from IoTuring.Settings.Deployments.AppSettings.AppSettings import AppSettings, CONFIG_KEY_UPDATE_INTERVAL, CONFIG_KEY_RETRY_INTERVAL class Warehouse(ConfiguratorObject, LogObject): @@ -21,6 +21,8 @@ def __init__(self, single_configuration: SingleConfiguration) -> None: self.loopTimeout = int( AppSettings.GetFromSettingsConfigurations(CONFIG_KEY_UPDATE_INTERVAL)) + self.retry_interval = int(AppSettings + .GetFromSettingsConfigurations(CONFIG_KEY_RETRY_INTERVAL)) def Start(self) -> None: """ Initial configuration and start the thread that will loop the Warehouse.Loop() function""" From 37aa8af2c078bdbcf66a0313e04e827cfce37675 Mon Sep 17 00:00:00 2001 From: Riccardo Briccola Date: Sun, 7 Apr 2024 13:05:49 +0200 Subject: [PATCH 3/3] Docstring --- IoTuring/Settings/Deployments/AppSettings/AppSettings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IoTuring/Settings/Deployments/AppSettings/AppSettings.py b/IoTuring/Settings/Deployments/AppSettings/AppSettings.py index b0eabe5d..a52b20c8 100644 --- a/IoTuring/Settings/Deployments/AppSettings/AppSettings.py +++ b/IoTuring/Settings/Deployments/AppSettings/AppSettings.py @@ -8,7 +8,7 @@ class AppSettings(Settings): - """Singleton for storing AppSettings, not related to a specifuc Entity or Warehouse """ + """Class that stores AppSettings, not related to a specifuc Entity or Warehouse """ NAME = "App" @classmethod