Skip to content

Commit

Permalink
Merge pull request #675 from djholt/feature/remote-config-position
Browse files Browse the repository at this point in the history
Enable setting and removing fixed position via remote admin
  • Loading branch information
ianmcorvidae authored Sep 19, 2024
2 parents 48a06c6 + 40353a3 commit de657ba
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 25 deletions.
15 changes: 5 additions & 10 deletions meshtastic/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,19 +286,14 @@ def onConnected(interface):
print("Connected to radio")

if args.remove_position:
if args.dest != BROADCAST_ADDR:
print("Setting positions of remote nodes is not supported.")
return
closeNow = True
waitForAckNak = True

print("Removing fixed position and disabling fixed position setting")
interface.localNode.removeFixedPosition()
interface.getNode(args.dest, False, **getNode_kwargs).removeFixedPosition()
elif args.setlat or args.setlon or args.setalt:
if args.dest != BROADCAST_ADDR:
print(
"Setting latitude, longitude, and altitude of remote nodes is not supported."
)
return
closeNow = True
waitForAckNak = True

alt = 0
lat = 0
Expand All @@ -321,7 +316,7 @@ def onConnected(interface):

print("Setting device position and enabling fixed position setting")
# can include lat/long/alt etc: latitude = 37.5, longitude = -122.1
interface.localNode.setFixedPosition(lat, lon, alt)
interface.getNode(args.dest, False, **getNode_kwargs).setFixedPosition(lat, lon, alt)

if args.set_owner or args.set_owner_short:
closeNow = True
Expand Down
16 changes: 11 additions & 5 deletions meshtastic/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -685,9 +685,6 @@ def resetNodeDb(self):
def setFixedPosition(self, lat: Union[int, float], lon: Union[int, float], alt: int):
"""Tell the node to set fixed position to the provided value and enable the fixed position setting"""
self.ensureSessionKey()
if self != self.iface.localNode:
logging.error("Setting position of remote nodes is not supported.")
return None

p = mesh_pb2.Position()
if isinstance(lat, float) and lat != 0.0:
Expand All @@ -705,7 +702,12 @@ def setFixedPosition(self, lat: Union[int, float], lon: Union[int, float], alt:

a = admin_pb2.AdminMessage()
a.set_fixed_position.CopyFrom(p)
return self._sendAdmin(a)

if self == self.iface.localNode:
onResponse = None
else:
onResponse = self.onAckNak
return self._sendAdmin(a, onResponse=onResponse)

def removeFixedPosition(self):
"""Tell the node to remove the fixed position and set the fixed position setting to false"""
Expand All @@ -714,7 +716,11 @@ def removeFixedPosition(self):
p.remove_fixed_position = True
logging.info(f"Telling node to remove fixed position")

return self._sendAdmin(p)
if self == self.iface.localNode:
onResponse = None
else:
onResponse = self.onAckNak
return self._sendAdmin(p, onResponse=onResponse)

def _fixupChannels(self):
"""Fixup indexes and add disabled channels as needed"""
Expand Down
22 changes: 12 additions & 10 deletions meshtastic/tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -726,31 +726,33 @@ def test_main_sendtext_with_dest(mock_findPorts, mock_serial, mocked_open, mock_

@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_removeposition_invalid(capsys):
"""Test --remove-position with an invalid dest"""
def test_main_removeposition_remote(capsys):
"""Test --remove-position with a remote dest"""
sys.argv = ["", "--remove-position", "--dest", "!12345678"]
mt_config.args = sys.argv
iface = MagicMock(autospec=SerialInterface)
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"remote nodes is not supported", out, re.MULTILINE)
assert re.search(r"Removing fixed position and disabling fixed position setting", out, re.MULTILINE)
assert re.search(r"Waiting for an acknowledgment from remote node", out, re.MULTILINE)
assert err == ""
mo.assert_called()

@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_setlat_invalid(capsys):
"""Test --setlat with an invalid dest"""
def test_main_setlat_remote(capsys):
"""Test --setlat with a remote dest"""
sys.argv = ["", "--setlat", "37.5", "--dest", "!12345678"]
mt_config.args = sys.argv
iface = MagicMock(autospec=SerialInterface)
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"remote nodes is not supported", out, re.MULTILINE)
assert re.search(r"Setting device position and enabling fixed position setting", out, re.MULTILINE)
assert re.search(r"Waiting for an acknowledgment from remote node", out, re.MULTILINE)
assert err == ""
mo.assert_called()

Expand All @@ -769,7 +771,7 @@ def mock_removeFixedPosition():
mocked_node.removeFixedPosition.side_effect = mock_removeFixedPosition

iface = MagicMock(autospec=SerialInterface)
iface.localNode = mocked_node
iface.getNode.return_value = mocked_node

with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
Expand All @@ -796,7 +798,7 @@ def mock_setFixedPosition(lat, lon, alt):
mocked_node.setFixedPosition.side_effect = mock_setFixedPosition

iface = MagicMock(autospec=SerialInterface)
iface.localNode = mocked_node
iface.getNode.return_value = mocked_node

with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
Expand Down Expand Up @@ -825,7 +827,7 @@ def mock_setFixedPosition(lat, lon, alt):
mocked_node.setFixedPosition.side_effect = mock_setFixedPosition

iface = MagicMock(autospec=SerialInterface)
iface.localNode = mocked_node
iface.getNode.return_value = mocked_node

with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
Expand Down Expand Up @@ -854,7 +856,7 @@ def mock_setFixedPosition(lat, lon, alt):
mocked_node.setFixedPosition.side_effect = mock_setFixedPosition

iface = MagicMock(autospec=SerialInterface)
iface.localNode = mocked_node
iface.getNode.return_value = mocked_node

with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
Expand Down

0 comments on commit de657ba

Please sign in to comment.