diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index fe25405..3900241 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -2,12 +2,12 @@ """ import collections +import json import logging import random import sys import threading import time -import json from datetime import datetime from typing import AnyStr @@ -61,6 +61,7 @@ class MeshInterface: self.noProto = noProto self.localNode = meshtastic.node.Node(self, -1) # We fixup nodenum later self.myInfo = None # We don't have device info yet + self.metadata = None # We don't have device metadata yet self.responseHandlers = {} # A map from request ID to the handler self.failure = ( None # If we've encountered a fatal exception it will be kept here @@ -102,6 +103,9 @@ class MeshInterface: myinfo = "" if self.myInfo: myinfo = f"\nMy info: {stripnl(MessageToJson(self.myInfo))}" + metadata = "" + if self.metadata: + metadata = f"\nMetadata: {stripnl(MessageToJson(self.metadata))}" mesh = "\n\nNodes in mesh: " nodes = {} if self.nodes: @@ -119,10 +123,10 @@ class MeshInterface: n2["user"]["macaddr"] = addr # use id as dictionary key for correct json format in list of nodes - nodeid = n2['user']['id'] - n2['user'].pop('id') + nodeid = n2["user"]["id"] + n2["user"].pop("id") nodes[nodeid] = n2 - infos = owner + myinfo + mesh + json.dumps(nodes) + infos = owner + myinfo + metadata + mesh + json.dumps(nodes) print(infos) return infos @@ -703,6 +707,10 @@ class MeshInterface: self.isConnected.set() # let waitConnected return this exception self.close() + elif fromRadio.HasField("metadata"): + self.metadata = fromRadio.metadata + logging.debug(f"Received device metadata: {stripnl(fromRadio.metadata)}") + elif fromRadio.HasField("node_info"): node = asDict["nodeInfo"] try: @@ -788,7 +796,9 @@ class MeshInterface: fromRadio.moduleConfig.remote_hardware ) elif fromRadio.moduleConfig.HasField("neighbor_info"): - self.localNode.moduleConfig.neighbor_info.CopyFrom(fromRadio.moduleConfig.neighbor_info) + self.localNode.moduleConfig.neighbor_info.CopyFrom( + fromRadio.moduleConfig.neighbor_info + ) else: logging.debug("Unexpected FromRadio payload") diff --git a/meshtastic/node.py b/meshtastic/node.py index 2b539c0..2626009 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -50,7 +50,7 @@ class Node: # print('c.settings.psk:', c.settings.psk) cStr = stripnl(MessageToJson(c.settings)) # don't show disabled channels - if channel_pb2.Channel.Role.Name(c.role)!="DISABLED": + if channel_pb2.Channel.Role.Name(c.role) != "DISABLED": print( f" {channel_pb2.Channel.Role.Name(c.role)} psk={pskToString(c.settings.psk)} {cStr}" ) @@ -189,9 +189,7 @@ class Node: self.moduleConfig.remote_hardware ) elif config_name == "neighbor_info": - p.set_module_config.neighbor_info.CopyFrom( - self.moduleConfig.neighbor_info - ) + p.set_module_config.neighbor_info.CopyFrom(self.moduleConfig.neighbor_info) else: our_exit(f"Error: No valid config with name {config_name}") @@ -237,7 +235,7 @@ class Node: self._fixupChannels() # expand back to 8 channels index = channelIndex - while index < self.iface.myInfo.max_channels: + while index < 8: self.writeChannel(index, adminIndex=adminIndex) index += 1 @@ -629,7 +627,7 @@ class Node: # Add extra disabled channels as needed index = len(self.channels) - while index < self.iface.myInfo.max_channels: + while index < 8: ch = channel_pb2.Channel() ch.role = channel_pb2.Channel.Role.DISABLED ch.index = index @@ -694,7 +692,7 @@ class Node: c.role == channel_pb2.Channel.Role.DISABLED ) and fastChannelDownload - if quitEarly or index >= self.iface.myInfo.max_channels - 1: + if quitEarly or index >= 8 - 1: logging.debug("Finished downloading channels") self.channels = self.partialChannels diff --git a/setup.py b/setup.py index 3ed9981..29b9664 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ with open("README.md", "r") as fh: # This call to setup() does all the work setup( name="meshtastic", - version="2.1.14", + version="2.2.0", description="Python API & client shell for talking to Meshtastic devices", long_description=long_description, long_description_content_type="text/markdown",