From 27be73c7075dfc0b1dd707bacd1111a7b64ad618 Mon Sep 17 00:00:00 2001 From: flavor omission Date: Sun, 17 Mar 2024 23:48:30 -0400 Subject: [PATCH] feat:506 show all module settings Problem: Missing fields are omitted. Solution: This fix sets the flag `always_print_fields_with_no_presence` in the invocation of the protobuff method `MessageToJson` will display the missing fields. see: MessageToJson https://github.com/protocolbuffers/protobuf/blob/6b36eb633ccc9c585ed1ead117fca91702814027/python/google/protobuf/json_format.py#L82 see: issue #506 https://github.com/meshtastic/python/issues/506 --- meshtastic/mesh_interface.py | 5 +++-- meshtastic/node.py | 8 ++++---- meshtastic/tests/test_util.py | 9 +++++++++ meshtastic/util.py | 6 +++++- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index 5f5b56db..e227ed90 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -35,6 +35,7 @@ our_exit, remove_keys_from_dict, stripnl, + message_to_json, ) @@ -102,10 +103,10 @@ def showInfo(self, file=sys.stdout): # pylint: disable=W0613 owner = f"Owner: {self.getLongName()} ({self.getShortName()})" myinfo = "" if self.myInfo: - myinfo = f"\nMy info: {stripnl(MessageToJson(self.myInfo))}" + myinfo = f"\nMy info: {message_to_json(self.myInfo)}" metadata = "" if self.metadata: - metadata = f"\nMetadata: {stripnl(MessageToJson(self.metadata))}" + metadata = f"\nMetadata: {message_to_json(self.metadata)}" mesh = "\n\nNodes in mesh: " nodes = {} if self.nodes: diff --git a/meshtastic/node.py b/meshtastic/node.py index c5a57bdd..8121f3ce 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -15,6 +15,7 @@ our_exit, pskToString, stripnl, + message_to_json, ) @@ -47,8 +48,7 @@ def showChannels(self): if self.channels: logging.debug(f"self.channels:{self.channels}") for c in self.channels: - # print('c.settings.psk:', c.settings.psk) - cStr = stripnl(MessageToJson(c.settings)) + cStr = message_to_json(c.settings) # don't show disabled channels if channel_pb2.Channel.Role.Name(c.role) != "DISABLED": print( @@ -64,11 +64,11 @@ def showInfo(self): """Show human readable description of our node""" prefs = "" if self.localConfig: - prefs = stripnl(MessageToJson(self.localConfig)) + prefs = message_to_json(self.localConfig) print(f"Preferences: {prefs}\n") prefs = "" if self.moduleConfig: - prefs = stripnl(MessageToJson(self.moduleConfig)) + prefs = message_to_json(self.moduleConfig) print(f"Module preferences: {prefs}\n") self.showChannels() diff --git a/meshtastic/tests/test_util.py b/meshtastic/tests/test_util.py index df760d15..8241eda3 100644 --- a/meshtastic/tests/test_util.py +++ b/meshtastic/tests/test_util.py @@ -1,5 +1,6 @@ """Meshtastic unit tests for util.py""" +import json import logging import re from unittest.mock import patch @@ -7,6 +8,7 @@ import pytest from meshtastic.supported_device import SupportedDevice +from meshtastic.mesh_pb2 import MyNodeInfo from meshtastic.util import ( Timeout, active_ports_on_supported_devices, @@ -30,6 +32,7 @@ snake_to_camel, stripnl, support_info, + message_to_json, ) @@ -545,3 +548,9 @@ def test_active_ports_on_supported_devices_mac_duplicates_check(mock_platform, m } mock_platform.assert_called() mock_sp.assert_called() + +@pytest.mark.unit +def test_message_to_json_shows_all(): + actual = json.loads(message_to_json(MyNodeInfo())) + expected = { "myNodeNum": 0, "rebootCount": 0, "minAppVersion": 0 } + assert actual == expected diff --git a/meshtastic/util.py b/meshtastic/util.py index 7a5dd100..96c985e8 100644 --- a/meshtastic/util.py +++ b/meshtastic/util.py @@ -11,6 +11,7 @@ import time import traceback from queue import Queue +from google.protobuf.json_format import MessageToJson import pkg_resources import requests @@ -22,7 +23,6 @@ """Some devices such as a seger jlink we never want to accidentally open""" blacklistVids = dict.fromkeys([0x1366]) - def quoteBooleans(a_string): """Quote booleans given a string that contains ": true", replace with ": 'true'" (or false) @@ -605,3 +605,7 @@ def check_if_newer_version(): ) <= pkg_resources.parse_version(act_version): return None return pypi_version + +def message_to_json(message): + return stripnl(MessageToJson(message, always_print_fields_with_no_presence=True)) +