From 590b60fefb6eca38fc07fdb59be198b196868923 Mon Sep 17 00:00:00 2001 From: Dan Welch Date: Wed, 6 Dec 2023 11:52:22 -0700 Subject: [PATCH 1/2] Allow 'configure' to import yaml settings nested deepr than 2 levels Resolves meshtastic/python#466 --- meshtastic/__main__.py | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 1d0c2480..88304da2 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -128,25 +128,45 @@ def getPref(node, comp_name): def splitCompoundName(comp_name): """Split compound (dot separated) preference name into parts""" - name = comp_name.split(".", 1) - if len(name) != 2: + name = comp_name.split(".") + if len(name) < 2: name[0] = comp_name name.append(comp_name) return name +def traverseConfig(config_root, config, interface_config): + snake_name = meshtastic.util.camel_to_snake(config_root) + for pref in config: + pref_name = f"{snake_name}.{pref}" + if isinstance(config[pref], dict): + traverseConfig(pref_name, config[pref], interface_config) + else: + setPref( + interface_config, + pref_name, + str(config[pref]) + ) + + return True def setPref(config, comp_name, valStr): """Set a channel or preferences value""" name = splitCompoundName(comp_name) - snake_name = meshtastic.util.camel_to_snake(name[1]) - camel_name = meshtastic.util.snake_to_camel(name[1]) + snake_name = meshtastic.util.camel_to_snake(name[-1]) + camel_name = meshtastic.util.snake_to_camel(name[-1]) logging.debug(f"snake_name:{snake_name}") logging.debug(f"camel_name:{camel_name}") objDesc = config.DESCRIPTOR + config_part = config config_type = objDesc.fields_by_name.get(name[0]) + if config_type and config_type.message_type is not None: + for name_part in name[1:-1]: + part_snake_name = meshtastic.util.camel_to_snake((name_part)) + config_part = getattr(config, config_type.name) + config_type = config_type.message_type.fields_by_name.get(part_snake_name) pref = False if config_type and config_type.message_type is not None: pref = config_type.message_type.fields_by_name.get(snake_name) @@ -193,13 +213,13 @@ def setPref(config, comp_name, valStr): if snake_name != "ignore_incoming": try: if config_type.message_type is not None: - config_values = getattr(config, config_type.name) + config_values = getattr(config_part, config_type.name) setattr(config_values, pref.name, val) else: - setattr(config, snake_name, val) + setattr(config_part, snake_name, val) except TypeError: # The setter didn't like our arg type guess try again as a string - config_values = getattr(config, config_type.name) + config_values = getattr(config_part, config_type.name) setattr(config_values, pref.name, valStr) else: if val == 0: @@ -559,12 +579,7 @@ def onConnected(interface): if "config" in configuration: localConfig = interface.getNode(args.dest).localConfig for section in configuration["config"]: - for pref in configuration["config"][section]: - setPref( - localConfig, - f"{meshtastic.util.camel_to_snake(section)}.{pref}", - str(configuration["config"][section][pref]), - ) + traverseConfig(section, configuration["config"][section], localConfig) interface.getNode(args.dest).writeConfig( meshtastic.util.camel_to_snake(section) ) From 03c1f08e452b9e296c2e7ad69535b30dd9010570 Mon Sep 17 00:00:00 2001 From: Dan Welch Date: Tue, 16 Apr 2024 14:46:35 -0600 Subject: [PATCH 2/2] Fix Lint Error - add docstring to traverseConfig function --- meshtastic/__main__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 88304da2..be22a768 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -135,6 +135,7 @@ def splitCompoundName(comp_name): return name def traverseConfig(config_root, config, interface_config): + """Iterate through current config level preferences and either traverse deeper if preference is a dict or set preference""" snake_name = meshtastic.util.camel_to_snake(config_root) for pref in config: pref_name = f"{snake_name}.{pref}"