From 9963587eb4792ffee351a518b20187ae9cff0438 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 27 Mar 2021 16:39:33 +0800 Subject: [PATCH] 1.2.16 --- docs/meshtastic/admin_pb2.html | 19 +++- docs/meshtastic/index.html | 183 ++++++++++++++++++++++----------- docs/meshtastic/mesh_pb2.html | 66 ++++++++---- docs/meshtastic/test.html | 22 ++-- docs/meshtastic/util.html | 4 +- meshtastic/__main__.py | 2 +- meshtastic/mesh_pb2.py | 43 ++++---- proto | 2 +- setup.py | 2 +- 9 files changed, 228 insertions(+), 115 deletions(-) diff --git a/docs/meshtastic/admin_pb2.html b/docs/meshtastic/admin_pb2.html index 1c2363f..67271a3 100644 --- a/docs/meshtastic/admin_pb2.html +++ b/docs/meshtastic/admin_pb2.html @@ -51,7 +51,7 @@ DESCRIPTOR = _descriptor.FileDescriptor( syntax='proto3', serialized_options=b'\n\023com.geeksville.meshB\013AdminProtosH\003', create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\x0b\x61\x64min.proto\x1a\nmesh.proto\x1a\x11radioconfig.proto\x1a\rchannel.proto\"\xe1\x02\n\x0c\x41\x64minMessage\x12!\n\tset_radio\x18\x01 \x01(\x0b\x32\x0c.RadioConfigH\x00\x12\x1a\n\tset_owner\x18\x02 \x01(\x0b\x32\x05.UserH\x00\x12\x1f\n\x0bset_channel\x18\x03 \x01(\x0b\x32\x08.ChannelH\x00\x12\x1b\n\x11get_radio_request\x18\x04 \x01(\x08H\x00\x12*\n\x12get_radio_response\x18\x05 \x01(\x0b\x32\x0c.RadioConfigH\x00\x12\x1d\n\x13get_channel_request\x18\x06 \x01(\rH\x00\x12(\n\x14get_channel_response\x18\x07 \x01(\x0b\x32\x08.ChannelH\x00\x12\x1d\n\x13\x63onfirm_set_channel\x18 \x01(\x08H\x00\x12\x1b\n\x11\x63onfirm_set_radio\x18! \x01(\x08H\x00\x12\x18\n\x0e\x65xit_simulator\x18\" \x01(\x08H\x00\x42\t\n\x07variantB$\n\x13\x63om.geeksville.meshB\x0b\x41\x64minProtosH\x03\x62\x06proto3' + serialized_pb=b'\n\x0b\x61\x64min.proto\x1a\nmesh.proto\x1a\x11radioconfig.proto\x1a\rchannel.proto\"\xfb\x02\n\x0c\x41\x64minMessage\x12!\n\tset_radio\x18\x01 \x01(\x0b\x32\x0c.RadioConfigH\x00\x12\x1a\n\tset_owner\x18\x02 \x01(\x0b\x32\x05.UserH\x00\x12\x1f\n\x0bset_channel\x18\x03 \x01(\x0b\x32\x08.ChannelH\x00\x12\x1b\n\x11get_radio_request\x18\x04 \x01(\x08H\x00\x12*\n\x12get_radio_response\x18\x05 \x01(\x0b\x32\x0c.RadioConfigH\x00\x12\x1d\n\x13get_channel_request\x18\x06 \x01(\rH\x00\x12(\n\x14get_channel_response\x18\x07 \x01(\x0b\x32\x08.ChannelH\x00\x12\x1d\n\x13\x63onfirm_set_channel\x18 \x01(\x08H\x00\x12\x1b\n\x11\x63onfirm_set_radio\x18! \x01(\x08H\x00\x12\x18\n\x0e\x65xit_simulator\x18\" \x01(\x08H\x00\x12\x18\n\x0ereboot_seconds\x18# \x01(\x05H\x00\x42\t\n\x07variantB$\n\x13\x63om.geeksville.meshB\x0b\x41\x64minProtosH\x03\x62\x06proto3' , dependencies=[mesh__pb2.DESCRIPTOR,radioconfig__pb2.DESCRIPTOR,channel__pb2.DESCRIPTOR,]) @@ -136,6 +136,13 @@ _ADMINMESSAGE = _descriptor.Descriptor( message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='reboot_seconds', full_name='AdminMessage.reboot_seconds', index=10, + number=35, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), ], extensions=[ ], @@ -154,7 +161,7 @@ _ADMINMESSAGE = _descriptor.Descriptor( fields=[]), ], serialized_start=62, - serialized_end=415, + serialized_end=441, ) _ADMINMESSAGE.fields_by_name['set_radio'].message_type = radioconfig__pb2._RADIOCONFIG @@ -192,6 +199,9 @@ _ADMINMESSAGE.fields_by_name['confirm_set_radio'].containing_oneof = _AD _ADMINMESSAGE.oneofs_by_name['variant'].fields.append( _ADMINMESSAGE.fields_by_name['exit_simulator']) _ADMINMESSAGE.fields_by_name['exit_simulator'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant'] +_ADMINMESSAGE.oneofs_by_name['variant'].fields.append( + _ADMINMESSAGE.fields_by_name['reboot_seconds']) +_ADMINMESSAGE.fields_by_name['reboot_seconds'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant'] DESCRIPTOR.message_types_by_name['AdminMessage'] = _ADMINMESSAGE _sym_db.RegisterFileDescriptor(DESCRIPTOR) @@ -264,6 +274,10 @@ DESCRIPTOR._options = None

Field AdminMessage.get_radio_response

+
var reboot_seconds
+
+

Field AdminMessage.reboot_seconds

+
var set_channel

Field AdminMessage.set_channel

@@ -305,6 +319,7 @@ DESCRIPTOR._options = None
  • get_channel_response
  • get_radio_request
  • get_radio_response
  • +
  • reboot_seconds
  • set_channel
  • set_owner
  • set_radio
  • diff --git a/docs/meshtastic/index.html b/docs/meshtastic/index.html index 02f1614..7bccb86 100644 --- a/docs/meshtastic/index.html +++ b/docs/meshtastic/index.html @@ -184,6 +184,7 @@ OUR_APP_VERSION = 20200 publishingThread = DeferredExecution("publishing") + class ResponseHandler(NamedTuple): """A pending response callback, waiting for a response to one of our messages""" # requestId: int - used only as a key @@ -214,7 +215,7 @@ def pskToString(psk: bytes): """Given an array of PSK bytes, decode them into a human readable (but privacy protecting) string""" if len(psk) == 0: return "unencrypted" - elif len(psk) == 1: + elif len(psk) == 1: b = psk[0] if b == 0: return "unencrypted" @@ -225,6 +226,7 @@ def pskToString(psk: bytes): else: return "secret" + class Node: """A model of a (local or remote) node in the mesh @@ -244,19 +246,20 @@ class Node: for c in self.channels: if c.role != channel_pb2.Channel.Role.DISABLED: cStr = stripnl(MessageToJson(c.settings)) - print(f" {channel_pb2.Channel.Role.Name(c.role)} psk={pskToString(c.settings.psk)} {cStr}") - publicURL = self.getURL(includeAll = False) - adminURL = self.getURL(includeAll = True) + print( + f" {channel_pb2.Channel.Role.Name(c.role)} psk={pskToString(c.settings.psk)} {cStr}") + publicURL = self.getURL(includeAll=False) + adminURL = self.getURL(includeAll=True) print(f"\nPrimary channel URL: {publicURL}") if adminURL != publicURL: print(f"Complete URL (includes all channels): {adminURL}") def showInfo(self): """Show human readable description of our node""" - print(f"Preferences: {stripnl(MessageToJson(self.radioConfig.preferences))}\n") + print( + f"Preferences: {stripnl(MessageToJson(self.radioConfig.preferences))}\n") self.showChannels() - def requestConfig(self): """ Send regular MeshPackets to ask for settings and channels @@ -282,7 +285,7 @@ class Node: self._sendAdmin(p) logging.debug("Wrote config") - def writeChannel(self, channelIndex, adminIndex = 0): + def writeChannel(self, channelIndex, adminIndex=0): """Write the current (edited) channel to the device""" p = admin_pb2.AdminMessage() @@ -302,7 +305,7 @@ class Node: adminIndex = self.iface.localNode._getAdminChannelIndex() self.channels.pop(channelIndex) - self._fixupChannels() # expand back to 8 channels + self._fixupChannels() # expand back to 8 channels index = channelIndex while index < self.iface.myInfo.max_channels: @@ -311,7 +314,8 @@ class Node: # if we are updating the local node, we might end up *moving* the admin channel index as we are writing if (self.iface.localNode == self) and index >= adminIndex: - adminIndex = 0 # We've now passed the old location for admin index (and writen it), so we can start finding it by name again + # We've now passed the old location for admin index (and writen it), so we can start finding it by name again + adminIndex = 0 def getChannelByName(self, name): """Try to find the named channel or return None""" @@ -419,7 +423,7 @@ class Node: """A closure to handle the response packet""" self.radioConfig = p["decoded"]["admin"]["raw"].get_radio_response logging.debug("Received radio config, now fetching channels...") - self._requestChannel(0) # now start fetching channels + self._requestChannel(0) # now start fetching channels return self._sendAdmin(p, wantResponse=True, @@ -432,14 +436,24 @@ class Node: p = admin_pb2.AdminMessage() p.exit_simulator = True - return self._sendAdmin(p) + return self._sendAdmin(p) + + def reboot(self, secs: int = 10): + """ + Tell the node to reboot + """ + p = admin_pb2.AdminMessage() + p.reboot_seconds = secs + logging.info(f"Telling node to reboot in {secs} seconds") + + return self._sendAdmin(p) def _fixupChannels(self): """Fixup indexes and add disabled channels as needed""" # Add extra disabled channels as needed for index, ch in enumerate(self.channels): - ch.index = index # fixup indexes + ch.index = index # fixup indexes self._fillChannels() @@ -493,11 +507,11 @@ class Node: onResponse=onResponse) def _sendAdmin(self, p: admin_pb2.AdminMessage, wantResponse=False, - onResponse=None, + onResponse=None, adminIndex=0): """Send an admin message to the specified node (or the local node if destNodeNum is zero)""" - if adminIndex == 0: # unless a special channel index was used, we want to use the admin index + if adminIndex == 0: # unless a special channel index was used, we want to use the admin index adminIndex = self.iface.localNode._getAdminChannelIndex() return self.iface.sendData(p, self.nodeNum, @@ -563,10 +577,11 @@ class MeshInterface: if nodeId == LOCAL_ADDR: return self.localNode else: - logging.info("Requesting configuration from remote node (this could take a while)") + logging.info( + "Requesting configuration from remote node (this could take a while)") n = Node(self, nodeId) n.requestConfig() - if not n.waitForConfig(maxsecs = 60): + if not n.waitForConfig(maxsecs=60): raise Exception("Timed out waiting for node config") return n @@ -693,7 +708,8 @@ class MeshInterface: nodeNum = BROADCAST_NUM elif destinationId == LOCAL_ADDR: nodeNum = self.myInfo.my_node_num - elif destinationId.startswith("!"): # A simple hex style nodeid - we can parse this without needing the DB + # A simple hex style nodeid - we can parse this without needing the DB + elif destinationId.startswith("!"): nodeNum = int(destinationId[1:], 16) else: node = self.nodes.get(destinationId) @@ -717,7 +733,8 @@ class MeshInterface: def waitForConfig(self): """Block until radio config is received. Returns True if config has been received.""" - success = waitForSet(self, attrs=('myInfo', 'nodes')) and self.localNode.waitForConfig() + success = waitForSet(self, attrs=('myInfo', 'nodes') + ) and self.localNode.waitForConfig() if not success: raise Exception("Timed out waiting for interface config") @@ -787,7 +804,7 @@ class MeshInterface: startConfig = mesh_pb2.ToRadio() self.configId = random.randint(0, 0xffffffff) - startConfig.want_config_id = self.configId + startConfig.want_config_id = self.configId self._sendToRadio(startConfig) def _sendDisconnect(self): @@ -856,7 +873,7 @@ class MeshInterface: if "user" in node: # Some nodes might not have user/ids assigned yet self.nodes[node["user"]["id"]] = node publishingThread.queueWork(lambda: pub.sendMessage("meshtastic.node.updated", - node=node, interface=self)) + node=node, interface=self)) elif fromRadio.config_complete_id == self.configId: # we ignore the config_complete_id, it is unneeded for our stream API fromRadio.config_complete_id logging.debug(f"Config complete ID {self.configId}") @@ -943,7 +960,7 @@ class MeshInterface: asDict["fromId"] = self._nodeNumToId(asDict["from"]) except Exception as ex: logging.warn(f"Not populating fromId {ex}") - try: + try: asDict["toId"] = self._nodeNumToId(asDict["to"]) except Exception as ex: logging.warn(f"Not populating toId {ex}") @@ -1040,7 +1057,7 @@ class BLEInterface(MeshInterface): self.device.char_write(TORADIO_UUID, b) def close(self): - MeshInterface.close(self) + MeshInterface.close(self) self.adapter.stop() def _readFromRadio(self): @@ -1051,6 +1068,7 @@ class BLEInterface(MeshInterface): if not wasEmpty: self._handleFromRadio(b) + class StreamInterface(MeshInterface): """Interface class for meshtastic devices over a stream link (serial, TCP, etc)""" @@ -1109,7 +1127,7 @@ class StreamInterface(MeshInterface): def _writeBytes(self, b): """Write an array of bytes to our stream and flush""" - if self.stream: # ignore writes when stream is closed + if self.stream: # ignore writes when stream is closed self.stream.write(b) self.stream.flush() @@ -1129,7 +1147,7 @@ class StreamInterface(MeshInterface): def close(self): """Close a connection to the device""" logging.debug("Closing stream") - MeshInterface.close(self) + MeshInterface.close(self) # pyserial cancel_read doesn't seem to work, therefore we ask the reader thread to close things for us self._wantExit = True if self._rxThread != threading.current_thread(): @@ -1268,7 +1286,7 @@ class TCPInterface(StreamInterface): def close(self): """Close a connection to the device""" logging.debug("Closing TCP stream") - StreamInterface.close(self) + StreamInterface.close(self) # Sometimes the socket read might be blocked in the reader thread. Therefore we force the shutdown by closing # the socket here self._wantExit = True @@ -1427,7 +1445,7 @@ protocols = { """Given an array of PSK bytes, decode them into a human readable (but privacy protecting) string""" if len(psk) == 0: return "unencrypted" - elif len(psk) == 1: + elif len(psk) == 1: b = psk[0] if b == 0: return "unencrypted" @@ -1502,7 +1520,7 @@ noProto – If True, don't try to run our protocol on the link - just be a d self.device.char_write(TORADIO_UUID, b) def close(self): - MeshInterface.close(self) + MeshInterface.close(self) self.adapter.stop() def _readFromRadio(self): @@ -1643,10 +1661,11 @@ noProto – If True, don't try to run our protocol on the link - just be a d if nodeId == LOCAL_ADDR: return self.localNode else: - logging.info("Requesting configuration from remote node (this could take a while)") + logging.info( + "Requesting configuration from remote node (this could take a while)") n = Node(self, nodeId) n.requestConfig() - if not n.waitForConfig(maxsecs = 60): + if not n.waitForConfig(maxsecs=60): raise Exception("Timed out waiting for node config") return n @@ -1773,7 +1792,8 @@ noProto – If True, don't try to run our protocol on the link - just be a d nodeNum = BROADCAST_NUM elif destinationId == LOCAL_ADDR: nodeNum = self.myInfo.my_node_num - elif destinationId.startswith("!"): # A simple hex style nodeid - we can parse this without needing the DB + # A simple hex style nodeid - we can parse this without needing the DB + elif destinationId.startswith("!"): nodeNum = int(destinationId[1:], 16) else: node = self.nodes.get(destinationId) @@ -1797,7 +1817,8 @@ noProto – If True, don't try to run our protocol on the link - just be a d def waitForConfig(self): """Block until radio config is received. Returns True if config has been received.""" - success = waitForSet(self, attrs=('myInfo', 'nodes')) and self.localNode.waitForConfig() + success = waitForSet(self, attrs=('myInfo', 'nodes') + ) and self.localNode.waitForConfig() if not success: raise Exception("Timed out waiting for interface config") @@ -1867,7 +1888,7 @@ noProto – If True, don't try to run our protocol on the link - just be a d startConfig = mesh_pb2.ToRadio() self.configId = random.randint(0, 0xffffffff) - startConfig.want_config_id = self.configId + startConfig.want_config_id = self.configId self._sendToRadio(startConfig) def _sendDisconnect(self): @@ -1936,7 +1957,7 @@ noProto – If True, don't try to run our protocol on the link - just be a d if "user" in node: # Some nodes might not have user/ids assigned yet self.nodes[node["user"]["id"]] = node publishingThread.queueWork(lambda: pub.sendMessage("meshtastic.node.updated", - node=node, interface=self)) + node=node, interface=self)) elif fromRadio.config_complete_id == self.configId: # we ignore the config_complete_id, it is unneeded for our stream API fromRadio.config_complete_id logging.debug(f"Config complete ID {self.configId}") @@ -2023,7 +2044,7 @@ noProto – If True, don't try to run our protocol on the link - just be a d asDict["fromId"] = self._nodeNumToId(asDict["from"]) except Exception as ex: logging.warn(f"Not populating fromId {ex}") - try: + try: asDict["toId"] = self._nodeNumToId(asDict["to"]) except Exception as ex: logging.warn(f"Not populating toId {ex}") @@ -2168,10 +2189,11 @@ noProto – If True, don't try to run our protocol on the link - just be a d if nodeId == LOCAL_ADDR: return self.localNode else: - logging.info("Requesting configuration from remote node (this could take a while)") + logging.info( + "Requesting configuration from remote node (this could take a while)") n = Node(self, nodeId) n.requestConfig() - if not n.waitForConfig(maxsecs = 60): + if not n.waitForConfig(maxsecs=60): raise Exception("Timed out waiting for node config") return n @@ -2366,7 +2388,8 @@ wantResponse – True if you want the service on the other side to send an a
    def waitForConfig(self):
         """Block until radio config is received. Returns True if config has been received."""
    -    success = waitForSet(self, attrs=('myInfo', 'nodes')) and self.localNode.waitForConfig()
    +    success = waitForSet(self, attrs=('myInfo', 'nodes')
    +                         ) and self.localNode.waitForConfig()
         if not success:
             raise Exception("Timed out waiting for interface config")
    @@ -2404,19 +2427,20 @@ wantResponse – True if you want the service on the other side to send an a for c in self.channels: if c.role != channel_pb2.Channel.Role.DISABLED: cStr = stripnl(MessageToJson(c.settings)) - print(f" {channel_pb2.Channel.Role.Name(c.role)} psk={pskToString(c.settings.psk)} {cStr}") - publicURL = self.getURL(includeAll = False) - adminURL = self.getURL(includeAll = True) + print( + f" {channel_pb2.Channel.Role.Name(c.role)} psk={pskToString(c.settings.psk)} {cStr}") + publicURL = self.getURL(includeAll=False) + adminURL = self.getURL(includeAll=True) print(f"\nPrimary channel URL: {publicURL}") if adminURL != publicURL: print(f"Complete URL (includes all channels): {adminURL}") def showInfo(self): """Show human readable description of our node""" - print(f"Preferences: {stripnl(MessageToJson(self.radioConfig.preferences))}\n") + print( + f"Preferences: {stripnl(MessageToJson(self.radioConfig.preferences))}\n") self.showChannels() - def requestConfig(self): """ Send regular MeshPackets to ask for settings and channels @@ -2442,7 +2466,7 @@ wantResponse – True if you want the service on the other side to send an a self._sendAdmin(p) logging.debug("Wrote config") - def writeChannel(self, channelIndex, adminIndex = 0): + def writeChannel(self, channelIndex, adminIndex=0): """Write the current (edited) channel to the device""" p = admin_pb2.AdminMessage() @@ -2462,7 +2486,7 @@ wantResponse – True if you want the service on the other side to send an a adminIndex = self.iface.localNode._getAdminChannelIndex() self.channels.pop(channelIndex) - self._fixupChannels() # expand back to 8 channels + self._fixupChannels() # expand back to 8 channels index = channelIndex while index < self.iface.myInfo.max_channels: @@ -2471,7 +2495,8 @@ wantResponse – True if you want the service on the other side to send an a # if we are updating the local node, we might end up *moving* the admin channel index as we are writing if (self.iface.localNode == self) and index >= adminIndex: - adminIndex = 0 # We've now passed the old location for admin index (and writen it), so we can start finding it by name again + # We've now passed the old location for admin index (and writen it), so we can start finding it by name again + adminIndex = 0 def getChannelByName(self, name): """Try to find the named channel or return None""" @@ -2579,7 +2604,7 @@ wantResponse – True if you want the service on the other side to send an a """A closure to handle the response packet""" self.radioConfig = p["decoded"]["admin"]["raw"].get_radio_response logging.debug("Received radio config, now fetching channels...") - self._requestChannel(0) # now start fetching channels + self._requestChannel(0) # now start fetching channels return self._sendAdmin(p, wantResponse=True, @@ -2592,14 +2617,24 @@ wantResponse – True if you want the service on the other side to send an a p = admin_pb2.AdminMessage() p.exit_simulator = True - return self._sendAdmin(p) + return self._sendAdmin(p) + + def reboot(self, secs: int = 10): + """ + Tell the node to reboot + """ + p = admin_pb2.AdminMessage() + p.reboot_seconds = secs + logging.info(f"Telling node to reboot in {secs} seconds") + + return self._sendAdmin(p) def _fixupChannels(self): """Fixup indexes and add disabled channels as needed""" # Add extra disabled channels as needed for index, ch in enumerate(self.channels): - ch.index = index # fixup indexes + ch.index = index # fixup indexes self._fillChannels() @@ -2653,11 +2688,11 @@ wantResponse – True if you want the service on the other side to send an a onResponse=onResponse) def _sendAdmin(self, p: admin_pb2.AdminMessage, wantResponse=False, - onResponse=None, + onResponse=None, adminIndex=0): """Send an admin message to the specified node (or the local node if destNodeNum is zero)""" - if adminIndex == 0: # unless a special channel index was used, we want to use the admin index + if adminIndex == 0: # unless a special channel index was used, we want to use the admin index adminIndex = self.iface.localNode._getAdminChannelIndex() return self.iface.sendData(p, self.nodeNum, @@ -2689,7 +2724,7 @@ wantResponse – True if you want the service on the other side to send an a adminIndex = self.iface.localNode._getAdminChannelIndex() self.channels.pop(channelIndex) - self._fixupChannels() # expand back to 8 channels + self._fixupChannels() # expand back to 8 channels index = channelIndex while index < self.iface.myInfo.max_channels: @@ -2698,7 +2733,8 @@ wantResponse – True if you want the service on the other side to send an a # if we are updating the local node, we might end up *moving* the admin channel index as we are writing if (self.iface.localNode == self) and index >= adminIndex: - adminIndex = 0 # We've now passed the old location for admin index (and writen it), so we can start finding it by name again + # We've now passed the old location for admin index (and writen it), so we can start finding it by name again + adminIndex = 0
    @@ -2717,7 +2753,7 @@ wantResponse – True if you want the service on the other side to send an a p = admin_pb2.AdminMessage() p.exit_simulator = True - return self._sendAdmin(p) + return self._sendAdmin(p)
    @@ -2776,6 +2812,26 @@ wantResponse – True if you want the service on the other side to send an a return f"https://www.meshtastic.org/d/#{s}".replace("=", "") +
    +def reboot(self, secs: int = 10) +
    +
    +

    Tell the node to reboot

    +
    + +Expand source code + +
    def reboot(self, secs: int = 10):
    +    """
    +    Tell the node to reboot
    +    """
    +    p = admin_pb2.AdminMessage()
    +    p.reboot_seconds = secs
    +    logging.info(f"Telling node to reboot in {secs} seconds")
    +
    +    return self._sendAdmin(p)
    +
    +
    def requestConfig(self)
    @@ -2892,9 +2948,10 @@ wantResponse – True if you want the service on the other side to send an a for c in self.channels: if c.role != channel_pb2.Channel.Role.DISABLED: cStr = stripnl(MessageToJson(c.settings)) - print(f" {channel_pb2.Channel.Role.Name(c.role)} psk={pskToString(c.settings.psk)} {cStr}") - publicURL = self.getURL(includeAll = False) - adminURL = self.getURL(includeAll = True) + print( + f" {channel_pb2.Channel.Role.Name(c.role)} psk={pskToString(c.settings.psk)} {cStr}") + publicURL = self.getURL(includeAll=False) + adminURL = self.getURL(includeAll=True) print(f"\nPrimary channel URL: {publicURL}") if adminURL != publicURL: print(f"Complete URL (includes all channels): {adminURL}") @@ -2911,7 +2968,8 @@ wantResponse – True if you want the service on the other side to send an a
    def showInfo(self):
         """Show human readable description of our node"""
    -    print(f"Preferences: {stripnl(MessageToJson(self.radioConfig.preferences))}\n")
    +    print(
    +        f"Preferences: {stripnl(MessageToJson(self.radioConfig.preferences))}\n")
         self.showChannels()
    @@ -2938,7 +2996,7 @@ wantResponse – True if you want the service on the other side to send an a Expand source code -
    def writeChannel(self, channelIndex, adminIndex = 0):
    +
    def writeChannel(self, channelIndex, adminIndex=0):
         """Write the current (edited) channel to the device"""
     
         p = admin_pb2.AdminMessage()
    @@ -3155,7 +3213,7 @@ debugOut {stream} – If a stream is provided, any debug serial output from
     
         def _writeBytes(self, b):
             """Write an array of bytes to our stream and flush"""
    -        if self.stream: # ignore writes when stream is closed
    +        if self.stream:  # ignore writes when stream is closed
                 self.stream.write(b)
                 self.stream.flush()
     
    @@ -3175,7 +3233,7 @@ debugOut {stream} – If a stream is provided, any debug serial output from
         def close(self):
             """Close a connection to the device"""
             logging.debug("Closing stream")
    -        MeshInterface.close(self)        
    +        MeshInterface.close(self)
             # pyserial cancel_read doesn't seem to work, therefore we ask the reader thread to close things for us
             self._wantExit = True
             if self._rxThread != threading.current_thread():
    @@ -3267,7 +3325,7 @@ debugOut {stream} – If a stream is provided, any debug serial output from
     
    def close(self):
         """Close a connection to the device"""
         logging.debug("Closing stream")
    -    MeshInterface.close(self)        
    +    MeshInterface.close(self)
         # pyserial cancel_read doesn't seem to work, therefore we ask the reader thread to close things for us
         self._wantExit = True
         if self._rxThread != threading.current_thread():
    @@ -3355,7 +3413,7 @@ hostname {string} – Hostname/IP address of the device to connect to

    getChannelByName
  • getDisabledChannel
  • getURL
  • +
  • reboot
  • requestConfig
  • setOwner
  • setURL
  • diff --git a/docs/meshtastic/mesh_pb2.html b/docs/meshtastic/mesh_pb2.html index a055d3e..6641657 100644 --- a/docs/meshtastic/mesh_pb2.html +++ b/docs/meshtastic/mesh_pb2.html @@ -50,7 +50,7 @@ DESCRIPTOR = _descriptor.FileDescriptor( syntax='proto3', serialized_options=b'\n\023com.geeksville.meshB\nMeshProtosH\003', create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\nmesh.proto\x1a\x0eportnums.proto\"v\n\x08Position\x12\x12\n\nlatitude_i\x18\x01 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x02 \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x03 \x01(\x05\x12\x15\n\rbattery_level\x18\x04 \x01(\x05\x12\x0c\n\x04time\x18\t \x01(\x07J\x04\x08\x07\x10\x08J\x04\x08\x08\x10\t\"l\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x0f\n\x07macaddr\x18\x04 \x01(\x0c\x12 \n\x08hw_model\x18\x06 \x01(\x0e\x32\x0e.HardwareModel\"\x1f\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x02 \x03(\x07\"\xc5\x02\n\x07Routing\x12(\n\rroute_request\x18\x01 \x01(\x0b\x32\x0f.RouteDiscoveryH\x00\x12&\n\x0broute_reply\x18\x02 \x01(\x0b\x32\x0f.RouteDiscoveryH\x00\x12&\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\x0e.Routing.ErrorH\x00\"\xb4\x01\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!B\t\n\x07variant\"{\n\x04\x44\x61ta\x12\x19\n\x07portnum\x18\x01 \x01(\x0e\x32\x08.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\"\xe0\x02\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12\x18\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x05.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\n \x01(\r\x12\x10\n\x08want_ack\x18\x0b \x01(\x08\x12&\n\x08priority\x18\x0c \x01(\x0e\x32\x14.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\r \x01(\x05\"[\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\x42\x10\n\x0epayloadVariant\"V\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x13\n\x04user\x18\x02 \x01(\x0b\x32\x05.User\x12\x1b\n\x08position\x18\x03 \x01(\x0b\x32\t.Position\x12\x0b\n\x03snr\x18\x07 \x01(\x02\"\xb5\x02\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x0f\n\x07has_gps\x18\x02 \x01(\x08\x12\x11\n\tnum_bands\x18\x03 \x01(\r\x12\x14\n\x0cmax_channels\x18\x0f \x01(\r\x12\x12\n\x06region\x18\x04 \x01(\tB\x02\x18\x01\x12\x1f\n\x13hw_model_deprecated\x18\x05 \x01(\tB\x02\x18\x01\x12\x18\n\x10\x66irmware_version\x18\x06 \x01(\t\x12&\n\nerror_code\x18\x07 \x01(\x0e\x32\x12.CriticalErrorCode\x12\x15\n\rerror_address\x18\x08 \x01(\r\x12\x13\n\x0b\x65rror_count\x18\t \x01(\r\x12\x1c\n\x14message_timeout_msec\x18\r \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0e \x01(\r\"\xb5\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x1f\n\x05level\x18\x04 \x01(\x0e\x32\x10.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"\xe9\x01\n\tFromRadio\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x1d\n\x06packet\x18\x0b \x01(\x0b\x32\x0b.MeshPacketH\x00\x12\x1e\n\x07my_info\x18\x03 \x01(\x0b\x32\x0b.MyNodeInfoH\x00\x12\x1e\n\tnode_info\x18\x04 \x01(\x0b\x32\t.NodeInfoH\x00\x12 \n\nlog_record\x18\x07 \x01(\x0b\x32\n.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x08 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\t \x01(\x08H\x00\x42\x10\n\x0epayloadVariantJ\x04\x08\x02\x10\x03J\x04\x08\x06\x10\x07\"\x82\x01\n\x07ToRadio\x12\x1d\n\x06packet\x18\x02 \x01(\x0b\x32\x0b.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x64 \x01(\rH\x00\x12\x14\n\ndisconnect\x18h \x01(\x08H\x00\x42\x10\n\x0epayloadVariantJ\x04\x08\x01\x10\x02J\x04\x08\x65\x10\x66J\x04\x08\x66\x10gJ\x04\x08g\x10h*\xfd\x01\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1p6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\n\n\x06HELTEC\x10\x05\x12\x0c\n\x08TBEAM0p7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1p3\x10\x08\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&*.\n\tConstants\x12\n\n\x06Unused\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xf0\x01*\xbd\x01\n\x11\x43riticalErrorCode\x12\x08\n\x04None\x10\x00\x12\x0e\n\nTxWatchdog\x10\x01\x12\x12\n\x0eSleepEnterWait\x10\x02\x12\x0b\n\x07NoRadio\x10\x03\x12\x0f\n\x0bUnspecified\x10\x04\x12\x13\n\x0fUBloxInitFailed\x10\x05\x12\x0c\n\x08NoAXP192\x10\x06\x12\x17\n\x13InvalidRadioSetting\x10\x07\x12\x12\n\x0eTransmitFailed\x10\x08\x12\x0c\n\x08\x42rownout\x10\tB#\n\x13\x63om.geeksville.meshB\nMeshProtosH\x03\x62\x06proto3' + serialized_pb=b'\n\nmesh.proto\x1a\x0eportnums.proto\"v\n\x08Position\x12\x12\n\nlatitude_i\x18\x01 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x02 \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x03 \x01(\x05\x12\x15\n\rbattery_level\x18\x04 \x01(\x05\x12\x0c\n\x04time\x18\t \x01(\x07J\x04\x08\x07\x10\x08J\x04\x08\x08\x10\t\"l\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x0f\n\x07macaddr\x18\x04 \x01(\x0c\x12 \n\x08hw_model\x18\x06 \x01(\x0e\x32\x0e.HardwareModel\"\x1f\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x02 \x03(\x07\"\xc5\x02\n\x07Routing\x12(\n\rroute_request\x18\x01 \x01(\x0b\x32\x0f.RouteDiscoveryH\x00\x12&\n\x0broute_reply\x18\x02 \x01(\x0b\x32\x0f.RouteDiscoveryH\x00\x12&\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\x0e.Routing.ErrorH\x00\"\xb4\x01\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!B\t\n\x07variant\"{\n\x04\x44\x61ta\x12\x19\n\x07portnum\x18\x01 \x01(\x0e\x32\x08.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\"\xe0\x02\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12\x18\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x05.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\n \x01(\r\x12\x10\n\x08want_ack\x18\x0b \x01(\x08\x12&\n\x08priority\x18\x0c \x01(\x0e\x32\x14.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\r \x01(\x05\"[\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\x42\x10\n\x0epayloadVariant\"j\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x13\n\x04user\x18\x02 \x01(\x0b\x32\x05.User\x12\x1b\n\x08position\x18\x03 \x01(\x0b\x32\t.Position\x12\x0b\n\x03snr\x18\x07 \x01(\x02\x12\x12\n\nlast_heard\x18\x04 \x01(\x07\"\xcb\x02\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x0f\n\x07has_gps\x18\x02 \x01(\x08\x12\x11\n\tnum_bands\x18\x03 \x01(\r\x12\x14\n\x0cmax_channels\x18\x0f \x01(\r\x12\x12\n\x06region\x18\x04 \x01(\tB\x02\x18\x01\x12\x1f\n\x13hw_model_deprecated\x18\x05 \x01(\tB\x02\x18\x01\x12\x18\n\x10\x66irmware_version\x18\x06 \x01(\t\x12&\n\nerror_code\x18\x07 \x01(\x0e\x32\x12.CriticalErrorCode\x12\x15\n\rerror_address\x18\x08 \x01(\r\x12\x13\n\x0b\x65rror_count\x18\t \x01(\r\x12\x14\n\x0creboot_count\x18\n \x01(\r\x12\x1c\n\x14message_timeout_msec\x18\r \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0e \x01(\r\"\xb5\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x1f\n\x05level\x18\x04 \x01(\x0e\x32\x10.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"\xe9\x01\n\tFromRadio\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x1d\n\x06packet\x18\x0b \x01(\x0b\x32\x0b.MeshPacketH\x00\x12\x1e\n\x07my_info\x18\x03 \x01(\x0b\x32\x0b.MyNodeInfoH\x00\x12\x1e\n\tnode_info\x18\x04 \x01(\x0b\x32\t.NodeInfoH\x00\x12 \n\nlog_record\x18\x07 \x01(\x0b\x32\n.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x08 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\t \x01(\x08H\x00\x42\x10\n\x0epayloadVariantJ\x04\x08\x02\x10\x03J\x04\x08\x06\x10\x07\"\x82\x01\n\x07ToRadio\x12\x1d\n\x06packet\x18\x02 \x01(\x0b\x32\x0b.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x64 \x01(\rH\x00\x12\x14\n\ndisconnect\x18h \x01(\x08H\x00\x42\x10\n\x0epayloadVariantJ\x04\x08\x01\x10\x02J\x04\x08\x65\x10\x66J\x04\x08\x66\x10gJ\x04\x08g\x10h*\xfd\x01\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1p6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\n\n\x06HELTEC\x10\x05\x12\x0c\n\x08TBEAM0p7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1p3\x10\x08\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&*.\n\tConstants\x12\n\n\x06Unused\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xf0\x01*\xbd\x01\n\x11\x43riticalErrorCode\x12\x08\n\x04None\x10\x00\x12\x0e\n\nTxWatchdog\x10\x01\x12\x12\n\x0eSleepEnterWait\x10\x02\x12\x0b\n\x07NoRadio\x10\x03\x12\x0f\n\x0bUnspecified\x10\x04\x12\x13\n\x0fUBloxInitFailed\x10\x05\x12\x0c\n\x08NoAXP192\x10\x06\x12\x17\n\x13InvalidRadioSetting\x10\x07\x12\x12\n\x0eTransmitFailed\x10\x08\x12\x0c\n\x08\x42rownout\x10\tB#\n\x13\x63om.geeksville.meshB\nMeshProtosH\x03\x62\x06proto3' , dependencies=[portnums__pb2.DESCRIPTOR,]) @@ -144,8 +144,8 @@ _HARDWAREMODEL = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=2055, - serialized_end=2308, + serialized_start=2097, + serialized_end=2350, ) _sym_db.RegisterEnumDescriptor(_HARDWAREMODEL) @@ -170,8 +170,8 @@ _CONSTANTS = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=2310, - serialized_end=2356, + serialized_start=2352, + serialized_end=2398, ) _sym_db.RegisterEnumDescriptor(_CONSTANTS) @@ -236,8 +236,8 @@ _CRITICALERRORCODE = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=2359, - serialized_end=2548, + serialized_start=2401, + serialized_end=2590, ) _sym_db.RegisterEnumDescriptor(_CRITICALERRORCODE) @@ -437,8 +437,8 @@ _LOGRECORD_LEVEL = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=1595, - serialized_end=1683, + serialized_start=1637, + serialized_end=1725, ) _sym_db.RegisterEnumDescriptor(_LOGRECORD_LEVEL) @@ -865,6 +865,13 @@ _NODEINFO = _descriptor.Descriptor( message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='last_heard', full_name='NodeInfo.last_heard', index=4, + number=4, type=7, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), ], extensions=[ ], @@ -878,7 +885,7 @@ _NODEINFO = _descriptor.Descriptor( oneofs=[ ], serialized_start=1101, - serialized_end=1187, + serialized_end=1207, ) @@ -961,14 +968,21 @@ _MYNODEINFO = _descriptor.Descriptor( is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='message_timeout_msec', full_name='MyNodeInfo.message_timeout_msec', index=10, + name='reboot_count', full_name='MyNodeInfo.reboot_count', index=10, + number=10, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='message_timeout_msec', full_name='MyNodeInfo.message_timeout_msec', index=11, number=13, type=13, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='min_app_version', full_name='MyNodeInfo.min_app_version', index=11, + name='min_app_version', full_name='MyNodeInfo.min_app_version', index=12, number=14, type=13, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, @@ -986,8 +1000,8 @@ _MYNODEINFO = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1190, - serialized_end=1499, + serialized_start=1210, + serialized_end=1541, ) @@ -1040,8 +1054,8 @@ _LOGRECORD = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1502, - serialized_end=1683, + serialized_start=1544, + serialized_end=1725, ) @@ -1119,8 +1133,8 @@ _FROMRADIO = _descriptor.Descriptor( create_key=_descriptor._internal_create_key, fields=[]), ], - serialized_start=1686, - serialized_end=1919, + serialized_start=1728, + serialized_end=1961, ) @@ -1170,8 +1184,8 @@ _TORADIO = _descriptor.Descriptor( create_key=_descriptor._internal_create_key, fields=[]), ], - serialized_start=1922, - serialized_end=2052, + serialized_start=1964, + serialized_end=2094, ) _USER.fields_by_name['hw_model'].enum_type = _HARDWAREMODEL @@ -1676,6 +1690,10 @@ _MYNODEINFO.fields_by_name['hw_model_deprecated']._options = None

    Field MyNodeInfo.num_bands

    +
    var reboot_count
    +
    +

    Field MyNodeInfo.reboot_count

    +
    var region

    Field MyNodeInfo.region

    @@ -1702,6 +1720,10 @@ _MYNODEINFO.fields_by_name['hw_model_deprecated']._options = None

    Instance variables

    +
    var last_heard
    +
    +

    Field NodeInfo.last_heard

    +
    var num

    Field NodeInfo.num

    @@ -2046,13 +2068,15 @@ _MYNODEINFO.fields_by_name['hw_model_deprecated']._options = None
  • min_app_version
  • my_node_num
  • num_bands
  • +
  • reboot_count
  • region
  • NodeInfo

    -
      +
      • DESCRIPTOR
      • +
      • last_heard
      • num
      • position
      • snr
      • diff --git a/docs/meshtastic/test.html b/docs/meshtastic/test.html index 9b68426..653ca1b 100644 --- a/docs/meshtastic/test.html +++ b/docs/meshtastic/test.html @@ -51,7 +51,7 @@ sendingInterface = None def onReceive(packet, interface): """Callback invoked when a packet arrives""" if sendingInterface == interface: - pass + pass # print("Ignoring sending interface") else: # print(f"From {interface.stream.port}: {packet}") @@ -93,7 +93,8 @@ def testSend(fromInterface, toInterface, isBroadcast=False, asBinary=False, want else: toNode = toInterface.myInfo.my_node_num - logging.debug(f"Sending test wantAck={wantAck} packet from {fromNode} to {toNode}") + logging.debug( + f"Sending test wantAck={wantAck} packet from {fromNode} to {toNode}") global sendingInterface sendingInterface = fromInterface if not asBinary: @@ -128,7 +129,7 @@ def runTests(numTests=50, wantAck=False, maxFailures=0): logging.info( f"Test succeeded {numSuccess} successes {numFail} failures so far") - #if numFail >= 3: + # if numFail >= 3: # for i in interfaces: # i.close() # return @@ -140,10 +141,12 @@ def runTests(numTests=50, wantAck=False, maxFailures=0): return numFail + def testThread(numTests=50): logging.info("Found devices, starting tests...") runTests(numTests, wantAck=True) - runTests(numTests, wantAck=False, maxFailures=5) # Allow a few dropped packets + # Allow a few dropped packets + runTests(numTests, wantAck=False, maxFailures=5) def onConnection(topic=pub.AUTO_TOPIC): @@ -180,6 +183,7 @@ def testAll(): for i in interfaces: i.close() + def testSimulator(): """ Assume that someone has launched meshtastic-native as a simulated node. @@ -254,7 +258,7 @@ def testSimulator():
        def onReceive(packet, interface):
             """Callback invoked when a packet arrives"""
             if sendingInterface == interface:
        -        pass 
        +        pass
                 # print("Ignoring sending interface")
             else:
                 # print(f"From {interface.stream.port}: {packet}")
        @@ -309,7 +313,7 @@ def testSimulator():
                     logging.info(
                         f"Test succeeded {numSuccess} successes {numFail} failures so far")
         
        -        #if numFail >= 3:
        +        # if numFail >= 3:
                 #    for i in interfaces:
                 #        i.close()
                 #    return
        @@ -409,7 +413,8 @@ toInterface {[type]} – [description]

        else: toNode = toInterface.myInfo.my_node_num - logging.debug(f"Sending test wantAck={wantAck} packet from {fromNode} to {toNode}") + logging.debug( + f"Sending test wantAck={wantAck} packet from {fromNode} to {toNode}") global sendingInterface sendingInterface = fromInterface if not asBinary: @@ -469,7 +474,8 @@ python3 -c 'from meshtastic.test import testSimulator; testSimulator()'

        def testThread(numTests=50): logging.info("Found devices, starting tests...") runTests(numTests, wantAck=True) - runTests(numTests, wantAck=False, maxFailures=5) # Allow a few dropped packets
        + # Allow a few dropped packets + runTests(numTests, wantAck=False, maxFailures=5)
  • diff --git a/docs/meshtastic/util.html b/docs/meshtastic/util.html index 5d83466..524e511 100644 --- a/docs/meshtastic/util.html +++ b/docs/meshtastic/util.html @@ -30,7 +30,9 @@ import serial import serial.tools.list_ports from queue import Queue -import threading, sys, logging +import threading +import sys +import logging """Some devices such as a seger jlink we never want to accidentally open""" blacklistVids = dict.fromkeys([0x1366]) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 160dcd5..5da17dc 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -152,7 +152,7 @@ def printNodes(nodes, myId): batt = formatFloat(node['position'].get("batteryLevel"), "{:.2f}", "%") snr = formatFloat(node.get("snr"), "{:.2f}", " dB") LH = getLH(node.get("lastHeard")) - timeAgo = getTimeAgo(node['position'].get("time")) + timeAgo = getTimeAgo(node.get("lastHeard")) tableData.append({"N": 0, "User": node['user']['longName'], "AKA": node['user']['shortName'], "ID": node['user']['id'], "Position": lat+", "+lon+", "+alt, diff --git a/meshtastic/mesh_pb2.py b/meshtastic/mesh_pb2.py index 66cb97a..58b588d 100644 --- a/meshtastic/mesh_pb2.py +++ b/meshtastic/mesh_pb2.py @@ -21,7 +21,7 @@ DESCRIPTOR = _descriptor.FileDescriptor( syntax='proto3', serialized_options=b'\n\023com.geeksville.meshB\nMeshProtosH\003', create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\nmesh.proto\x1a\x0eportnums.proto\"v\n\x08Position\x12\x12\n\nlatitude_i\x18\x01 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x02 \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x03 \x01(\x05\x12\x15\n\rbattery_level\x18\x04 \x01(\x05\x12\x0c\n\x04time\x18\t \x01(\x07J\x04\x08\x07\x10\x08J\x04\x08\x08\x10\t\"l\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x0f\n\x07macaddr\x18\x04 \x01(\x0c\x12 \n\x08hw_model\x18\x06 \x01(\x0e\x32\x0e.HardwareModel\"\x1f\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x02 \x03(\x07\"\xc5\x02\n\x07Routing\x12(\n\rroute_request\x18\x01 \x01(\x0b\x32\x0f.RouteDiscoveryH\x00\x12&\n\x0broute_reply\x18\x02 \x01(\x0b\x32\x0f.RouteDiscoveryH\x00\x12&\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\x0e.Routing.ErrorH\x00\"\xb4\x01\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!B\t\n\x07variant\"{\n\x04\x44\x61ta\x12\x19\n\x07portnum\x18\x01 \x01(\x0e\x32\x08.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\"\xe0\x02\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12\x18\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x05.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\n \x01(\r\x12\x10\n\x08want_ack\x18\x0b \x01(\x08\x12&\n\x08priority\x18\x0c \x01(\x0e\x32\x14.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\r \x01(\x05\"[\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\x42\x10\n\x0epayloadVariant\"j\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x13\n\x04user\x18\x02 \x01(\x0b\x32\x05.User\x12\x1b\n\x08position\x18\x03 \x01(\x0b\x32\t.Position\x12\x0b\n\x03snr\x18\x07 \x01(\x02\x12\x12\n\nlast_heard\x18\x04 \x01(\x07\"\xb5\x02\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x0f\n\x07has_gps\x18\x02 \x01(\x08\x12\x11\n\tnum_bands\x18\x03 \x01(\r\x12\x14\n\x0cmax_channels\x18\x0f \x01(\r\x12\x12\n\x06region\x18\x04 \x01(\tB\x02\x18\x01\x12\x1f\n\x13hw_model_deprecated\x18\x05 \x01(\tB\x02\x18\x01\x12\x18\n\x10\x66irmware_version\x18\x06 \x01(\t\x12&\n\nerror_code\x18\x07 \x01(\x0e\x32\x12.CriticalErrorCode\x12\x15\n\rerror_address\x18\x08 \x01(\r\x12\x13\n\x0b\x65rror_count\x18\t \x01(\r\x12\x1c\n\x14message_timeout_msec\x18\r \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0e \x01(\r\"\xb5\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x1f\n\x05level\x18\x04 \x01(\x0e\x32\x10.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"\xe9\x01\n\tFromRadio\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x1d\n\x06packet\x18\x0b \x01(\x0b\x32\x0b.MeshPacketH\x00\x12\x1e\n\x07my_info\x18\x03 \x01(\x0b\x32\x0b.MyNodeInfoH\x00\x12\x1e\n\tnode_info\x18\x04 \x01(\x0b\x32\t.NodeInfoH\x00\x12 \n\nlog_record\x18\x07 \x01(\x0b\x32\n.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x08 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\t \x01(\x08H\x00\x42\x10\n\x0epayloadVariantJ\x04\x08\x02\x10\x03J\x04\x08\x06\x10\x07\"\x82\x01\n\x07ToRadio\x12\x1d\n\x06packet\x18\x02 \x01(\x0b\x32\x0b.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x64 \x01(\rH\x00\x12\x14\n\ndisconnect\x18h \x01(\x08H\x00\x42\x10\n\x0epayloadVariantJ\x04\x08\x01\x10\x02J\x04\x08\x65\x10\x66J\x04\x08\x66\x10gJ\x04\x08g\x10h*\xfd\x01\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1p6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\n\n\x06HELTEC\x10\x05\x12\x0c\n\x08TBEAM0p7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1p3\x10\x08\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&*.\n\tConstants\x12\n\n\x06Unused\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xf0\x01*\xbd\x01\n\x11\x43riticalErrorCode\x12\x08\n\x04None\x10\x00\x12\x0e\n\nTxWatchdog\x10\x01\x12\x12\n\x0eSleepEnterWait\x10\x02\x12\x0b\n\x07NoRadio\x10\x03\x12\x0f\n\x0bUnspecified\x10\x04\x12\x13\n\x0fUBloxInitFailed\x10\x05\x12\x0c\n\x08NoAXP192\x10\x06\x12\x17\n\x13InvalidRadioSetting\x10\x07\x12\x12\n\x0eTransmitFailed\x10\x08\x12\x0c\n\x08\x42rownout\x10\tB#\n\x13\x63om.geeksville.meshB\nMeshProtosH\x03\x62\x06proto3' + serialized_pb=b'\n\nmesh.proto\x1a\x0eportnums.proto\"v\n\x08Position\x12\x12\n\nlatitude_i\x18\x01 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x02 \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x03 \x01(\x05\x12\x15\n\rbattery_level\x18\x04 \x01(\x05\x12\x0c\n\x04time\x18\t \x01(\x07J\x04\x08\x07\x10\x08J\x04\x08\x08\x10\t\"l\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x0f\n\x07macaddr\x18\x04 \x01(\x0c\x12 \n\x08hw_model\x18\x06 \x01(\x0e\x32\x0e.HardwareModel\"\x1f\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x02 \x03(\x07\"\xc5\x02\n\x07Routing\x12(\n\rroute_request\x18\x01 \x01(\x0b\x32\x0f.RouteDiscoveryH\x00\x12&\n\x0broute_reply\x18\x02 \x01(\x0b\x32\x0f.RouteDiscoveryH\x00\x12&\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\x0e.Routing.ErrorH\x00\"\xb4\x01\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!B\t\n\x07variant\"{\n\x04\x44\x61ta\x12\x19\n\x07portnum\x18\x01 \x01(\x0e\x32\x08.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\"\xe0\x02\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12\x18\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x05.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\n \x01(\r\x12\x10\n\x08want_ack\x18\x0b \x01(\x08\x12&\n\x08priority\x18\x0c \x01(\x0e\x32\x14.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\r \x01(\x05\"[\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\x42\x10\n\x0epayloadVariant\"j\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x13\n\x04user\x18\x02 \x01(\x0b\x32\x05.User\x12\x1b\n\x08position\x18\x03 \x01(\x0b\x32\t.Position\x12\x0b\n\x03snr\x18\x07 \x01(\x02\x12\x12\n\nlast_heard\x18\x04 \x01(\x07\"\xcb\x02\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x0f\n\x07has_gps\x18\x02 \x01(\x08\x12\x11\n\tnum_bands\x18\x03 \x01(\r\x12\x14\n\x0cmax_channels\x18\x0f \x01(\r\x12\x12\n\x06region\x18\x04 \x01(\tB\x02\x18\x01\x12\x1f\n\x13hw_model_deprecated\x18\x05 \x01(\tB\x02\x18\x01\x12\x18\n\x10\x66irmware_version\x18\x06 \x01(\t\x12&\n\nerror_code\x18\x07 \x01(\x0e\x32\x12.CriticalErrorCode\x12\x15\n\rerror_address\x18\x08 \x01(\r\x12\x13\n\x0b\x65rror_count\x18\t \x01(\r\x12\x14\n\x0creboot_count\x18\n \x01(\r\x12\x1c\n\x14message_timeout_msec\x18\r \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0e \x01(\r\"\xb5\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x1f\n\x05level\x18\x04 \x01(\x0e\x32\x10.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"\xe9\x01\n\tFromRadio\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x1d\n\x06packet\x18\x0b \x01(\x0b\x32\x0b.MeshPacketH\x00\x12\x1e\n\x07my_info\x18\x03 \x01(\x0b\x32\x0b.MyNodeInfoH\x00\x12\x1e\n\tnode_info\x18\x04 \x01(\x0b\x32\t.NodeInfoH\x00\x12 \n\nlog_record\x18\x07 \x01(\x0b\x32\n.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x08 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\t \x01(\x08H\x00\x42\x10\n\x0epayloadVariantJ\x04\x08\x02\x10\x03J\x04\x08\x06\x10\x07\"\x82\x01\n\x07ToRadio\x12\x1d\n\x06packet\x18\x02 \x01(\x0b\x32\x0b.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x64 \x01(\rH\x00\x12\x14\n\ndisconnect\x18h \x01(\x08H\x00\x42\x10\n\x0epayloadVariantJ\x04\x08\x01\x10\x02J\x04\x08\x65\x10\x66J\x04\x08\x66\x10gJ\x04\x08g\x10h*\xfd\x01\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1p6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\n\n\x06HELTEC\x10\x05\x12\x0c\n\x08TBEAM0p7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1p3\x10\x08\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&*.\n\tConstants\x12\n\n\x06Unused\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xf0\x01*\xbd\x01\n\x11\x43riticalErrorCode\x12\x08\n\x04None\x10\x00\x12\x0e\n\nTxWatchdog\x10\x01\x12\x12\n\x0eSleepEnterWait\x10\x02\x12\x0b\n\x07NoRadio\x10\x03\x12\x0f\n\x0bUnspecified\x10\x04\x12\x13\n\x0fUBloxInitFailed\x10\x05\x12\x0c\n\x08NoAXP192\x10\x06\x12\x17\n\x13InvalidRadioSetting\x10\x07\x12\x12\n\x0eTransmitFailed\x10\x08\x12\x0c\n\x08\x42rownout\x10\tB#\n\x13\x63om.geeksville.meshB\nMeshProtosH\x03\x62\x06proto3' , dependencies=[portnums__pb2.DESCRIPTOR,]) @@ -115,8 +115,8 @@ _HARDWAREMODEL = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=2075, - serialized_end=2328, + serialized_start=2097, + serialized_end=2350, ) _sym_db.RegisterEnumDescriptor(_HARDWAREMODEL) @@ -141,8 +141,8 @@ _CONSTANTS = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=2330, - serialized_end=2376, + serialized_start=2352, + serialized_end=2398, ) _sym_db.RegisterEnumDescriptor(_CONSTANTS) @@ -207,8 +207,8 @@ _CRITICALERRORCODE = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=2379, - serialized_end=2568, + serialized_start=2401, + serialized_end=2590, ) _sym_db.RegisterEnumDescriptor(_CRITICALERRORCODE) @@ -408,8 +408,8 @@ _LOGRECORD_LEVEL = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=1615, - serialized_end=1703, + serialized_start=1637, + serialized_end=1725, ) _sym_db.RegisterEnumDescriptor(_LOGRECORD_LEVEL) @@ -939,14 +939,21 @@ _MYNODEINFO = _descriptor.Descriptor( is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='message_timeout_msec', full_name='MyNodeInfo.message_timeout_msec', index=10, + name='reboot_count', full_name='MyNodeInfo.reboot_count', index=10, + number=10, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='message_timeout_msec', full_name='MyNodeInfo.message_timeout_msec', index=11, number=13, type=13, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='min_app_version', full_name='MyNodeInfo.min_app_version', index=11, + name='min_app_version', full_name='MyNodeInfo.min_app_version', index=12, number=14, type=13, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, @@ -965,7 +972,7 @@ _MYNODEINFO = _descriptor.Descriptor( oneofs=[ ], serialized_start=1210, - serialized_end=1519, + serialized_end=1541, ) @@ -1018,8 +1025,8 @@ _LOGRECORD = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1522, - serialized_end=1703, + serialized_start=1544, + serialized_end=1725, ) @@ -1097,8 +1104,8 @@ _FROMRADIO = _descriptor.Descriptor( create_key=_descriptor._internal_create_key, fields=[]), ], - serialized_start=1706, - serialized_end=1939, + serialized_start=1728, + serialized_end=1961, ) @@ -1148,8 +1155,8 @@ _TORADIO = _descriptor.Descriptor( create_key=_descriptor._internal_create_key, fields=[]), ], - serialized_start=1942, - serialized_end=2072, + serialized_start=1964, + serialized_end=2094, ) _USER.fields_by_name['hw_model'].enum_type = _HARDWAREMODEL diff --git a/proto b/proto index f9c4f87..1f56681 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit f9c4f875818c9aa6995e6e25803d52557a1779c7 +Subproject commit 1f56681b2b629a92a099784f78cd11dff31a5a8f diff --git a/setup.py b/setup.py index a6844cc..78689b4 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ with open("README.md", "r") as fh: # This call to setup() does all the work setup( name="meshtastic", - version="1.2.15", + version="1.2.16", description="Python API & client shell for talking to Meshtastic devices", long_description=long_description, long_description_content_type="text/markdown",