almost working

This commit is contained in:
Thomas Göttgens
2022-06-17 12:31:18 +02:00
parent 682fdb7ef4
commit 8dbd6431f7
5 changed files with 66 additions and 40 deletions

View File

@@ -34,7 +34,7 @@ Basic functionality is complete now.
- DONE add fromId and toId to received messages dictionaries
- make command line options for displaying/changing config
- update nodedb as nodes change
- radioConfig - getter/setter syntax: https://www.python-course.eu/python3_properties.php
- localConfig - getter/setter syntax: https://www.python-course.eu/python3_properties.php
- let user change radio params via commandline options
- keep nodedb up-to-date based on received MeshPackets
- handle radio reboots and redownload db when that happens. Look for a special FromRadio.rebooted packet

View File

@@ -7,7 +7,7 @@ Source code on [github](https://github.com/meshtastic/Meshtastic-python)
properties of SerialInterface:
- radioConfig - Current radio configuration and device settings, if you write to this the new settings will be applied to
- localConfig - Current radio configuration and device settings, if you write to this the new settings will be applied to
the device.
- nodes - The database of received nodes. Includes always up-to-date location and username information for each
node in the mesh. This is a read-only datastructure.

View File

@@ -183,7 +183,7 @@ def onConnected(interface):
alt = 0
lat = 0.0
lon = 0.0
prefs = interface.localNode.radioConfig.preferences
prefs = interface.localNode.localConfig
if args.setalt:
alt = int(args.setalt)
prefs.fixed_position = True
@@ -224,7 +224,7 @@ def onConnected(interface):
if args.pos_fields:
# If --pos-fields invoked with args, set position fields
closeNow = True
prefs = interface.getNode(args.dest).radioConfig.preferences
prefs = interface.getNode(args.dest).localConfig
allFields = 0
try:
@@ -246,7 +246,8 @@ def onConnected(interface):
elif args.pos_fields is not None:
# If --pos-fields invoked without args, read and display current value
closeNow = True
prefs = interface.getNode(args.dest).radioConfig.preferences
prefs = interface.getNode(args.dest).localConfig
ces
fieldNames = []
for bit in config_pb2.PositionFlags.values():
@@ -326,7 +327,7 @@ def onConnected(interface):
# handle settings
if args.set:
closeNow = True
prefs = interface.getNode(args.dest).radioConfig.preferences
prefs = interface.getNode(args.dest).localConfig
# Handle the int/float/bool arguments
for pref in args.set:
@@ -364,7 +365,7 @@ def onConnected(interface):
alt = 0
lat = 0.0
lon = 0.0
prefs = interface.localNode.radioConfig.preferences
prefs = interface.localNode.localConfig
if 'alt' in configuration['location']:
alt = int(configuration['location']['alt'])
@@ -383,14 +384,14 @@ def onConnected(interface):
interface.localNode.writeConfig()
if 'user_prefs' in configuration:
prefs = interface.getNode(args.dest).radioConfig.preferences
prefs = interface.getNode(args.dest).localConfig
for pref in configuration['user_prefs']:
setPref(prefs, pref, str(configuration['user_prefs'][pref]))
print("Writing modified preferences to device")
interface.getNode(args.dest).writeConfig()
if 'userPrefs' in configuration:
prefs = interface.getNode(args.dest).radioConfig.preferences
prefs = interface.getNode(args.dest).localConfig
for pref in configuration['userPrefs']:
setPref(prefs, pref, str(configuration['userPrefs'][pref]))
print("Writing modified preferences to device")
@@ -539,7 +540,7 @@ def onConnected(interface):
if args.get:
closeNow = True
prefs = interface.getNode(args.dest).radioConfig.preferences
prefs = interface.getNode(args.dest).localConfig
# Handle the int/float/bool arguments
for pref in args.get:
@@ -628,7 +629,7 @@ def export_config(interface):
if alt:
config += f" alt: {alt}\n"
config += "\n"
preferences = f'{interface.localNode.radioConfig.preferences}'
preferences = f'{interface.localNode.localConfig}'
prefs = preferences.splitlines()
if prefs:
if Globals.getInstance().get_camel_case():

View File

@@ -422,10 +422,8 @@ class MeshInterface:
"""We need to send a heartbeat message to the device every X seconds"""
def callback():
self.heartbeatTimer = None
# TODO
# prefs = self.localNode.radioConfig.preferences
#i = prefs.phone_timeout_secs / 2
i = 0
prefs = self.localNode.localConfig
i = prefs.power.ls_secs / 2
logging.debug(f"Sending heartbeat, interval {i}")
if i != 0:
self.heartbeatTimer = threading.Timer(i, callback)
@@ -543,20 +541,18 @@ class MeshInterface:
self._startConfig() # redownload the node db etc...
elif fromRadio.config:
logging.debug("Hey! We got some configs")
if fromRadio.config.HasField("device"):
logging.debug("device!")
# TODO: do something with this config
self.localNode.localConfig.device.CopyFrom(fromRadio.config.device)
elif fromRadio.config.HasField("position"):
logging.debug("position!")
self.localNode.localConfig.position.CopyFrom(fromRadio.config.position)
elif fromRadio.config.HasField("power"):
logging.debug("power!")
self.localNode.localConfig.power.CopyFrom(fromRadio.config.power)
elif fromRadio.config.HasField("wifi"):
logging.debug("wifi!")
self.localNode.localConfig.wifi.CopyFrom(fromRadio.config.wifi)
elif fromRadio.config.HasField("display"):
logging.debug("display!")
self.localNode.localConfig.display.CopyFrom(fromRadio.config.display)
elif fromRadio.config.HasField("lora"):
logging.debug("lora!")
self.localNode.localConfig.lora.CopyFrom(fromRadio.config.lora)
else:
logging.debug("Unexpected FromRadio payload")

View File

@@ -5,22 +5,21 @@ import logging
import base64
import time
from google.protobuf.json_format import MessageToJson
from meshtastic import portnums_pb2, apponly_pb2, admin_pb2, channel_pb2
from meshtastic import portnums_pb2, apponly_pb2, admin_pb2, channel_pb2, localonly_pb2
from meshtastic.util import pskToString, stripnl, Timeout, our_exit, fromPSK
class Node:
"""A model of a (local or remote) node in the mesh
Includes methods for radioConfig and channels
Includes methods for localConfig and channels
"""
def __init__(self, iface, nodeNum, noProto=False):
"""Constructor"""
self.iface = iface
self.nodeNum = nodeNum
self.radioConfig = None
self.partialConfig = None
self.localConfig = localonly_pb2.LocalConfig()
self.channels = None
self._timeout = Timeout(maxSecs=300)
self.partialChannels = None
@@ -55,15 +54,15 @@ class Node:
def showInfo(self):
"""Show human readable description of our node"""
prefs = ""
if self.radioConfig and self.radioConfig.preferences:
prefs = stripnl(MessageToJson(self.radioConfig.preferences))
if self.localConfig:
prefs = stripnl(MessageToJson(self.localConfig))
print(f"Preferences: {prefs}\n")
self.showChannels()
def requestConfig(self):
"""Send regular MeshPackets to ask for settings and channels."""
logging.debug(f"requestConfig for nodeNum:{self.nodeNum}")
self.radioConfig = None
self.localConfig = localonly_pb2.LocalConfig()
self.channels = None
self.partialChannels = [] # We keep our channels in a temp array until finished
@@ -85,18 +84,48 @@ class Node:
def waitForConfig(self, attribute='channels'):
"""Block until radio config is received. Returns True if config has been received."""
return self._timeout.waitForSet(self, attrs=('config', attribute))
return self._timeout.waitForSet(self, attrs=('localConfig', attribute))
def writeConfig(self):
"""Write the current (edited) radioConfig to the device"""
if self.radioConfig is None:
our_exit("Error: No RadioConfig has been read")
"""Write the current (edited) localConfig to the device"""
if self.localConfig is None:
our_exit("Error: No localConfig has been read")
p = admin_pb2.AdminMessage()
p.set_radio.CopyFrom(self.radioConfig)
if self.localConfig.device:
p = admin_pb2.AdminMessage()
p.set_config.device.CopyFrom(self.localConfig.device)
self._sendAdmin(p)
logging.debug("Wrote device")
self._sendAdmin(p)
logging.debug("Wrote config")
if self.localConfig.position:
p = admin_pb2.AdminMessage()
p.set_config.position.CopyFrom(self.localConfig.position)
self._sendAdmin(p)
logging.debug("Wrote position")
if self.localConfig.power:
p = admin_pb2.AdminMessage()
p.set_config.power.CopyFrom(self.localConfig.power)
self._sendAdmin(p)
logging.debug("Wrote power")
if self.localConfig.wifi:
p = admin_pb2.AdminMessage()
p.set_config.wifi.CopyFrom(self.localConfig.wifi)
self._sendAdmin(p)
logging.debug("Wrote wifi")
if self.localConfig.display:
p = admin_pb2.AdminMessage()
p.set_config.display.CopyFrom(self.localConfig.display)
self._sendAdmin(p)
logging.debug("Wrote display")
if self.localConfig.lora:
p = admin_pb2.AdminMessage()
p.set_config.lora.CopyFrom(self.localConfig.lora)
self._sendAdmin(p)
logging.debug("Wrote lora")
def writeChannel(self, channelIndex, adminIndex=0):
"""Write the current (edited) channel to the device"""
@@ -214,8 +243,8 @@ class Node:
def setURL(self, url):
"""Set mesh network URL"""
if self.radioConfig is None:
our_exit("Warning: No RadioConfig has been read")
if self.localConfig is None:
our_exit("Warning: No Config has been read")
# URLs are of the form https://www.meshtastic.org/d/#{base64_channel_set}
# Split on '/#' to find the base64 encoded channel settings