From 7fa738d240d34d52b5b5b4a872dfd140c3b5c825 Mon Sep 17 00:00:00 2001 From: avollkopf <43980694+avollkopf@users.noreply.github.com> Date: Sat, 1 Apr 2023 14:13:04 +0200 Subject: [PATCH 01/20] test --- cbpi/__init__.py | 2 +- cbpi/api/dataclasses.py | 3 ++- cbpi/controller/config_controller.py | 9 +++------ cbpi/controller/plugin_controller.py | 24 ++++++++++++++++++++++++ 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/cbpi/__init__.py b/cbpi/__init__.py index be197c8..7b27d51 100644 --- a/cbpi/__init__.py +++ b/cbpi/__init__.py @@ -1,3 +1,3 @@ -__version__ = "4.1.7" +__version__ = "4.1.8.a1" __codename__ = "Groundhog Day" diff --git a/cbpi/api/dataclasses.py b/cbpi/api/dataclasses.py index 5007a64..c840f5c 100644 --- a/cbpi/api/dataclasses.py +++ b/cbpi/api/dataclasses.py @@ -199,11 +199,12 @@ class Config: description: str = None type: ConfigType = ConfigType.STRING options: Any = None + source: str = None def __str__(self): return "....name={} value={}".format(self.name, self.value) def to_dict(self): - return dict(name=self.name, value=self.value, type=self.type.value, description=self.description, options=self.options) + return dict(name=self.name, value=self.value, type=self.type.value, description=self.description, options=self.options, source=self.source) @dataclass class NotificationAction: diff --git a/cbpi/controller/config_controller.py b/cbpi/controller/config_controller.py index 6d62d79..2159706 100644 --- a/cbpi/controller/config_controller.py +++ b/cbpi/controller/config_controller.py @@ -19,21 +19,18 @@ class ConfigController: self.path_static = cbpi.config_folder.get_file_path("config.yaml") self.logger.info("Config folder path : " + os.path.join(Path(self.cbpi.config_folder.configFolderPath).absolute())) - def get_state(self): - + def get_state(self): result = {} for key, value in self.cache.items(): result[key] = value.to_dict() - - return result - + return result async def init(self): self.static = load_config(self.path_static) with open(self.path) as json_file: data = json.load(json_file) for key, value in data.items(): - self.cache[key] = Config(name=value.get("name"), value=value.get("value"), description=value.get("description"), type=ConfigType(value.get("type", "string")), options=value.get("options", None) ) + self.cache[key] = Config(name=value.get("name"), value=value.get("value"), description=value.get("description"), type=ConfigType(value.get("type", "string")), options=value.get("options", None), source=value.get("source", "craftbeerpi") ) def get(self, name, default=None): self.logger.debug("GET CONFIG VALUE %s (default %s)" % (name, default)) diff --git a/cbpi/controller/plugin_controller.py b/cbpi/controller/plugin_controller.py index e958371..23da582 100644 --- a/cbpi/controller/plugin_controller.py +++ b/cbpi/controller/plugin_controller.py @@ -205,6 +205,7 @@ class PluginController(): from importlib.metadata import (distribution, metadata, version) meta = metadata(key) + logging.warning(key) result.append({row: meta[row] for row in list(metadata(key))}) except Exception as e: @@ -215,3 +216,26 @@ class PluginController(): logger.error(e) return [] return result + + async def load_plugin_names(self, filter="cbpi"): + result = [] + result.append(dict(Name="craftbeerpi")) + try: + discovered_plugins = { + name: importlib.import_module(name) + for finder, name, ispkg + in pkgutil.iter_modules() + if name.startswith('cbpi') and len(name) > 4 + } + for key, module in discovered_plugins.items(): + try: + meta = metadata(key) + result.append(dict(Name=meta["Name"])) + + except Exception as e: + logger.error("FAILED to load plugin {} ".format(key)) + logger.error(e) + except Exception as e: + logger.error(e) + return result + return result From a70c63edf4d15f94719fde5943985ffc4447db50 Mon Sep 17 00:00:00 2001 From: avollkopf <43980694+avollkopf@users.noreply.github.com> Date: Sat, 1 Apr 2023 14:18:44 +0200 Subject: [PATCH 02/20] add http api to retreive only plugin names --- cbpi/controller/plugin_controller.py | 3 ++- cbpi/http_endpoints/http_plugin.py | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/cbpi/controller/plugin_controller.py b/cbpi/controller/plugin_controller.py index 23da582..6ac1f00 100644 --- a/cbpi/controller/plugin_controller.py +++ b/cbpi/controller/plugin_controller.py @@ -230,7 +230,8 @@ class PluginController(): for key, module in discovered_plugins.items(): try: meta = metadata(key) - result.append(dict(Name=meta["Name"])) + if meta["Name"] != "cbpi4gui": + result.append(dict(Name=meta["Name"])) except Exception as e: logger.error("FAILED to load plugin {} ".format(key)) diff --git a/cbpi/http_endpoints/http_plugin.py b/cbpi/http_endpoints/http_plugin.py index fc3ae2c..9a36beb 100644 --- a/cbpi/http_endpoints/http_plugin.py +++ b/cbpi/http_endpoints/http_plugin.py @@ -86,3 +86,21 @@ class PluginHttpEndpoints: """ plugin_list = await self.cbpi.plugin.load_plugin_list() return web.json_response(plugin_list, dumps=json_dumps) + + @request_mapping(path="/names", method="GET", auth_required=False) + async def list(self, request): + """ + --- + description: Get a list of avialable plugin names + tags: + - Plugin + produces: + - application/json + responses: + "200": + description: successful operation. Return "pong" text + "405": + description: invalid HTTP Method + """ + plugin_names = await self.cbpi.plugin.load_plugin_names() + return web.json_response(plugin_names, dumps=json_dumps) From 5f3e3ea60d7cefadc32eea3079ad04e44e9a504e Mon Sep 17 00:00:00 2001 From: avollkopf <43980694+avollkopf@users.noreply.github.com> Date: Sun, 2 Apr 2023 13:05:48 +0200 Subject: [PATCH 03/20] Add 'All' and 'steps' as categories --- cbpi/__init__.py | 2 +- cbpi/controller/plugin_controller.py | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/cbpi/__init__.py b/cbpi/__init__.py index 7b27d51..5b89767 100644 --- a/cbpi/__init__.py +++ b/cbpi/__init__.py @@ -1,3 +1,3 @@ -__version__ = "4.1.8.a1" +__version__ = "4.1.8.a2" __codename__ = "Groundhog Day" diff --git a/cbpi/controller/plugin_controller.py b/cbpi/controller/plugin_controller.py index 6ac1f00..5bfb8fd 100644 --- a/cbpi/controller/plugin_controller.py +++ b/cbpi/controller/plugin_controller.py @@ -219,7 +219,9 @@ class PluginController(): async def load_plugin_names(self, filter="cbpi"): result = [] - result.append(dict(Name="craftbeerpi")) + result.append(dict(label="All", value="All")) + result.append(dict(label="craftbeerpi", value="craftbeerpi")) + result.append(dict(label="steps", value="steps")) try: discovered_plugins = { name: importlib.import_module(name) @@ -231,7 +233,7 @@ class PluginController(): try: meta = metadata(key) if meta["Name"] != "cbpi4gui": - result.append(dict(Name=meta["Name"])) + result.append(dict(label=meta["Name"], value=meta["Name"])) except Exception as e: logger.error("FAILED to load plugin {} ".format(key)) From be77d90c7eb2ef93f34e313677eca8b3c458155a Mon Sep 17 00:00:00 2001 From: avollkopf <43980694+avollkopf@users.noreply.github.com> Date: Sun, 2 Apr 2023 16:14:33 +0200 Subject: [PATCH 04/20] automatic config update test --- cbpi/__init__.py | 2 +- cbpi/api/base.py | 4 +- cbpi/api/dataclasses.py | 2 +- cbpi/config/config.json | 121 +------------- cbpi/controller/config_controller.py | 4 +- cbpi/extension/ConfigUpdate/__init__.py | 199 +++++++++++++++++------- 6 files changed, 151 insertions(+), 181 deletions(-) diff --git a/cbpi/__init__.py b/cbpi/__init__.py index 5b89767..5f83b3a 100644 --- a/cbpi/__init__.py +++ b/cbpi/__init__.py @@ -1,3 +1,3 @@ -__version__ = "4.1.8.a2" +__version__ = "4.1.8.a3" __codename__ = "Groundhog Day" diff --git a/cbpi/api/base.py b/cbpi/api/base.py index 837b4a2..9fd4692 100644 --- a/cbpi/api/base.py +++ b/cbpi/api/base.py @@ -17,8 +17,8 @@ class CBPiBase(metaclass=ABCMeta): async def set_config_value(self,name,value): return await self.cbpi.config.set(name,value) - async def add_config_value(self, name, value, type: ConfigType, description, options=None): - await self.cbpi.config.add(name, value, type, description, options=None) + async def add_config_value(self, name, value, type: ConfigType, description, source, options=None): + await self.cbpi.config.add(name, value, type, description, source,options=None) def get_kettle(self,id): return self.cbpi.kettle.find_by_id(id) diff --git a/cbpi/api/dataclasses.py b/cbpi/api/dataclasses.py index c840f5c..6885912 100644 --- a/cbpi/api/dataclasses.py +++ b/cbpi/api/dataclasses.py @@ -198,8 +198,8 @@ class Config: value: Any = None description: str = None type: ConfigType = ConfigType.STRING - options: Any = None source: str = None + options: Any = None def __str__(self): return "....name={} value={}".format(self.name, self.value) diff --git a/cbpi/config/config.json b/cbpi/config/config.json index 56f98c5..6359b99 100644 --- a/cbpi/config/config.json +++ b/cbpi/config/config.json @@ -4,6 +4,7 @@ "name": "AUTHOR", "options": null, "type": "string", + "source": "craftbeerpi", "value": "John Doe" }, "BREWERY_NAME": { @@ -11,52 +12,9 @@ "name": "BREWERY_NAME", "options": null, "type": "string", + "source": "craftbeerpi", "value": "CraftBeerPi Brewery" }, - "MASH_TUN": { - "description": "Default Mash Tun", - "name": "MASH_TUN", - "options": null, - "type": "kettle", - "value": "" - }, - "AddMashInStep": { - "description": "Add MashIn Step automatically if not defined in recipe", - "name": "AddMashInStep", - "options": [ - { - "label": "Yes", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ], - "type": "select", - "value": "Yes" - }, - "RECIPE_CREATION_PATH": { - "description": "API path to creation plugin. Default: empty", - "name": "RECIPE_CREATION_PATH", - "options": null, - "type": "string", - "value": "" - }, - "brewfather_api_key": { - "description": "Brewfather API Kay", - "name": "brewfather_api_key", - "options": null, - "type": "string", - "value": "" - }, - "brewfather_user_id": { - "description": "Brewfather User ID", - "name": "brewfather_user_id", - "options": null, - "type": "string", - "value": "" - }, "TEMP_UNIT": { "description": "Temperature Unit", "name": "TEMP_UNIT", @@ -71,78 +29,9 @@ } ], "type": "select", + "source": "craftbeerpi", "value": "C" - }, - "AutoMode": { - "description": "Use AutoMode in steps", - "name": "AutoMode", - "options": [ - { - "label": "Yes", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ], - "type": "select", - "value": "Yes" - }, - "steps_boil": { - "description": "Boil step type", - "name": "steps_boil", - "options": null, - "type": "step", - "value": "BoilStep" - }, - "steps_boil_temp": { - "description": "Default Boil Temperature for Recipe Creation", - "name": "steps_boil_temp", - "options": null, - "type": "number", - "value": "99" - }, - "steps_cooldown": { - "description": "Cooldown step type", - "name": "steps_cooldown", - "options": null, - "type": "step", - "value": "CooldownStep" - }, - "steps_cooldown_sensor": { - "description": "Alternative Sensor to monitor temperature durring cooldown (if not selected, Kettle Sensor will be used)", - "name": "steps_cooldown_sensor", - "options": null, - "type": "sensor", - "value": "" - }, - "steps_cooldown_temp": { - "description": "Cooldown temp will send notification when this temeprature is reached", - "name": "steps_cooldown_temp", - "options": null, - "type": "number", - "value": "20" - }, - "steps_mash": { - "description": "Mash step type", - "name": "steps_mash", - "options": null, - "type": "step", - "value": "MashStep" - }, - "steps_mashin": { - "description": "MashIn step type", - "name": "steps_mashin", - "options": null, - "type": "step", - "value": "MashInStep" - }, - "steps_mashout": { - "description": "MashOut step type", - "name": "steps_mashout", - "options": null, - "type": "step", - "value": "NotificationStep" } + + } diff --git a/cbpi/controller/config_controller.py b/cbpi/controller/config_controller.py index 2159706..e0c5587 100644 --- a/cbpi/controller/config_controller.py +++ b/cbpi/controller/config_controller.py @@ -50,8 +50,8 @@ class ConfigController: with open(self.path, "w") as file: json.dump(data, file, indent=4, sort_keys=True) - async def add(self, name, value, type: ConfigType, description, options=None): - self.cache[name] = Config(name,value,description,type,options) + async def add(self, name, value, type: ConfigType, description, source="", options=None): + self.cache[name] = Config(name,value,description,type,source,options) data = {} for key, value in self.cache.items(): data[key] = value.to_dict() diff --git a/cbpi/extension/ConfigUpdate/__init__.py b/cbpi/extension/ConfigUpdate/__init__.py index 0aab218..a8c52ab 100644 --- a/cbpi/extension/ConfigUpdate/__init__.py +++ b/cbpi/extension/ConfigUpdate/__init__.py @@ -40,7 +40,6 @@ class ConfigUpdate(CBPiExtension): logfiles = self.cbpi.config.get("CSVLOGFILES", None) influxdb = self.cbpi.config.get("INFLUXDB", None) influxdbaddr = self.cbpi.config.get("INFLUXDBADDR", None) - #influxdbport = self.cbpi.config.get("INFLUXDBPORT", None) influxdbname = self.cbpi.config.get("INFLUXDBNAME", None) influxdbuser = self.cbpi.config.get("INFLUXDBUSER", None) influxdbpwd = self.cbpi.config.get("INFLUXDBPWD", None) @@ -54,76 +53,112 @@ class ConfigUpdate(CBPiExtension): NOTIFY_ON_ERROR = self.cbpi.config.get("NOTIFY_ON_ERROR", None) PLAY_BUZZER = self.cbpi.config.get("PLAY_BUZZER", None) BoilAutoTimer = self.cbpi.config.get("BoilAutoTimer", None) - - + MASH_TUN = self.cbpi.config.get("MASH_TUN", None) + AutoMode = self.cbpi.config.get("AutoMode", None) + AddMashIn = self.cbpi.config.get("AddMashInStep", None) + bfuserid = self.cbpi.config.get("brewfather_user_id", None) + bfapikey = self.cbpi.config.get("brewfather_api_key", None) + RecipeCreationPath = self.cbpi.config.get("RECIPE_CREATION_PATH", None) + BoilKettle = self.cbpi.config.get("BoilKettle", None) + CONFIG_STATUS = self.cbpi.config.get("CONFIG_STATUS", None) + + if boil_temp is None: logger.info("INIT Boil Temp Setting") try: - await self.cbpi.config.add("steps_boil_temp", default_boil_temp, ConfigType.NUMBER, "Default Boil Temperature for Recipe Creation") + await self.cbpi.config.add("steps_boil_temp", default_boil_temp, type=ConfigType.NUMBER, description="Default Boil Temperature for Recipe Creation", source="steps") except: logger.warning('Unable to update database') + else: + if CONFIG_STATUS is None: + await self.cbpi.config.add("steps_boil_temp", boil_temp, type=ConfigType.NUMBER, description="Default Boil Temperature for Recipe Creation", source="steps") if cooldown_sensor is None: logger.info("INIT Cooldown Sensor Setting") try: - await self.cbpi.config.add("steps_cooldown_sensor", "", ConfigType.SENSOR, "Alternative Sensor to monitor temperature durring cooldown (if not selected, Kettle Sensor will be used)") + await self.cbpi.config.add("steps_cooldown_sensor", "", type=ConfigType.SENSOR, description="Alternative Sensor to monitor temperature durring cooldown (if not selected, Kettle Sensor will be used)", source="steps") except: logger.warning('Unable to update database') + else: + if CONFIG_STATUS is None: + await self.cbpi.config.add("steps_cooldown_sensor", cooldown_sensor, type=ConfigType.SENSOR, description="Alternative Sensor to monitor temperature durring cooldown (if not selected, Kettle Sensor will be used)", source="steps") if cooldown_actor is None: logger.info("INIT Cooldown Actor Setting") try: - await self.cbpi.config.add("steps_cooldown_actor", "", ConfigType.ACTOR, "Actor to trigger cooldown water on and off (default: None)") + await self.cbpi.config.add("steps_cooldown_actor", "", type=ConfigType.ACTOR, description="Actor to trigger cooldown water on and off (default: None)", source="steps") except: logger.warning('Unable to update database') + else: + if CONFIG_STATUS is None: + await self.cbpi.config.add("steps_cooldown_actor", cooldown_actor, type=ConfigType.ACTOR, description="Actor to trigger cooldown water on and off (default: None)", source="steps") if cooldown_temp is None: logger.info("INIT Cooldown Temp Setting") try: - await self.cbpi.config.add("steps_cooldown_temp", default_cool_temp, ConfigType.NUMBER, "Cooldown temp will send notification when this temeprature is reached") + await self.cbpi.config.add("steps_cooldown_temp", default_cool_temp, type=ConfigType.NUMBER, description="Cooldown temp will send notification when this temeprature is reached", source="steps") except: logger.warning('Unable to update database') + else: + if CONFIG_STATUS is None: + await self.cbpi.config.add("steps_cooldown_temp", cooldown_temp, type=ConfigType.NUMBER, description="Cooldown temp will send notification when this temeprature is reached", source="steps") if cooldown_step is None: logger.info("INIT Cooldown Step Type") try: - await self.cbpi.config.add("steps_cooldown", "", ConfigType.STEP, "Cooldown step type") + await self.cbpi.config.add("steps_cooldown", "", type=ConfigType.STEP, description="Cooldown step type", source="steps") except: logger.warning('Unable to update database') + else: + if CONFIG_STATUS is None: + await self.cbpi.config.add("steps_cooldown", cooldown_step, type=ConfigType.STEP, description="Cooldown step type", source="steps") if mashin_step is None: logger.info("INIT MashIn Step Type") try: - await self.cbpi.config.add("steps_mashin", "", ConfigType.STEP, "MashIn step type") + await self.cbpi.config.add("steps_mashin", "", type=ConfigType.STEP, description="MashIn step type", source="steps") except: logger.warning('Unable to update database') + else: + if CONFIG_STATUS is None: + await self.cbpi.config.add("steps_mashin", mashin_step, type=ConfigType.STEP, description="MashIn step type", source="steps") if mash_step is None: logger.info("INIT Mash Step Type") try: - await self.cbpi.config.add("steps_mash", "", ConfigType.STEP, "Mash step type") + await self.cbpi.config.add("steps_mash", "", type=ConfigType.STEP, description="Mash step type", source="steps") except: logger.warning('Unable to update database') + else: + if CONFIG_STATUS is None: + await self.cbpi.config.add("steps_mash", mash_step, type=ConfigType.STEP, description="Mash step type", source="steps") if mashout_step is None: logger.info("INIT MashOut Step Type") try: - await self.cbpi.config.add("steps_mashout", "", ConfigType.STEP, "MashOut step type") + await self.cbpi.config.add("steps_mashout", "", type=ConfigType.STEP, description="MashOut step type", source="steps") except: logger.warning('Unable to update database') + else: + if CONFIG_STATUS is None: + await self.cbpi.config.add("steps_mashout", mashout_step, type=ConfigType.STEP, description="MashOut step type", source="steps") if boil_step is None: logger.info("INIT Boil Step Type") try: - await self.cbpi.config.add("steps_boil", "", ConfigType.STEP, "Boil step type") + await self.cbpi.config.add("steps_boil", "", type=ConfigType.STEP, description="Boil step type", source="steps") except: logger.warning('Unable to update database') + else: + if CONFIG_STATUS is None: + await self.cbpi.config.add("steps_boil", boil_step, type=ConfigType.STEP, description="Boil step type", source="steps") if max_dashboard_number is None: logger.info("INIT Max Dashboard Numbers for multiple dashboards") try: - await self.cbpi.config.add("max_dashboard_number", 4, ConfigType.SELECT, "Max Number of Dashboards", - [{"label": "1", "value": 1}, + await self.cbpi.config.add("max_dashboard_number", 4, type=ConfigType.SELECT, description="Max Number of Dashboards", + + options= [{"label": "1", "value": 1}, {"label": "2", "value": 2}, {"label": "3", "value": 3}, {"label": "4", "value": 4}, @@ -132,81 +167,109 @@ class ConfigUpdate(CBPiExtension): {"label": "7", "value": 7}, {"label": "8", "value": 8}, {"label": "9", "value": 9}, - {"label": "10", "value": 10}]) + {"label": "10", "value": 10}], + source="craftbeerpi") except: logger.warning('Unable to update database') if current_dashboard_number is None: logger.info("INIT Current Dashboard Number") try: - await self.cbpi.config.add("current_dashboard_number", 1, ConfigType.NUMBER, "Number of current Dashboard") + await self.cbpi.config.add("current_dashboard_number", 1, type=ConfigType.NUMBER, description="Number of current Dashboard",source="hidden") except: logger.warning('Unable to update database') ## Check if AtuoMode for Steps is in config - AutoMode = self.cbpi.config.get("AutoMode", None) + if AutoMode is None: logger.info("INIT AutoMode") try: - await self.cbpi.config.add("AutoMode", "Yes", ConfigType.SELECT, "Use AutoMode in steps", - [{"label": "Yes", "value": "Yes"}, - {"label": "No", "value": "No"}]) + await self.cbpi.config.add("AutoMode", "Yes", type=ConfigType.SELECT, description="Use AutoMode in steps", + options=[{"label": "Yes", "value": "Yes"}, + {"label": "No", "value": "No"}], + source="steps") except: logger.warning('Unable to update config') + else: + if CONFIG_STATUS is None: + await self.cbpi.config.add("AutoMode", AutoMode, type=ConfigType.SELECT, description="Use AutoMode in steps", options= + [{"label": "Yes", "value": "Yes"}, + {"label": "No", "value": "No"}], + source="steps") ## Check if AddMashInStep for Steps is in config - AddMashIn = self.cbpi.config.get("AddMashInStep", None) + if AddMashIn is None: logger.info("INIT AddMashInStep") try: - await self.cbpi.config.add("AddMashInStep", "Yes", ConfigType.SELECT, "Add MashIn Step automatically if not defined in recipe", - [{"label": "Yes", "value": "Yes"}, - {"label": "No", "value": "No"}]) + await self.cbpi.config.add("AddMashInStep", "Yes", type=ConfigType.SELECT, description= "Add MashIn Step automatically if not defined in recipe", + options = [{"label": "Yes", "value": "Yes"}, + {"label": "No", "value": "No"}], + source="steps") except: logger.warning('Unable to update config') + else: + if CONFIG_STATUS is None: + await self.cbpi.config.add("AddMashInStep", AddMashIn, type=ConfigType.SELECT, description="Add MashIn Step automatically if not defined in recipe", + options= [{"label": "Yes", "value": "Yes"}, + {"label": "No", "value": "No"}], + source="steps") ## Check if Brewfather UserID is in config - bfuserid = self.cbpi.config.get("brewfather_user_id", None) + if bfuserid is None: logger.info("INIT Brewfather User ID") try: - await self.cbpi.config.add("brewfather_user_id", "", ConfigType.STRING, "Brewfather User ID") + await self.cbpi.config.add("brewfather_user_id", "", type=ConfigType.STRING, description="Brewfather User ID") except: logger.warning('Unable to update config') ## Check if Brewfather API Key is in config - bfapikey = self.cbpi.config.get("brewfather_api_key", None) + if bfapikey is None: logger.info("INIT Brewfather API Key") try: - await self.cbpi.config.add("brewfather_api_key", "", ConfigType.STRING, "Brewfather API Key") + await self.cbpi.config.add("brewfather_api_key", "", type=ConfigType.STRING, description="Brewfather API Key") except: logger.warning('Unable to update config') ## Check if Brewfather API Key is in config - RecipeCreationPath = self.cbpi.config.get("RECIPE_CREATION_PATH", None) + if RecipeCreationPath is None: logger.info("INIT Recipe Creation Path") try: - await self.cbpi.config.add("RECIPE_CREATION_PATH", "upload", ConfigType.STRING, "API path to creation plugin. Default: upload . CHANGE ONLY IF USING A RECIPE CREATION PLUGIN") + await self.cbpi.config.add("RECIPE_CREATION_PATH", "upload", type=ConfigType.STRING, description="API path to creation plugin. Default: upload . CHANGE ONLY IF USING A RECIPE CREATION PLUGIN") except: logger.warning('Unable to update config') ## Check if Kettle for Boil, Whirlpool and Cooldown is in config - BoilKettle = self.cbpi.config.get("BoilKettle", None) + if BoilKettle is None: logger.info("INIT BoilKettle") try: - await self.cbpi.config.add("BoilKettle", "", ConfigType.KETTLE, "Define Kettle that is used for Boil, Whirlpool and Cooldown. If not selected, MASH_TUN will be used") + await self.cbpi.config.add("BoilKettle", "", type=ConfigType.KETTLE, description="Define Kettle that is used for Boil, Whirlpool and Cooldown. If not selected, MASH_TUN will be used",source="steps") except: logger.warning('Unable to update config') + else: + if CONFIG_STATUS is None: + await self.cbpi.config.add("BoilKettle", BoilKettle, type=ConfigType.KETTLE, description="Define Kettle that is used for Boil, Whirlpool and Cooldown. If not selected, MASH_TUN will be used",source="steps") + + if MASH_TUN is None: + logger.info("INIT MASH_TUN") + try: + await self.cbpi.config.add("MASH_TUN", "", type=ConfigType.KETTLE, description="Default Mash Tun",source="steps") + except: + logger.warning('Unable to update config') + else: + if CONFIG_STATUS is None: + await self.cbpi.config.add("MASH_TUN", MASH_TUN, type=ConfigType.KETTLE, description="Default Mash Tun",source="steps") ## Check if CSV logfiles is on config if logfiles is None: logger.info("INIT CSV logfiles") try: - await self.cbpi.config.add("CSVLOGFILES", "Yes", ConfigType.SELECT, "Write sensor data to csv logfiles", - [{"label": "Yes", "value": "Yes"}, + await self.cbpi.config.add("CSVLOGFILES", "Yes", type=ConfigType.SELECT, description="Write sensor data to csv logfiles", + options= [{"label": "Yes", "value": "Yes"}, {"label": "No", "value": "No"}]) except: logger.warning('Unable to update config') @@ -215,8 +278,8 @@ class ConfigUpdate(CBPiExtension): if influxdb is None: logger.info("INIT Influxdb") try: - await self.cbpi.config.add("INFLUXDB", "No", ConfigType.SELECT, "Write sensor data to influxdb", - [{"label": "Yes", "value": "Yes"}, + await self.cbpi.config.add("INFLUXDB", "No", type=ConfigType.SELECT, description="Write sensor data to influxdb", + options= [{"label": "Yes", "value": "Yes"}, {"label": "No", "value": "No"}]) except: logger.warning('Unable to update config') @@ -225,7 +288,7 @@ class ConfigUpdate(CBPiExtension): if influxdbaddr is None: logger.info("INIT Influxdbaddr") try: - await self.cbpi.config.add("INFLUXDBADDR", "http://localhost:8086", ConfigType.STRING, "URL Address of your influxdb server (If INFLUXDBCLOUD set to Yes use URL Address of your influxdb cloud server)") + await self.cbpi.config.add("INFLUXDBADDR", "http://localhost:8086", type=ConfigType.STRING, description="URL Address of your influxdb server (If INFLUXDBCLOUD set to Yes use URL Address of your influxdb cloud server)") except: logger.warning('Unable to update config') @@ -233,7 +296,7 @@ class ConfigUpdate(CBPiExtension): if influxdbname is None: logger.info("INIT Influxdbname") try: - await self.cbpi.config.add("INFLUXDBNAME", "cbpi4", ConfigType.STRING, "Name of your influxdb database name (If INFLUXDBCLOUD set to Yes use bucket of your influxdb cloud database)") + await self.cbpi.config.add("INFLUXDBNAME", "cbpi4", type=ConfigType.STRING, description="Name of your influxdb database name (If INFLUXDBCLOUD set to Yes use bucket of your influxdb cloud database)") except: logger.warning('Unable to update config') @@ -241,7 +304,7 @@ class ConfigUpdate(CBPiExtension): if influxdbuser is None: logger.info("INIT Influxdbuser") try: - await self.cbpi.config.add("INFLUXDBUSER", " ", ConfigType.STRING, "User name for your influxdb database (only if required)(If INFLUXDBCLOUD set to Yes use organisation of your influxdb cloud database)") + await self.cbpi.config.add("INFLUXDBUSER", " ", type=ConfigType.STRING, description="User name for your influxdb database (only if required)(If INFLUXDBCLOUD set to Yes use organisation of your influxdb cloud database)") except: logger.warning('Unable to update config') @@ -249,7 +312,7 @@ class ConfigUpdate(CBPiExtension): if influxdbpwd is None: logger.info("INIT Influxdbpwd") try: - await self.cbpi.config.add("INFLUXDBPWD", " ", ConfigType.STRING, "Password for your influxdb database (only if required)(If INFLUXDBCLOUD set to Yes use token of your influxdb cloud database)") + await self.cbpi.config.add("INFLUXDBPWD", " ", type=ConfigType.STRING, description="Password for your influxdb database (only if required)(If INFLUXDBCLOUD set to Yes use token of your influxdb cloud database)") except: logger.warning('Unable to update config') @@ -257,8 +320,8 @@ class ConfigUpdate(CBPiExtension): if influxdbcloud is None: logger.info("INIT influxdbcloud") try: - await self.cbpi.config.add("INFLUXDBCLOUD", "No", ConfigType.SELECT, "Write sensor data to influxdb cloud (INFLUXDB must set to Yes)", - [{"label": "Yes", "value": "Yes"}, + await self.cbpi.config.add("INFLUXDBCLOUD", "No", type=ConfigType.SELECT, description="Write sensor data to influxdb cloud (INFLUXDB must set to Yes)", + options= [{"label": "Yes", "value": "Yes"}, {"label": "No", "value": "No"}]) except: logger.warning('Unable to update config') @@ -267,15 +330,15 @@ class ConfigUpdate(CBPiExtension): if influxdbmeasurement is None: logger.info("INIT Influxdb measurementname") try: - await self.cbpi.config.add("INFLUXDBMEASUREMENT", "measurement", ConfigType.STRING, "Name of the measurement in your INFLUXDB database (default: measurement)") + await self.cbpi.config.add("INFLUXDBMEASUREMENT", "measurement", type=ConfigType.STRING, description="Name of the measurement in your INFLUXDB database (default: measurement)") except: logger.warning('Unable to update config') if mqttupdate is None: logger.info("INIT MQTT update frequency for Kettles and Fermenters") try: - await self.cbpi.config.add("MQTTUpdate", 0, ConfigType.SELECT, "Forced MQTT Update frequency in s for Kettle and Fermenter (no changes in payload required). Restart required after change", - [{"label": "30", "value": 30}, + await self.cbpi.config.add("MQTTUpdate", 0, type=ConfigType.SELECT, description="Forced MQTT Update frequency in s for Kettle and Fermenter (no changes in payload required). Restart required after change", + options= [{"label": "30", "value": 30}, {"label": "60", "value": 60}, {"label": "120", "value": 120}, {"label": "300", "value": 300}, @@ -287,8 +350,8 @@ class ConfigUpdate(CBPiExtension): if PRESSURE_UNIT is None: logger.info("INIT PRESSURE_UNIT") try: - await self.cbpi.config.add("PRESSURE_UNIT", "kPa", ConfigType.SELECT, "Set unit for pressure", - [{"label": "kPa", "value": "kPa"}, + await self.cbpi.config.add("PRESSURE_UNIT", "kPa", type=ConfigType.SELECT, description="Set unit for pressure", + options= [{"label": "kPa", "value": "kPa"}, {"label": "PSI", "value": "PSI"}]) except: logger.warning('Unable to update config') @@ -297,7 +360,7 @@ class ConfigUpdate(CBPiExtension): if SENSOR_LOG_BACKUP_COUNT is None: logger.info("INIT SENSOR_LOG_BACKUP_COUNT") try: - await self.cbpi.config.add("SENSOR_LOG_BACKUP_COUNT", 3, ConfigType.NUMBER, "Max. number of backup logs") + await self.cbpi.config.add("SENSOR_LOG_BACKUP_COUNT", 3, type=ConfigType.NUMBER, description="Max. number of backup logs") except: logger.warning('Unable to update database') @@ -305,7 +368,7 @@ class ConfigUpdate(CBPiExtension): if SENSOR_LOG_MAX_BYTES is None: logger.info("Init maximum size of sensor logfiles") try: - await self.cbpi.config.add("SENSOR_LOG_MAX_BYTES", 100000, ConfigType.NUMBER, "Max. number of bytes in sensor logs") + await self.cbpi.config.add("SENSOR_LOG_MAX_BYTES", 100000, type=ConfigType.NUMBER, description="Max. number of bytes in sensor logs") except: logger.warning('Unable to update database') @@ -313,8 +376,8 @@ class ConfigUpdate(CBPiExtension): if slow_pipe_animation is None: logger.info("INIT slow_pipe_animation") try: - await self.cbpi.config.add("slow_pipe_animation", "Yes", ConfigType.SELECT, "Slow down dashboard pipe animation taking up close to 100% of the CPU's capacity", - [{"label": "Yes", "value": "Yes"}, + await self.cbpi.config.add("slow_pipe_animation", "Yes", type=ConfigType.SELECT, description="Slow down dashboard pipe animation taking up close to 100% of the CPU's capacity", + options= [{"label": "Yes", "value": "Yes"}, {"label": "No", "value": "No"}]) except: logger.warning('Unable to update config') @@ -323,8 +386,8 @@ class ConfigUpdate(CBPiExtension): if NOTIFY_ON_ERROR is None: logger.info("INIT NOTIFY_ON_ERROR") try: - await self.cbpi.config.add("NOTIFY_ON_ERROR", "No", ConfigType.SELECT, "Send Notification on Logging Error", - [{"label": "Yes", "value": "Yes"}, + await self.cbpi.config.add("NOTIFY_ON_ERROR", "No", type=ConfigType.SELECT, description="Send Notification on Logging Error", + options= [{"label": "Yes", "value": "Yes"}, {"label": "No", "value": "No"}]) except: logger.warning('Unable to update config') @@ -333,8 +396,8 @@ class ConfigUpdate(CBPiExtension): if PLAY_BUZZER is None: logger.info("INIT PLAY_BUZZER") try: - await self.cbpi.config.add("PLAY_BUZZER", "No", ConfigType.SELECT, "Play buzzer sound in Web interface on Notifications", - [{"label": "Yes", "value": "Yes"}, + await self.cbpi.config.add("PLAY_BUZZER", "No", type=ConfigType.SELECT, description="Play buzzer sound in Web interface on Notifications", + options= [{"label": "Yes", "value": "Yes"}, {"label": "No", "value": "No"}]) except: logger.warning('Unable to update config') @@ -342,13 +405,31 @@ class ConfigUpdate(CBPiExtension): if BoilAutoTimer is None: logging.info("INIT BoilAutoTimer") try: - await self.cbpi.config.add('BoilAutoTimer', 'No', ConfigType.SELECT, - 'Start Boil timer automatically if Temp does not change for 5 Minutes and is above 95C/203F', - [{"label": "Yes", "value": "Yes"}, - {"label": "No", "value": "No"}]) + await self.cbpi.config.add('BoilAutoTimer', 'No', type=ConfigType.SELECT, + description='Start Boil timer automatically if Temp does not change for 5 Minutes and is above 95C/203F', + options= [{"label": "Yes", "value": "Yes"}, + {"label": "No", "value": "No"}], + source="steps") BoilAutoTimer = self.cbpi.config.get("BoilAutoTimer", "No") except: logging.warning('Unable to update database') + else: + if CONFIG_STATUS is None: + await self.cbpi.config.add('BoilAutoTimer', BoilAutoTimer, type=ConfigType.SELECT, + description='Start Boil timer automatically if Temp does not change for 5 Minutes and is above 95C/203F', + options=[{"label": "Yes", "value": "Yes"}, + {"label": "No", "value": "No"}], + source="steps") + + + ## Check if influxdbname is in config + if CONFIG_STATUS is None: + logger.warning("Setting Config Status") + try: + await self.cbpi.config.add("CONFIG_STATUS", "4.1.8", type=ConfigType.STRING, description="Status of the cofig file. Internal use for maintenance", source="hidden") + except: + logger.warning('Unable to update config') + def setup(cbpi): cbpi.plugin.register("ConfigUpdate", ConfigUpdate) From 754d8be21fae2ce43aff0226e4d8e41b9ed9a057 Mon Sep 17 00:00:00 2001 From: avollkopf <43980694+avollkopf@users.noreply.github.com> Date: Sun, 2 Apr 2023 16:32:10 +0200 Subject: [PATCH 05/20] update currentdashbardnumber to hidden --- cbpi/__init__.py | 2 +- cbpi/extension/ConfigUpdate/__init__.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/cbpi/__init__.py b/cbpi/__init__.py index 5f83b3a..212d1ee 100644 --- a/cbpi/__init__.py +++ b/cbpi/__init__.py @@ -1,3 +1,3 @@ -__version__ = "4.1.8.a3" +__version__ = "4.1.8.a4" __codename__ = "Groundhog Day" diff --git a/cbpi/extension/ConfigUpdate/__init__.py b/cbpi/extension/ConfigUpdate/__init__.py index a8c52ab..a12ee88 100644 --- a/cbpi/extension/ConfigUpdate/__init__.py +++ b/cbpi/extension/ConfigUpdate/__init__.py @@ -178,6 +178,9 @@ class ConfigUpdate(CBPiExtension): await self.cbpi.config.add("current_dashboard_number", 1, type=ConfigType.NUMBER, description="Number of current Dashboard",source="hidden") except: logger.warning('Unable to update database') + else: + if CONFIG_STATUS is None: + await self.cbpi.config.add("current_dashboard_number", current_dashboard_number, type=ConfigType.NUMBER, description="Number of current Dashboard",source="hidden") ## Check if AtuoMode for Steps is in config From 73200890a1feb9e2aa0e849d20eda03f56f1746c Mon Sep 17 00:00:00 2001 From: avollkopf <43980694+avollkopf@users.noreply.github.com> Date: Sun, 2 Apr 2023 17:01:56 +0200 Subject: [PATCH 06/20] removed logging item --- cbpi/controller/plugin_controller.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cbpi/controller/plugin_controller.py b/cbpi/controller/plugin_controller.py index 5bfb8fd..7c24332 100644 --- a/cbpi/controller/plugin_controller.py +++ b/cbpi/controller/plugin_controller.py @@ -205,7 +205,6 @@ class PluginController(): from importlib.metadata import (distribution, metadata, version) meta = metadata(key) - logging.warning(key) result.append({row: meta[row] for row in list(metadata(key))}) except Exception as e: From 1357aa2a0e3d5eb3e195bfbb9340c24b8f3bd67b Mon Sep 17 00:00:00 2001 From: avollkopf <43980694+avollkopf@users.noreply.github.com> Date: Sun, 2 Apr 2023 18:27:15 +0200 Subject: [PATCH 07/20] fix in http_plugin endpoint --- cbpi/http_endpoints/http_plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cbpi/http_endpoints/http_plugin.py b/cbpi/http_endpoints/http_plugin.py index 9a36beb..27b5149 100644 --- a/cbpi/http_endpoints/http_plugin.py +++ b/cbpi/http_endpoints/http_plugin.py @@ -88,7 +88,7 @@ class PluginHttpEndpoints: return web.json_response(plugin_list, dumps=json_dumps) @request_mapping(path="/names", method="GET", auth_required=False) - async def list(self, request): + async def names(self, request): """ --- description: Get a list of avialable plugin names From 7d9d010e0c79d5ae5ae862bff9085dba5ecfb605 Mon Sep 17 00:00:00 2001 From: avollkopf <43980694+avollkopf@users.noreply.github.com> Date: Mon, 3 Apr 2023 20:39:35 +0200 Subject: [PATCH 08/20] keyword 'globalsettings' in plugin setup.py required to show up on settings page --- cbpi/controller/plugin_controller.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cbpi/controller/plugin_controller.py b/cbpi/controller/plugin_controller.py index 7c24332..b361d89 100644 --- a/cbpi/controller/plugin_controller.py +++ b/cbpi/controller/plugin_controller.py @@ -231,7 +231,7 @@ class PluginController(): for key, module in discovered_plugins.items(): try: meta = metadata(key) - if meta["Name"] != "cbpi4gui": + if meta["Name"] != "cbpi4gui" and meta["Keywords"] == "globalsettings": result.append(dict(label=meta["Name"], value=meta["Name"])) except Exception as e: From 5e2dc35b30a0ca44eb7c93a74b9d7fd8c49848c7 Mon Sep 17 00:00:00 2001 From: avollkopf <43980694+avollkopf@users.noreply.github.com> Date: Wed, 5 Apr 2023 06:45:33 +0200 Subject: [PATCH 09/20] test newer cryptography version as 40.0.0 may cuase issues on older 32 bit systems --- cbpi/__init__.py | 2 +- cbpi/controller/plugin_controller.py | 3 +-- requirements.txt | 2 +- setup.py | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/cbpi/__init__.py b/cbpi/__init__.py index 212d1ee..0b47676 100644 --- a/cbpi/__init__.py +++ b/cbpi/__init__.py @@ -1,3 +1,3 @@ -__version__ = "4.1.8.a4" +__version__ = "4.1.8.a5" __codename__ = "Groundhog Day" diff --git a/cbpi/controller/plugin_controller.py b/cbpi/controller/plugin_controller.py index b361d89..9bd32b4 100644 --- a/cbpi/controller/plugin_controller.py +++ b/cbpi/controller/plugin_controller.py @@ -233,9 +233,8 @@ class PluginController(): meta = metadata(key) if meta["Name"] != "cbpi4gui" and meta["Keywords"] == "globalsettings": result.append(dict(label=meta["Name"], value=meta["Name"])) - except Exception as e: - logger.error("FAILED to load plugin {} ".format(key)) + logger.error("FAILED to read metadata for plugin {} ".format(key)) logger.error(e) except Exception as e: logger.error(e) diff --git a/requirements.txt b/requirements.txt index bce7636..c02ae4a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ aiohttp-session==2.12.0 aiohttp-swagger==1.0.16 aiojobs==1.1.0 aiosqlite==0.17.0 -cryptography==40.0.0 +cryptography==40.0.1 requests==2.28.1 voluptuous==0.13.1 pyfiglet==0.8.post1 diff --git a/setup.py b/setup.py index 4b173cc..c1d3129 100644 --- a/setup.py +++ b/setup.py @@ -47,7 +47,7 @@ setup(name='cbpi4', "aiohttp-swagger==1.0.16", "aiojobs==1.1.0 ", "aiosqlite==0.17.0", - "cryptography==40.0.0", + "cryptography==40.0.1", "requests==2.28.1", "voluptuous==0.13.1", "pyfiglet==0.8.post1", From dc36cc1ed34cf9d217f01df07162745559d93957 Mon Sep 17 00:00:00 2001 From: avollkopf <43980694+avollkopf@users.noreply.github.com> Date: Thu, 6 Apr 2023 12:40:49 +0200 Subject: [PATCH 10/20] test withconfig parameter removal --- cbpi/__init__.py | 2 +- cbpi/api/base.py | 3 +++ cbpi/controller/config_controller.py | 19 ++++++++++++++++++- cbpi/http_endpoints/http_config.py | 25 ++++++++++++++++++++++++- 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/cbpi/__init__.py b/cbpi/__init__.py index 0b47676..622871d 100644 --- a/cbpi/__init__.py +++ b/cbpi/__init__.py @@ -1,3 +1,3 @@ -__version__ = "4.1.8.a5" +__version__ = "4.1.8.a6" __codename__ = "Groundhog Day" diff --git a/cbpi/api/base.py b/cbpi/api/base.py index 9fd4692..51b7c46 100644 --- a/cbpi/api/base.py +++ b/cbpi/api/base.py @@ -16,6 +16,9 @@ class CBPiBase(metaclass=ABCMeta): async def set_config_value(self,name,value): return await self.cbpi.config.set(name,value) + + async def remove_config_parameter(self,name): + return await self.cbpi.config.remove(name) async def add_config_value(self, name, value, type: ConfigType, description, source, options=None): await self.cbpi.config.add(name, value, type, description, source,options=None) diff --git a/cbpi/controller/config_controller.py b/cbpi/controller/config_controller.py index e0c5587..2000b13 100644 --- a/cbpi/controller/config_controller.py +++ b/cbpi/controller/config_controller.py @@ -50,10 +50,27 @@ class ConfigController: with open(self.path, "w") as file: json.dump(data, file, indent=4, sort_keys=True) - async def add(self, name, value, type: ConfigType, description, source="", options=None): + async def add(self, name, value, type: ConfigType, description, source="craftbeerpi", options=None): self.cache[name] = Config(name,value,description,type,source,options) data = {} for key, value in self.cache.items(): data[key] = value.to_dict() with open(self.path, "w") as file: json.dump(data, file, indent=4, sort_keys=True) + + async def remove(self, name): + data = {} + self.testcache={} + for key, value in self.cache.items(): + try: + if key != name: + data[key] = value.to_dict() + self.testcache[key] = Config(name=data[key].get("name"), value=data[key].get("value"), description=data[key].get("description"), + type=ConfigType(data[key].get("type", "string")), options=data[key].get("options", None), + source=data[key].get("source", "craftbeerpi") ) + except Exception as e: + print(e) + with open(self.path, "w") as file: + json.dump(data, file, indent=4, sort_keys=True) + self.cache=self.testcache + diff --git a/cbpi/http_endpoints/http_config.py b/cbpi/http_endpoints/http_config.py index 5e233d2..fc2d643 100644 --- a/cbpi/http_endpoints/http_config.py +++ b/cbpi/http_endpoints/http_config.py @@ -78,5 +78,28 @@ class ConfigHttpEndpoints: name = request.match_info['name'] # if name not in self.cache: # raise CBPiException("Parameter %s not found" % name) - data = self.controller.get(name) +# data = self.controller.get(name) return web.json_response(self.controller.get(name), dumps=json_dumps) + + @request_mapping(path="/remove/{name}/", method="PUT", auth_required=False) + async def http_remove(self, request) -> web.Response: + + """ + --- + description: Remove config parameter + tags: + - Config + parameters: + - name: "name" + in: "path" + description: "Parameter name" + required: true + type: "string" + responses: + "200": + description: successful operation + """ + + name = request.match_info['name'] + await self.controller.remove(name=name) + return web.Response(status=200) \ No newline at end of file From 5e69ce4c40a7b2abc310bcd453060a551c8b73a7 Mon Sep 17 00:00:00 2001 From: avollkopf <43980694+avollkopf@users.noreply.github.com> Date: Fri, 7 Apr 2023 16:26:03 +0200 Subject: [PATCH 11/20] handling in case of error (config controller -> remove) --- cbpi/__init__.py | 2 +- cbpi/controller/config_controller.py | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/cbpi/__init__.py b/cbpi/__init__.py index 622871d..7fcced5 100644 --- a/cbpi/__init__.py +++ b/cbpi/__init__.py @@ -1,3 +1,3 @@ -__version__ = "4.1.8.a6" +__version__ = "4.1.8.a7" __codename__ = "Groundhog Day" diff --git a/cbpi/controller/config_controller.py b/cbpi/controller/config_controller.py index 2000b13..bb1b5b0 100644 --- a/cbpi/controller/config_controller.py +++ b/cbpi/controller/config_controller.py @@ -61,16 +61,20 @@ class ConfigController: async def remove(self, name): data = {} self.testcache={} + success=False for key, value in self.cache.items(): try: if key != name: data[key] = value.to_dict() self.testcache[key] = Config(name=data[key].get("name"), value=data[key].get("value"), description=data[key].get("description"), type=ConfigType(data[key].get("type", "string")), options=data[key].get("options", None), - source=data[key].get("source", "craftbeerpi") ) + source=data[key].get("source", "craftbeerpi") ) + success=True except Exception as e: print(e) - with open(self.path, "w") as file: - json.dump(data, file, indent=4, sort_keys=True) - self.cache=self.testcache + success=False + if success == True: + with open(self.path, "w") as file: + json.dump(data, file, indent=4, sort_keys=True) + self.cache=self.testcache From 9041ad7daa7fafdc88900d83e3fec9b7d1dd9ff3 Mon Sep 17 00:00:00 2001 From: avollkopf <43980694+avollkopf@users.noreply.github.com> Date: Sat, 8 Apr 2023 11:55:49 +0200 Subject: [PATCH 12/20] added error handling in case of corrupt json config files. --- cbpi/__init__.py | 2 +- cbpi/controller/basic_controller2.py | 42 ++++++++++++++++++++-------- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/cbpi/__init__.py b/cbpi/__init__.py index 7fcced5..8d7482d 100644 --- a/cbpi/__init__.py +++ b/cbpi/__init__.py @@ -1,3 +1,3 @@ -__version__ = "4.1.8.a7" +__version__ = "4.1.8.a8" __codename__ = "Groundhog Day" diff --git a/cbpi/controller/basic_controller2.py b/cbpi/controller/basic_controller2.py index 7ef8b4f..6a4a64f 100644 --- a/cbpi/controller/basic_controller2.py +++ b/cbpi/controller/basic_controller2.py @@ -34,19 +34,39 @@ class BasicController: return self.resource(data.get("id"), data.get("name"), type=data.get("type"), props=Props(data.get("props", {})) ) async def load(self): - logging.info("{} Load ".format(self.name)) - with open(self.path) as json_file: - data = json.load(json_file) - data['data'].sort(key=lambda x: x.get('name').upper()) + try: + logging.info("{} Load ".format(self.name)) + with open(self.path) as json_file: + data = json.load(json_file) + data['data'].sort(key=lambda x: x.get('name').upper()) - for i in data["data"]: - self.data.append(self.create(i)) + for i in data["data"]: + self.data.append(self.create(i)) - if self.autostart is True: - for item in self.data: - logging.info("{} Starting ".format(self.name)) - await self.start(item.id) - await self.push_udpate() + if self.autostart is True: + for item in self.data: + logging.info("{} Starting ".format(self.name)) + await self.start(item.id) + await self.push_udpate() + except Exception as e: + logging.warning("Invalid {} file - Creating empty file".format(self.path)) + os.remove(self.path) + with open(self.path, "w") as file: + json.dump(dict( data=[]), file, indent=4, sort_keys=True) + + with open(self.path) as json_file: + data = json.load(json_file) + data['data'].sort(key=lambda x: x.get('name').upper()) + + for i in data["data"]: + self.data.append(self.create(i)) + + if self.autostart is True: + for item in self.data: + logging.info("{} Starting ".format(self.name)) + await self.start(item.id) + await self.push_udpate() + async def save(self): logging.info("{} Save ".format(self.name)) From efc3e3737c873c7877cb7802104b38c98a8dea8f Mon Sep 17 00:00:00 2001 From: avollkopf <43980694+avollkopf@users.noreply.github.com> Date: Sat, 8 Apr 2023 12:26:10 +0200 Subject: [PATCH 13/20] variable CONFIG_STATUS (cbpi version) --- cbpi/__init__.py | 2 +- cbpi/extension/ConfigUpdate/__init__.py | 36 +++++++++++++------------ 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/cbpi/__init__.py b/cbpi/__init__.py index 8d7482d..6e25b40 100644 --- a/cbpi/__init__.py +++ b/cbpi/__init__.py @@ -1,3 +1,3 @@ -__version__ = "4.1.8.a8" +__version__ = "4.1.8.a9" __codename__ = "Groundhog Day" diff --git a/cbpi/extension/ConfigUpdate/__init__.py b/cbpi/extension/ConfigUpdate/__init__.py index a12ee88..e7fca81 100644 --- a/cbpi/extension/ConfigUpdate/__init__.py +++ b/cbpi/extension/ConfigUpdate/__init__.py @@ -8,6 +8,7 @@ import json from cbpi.api import * from cbpi.api.config import ConfigType from cbpi.api.base import CBPiBase +from cbpi import __version__ logger = logging.getLogger(__name__) @@ -61,6 +62,7 @@ class ConfigUpdate(CBPiExtension): RecipeCreationPath = self.cbpi.config.get("RECIPE_CREATION_PATH", None) BoilKettle = self.cbpi.config.get("BoilKettle", None) CONFIG_STATUS = self.cbpi.config.get("CONFIG_STATUS", None) + self.version=__version__ if boil_temp is None: @@ -70,7 +72,7 @@ class ConfigUpdate(CBPiExtension): except: logger.warning('Unable to update database') else: - if CONFIG_STATUS is None: + if CONFIG_STATUS is None or CONFIG_STATUS != self.version: await self.cbpi.config.add("steps_boil_temp", boil_temp, type=ConfigType.NUMBER, description="Default Boil Temperature for Recipe Creation", source="steps") if cooldown_sensor is None: @@ -80,7 +82,7 @@ class ConfigUpdate(CBPiExtension): except: logger.warning('Unable to update database') else: - if CONFIG_STATUS is None: + if CONFIG_STATUS is None or CONFIG_STATUS != self.version: await self.cbpi.config.add("steps_cooldown_sensor", cooldown_sensor, type=ConfigType.SENSOR, description="Alternative Sensor to monitor temperature durring cooldown (if not selected, Kettle Sensor will be used)", source="steps") if cooldown_actor is None: @@ -90,7 +92,7 @@ class ConfigUpdate(CBPiExtension): except: logger.warning('Unable to update database') else: - if CONFIG_STATUS is None: + if CONFIG_STATUS is None or CONFIG_STATUS != self.version: await self.cbpi.config.add("steps_cooldown_actor", cooldown_actor, type=ConfigType.ACTOR, description="Actor to trigger cooldown water on and off (default: None)", source="steps") if cooldown_temp is None: @@ -100,7 +102,7 @@ class ConfigUpdate(CBPiExtension): except: logger.warning('Unable to update database') else: - if CONFIG_STATUS is None: + if CONFIG_STATUS is None or CONFIG_STATUS != self.version: await self.cbpi.config.add("steps_cooldown_temp", cooldown_temp, type=ConfigType.NUMBER, description="Cooldown temp will send notification when this temeprature is reached", source="steps") if cooldown_step is None: @@ -110,7 +112,7 @@ class ConfigUpdate(CBPiExtension): except: logger.warning('Unable to update database') else: - if CONFIG_STATUS is None: + if CONFIG_STATUS is None or CONFIG_STATUS != self.version: await self.cbpi.config.add("steps_cooldown", cooldown_step, type=ConfigType.STEP, description="Cooldown step type", source="steps") if mashin_step is None: @@ -120,7 +122,7 @@ class ConfigUpdate(CBPiExtension): except: logger.warning('Unable to update database') else: - if CONFIG_STATUS is None: + if CONFIG_STATUS is None or CONFIG_STATUS != self.version: await self.cbpi.config.add("steps_mashin", mashin_step, type=ConfigType.STEP, description="MashIn step type", source="steps") if mash_step is None: @@ -130,7 +132,7 @@ class ConfigUpdate(CBPiExtension): except: logger.warning('Unable to update database') else: - if CONFIG_STATUS is None: + if CONFIG_STATUS is None or CONFIG_STATUS != self.version: await self.cbpi.config.add("steps_mash", mash_step, type=ConfigType.STEP, description="Mash step type", source="steps") if mashout_step is None: @@ -140,7 +142,7 @@ class ConfigUpdate(CBPiExtension): except: logger.warning('Unable to update database') else: - if CONFIG_STATUS is None: + if CONFIG_STATUS is None or CONFIG_STATUS != self.version: await self.cbpi.config.add("steps_mashout", mashout_step, type=ConfigType.STEP, description="MashOut step type", source="steps") if boil_step is None: @@ -150,7 +152,7 @@ class ConfigUpdate(CBPiExtension): except: logger.warning('Unable to update database') else: - if CONFIG_STATUS is None: + if CONFIG_STATUS is None or CONFIG_STATUS != self.version: await self.cbpi.config.add("steps_boil", boil_step, type=ConfigType.STEP, description="Boil step type", source="steps") if max_dashboard_number is None: @@ -179,7 +181,7 @@ class ConfigUpdate(CBPiExtension): except: logger.warning('Unable to update database') else: - if CONFIG_STATUS is None: + if CONFIG_STATUS is None or CONFIG_STATUS != self.version: await self.cbpi.config.add("current_dashboard_number", current_dashboard_number, type=ConfigType.NUMBER, description="Number of current Dashboard",source="hidden") ## Check if AtuoMode for Steps is in config @@ -194,7 +196,7 @@ class ConfigUpdate(CBPiExtension): except: logger.warning('Unable to update config') else: - if CONFIG_STATUS is None: + if CONFIG_STATUS is None or CONFIG_STATUS != self.version: await self.cbpi.config.add("AutoMode", AutoMode, type=ConfigType.SELECT, description="Use AutoMode in steps", options= [{"label": "Yes", "value": "Yes"}, {"label": "No", "value": "No"}], @@ -212,7 +214,7 @@ class ConfigUpdate(CBPiExtension): except: logger.warning('Unable to update config') else: - if CONFIG_STATUS is None: + if CONFIG_STATUS is None or CONFIG_STATUS != self.version: await self.cbpi.config.add("AddMashInStep", AddMashIn, type=ConfigType.SELECT, description="Add MashIn Step automatically if not defined in recipe", options= [{"label": "Yes", "value": "Yes"}, {"label": "No", "value": "No"}], @@ -254,7 +256,7 @@ class ConfigUpdate(CBPiExtension): except: logger.warning('Unable to update config') else: - if CONFIG_STATUS is None: + if CONFIG_STATUS is None or CONFIG_STATUS != self.version: await self.cbpi.config.add("BoilKettle", BoilKettle, type=ConfigType.KETTLE, description="Define Kettle that is used for Boil, Whirlpool and Cooldown. If not selected, MASH_TUN will be used",source="steps") if MASH_TUN is None: @@ -264,7 +266,7 @@ class ConfigUpdate(CBPiExtension): except: logger.warning('Unable to update config') else: - if CONFIG_STATUS is None: + if CONFIG_STATUS is None or CONFIG_STATUS != self.version: await self.cbpi.config.add("MASH_TUN", MASH_TUN, type=ConfigType.KETTLE, description="Default Mash Tun",source="steps") ## Check if CSV logfiles is on config @@ -417,7 +419,7 @@ class ConfigUpdate(CBPiExtension): except: logging.warning('Unable to update database') else: - if CONFIG_STATUS is None: + if CONFIG_STATUS is None or CONFIG_STATUS != self.version: await self.cbpi.config.add('BoilAutoTimer', BoilAutoTimer, type=ConfigType.SELECT, description='Start Boil timer automatically if Temp does not change for 5 Minutes and is above 95C/203F', options=[{"label": "Yes", "value": "Yes"}, @@ -426,10 +428,10 @@ class ConfigUpdate(CBPiExtension): ## Check if influxdbname is in config - if CONFIG_STATUS is None: + if CONFIG_STATUS is None or CONFIG_STATUS != self.version: logger.warning("Setting Config Status") try: - await self.cbpi.config.add("CONFIG_STATUS", "4.1.8", type=ConfigType.STRING, description="Status of the cofig file. Internal use for maintenance", source="hidden") + await self.cbpi.config.add("CONFIG_STATUS", self.version, type=ConfigType.STRING, description="Status of the config file. Internal use for maintenance", source="hidden") except: logger.warning('Unable to update config') From 668705e1e084a28bea06941b6b936c947a4f903a Mon Sep 17 00:00:00 2001 From: avollkopf <43980694+avollkopf@users.noreply.github.com> Date: Sat, 8 Apr 2023 14:15:08 +0200 Subject: [PATCH 14/20] api function to remove oboslete settings parameters --- cbpi/__init__.py | 2 +- cbpi/controller/config_controller.py | 12 ++++++++++++ cbpi/http_endpoints/http_config.py | 15 ++++++++++++++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/cbpi/__init__.py b/cbpi/__init__.py index 6e25b40..29df26c 100644 --- a/cbpi/__init__.py +++ b/cbpi/__init__.py @@ -1,3 +1,3 @@ -__version__ = "4.1.8.a9" +__version__ = "4.1.8.a10" __codename__ = "Groundhog Day" diff --git a/cbpi/controller/config_controller.py b/cbpi/controller/config_controller.py index bb1b5b0..b0324b2 100644 --- a/cbpi/controller/config_controller.py +++ b/cbpi/controller/config_controller.py @@ -78,3 +78,15 @@ class ConfigController: json.dump(data, file, indent=4, sort_keys=True) self.cache=self.testcache + async def remove_obsolete(self): + result = {} + for key, value in self.cache.items(): + if (value.source not in ('craftbeerpi','steps','hidden')): + test = await self.cbpi.plugin.load_plugin_list(value.source) + if test == []: + update=self.get(str(value.source)+'_update') + if update: + await self.remove(str(value.source)+'_update') + await self.remove(key) + result[key] = value.to_dict() + return result \ No newline at end of file diff --git a/cbpi/http_endpoints/http_config.py b/cbpi/http_endpoints/http_config.py index fc2d643..ace5f17 100644 --- a/cbpi/http_endpoints/http_config.py +++ b/cbpi/http_endpoints/http_config.py @@ -102,4 +102,17 @@ class ConfigHttpEndpoints: name = request.match_info['name'] await self.controller.remove(name=name) - return web.Response(status=200) \ No newline at end of file + return web.Response(status=200) + + @request_mapping(path="/obsolete", auth_required=False) + async def http_remove_obsolete(self, request) -> web.Response: + """ + --- + description: Get all config parameters + tags: + - Config + responses: + "200": + description: successful operation + """ + return web.json_response(await self.controller.remove_obsolete(), dumps=json_dumps) \ No newline at end of file From f036a2f97260161d0181363c0d364ed558c498e6 Mon Sep 17 00:00:00 2001 From: avollkopf <43980694+avollkopf@users.noreply.github.com> Date: Sat, 8 Apr 2023 15:12:26 +0200 Subject: [PATCH 15/20] fix api description --- cbpi/__init__.py | 2 +- cbpi/http_endpoints/http_config.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cbpi/__init__.py b/cbpi/__init__.py index 29df26c..e5432a1 100644 --- a/cbpi/__init__.py +++ b/cbpi/__init__.py @@ -1,3 +1,3 @@ -__version__ = "4.1.8.a10" +__version__ = "4.1.8.a11" __codename__ = "Groundhog Day" diff --git a/cbpi/http_endpoints/http_config.py b/cbpi/http_endpoints/http_config.py index ace5f17..8ba88f0 100644 --- a/cbpi/http_endpoints/http_config.py +++ b/cbpi/http_endpoints/http_config.py @@ -108,7 +108,7 @@ class ConfigHttpEndpoints: async def http_remove_obsolete(self, request) -> web.Response: """ --- - description: Get all config parameters + description: Remove obsolete config parameters tags: - Config responses: From f990e0e0a35ba9b4259d254abcdbfeef0ebade13 Mon Sep 17 00:00:00 2001 From: avollkopf <43980694+avollkopf@users.noreply.github.com> Date: Sat, 8 Apr 2023 15:21:17 +0200 Subject: [PATCH 16/20] requirement aiohttp -> 3.8.4 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index c1d3129..d9478a4 100644 --- a/setup.py +++ b/setup.py @@ -39,7 +39,7 @@ setup(name='cbpi4', long_description_content_type='text/markdown', install_requires=[ "typing-extensions>=4", - "aiohttp==3.8.3", + "aiohttp==3.8.4", "aiohttp-auth==0.1.1", "aiohttp-route-decorator==0.1.4", "aiohttp-security==0.4.0", From 1d6cd75f8caf49e3f234f6f15be89c0cb57878d8 Mon Sep 17 00:00:00 2001 From: avollkopf <43980694+avollkopf@users.noreply.github.com> Date: Sun, 16 Apr 2023 17:22:33 +0200 Subject: [PATCH 17/20] fixed bug in parameter generation -> source | options order --- cbpi/__init__.py | 2 +- cbpi/api/base.py | 2 +- cbpi/api/dataclasses.py | 2 +- cbpi/controller/config_controller.py | 12 ++-- cbpi/extension/ConfigUpdate/__init__.py | 70 +++++++++++-------- cbpi/http_endpoints/http_config.py | 18 ++++- tests/cbpi-test-config/config.json | 62 ++++++++++++++++ .../dashboard/cbpi_dashboard_1.json | 6 +- 8 files changed, 136 insertions(+), 38 deletions(-) diff --git a/cbpi/__init__.py b/cbpi/__init__.py index e5432a1..4d52643 100644 --- a/cbpi/__init__.py +++ b/cbpi/__init__.py @@ -1,3 +1,3 @@ -__version__ = "4.1.8.a11" +__version__ = "4.1.8.a12" __codename__ = "Groundhog Day" diff --git a/cbpi/api/base.py b/cbpi/api/base.py index 51b7c46..7e6365c 100644 --- a/cbpi/api/base.py +++ b/cbpi/api/base.py @@ -21,7 +21,7 @@ class CBPiBase(metaclass=ABCMeta): return await self.cbpi.config.remove(name) async def add_config_value(self, name, value, type: ConfigType, description, source, options=None): - await self.cbpi.config.add(name, value, type, description, source,options=None) + await self.cbpi.config.add(name, value, type, description, source, options=None) def get_kettle(self,id): return self.cbpi.kettle.find_by_id(id) diff --git a/cbpi/api/dataclasses.py b/cbpi/api/dataclasses.py index 6885912..eb545db 100644 --- a/cbpi/api/dataclasses.py +++ b/cbpi/api/dataclasses.py @@ -204,7 +204,7 @@ class Config: def __str__(self): return "....name={} value={}".format(self.name, self.value) def to_dict(self): - return dict(name=self.name, value=self.value, type=self.type.value, description=self.description, options=self.options, source=self.source) + return dict(name=self.name, value=self.value, type=self.type.value, description=self.description, source=self.source, options=self.options) @dataclass class NotificationAction: diff --git a/cbpi/controller/config_controller.py b/cbpi/controller/config_controller.py index b0324b2..16c7c02 100644 --- a/cbpi/controller/config_controller.py +++ b/cbpi/controller/config_controller.py @@ -30,7 +30,8 @@ class ConfigController: with open(self.path) as json_file: data = json.load(json_file) for key, value in data.items(): - self.cache[key] = Config(name=value.get("name"), value=value.get("value"), description=value.get("description"), type=ConfigType(value.get("type", "string")), options=value.get("options", None), source=value.get("source", "craftbeerpi") ) + self.cache[key] = Config(name=value.get("name"), value=value.get("value"), description=value.get("description"), type=ConfigType(value.get("type", "string")), source=value.get("source", "craftbeerpi"), options=value.get("options", None)) + logging.error(self.cache) def get(self, name, default=None): self.logger.debug("GET CONFIG VALUE %s (default %s)" % (name, default)) @@ -78,7 +79,7 @@ class ConfigController: json.dump(data, file, indent=4, sort_keys=True) self.cache=self.testcache - async def remove_obsolete(self): + async def obsolete(self, remove=False): result = {} for key, value in self.cache.items(): if (value.source not in ('craftbeerpi','steps','hidden')): @@ -86,7 +87,10 @@ class ConfigController: if test == []: update=self.get(str(value.source)+'_update') if update: - await self.remove(str(value.source)+'_update') - await self.remove(key) + logging.warning(update) + if remove: + await self.remove(str(value.source)+'_update') + if remove: + await self.remove(key) result[key] = value.to_dict() return result \ No newline at end of file diff --git a/cbpi/extension/ConfigUpdate/__init__.py b/cbpi/extension/ConfigUpdate/__init__.py index e7fca81..56eefab 100644 --- a/cbpi/extension/ConfigUpdate/__init__.py +++ b/cbpi/extension/ConfigUpdate/__init__.py @@ -159,7 +159,7 @@ class ConfigUpdate(CBPiExtension): logger.info("INIT Max Dashboard Numbers for multiple dashboards") try: await self.cbpi.config.add("max_dashboard_number", 4, type=ConfigType.SELECT, description="Max Number of Dashboards", - + source="craftbeerpi", options= [{"label": "1", "value": 1}, {"label": "2", "value": 2}, {"label": "3", "value": 3}, @@ -169,8 +169,8 @@ class ConfigUpdate(CBPiExtension): {"label": "7", "value": 7}, {"label": "8", "value": 8}, {"label": "9", "value": 9}, - {"label": "10", "value": 10}], - source="craftbeerpi") + {"label": "10", "value": 10}]) + except: logger.warning('Unable to update database') @@ -190,17 +190,19 @@ class ConfigUpdate(CBPiExtension): logger.info("INIT AutoMode") try: await self.cbpi.config.add("AutoMode", "Yes", type=ConfigType.SELECT, description="Use AutoMode in steps", + source="steps", options=[{"label": "Yes", "value": "Yes"}, - {"label": "No", "value": "No"}], - source="steps") + {"label": "No", "value": "No"}]) + except: logger.warning('Unable to update config') else: if CONFIG_STATUS is None or CONFIG_STATUS != self.version: - await self.cbpi.config.add("AutoMode", AutoMode, type=ConfigType.SELECT, description="Use AutoMode in steps", options= - [{"label": "Yes", "value": "Yes"}, - {"label": "No", "value": "No"}], - source="steps") + await self.cbpi.config.add("AutoMode", AutoMode, type=ConfigType.SELECT, description="Use AutoMode in steps", + source="steps", + options=[{"label": "Yes", "value": "Yes"}, + {"label": "No", "value": "No"}]) + ## Check if AddMashInStep for Steps is in config @@ -208,24 +210,26 @@ class ConfigUpdate(CBPiExtension): logger.info("INIT AddMashInStep") try: await self.cbpi.config.add("AddMashInStep", "Yes", type=ConfigType.SELECT, description= "Add MashIn Step automatically if not defined in recipe", + source="steps", options = [{"label": "Yes", "value": "Yes"}, - {"label": "No", "value": "No"}], - source="steps") + {"label": "No", "value": "No"}]) + except: logger.warning('Unable to update config') else: if CONFIG_STATUS is None or CONFIG_STATUS != self.version: await self.cbpi.config.add("AddMashInStep", AddMashIn, type=ConfigType.SELECT, description="Add MashIn Step automatically if not defined in recipe", + source="steps", options= [{"label": "Yes", "value": "Yes"}, - {"label": "No", "value": "No"}], - source="steps") + {"label": "No", "value": "No"}]) + ## Check if Brewfather UserID is in config if bfuserid is None: logger.info("INIT Brewfather User ID") try: - await self.cbpi.config.add("brewfather_user_id", "", type=ConfigType.STRING, description="Brewfather User ID") + await self.cbpi.config.add("brewfather_user_id", "", type=ConfigType.STRING, description="Brewfather User ID", source="craftbeerpi") except: logger.warning('Unable to update config') @@ -234,7 +238,7 @@ class ConfigUpdate(CBPiExtension): if bfapikey is None: logger.info("INIT Brewfather API Key") try: - await self.cbpi.config.add("brewfather_api_key", "", type=ConfigType.STRING, description="Brewfather API Key") + await self.cbpi.config.add("brewfather_api_key", "", type=ConfigType.STRING, description="Brewfather API Key", source="craftbeerpi") except: logger.warning('Unable to update config') @@ -243,7 +247,7 @@ class ConfigUpdate(CBPiExtension): if RecipeCreationPath is None: logger.info("INIT Recipe Creation Path") try: - await self.cbpi.config.add("RECIPE_CREATION_PATH", "upload", type=ConfigType.STRING, description="API path to creation plugin. Default: upload . CHANGE ONLY IF USING A RECIPE CREATION PLUGIN") + await self.cbpi.config.add("RECIPE_CREATION_PATH", "upload", type=ConfigType.STRING, description="API path to creation plugin. Default: upload . CHANGE ONLY IF USING A RECIPE CREATION PLUGIN", source="craftbeerpi") except: logger.warning('Unable to update config') @@ -274,6 +278,7 @@ class ConfigUpdate(CBPiExtension): logger.info("INIT CSV logfiles") try: await self.cbpi.config.add("CSVLOGFILES", "Yes", type=ConfigType.SELECT, description="Write sensor data to csv logfiles", + source="craftbeerpi", options= [{"label": "Yes", "value": "Yes"}, {"label": "No", "value": "No"}]) except: @@ -284,6 +289,7 @@ class ConfigUpdate(CBPiExtension): logger.info("INIT Influxdb") try: await self.cbpi.config.add("INFLUXDB", "No", type=ConfigType.SELECT, description="Write sensor data to influxdb", + source="craftbeerpi", options= [{"label": "Yes", "value": "Yes"}, {"label": "No", "value": "No"}]) except: @@ -293,7 +299,7 @@ class ConfigUpdate(CBPiExtension): if influxdbaddr is None: logger.info("INIT Influxdbaddr") try: - await self.cbpi.config.add("INFLUXDBADDR", "http://localhost:8086", type=ConfigType.STRING, description="URL Address of your influxdb server (If INFLUXDBCLOUD set to Yes use URL Address of your influxdb cloud server)") + await self.cbpi.config.add("INFLUXDBADDR", "http://localhost:8086", type=ConfigType.STRING, description="URL Address of your influxdb server (If INFLUXDBCLOUD set to Yes use URL Address of your influxdb cloud server)", source="craftbeerpi") except: logger.warning('Unable to update config') @@ -301,7 +307,7 @@ class ConfigUpdate(CBPiExtension): if influxdbname is None: logger.info("INIT Influxdbname") try: - await self.cbpi.config.add("INFLUXDBNAME", "cbpi4", type=ConfigType.STRING, description="Name of your influxdb database name (If INFLUXDBCLOUD set to Yes use bucket of your influxdb cloud database)") + await self.cbpi.config.add("INFLUXDBNAME", "cbpi4", type=ConfigType.STRING, description="Name of your influxdb database name (If INFLUXDBCLOUD set to Yes use bucket of your influxdb cloud database)", source="craftbeerpi") except: logger.warning('Unable to update config') @@ -309,7 +315,7 @@ class ConfigUpdate(CBPiExtension): if influxdbuser is None: logger.info("INIT Influxdbuser") try: - await self.cbpi.config.add("INFLUXDBUSER", " ", type=ConfigType.STRING, description="User name for your influxdb database (only if required)(If INFLUXDBCLOUD set to Yes use organisation of your influxdb cloud database)") + await self.cbpi.config.add("INFLUXDBUSER", " ", type=ConfigType.STRING, description="User name for your influxdb database (only if required)(If INFLUXDBCLOUD set to Yes use organisation of your influxdb cloud database)", source="craftbeerpi") except: logger.warning('Unable to update config') @@ -317,7 +323,7 @@ class ConfigUpdate(CBPiExtension): if influxdbpwd is None: logger.info("INIT Influxdbpwd") try: - await self.cbpi.config.add("INFLUXDBPWD", " ", type=ConfigType.STRING, description="Password for your influxdb database (only if required)(If INFLUXDBCLOUD set to Yes use token of your influxdb cloud database)") + await self.cbpi.config.add("INFLUXDBPWD", " ", type=ConfigType.STRING, description="Password for your influxdb database (only if required)(If INFLUXDBCLOUD set to Yes use token of your influxdb cloud database)", source="craftbeerpi") except: logger.warning('Unable to update config') @@ -326,6 +332,7 @@ class ConfigUpdate(CBPiExtension): logger.info("INIT influxdbcloud") try: await self.cbpi.config.add("INFLUXDBCLOUD", "No", type=ConfigType.SELECT, description="Write sensor data to influxdb cloud (INFLUXDB must set to Yes)", + source="craftbeerpi", options= [{"label": "Yes", "value": "Yes"}, {"label": "No", "value": "No"}]) except: @@ -335,7 +342,7 @@ class ConfigUpdate(CBPiExtension): if influxdbmeasurement is None: logger.info("INIT Influxdb measurementname") try: - await self.cbpi.config.add("INFLUXDBMEASUREMENT", "measurement", type=ConfigType.STRING, description="Name of the measurement in your INFLUXDB database (default: measurement)") + await self.cbpi.config.add("INFLUXDBMEASUREMENT", "measurement", type=ConfigType.STRING, description="Name of the measurement in your INFLUXDB database (default: measurement)", source="craftbeerpi") except: logger.warning('Unable to update config') @@ -343,6 +350,7 @@ class ConfigUpdate(CBPiExtension): logger.info("INIT MQTT update frequency for Kettles and Fermenters") try: await self.cbpi.config.add("MQTTUpdate", 0, type=ConfigType.SELECT, description="Forced MQTT Update frequency in s for Kettle and Fermenter (no changes in payload required). Restart required after change", + source="craftbeerpi", options= [{"label": "30", "value": 30}, {"label": "60", "value": 60}, {"label": "120", "value": 120}, @@ -356,6 +364,7 @@ class ConfigUpdate(CBPiExtension): logger.info("INIT PRESSURE_UNIT") try: await self.cbpi.config.add("PRESSURE_UNIT", "kPa", type=ConfigType.SELECT, description="Set unit for pressure", + source="craftbeerpi", options= [{"label": "kPa", "value": "kPa"}, {"label": "PSI", "value": "PSI"}]) except: @@ -365,7 +374,7 @@ class ConfigUpdate(CBPiExtension): if SENSOR_LOG_BACKUP_COUNT is None: logger.info("INIT SENSOR_LOG_BACKUP_COUNT") try: - await self.cbpi.config.add("SENSOR_LOG_BACKUP_COUNT", 3, type=ConfigType.NUMBER, description="Max. number of backup logs") + await self.cbpi.config.add("SENSOR_LOG_BACKUP_COUNT", 3, type=ConfigType.NUMBER, description="Max. number of backup logs", source="craftbeerpi") except: logger.warning('Unable to update database') @@ -373,7 +382,7 @@ class ConfigUpdate(CBPiExtension): if SENSOR_LOG_MAX_BYTES is None: logger.info("Init maximum size of sensor logfiles") try: - await self.cbpi.config.add("SENSOR_LOG_MAX_BYTES", 100000, type=ConfigType.NUMBER, description="Max. number of bytes in sensor logs") + await self.cbpi.config.add("SENSOR_LOG_MAX_BYTES", 100000, type=ConfigType.NUMBER, description="Max. number of bytes in sensor logs", source="craftbeerpi") except: logger.warning('Unable to update database') @@ -382,6 +391,7 @@ class ConfigUpdate(CBPiExtension): logger.info("INIT slow_pipe_animation") try: await self.cbpi.config.add("slow_pipe_animation", "Yes", type=ConfigType.SELECT, description="Slow down dashboard pipe animation taking up close to 100% of the CPU's capacity", + source="craftbeerpi", options= [{"label": "Yes", "value": "Yes"}, {"label": "No", "value": "No"}]) except: @@ -392,6 +402,7 @@ class ConfigUpdate(CBPiExtension): logger.info("INIT NOTIFY_ON_ERROR") try: await self.cbpi.config.add("NOTIFY_ON_ERROR", "No", type=ConfigType.SELECT, description="Send Notification on Logging Error", + source="craftbeerpi", options= [{"label": "Yes", "value": "Yes"}, {"label": "No", "value": "No"}]) except: @@ -402,6 +413,7 @@ class ConfigUpdate(CBPiExtension): logger.info("INIT PLAY_BUZZER") try: await self.cbpi.config.add("PLAY_BUZZER", "No", type=ConfigType.SELECT, description="Play buzzer sound in Web interface on Notifications", + source="craftbeerpi", options= [{"label": "Yes", "value": "Yes"}, {"label": "No", "value": "No"}]) except: @@ -411,10 +423,11 @@ class ConfigUpdate(CBPiExtension): logging.info("INIT BoilAutoTimer") try: await self.cbpi.config.add('BoilAutoTimer', 'No', type=ConfigType.SELECT, - description='Start Boil timer automatically if Temp does not change for 5 Minutes and is above 95C/203F', + description='Start Boil timer automatically if Temp does not change for 5 Minutes and is above 95C/203F', + source="steps", options= [{"label": "Yes", "value": "Yes"}, - {"label": "No", "value": "No"}], - source="steps") + {"label": "No", "value": "No"}]) + BoilAutoTimer = self.cbpi.config.get("BoilAutoTimer", "No") except: logging.warning('Unable to update database') @@ -422,9 +435,10 @@ class ConfigUpdate(CBPiExtension): if CONFIG_STATUS is None or CONFIG_STATUS != self.version: await self.cbpi.config.add('BoilAutoTimer', BoilAutoTimer, type=ConfigType.SELECT, description='Start Boil timer automatically if Temp does not change for 5 Minutes and is above 95C/203F', + source="steps", options=[{"label": "Yes", "value": "Yes"}, - {"label": "No", "value": "No"}], - source="steps") + {"label": "No", "value": "No"}]) + ## Check if influxdbname is in config diff --git a/cbpi/http_endpoints/http_config.py b/cbpi/http_endpoints/http_config.py index 8ba88f0..8efd20f 100644 --- a/cbpi/http_endpoints/http_config.py +++ b/cbpi/http_endpoints/http_config.py @@ -104,7 +104,20 @@ class ConfigHttpEndpoints: await self.controller.remove(name=name) return web.Response(status=200) - @request_mapping(path="/obsolete", auth_required=False) + @request_mapping(path="/getobsolete", auth_required=False) + async def http_get_obsolete(self, request) -> web.Response: + """ + --- + description: Get obsolete config parameters + tags: + - Config + responses: + "List of Obsolete Parameters": + description: successful operation + """ + return web.json_response(await self.controller.obsolete(False), dumps=json_dumps) + + @request_mapping(path="/removeobsolete", auth_required=False) async def http_remove_obsolete(self, request) -> web.Response: """ --- @@ -115,4 +128,5 @@ class ConfigHttpEndpoints: "200": description: successful operation """ - return web.json_response(await self.controller.remove_obsolete(), dumps=json_dumps) \ No newline at end of file + await self.controller.obsolete(True) + return web.Response(status=200) \ No newline at end of file diff --git a/tests/cbpi-test-config/config.json b/tests/cbpi-test-config/config.json index 8fef776..da7fab4 100644 --- a/tests/cbpi-test-config/config.json +++ b/tests/cbpi-test-config/config.json @@ -3,6 +3,7 @@ "description": "Author", "name": "AUTHOR", "options": null, + "source": "craftbeerpi", "type": "string", "value": "John Doe" }, @@ -19,6 +20,7 @@ "value": "No" } ], + "source": "steps", "type": "select", "value": "Yes" }, @@ -35,6 +37,7 @@ "value": "No" } ], + "source": "steps", "type": "select", "value": "Yes" }, @@ -42,6 +45,7 @@ "description": "Brewery Name", "name": "BREWERY_NAME", "options": null, + "source": "craftbeerpi", "type": "string", "value": "Some New Brewery Name" }, @@ -58,6 +62,7 @@ "value": "No" } ], + "source": "steps", "type": "select", "value": "No" }, @@ -65,9 +70,18 @@ "description": "Define Kettle that is used for Boil, Whirlpool and Cooldown. If not selected, MASH_TUN will be used", "name": "BoilKettle", "options": null, + "source": "steps", "type": "kettle", "value": "" }, + "CONFIG_STATUS": { + "description": "Status of the config file. Internal use for maintenance", + "name": "CONFIG_STATUS", + "options": null, + "source": "hidden", + "type": "string", + "value": "4.1.8.a11" + }, "CSVLOGFILES": { "description": "Write sensor data to csv logfiles", "name": "CSVLOGFILES", @@ -81,6 +95,7 @@ "value": "No" } ], + "source": "craftbeerpi", "type": "select", "value": "Yes" }, @@ -97,6 +112,7 @@ "value": "No" } ], + "source": "craftbeerpi", "type": "select", "value": "No" }, @@ -104,6 +120,7 @@ "description": "IP Address of your influxdb server (If INFLUXDBCLOUD set to Yes use URL Address of your influxdb cloud server)", "name": "INFLUXDBADDR", "options": null, + "source": "craftbeerpi", "type": "string", "value": "localhost" }, @@ -120,6 +137,7 @@ "value": "No" } ], + "source": "craftbeerpi", "type": "select", "value": "No" }, @@ -127,6 +145,7 @@ "description": "Name of the measurement in your INFLUXDB database (default: measurement)", "name": "INFLUXDBMEASUREMENT", "options": null, + "source": "craftbeerpi", "type": "string", "value": "measurement" }, @@ -134,6 +153,7 @@ "description": "Name of your influxdb database name (If INFLUXDBCLOUD set to Yes use bucket of your influxdb cloud database)", "name": "INFLUXDBNAME", "options": null, + "source": "craftbeerpi", "type": "string", "value": "cbpi4" }, @@ -141,6 +161,7 @@ "description": "Port of your influxdb server", "name": "INFLUXDBPORT", "options": null, + "source": "craftbeerpi", "type": "string", "value": "8086" }, @@ -148,6 +169,7 @@ "description": "Password for your influxdb database (only if required)(If INFLUXDBCLOUD set to Yes use token of your influxdb cloud database)", "name": "INFLUXDBPWD", "options": null, + "source": "craftbeerpi", "type": "string", "value": " " }, @@ -155,6 +177,7 @@ "description": "User name for your influxdb database (only if required)(If INFLUXDBCLOUD set to Yes use organisation of your influxdb cloud database)", "name": "INFLUXDBUSER", "options": null, + "source": "craftbeerpi", "type": "string", "value": " " }, @@ -162,6 +185,7 @@ "description": "Default Mash Tun", "name": "MASH_TUN", "options": null, + "source": "steps", "type": "kettle", "value": "" }, @@ -190,6 +214,7 @@ "value": 0 } ], + "source": "craftbeerpi", "type": "select", "value": 0 }, @@ -206,6 +231,24 @@ "value": "No" } ], + "source": "craftbeerpi", + "type": "select", + "value": "No" + }, + "PLAY_BUZZER": { + "description": "Play buzzer sound in Web interface on Notifications", + "name": "PLAY_BUZZER", + "options": [ + { + "label": "Yes", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ], + "source": "craftbeerpi", "type": "select", "value": "No" }, @@ -222,6 +265,7 @@ "value": "PSI" } ], + "source": "craftbeerpi", "type": "select", "value": "kPa" }, @@ -229,6 +273,7 @@ "description": "API path to creation plugin. Default: upload . CHANGE ONLY IF USING A RECIPE CREATION PLUGIN", "name": "RECIPE_CREATION_PATH", "options": null, + "source": "craftbeerpi", "type": "string", "value": "upload" }, @@ -236,6 +281,7 @@ "description": "Max. number of backup logs", "name": "SENSOR_LOG_BACKUP_COUNT", "options": null, + "source": "craftbeerpi", "type": "number", "value": 3 }, @@ -243,6 +289,7 @@ "description": "Max. number of bytes in sensor logs", "name": "SENSOR_LOG_MAX_BYTES", "options": null, + "source": "craftbeerpi", "type": "number", "value": 100000 }, @@ -259,6 +306,7 @@ "value": "F" } ], + "source": "craftbeerpi", "type": "select", "value": "C" }, @@ -266,6 +314,7 @@ "description": "Brewfather API Key", "name": "brewfather_api_key", "options": null, + "source": "craftbeerpi", "type": "string", "value": "" }, @@ -273,6 +322,7 @@ "description": "Brewfather User ID", "name": "brewfather_user_id", "options": null, + "source": "craftbeerpi", "type": "string", "value": "" }, @@ -280,6 +330,7 @@ "description": "Number of current Dashboard", "name": "current_dashboard_number", "options": null, + "source": "hidden", "type": "number", "value": 1 }, @@ -328,6 +379,7 @@ "value": 10 } ], + "source": "craftbeerpi", "type": "select", "value": 4 }, @@ -344,6 +396,7 @@ "value": "No" } ], + "source": "craftbeerpi", "type": "select", "value": "Yes" }, @@ -351,6 +404,7 @@ "description": "Boil step type", "name": "steps_boil", "options": null, + "source": "steps", "type": "step", "value": "BoilStep" }, @@ -358,6 +412,7 @@ "description": "Default Boil Temperature for Recipe Creation", "name": "steps_boil_temp", "options": null, + "source": "steps", "type": "number", "value": "99" }, @@ -365,6 +420,7 @@ "description": "Cooldown step type", "name": "steps_cooldown", "options": null, + "source": "steps", "type": "step", "value": "CooldownStep" }, @@ -372,6 +428,7 @@ "description": "Actor to trigger cooldown water on and off (default: None)", "name": "steps_cooldown_actor", "options": null, + "source": "steps", "type": "actor", "value": "" }, @@ -379,6 +436,7 @@ "description": "Alternative Sensor to monitor temperature durring cooldown (if not selected, Kettle Sensor will be used)", "name": "steps_cooldown_sensor", "options": null, + "source": "steps", "type": "sensor", "value": "" }, @@ -386,6 +444,7 @@ "description": "Cooldown temp will send notification when this temeprature is reached", "name": "steps_cooldown_temp", "options": null, + "source": "steps", "type": "number", "value": 35 }, @@ -393,6 +452,7 @@ "description": "Mash step type", "name": "steps_mash", "options": null, + "source": "steps", "type": "step", "value": "MashStep" }, @@ -400,6 +460,7 @@ "description": "MashIn step type", "name": "steps_mashin", "options": null, + "source": "steps", "type": "step", "value": "MashInStep" }, @@ -407,6 +468,7 @@ "description": "MashOut step type", "name": "steps_mashout", "options": null, + "source": "steps", "type": "step", "value": "NotificationStep" } diff --git a/tests/cbpi-test-config/dashboard/cbpi_dashboard_1.json b/tests/cbpi-test-config/dashboard/cbpi_dashboard_1.json index 92079a0..b737cf7 100644 --- a/tests/cbpi-test-config/dashboard/cbpi_dashboard_1.json +++ b/tests/cbpi-test-config/dashboard/cbpi_dashboard_1.json @@ -1,3 +1,7 @@ { - "elements": [] + "config": {}, + "dbid": 1, + "type": "Test", + "x": 0, + "y": 0 } \ No newline at end of file From 639efe72c496bda5836cee3ba133c721bbc6bf24 Mon Sep 17 00:00:00 2001 From: avollkopf <43980694+avollkopf@users.noreply.github.com> Date: Sun, 16 Apr 2023 17:48:19 +0200 Subject: [PATCH 18/20] added update parameter to list --- cbpi/__init__.py | 2 +- cbpi/controller/config_controller.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cbpi/__init__.py b/cbpi/__init__.py index 4d52643..9843a78 100644 --- a/cbpi/__init__.py +++ b/cbpi/__init__.py @@ -1,3 +1,3 @@ -__version__ = "4.1.8.a12" +__version__ = "4.1.8.a13" __codename__ = "Groundhog Day" diff --git a/cbpi/controller/config_controller.py b/cbpi/controller/config_controller.py index 16c7c02..d63685a 100644 --- a/cbpi/controller/config_controller.py +++ b/cbpi/controller/config_controller.py @@ -87,7 +87,7 @@ class ConfigController: if test == []: update=self.get(str(value.source)+'_update') if update: - logging.warning(update) + result[str(value.source)+'_update']={"value": update} if remove: await self.remove(str(value.source)+'_update') if remove: From 9f2f4c87c7b7063f7dca5f8abd961ee0d6dd591a Mon Sep 17 00:00:00 2001 From: avollkopf <43980694+avollkopf@users.noreply.github.com> Date: Sun, 16 Apr 2023 17:56:00 +0200 Subject: [PATCH 19/20] changed api get all config parameters --- cbpi/__init__.py | 2 +- cbpi/controller/config_controller.py | 1 - cbpi/http_endpoints/http_config.py | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/cbpi/__init__.py b/cbpi/__init__.py index 9843a78..273ff68 100644 --- a/cbpi/__init__.py +++ b/cbpi/__init__.py @@ -1,3 +1,3 @@ -__version__ = "4.1.8.a13" +__version__ = "4.1.8.a14" __codename__ = "Groundhog Day" diff --git a/cbpi/controller/config_controller.py b/cbpi/controller/config_controller.py index d63685a..d56fe50 100644 --- a/cbpi/controller/config_controller.py +++ b/cbpi/controller/config_controller.py @@ -31,7 +31,6 @@ class ConfigController: data = json.load(json_file) for key, value in data.items(): self.cache[key] = Config(name=value.get("name"), value=value.get("value"), description=value.get("description"), type=ConfigType(value.get("type", "string")), source=value.get("source", "craftbeerpi"), options=value.get("options", None)) - logging.error(self.cache) def get(self, name, default=None): self.logger.debug("GET CONFIG VALUE %s (default %s)" % (name, default)) diff --git a/cbpi/http_endpoints/http_config.py b/cbpi/http_endpoints/http_config.py index 8efd20f..d762c60 100644 --- a/cbpi/http_endpoints/http_config.py +++ b/cbpi/http_endpoints/http_config.py @@ -56,7 +56,7 @@ class ConfigHttpEndpoints: "200": description: successful operation """ - return web.json_response(self.controller.cache, dumps=json_dumps) + return web.json_response(self.controller.get_state(), dumps=json_dumps) @request_mapping(path="/{name}/", method="POST", auth_required=False) async def http_paramter(self, request) -> web.Response: From e483ef6287b134f37d7a379ab5bb5d8468a55fc4 Mon Sep 17 00:00:00 2001 From: avollkopf <43980694+avollkopf@users.noreply.github.com> Date: Fri, 21 Apr 2023 07:29:05 +0200 Subject: [PATCH 20/20] update influx parameter description and remove port parameter automatically --- cbpi/__init__.py | 2 +- cbpi/extension/ConfigUpdate/__init__.py | 37 ++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/cbpi/__init__.py b/cbpi/__init__.py index 273ff68..fbaef73 100644 --- a/cbpi/__init__.py +++ b/cbpi/__init__.py @@ -1,3 +1,3 @@ -__version__ = "4.1.8.a14" +__version__ = "4.1.8.a15" __codename__ = "Groundhog Day" diff --git a/cbpi/extension/ConfigUpdate/__init__.py b/cbpi/extension/ConfigUpdate/__init__.py index 56eefab..419e523 100644 --- a/cbpi/extension/ConfigUpdate/__init__.py +++ b/cbpi/extension/ConfigUpdate/__init__.py @@ -45,6 +45,7 @@ class ConfigUpdate(CBPiExtension): influxdbuser = self.cbpi.config.get("INFLUXDBUSER", None) influxdbpwd = self.cbpi.config.get("INFLUXDBPWD", None) influxdbcloud = self.cbpi.config.get("INFLUXDBCLOUD", None) + influxdbport = self.cbpi.config.get("INFLUXDBPORT", None) influxdbmeasurement = self.cbpi.config.get("INFLUXDBMEASUREMENT", None) mqttupdate = self.cbpi.config.get("MQTTUpdate", None) PRESSURE_UNIT = self.cbpi.config.get("PRESSURE_UNIT", None) @@ -295,13 +296,29 @@ class ConfigUpdate(CBPiExtension): except: logger.warning('Unable to update config') + + ## Check if influxdbport is in config and remove it as it is obsolete + if influxdbport is not None: + logger.warning("Remove obsolete Influxdbport config parameter") + try: + await self.cbpi.config.remove("INFLUXDBPORT") + except: + logger.warning('Unable to update config') + + ## Check if influxdbaddr is in config if influxdbaddr is None: logger.info("INIT Influxdbaddr") try: - await self.cbpi.config.add("INFLUXDBADDR", "http://localhost:8086", type=ConfigType.STRING, description="URL Address of your influxdb server (If INFLUXDBCLOUD set to Yes use URL Address of your influxdb cloud server)", source="craftbeerpi") + await self.cbpi.config.add("INFLUXDBADDR", "http://localhost:8086", type=ConfigType.STRING, description="URL Address of your influxdb server incl. http:// and port, e.g. http://localhost:8086 (If INFLUXDBCLOUD set to Yes use URL Address of your influxdb cloud server)", source="craftbeerpi") except: logger.warning('Unable to update config') + else: + if CONFIG_STATUS is None or CONFIG_STATUS != self.version: + try: + await self.cbpi.config.add("INFLUXDBADDR", influxdbaddr, type=ConfigType.STRING, description="URL Address of your influxdb server incl. http:// and port, e.g. http://localhost:8086 (If INFLUXDBCLOUD set to Yes use URL Address of your influxdb cloud server)", source="craftbeerpi") + except: + logger.warning('Unable to update config') ## Check if influxdbname is in config if influxdbname is None: @@ -310,6 +327,12 @@ class ConfigUpdate(CBPiExtension): await self.cbpi.config.add("INFLUXDBNAME", "cbpi4", type=ConfigType.STRING, description="Name of your influxdb database name (If INFLUXDBCLOUD set to Yes use bucket of your influxdb cloud database)", source="craftbeerpi") except: logger.warning('Unable to update config') + else: + if CONFIG_STATUS is None or CONFIG_STATUS != self.version: + try: + await self.cbpi.config.add("INFLUXDBNAME", influxdbname, type=ConfigType.STRING, description="Name of your influxdb database name (If INFLUXDBCLOUD set to Yes use bucket of your influxdb cloud database)", source="craftbeerpi") + except: + logger.warning('Unable to update config') ## Check if influxduser is in config if influxdbuser is None: @@ -318,6 +341,12 @@ class ConfigUpdate(CBPiExtension): await self.cbpi.config.add("INFLUXDBUSER", " ", type=ConfigType.STRING, description="User name for your influxdb database (only if required)(If INFLUXDBCLOUD set to Yes use organisation of your influxdb cloud database)", source="craftbeerpi") except: logger.warning('Unable to update config') + else: + if CONFIG_STATUS is None or CONFIG_STATUS != self.version: + try: + await self.cbpi.config.add("INFLUXDBUSER", influxdbuser, type=ConfigType.STRING, description="User Name for your influxdb database (only if required)(If INFLUXDBCLOUD set to Yes use organisation of your influxdb cloud database)", source="craftbeerpi") + except: + logger.warning('Unable to update config') ## Check if influxdpwd is in config if influxdbpwd is None: @@ -326,6 +355,12 @@ class ConfigUpdate(CBPiExtension): await self.cbpi.config.add("INFLUXDBPWD", " ", type=ConfigType.STRING, description="Password for your influxdb database (only if required)(If INFLUXDBCLOUD set to Yes use token of your influxdb cloud database)", source="craftbeerpi") except: logger.warning('Unable to update config') + else: + if CONFIG_STATUS is None or CONFIG_STATUS != self.version: + try: + await self.cbpi.config.add("INFLUXDBPWD", influxdbpwd, type=ConfigType.STRING, description="Password for your influxdb database (only if required)(If INFLUXDBCLOUD set to Yes use token of your influxdb cloud database)", source="craftbeerpi") + except: + logger.warning('Unable to update config') ## Check if influxdb cloud is on config if influxdbcloud is None: