From 9949d144a1e4ff0fb247796ba8607df9d8e850cf Mon Sep 17 00:00:00 2001 From: DJ Holt Date: Thu, 19 Sep 2024 02:22:04 -0600 Subject: [PATCH 1/2] Enable setting and removing fixed position via remote admin --- meshtastic/__main__.py | 15 +++++---------- meshtastic/node.py | 16 +++++++++++----- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 8eb04eb..686d207 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -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 @@ -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 diff --git a/meshtastic/node.py b/meshtastic/node.py index 278ea8a..bef632e 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -685,9 +685,6 @@ class Node: 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: @@ -705,7 +702,12 @@ class Node: 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""" @@ -714,7 +716,11 @@ class Node: 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""" From 40353a387e1782c4bcc7a882a3800ca52d4b30d3 Mon Sep 17 00:00:00 2001 From: DJ Holt Date: Thu, 19 Sep 2024 03:31:01 -0600 Subject: [PATCH 2/2] Fix tests for remote position configs --- meshtastic/tests/test_main.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/meshtastic/tests/test_main.py b/meshtastic/tests/test_main.py index 6f2dd26..6fe5c67 100644 --- a/meshtastic/tests/test_main.py +++ b/meshtastic/tests/test_main.py @@ -726,8 +726,8 @@ 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) @@ -735,14 +735,15 @@ def test_main_removeposition_invalid(capsys): 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) @@ -750,7 +751,8 @@ def test_main_setlat_invalid(capsys): 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() @@ -769,7 +771,7 @@ def test_main_removeposition(capsys): 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() @@ -796,7 +798,7 @@ def test_main_setlat(capsys): 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() @@ -825,7 +827,7 @@ def test_main_setlon(capsys): 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() @@ -854,7 +856,7 @@ def test_main_setalt(capsys): 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()