From 5f43a32242138b308ebffd1520253abf7f52e035 Mon Sep 17 00:00:00 2001
From: Kevin Hester
Date: Sat, 20 Mar 2021 10:47:04 +0800
Subject: [PATCH] 1.2.12
---
docs/meshtastic/index.html | 171 ++++++++++++++++++++++++++++++-------
setup.py | 2 +-
2 files changed, 143 insertions(+), 30 deletions(-)
diff --git a/docs/meshtastic/index.html b/docs/meshtastic/index.html
index 81797b8..9715d8b 100644
--- a/docs/meshtastic/index.html
+++ b/docs/meshtastic/index.html
@@ -258,15 +258,37 @@ class Node:
self._sendAdmin(p)
logging.debug("Wrote config")
- def writeChannel(self, channelIndex):
+ def writeChannel(self, channelIndex, adminIndex = 0):
"""Write the current (edited) channel to the device"""
p = admin_pb2.AdminMessage()
p.set_channel.CopyFrom(self.channels[channelIndex])
- self._sendAdmin(p)
+ self._sendAdmin(p, adminIndex=adminIndex)
logging.debug("Wrote channel {channelIndex}")
+ def deleteChannel(self, channelIndex):
+ """Delete the specifed channelIndex and shift other channels up"""
+ ch = self.channels[channelIndex]
+ if ch.role != channel_pb2.Channel.Role.SECONDARY:
+ raise Exception("Only SECONDARY channels can be deleted")
+
+ # we are careful here because if we move the "admin" channel the channelIndex we need to use
+ # for sending admin channels will also change
+ adminIndex = self.iface.localNode._getAdminChannelIndex()
+
+ self.channels.pop(channelIndex)
+ self._fixupChannels() # expand back to 8 channels
+
+ index = channelIndex
+ while index < self.iface.myInfo.max_channels:
+ self.writeChannel(index, adminIndex=adminIndex)
+ index += 1
+
+ # 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
+
def getChannelByName(self, name):
"""Try to find the named channel or return None"""
for c in (self.channels or []):
@@ -389,6 +411,27 @@ class Node:
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
+
+ self._fillChannels()
+
+ def _fillChannels(self):
+ """Mark unused channels as disabled"""
+
+ # Add extra disabled channels as needed
+ index = len(self.channels)
+ while index < self.iface.myInfo.max_channels:
+ ch = channel_pb2.Channel()
+ ch.role = channel_pb2.Channel.Role.DISABLED
+ ch.index = index
+ self.channels.append(ch)
+ index += 1
+
def _requestChannel(self, channelNum: int):
"""
Done with initial config messages, now send regular MeshPackets to ask for settings
@@ -414,16 +457,9 @@ class Node:
if quitEarly or index >= self.iface.myInfo.max_channels - 1:
logging.debug("Finished downloading channels")
- # Fill the rest of array with DISABLED channels
- index += 1
- while index < self.iface.myInfo.max_channels:
- ch = channel_pb2.Channel()
- ch.role = channel_pb2.Channel.Role.DISABLED
- ch.index = index
- self.partialChannels.append(ch)
- index += 1
-
self.channels = self.partialChannels
+ self._fixupChannels()
+
# FIXME, the following should only be called after we have settings and channels
self.iface._connected() # Tell everone else we are ready to go
else:
@@ -434,15 +470,19 @@ 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
+ adminIndex = self.iface.localNode._getAdminChannelIndex()
+
return self.iface.sendData(p, self.nodeNum,
portNum=portnums_pb2.PortNum.ADMIN_APP,
wantAck=True,
wantResponse=wantResponse,
onResponse=onResponse,
- channelIndex=self.iface.localNode._getAdminChannelIndex())
+ channelIndex=adminIndex)
class MeshInterface:
@@ -2321,15 +2361,37 @@ 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):
+ def writeChannel(self, channelIndex, adminIndex = 0):
"""Write the current (edited) channel to the device"""
p = admin_pb2.AdminMessage()
p.set_channel.CopyFrom(self.channels[channelIndex])
- self._sendAdmin(p)
+ self._sendAdmin(p, adminIndex=adminIndex)
logging.debug("Wrote channel {channelIndex}")
+ def deleteChannel(self, channelIndex):
+ """Delete the specifed channelIndex and shift other channels up"""
+ ch = self.channels[channelIndex]
+ if ch.role != channel_pb2.Channel.Role.SECONDARY:
+ raise Exception("Only SECONDARY channels can be deleted")
+
+ # we are careful here because if we move the "admin" channel the channelIndex we need to use
+ # for sending admin channels will also change
+ adminIndex = self.iface.localNode._getAdminChannelIndex()
+
+ self.channels.pop(channelIndex)
+ self._fixupChannels() # expand back to 8 channels
+
+ index = channelIndex
+ while index < self.iface.myInfo.max_channels:
+ self.writeChannel(index, adminIndex=adminIndex)
+ index += 1
+
+ # 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
+
def getChannelByName(self, name):
"""Try to find the named channel or return None"""
for c in (self.channels or []):
@@ -2452,6 +2514,27 @@ wantResponse – True if you want the service on the other side to send an a
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
+
+ self._fillChannels()
+
+ def _fillChannels(self):
+ """Mark unused channels as disabled"""
+
+ # Add extra disabled channels as needed
+ index = len(self.channels)
+ while index < self.iface.myInfo.max_channels:
+ ch = channel_pb2.Channel()
+ ch.role = channel_pb2.Channel.Role.DISABLED
+ ch.index = index
+ self.channels.append(ch)
+ index += 1
+
def _requestChannel(self, channelNum: int):
"""
Done with initial config messages, now send regular MeshPackets to ask for settings
@@ -2477,16 +2560,9 @@ wantResponse – True if you want the service on the other side to send an a
if quitEarly or index >= self.iface.myInfo.max_channels - 1:
logging.debug("Finished downloading channels")
- # Fill the rest of array with DISABLED channels
- index += 1
- while index < self.iface.myInfo.max_channels:
- ch = channel_pb2.Channel()
- ch.role = channel_pb2.Channel.Role.DISABLED
- ch.index = index
- self.partialChannels.append(ch)
- index += 1
-
self.channels = self.partialChannels
+ self._fixupChannels()
+
# FIXME, the following should only be called after we have settings and channels
self.iface._connected() # Tell everone else we are ready to go
else:
@@ -2497,15 +2573,19 @@ 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
+ adminIndex = self.iface.localNode._getAdminChannelIndex()
+
return self.iface.sendData(p, self.nodeNum,
portNum=portnums_pb2.PortNum.ADMIN_APP,
wantAck=True,
wantResponse=wantResponse,
onResponse=onResponse,
- channelIndex=self.iface.localNode._getAdminChannelIndex())
+ channelIndex=adminIndex)
Instance variables
@@ -2533,6 +2613,38 @@ def channelURL(self):
Methods
+
+def deleteChannel(self, channelIndex)
+
+-
+
Delete the specifed channelIndex and shift other channels up
+
+
+Expand source code
+
+def deleteChannel(self, channelIndex):
+ """Delete the specifed channelIndex and shift other channels up"""
+ ch = self.channels[channelIndex]
+ if ch.role != channel_pb2.Channel.Role.SECONDARY:
+ raise Exception("Only SECONDARY channels can be deleted")
+
+ # we are careful here because if we move the "admin" channel the channelIndex we need to use
+ # for sending admin channels will also change
+ adminIndex = self.iface.localNode._getAdminChannelIndex()
+
+ self.channels.pop(channelIndex)
+ self._fixupChannels() # expand back to 8 channels
+
+ index = channelIndex
+ while index < self.iface.myInfo.max_channels:
+ self.writeChannel(index, adminIndex=adminIndex)
+ index += 1
+
+ # 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
+
+
def exitSimulator(self)
@@ -2722,7 +2834,7 @@ def channelURL(self):
-def writeChannel(self, channelIndex)
+def writeChannel(self, channelIndex, adminIndex=0)
-
Write the current (edited) channel to the device
@@ -2730,13 +2842,13 @@ def channelURL(self):
Expand source code
-def writeChannel(self, channelIndex):
+def writeChannel(self, channelIndex, adminIndex = 0):
"""Write the current (edited) channel to the device"""
p = admin_pb2.AdminMessage()
p.set_channel.CopyFrom(self.channels[channelIndex])
- self._sendAdmin(p)
+ self._sendAdmin(p, adminIndex=adminIndex)
logging.debug("Wrote channel {channelIndex}")
@@ -3258,6 +3370,7 @@ hostname {string} – Hostname/IP address of the device to connect to
Node
channelURL
+deleteChannel
exitSimulator
getChannelByName
getDisabledChannel
diff --git a/setup.py b/setup.py
index 5f768c5..27e16fc 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.11",
+ version="1.2.12",
description="Python API & client shell for talking to Meshtastic devices",
long_description=long_description,
long_description_content_type="text/markdown",