config: correctly print byte and array types on get

When getting config values of type bytes or list (technically a protobuf
repeated container type), these were directly printed on the output.
However, the retrieved values could not be set by --set again, as the
format was different (e.g. python string representation of bytes vs.
base64 prefixed and encoded as expected by --set).

We fix this by adding a toStr utility function (similar to the fromStr)
function to convert byte types correctly to the base64 representation.
Further, we check if the type is repeated and apply this operation to
all values.
This commit is contained in:
Felix Moessbauer
2024-10-25 14:50:25 +02:00
committed by Felix Moessbauer
parent 1abb9fb213
commit 839bbbcad2
2 changed files with 16 additions and 3 deletions

View File

@@ -87,8 +87,12 @@ def checkChannel(interface: MeshInterface, channelIndex: int) -> bool:
def getPref(node, comp_name):
"""Get a channel or preferences value"""
def _printSetting(config_type, uni_name, pref_value):
def _printSetting(config_type, uni_name, pref_value, repeated):
"""Pretty print the setting"""
if repeated:
pref_value = [meshtastic.util.toStr(v) for v in pref_value]
else:
pref_value = meshtastic.util.toStr(pref_value)
print(f"{str(config_type.name)}.{uni_name}: {str(pref_value)}")
logging.debug(f"{str(config_type.name)}.{uni_name}: {str(pref_value)}")
@@ -131,10 +135,12 @@ def getPref(node, comp_name):
config_values = getattr(config, config_type.name)
if not wholeField:
pref_value = getattr(config_values, pref.name)
_printSetting(config_type, uni_name, pref_value)
repeated = pref.label == pref.LABEL_REPEATED
_printSetting(config_type, uni_name, pref_value, repeated)
else:
for field in config_values.ListFields():
_printSetting(config_type, field[0].name, field[1])
repeated = field[0].label == field[0].LABEL_REPEATED
_printSetting(config_type, field[0].name, field[1], repeated)
else:
# Always show whole field for remote node
node.requestConfig(config_type)

View File

@@ -100,6 +100,13 @@ def fromStr(valstr):
return val
def toStr(raw_value):
"""Convert a value to a string that can be used in a config file"""
if isinstance(raw_value, bytes):
return "base64:" + base64.b64encode(raw_value).decode("utf-8")
return str(raw_value)
def pskToString(psk: bytes):
"""Given an array of PSK bytes, decode them into a human readable (but privacy protecting) string"""
if len(psk) == 0: