Merge pull request #170 from mkinney/add_configure_dump

Add configure dump
This commit is contained in:
mkinney
2021-12-17 13:01:52 -08:00
committed by GitHub
4 changed files with 101 additions and 2 deletions

View File

@@ -335,6 +335,11 @@ def onConnected(interface):
print("Writing modified preferences to device")
getNode().writeConfig()
if args.export_config:
# export the configuration (the opposite of '--configure')
closeNow = True
export_config(interface)
if args.seturl:
closeNow = True
getNode().setURL(args.seturl)
@@ -515,6 +520,44 @@ def subscribe():
# pub.subscribe(onNode, "meshtastic.node")
def export_config(interface):
"""used in--export-config"""
owner = interface.getLongName()
channel_url = interface.localNode.getURL()
myinfo = interface.getMyNodeInfo()
pos = myinfo.get('position')
lat = None
lon = None
alt = None
if pos:
lat = pos.get('latitude')
lon = pos.get('longitude')
alt = pos.get('altitude')
config = "# start of Meshtastic configure yaml\n"
if owner:
config += f"owner: {owner}\n\n"
if channel_url:
config += f"channel_url: {channel_url}\n\n"
if lat or lon or alt:
config += "location:\n"
if lat:
config += f" lat: {lat}\n"
if lon:
config += f" lon: {lon}\n"
if alt:
config += f" alt: {alt}\n"
config += "\n"
preferences = f'{interface.localNode.radioConfig.preferences}'
prefs = preferences.splitlines()
if prefs:
config += "user_prefs:\n"
for pref in prefs:
config += f" {meshtastic.util.quoteBooleans(pref)}\n"
print(config)
return config
def common():
"""Shared code for all of our command line wrappers"""
our_globals = Globals.getInstance()
@@ -605,6 +648,11 @@ def initParser():
help="Specify a path to a yaml(.yml) file containing the desired settings for the connected device.",
action='append')
parser.add_argument(
"--export-config",
help="Export the configuration in yaml(.yml) format.",
action='store_true')
parser.add_argument(
"--port",
help="The port the Meshtastic device is connected to, i.e. /dev/ttyUSB0. If unspecified, we'll try to find it.",

View File

@@ -1,4 +1,5 @@
"""Meshtastic unit tests for __main__.py"""
# pylint: disable=C0302
import sys
import os
@@ -7,7 +8,7 @@ import re
from unittest.mock import patch, MagicMock
import pytest
from meshtastic.__main__ import initParser, main, Globals, onReceive, onConnection
from meshtastic.__main__ import initParser, main, Globals, onReceive, onConnection, export_config
import meshtastic.radioconfig_pb2
from ..serial_interface import SerialInterface
from ..tcp_interface import TCPInterface
@@ -1196,3 +1197,35 @@ def test_main_onConnection(reset_globals, capsys):
out, err = capsys.readouterr()
assert re.search(r'Connection changed: foo', out, re.MULTILINE)
assert err == ''
@pytest.mark.unit
def test_main_export_config(reset_globals, capsys):
"""Test export_config"""
iface = MagicMock(autospec=SerialInterface)
with patch('meshtastic.serial_interface.SerialInterface', return_value=iface) as mo:
mo.getLongName.return_value = 'foo'
mo.localNode.getURL.return_value = 'bar'
mo.getMyNodeInfo().get.return_value = { 'latitudeI': 1100000000, 'longitudeI': 1200000000,
'altitude': 100, 'batteryLevel': 34, 'latitude': 110.0,
'longitude': 120.0}
mo.localNode.radioConfig.preferences = """phone_timeout_secs: 900
ls_secs: 300
position_broadcast_smart: true
fixed_position: true
position_flags: 35"""
export_config(mo)
out, err = capsys.readouterr()
assert re.search(r'owner: foo', out, re.MULTILINE)
assert re.search(r'channel_url: bar', out, re.MULTILINE)
assert re.search(r'location:', out, re.MULTILINE)
assert re.search(r'lat: 110.0', out, re.MULTILINE)
assert re.search(r'lon: 120.0', out, re.MULTILINE)
assert re.search(r'alt: 100', out, re.MULTILINE)
assert re.search(r'user_prefs:', out, re.MULTILINE)
assert re.search(r'phone_timeout_secs: 900', out, re.MULTILINE)
assert re.search(r'ls_secs: 300', out, re.MULTILINE)
assert re.search(r"position_broadcast_smart: 'true'", out, re.MULTILINE)
assert re.search(r"fixed_position: 'true'", out, re.MULTILINE)
assert re.search(r"position_flags: 35", out, re.MULTILINE)
assert err == ''

View File

@@ -4,7 +4,7 @@ import re
import pytest
from meshtastic.util import fixme, stripnl, pskToString, our_exit, support_info, genPSK256, fromStr, fromPSK
from meshtastic.util import fixme, stripnl, pskToString, our_exit, support_info, genPSK256, fromStr, fromPSK, quoteBooleans
@pytest.mark.unit
@@ -35,6 +35,16 @@ def test_fromStr():
assert fromStr('abc') == 'abc'
@pytest.mark.unit
def test_quoteBooleans():
"""Test quoteBooleans"""
assert quoteBooleans('') == ''
assert quoteBooleans('foo') == 'foo'
assert quoteBooleans('true') == 'true'
assert quoteBooleans('false') == 'false'
assert quoteBooleans(': true') == ": 'true'"
assert quoteBooleans(': false') == ": 'false'"
@pytest.mark.unit
def test_fromPSK():
"""Test fromPSK"""

View File

@@ -16,6 +16,14 @@ import pkg_resources
blacklistVids = dict.fromkeys([0x1366])
def quoteBooleans(a_string):
"""Quote booleans
given a string that contains ": true", replace with ": 'true'" (or false)
"""
tmp = a_string.replace(": true", ": 'true'")
tmp = tmp.replace(": false", ": 'false'")
return tmp
def genPSK256():
"""Generate a random preshared key"""
return os.urandom(32)