diff --git a/example_config.yaml b/example_config.yaml index 4020525b..acbdc332 100644 --- a/example_config.yaml +++ b/example_config.yaml @@ -4,6 +4,9 @@ owner_short: BOB channel_url: https://www.meshtastic.org/e/#CgMSAQESCDgBQANIAVAe +canned_messages: Hi|Bye|Yes|No|Ok +ringtone: 24:d=32,o=5,b=565:f6,p,f6,4p,p,f6,p,f6,2p,p,b6,p,b6,p,b6,p,b6,p,b,p,b,p,b,p,b,p,b,p,b,p,b,p,b,1p.,2p.,p + location: lat: 35.88888 lon: -93.88888 diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index ec755913..f751f07a 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -362,7 +362,6 @@ def onConnected(interface): print(f"Setting device owner short to {args.set_owner_short}") interface.getNode(args.dest, False, **getNode_kwargs).setOwner(long_name=args.set_owner, short_name=args.set_owner_short) - # TODO: add to export-config and configure if args.set_canned_message: closeNow = True waitForAckNak = True @@ -371,7 +370,6 @@ def onConnected(interface): args.set_canned_message ) - # TODO: add to export-config and configure if args.set_ringtone: closeNow = True waitForAckNak = True @@ -705,6 +703,16 @@ def onConnected(interface): interface.getNode(args.dest, **getNode_kwargs).setURL(configuration["channelUrl"]) time.sleep(0.5) + if "canned_messages" in configuration: + print("Setting canned message messages to", configuration["canned_messages"]) + interface.getNode(args.dest, **getNode_kwargs).set_canned_message(configuration["canned_messages"]) + time.sleep(0.5) + + if "ringtone" in configuration: + print("Setting ringtone to", configuration["ringtone"]) + interface.getNode(args.dest, **getNode_kwargs).set_ringtone(configuration["ringtone"]) + time.sleep(0.5) + if "location" in configuration: alt = 0 lat = 0.0 @@ -928,12 +936,14 @@ def setSimpleConfig(modem_preset): if args.get_canned_message: closeNow = True print("") - interface.getNode(args.dest, **getNode_kwargs).get_canned_message() + messages = interface.getNode(args.dest, **getNode_kwargs).get_canned_message() + print(f"canned_plugin_message:{messages}") if args.get_ringtone: closeNow = True print("") - interface.getNode(args.dest, **getNode_kwargs).get_ringtone() + ringtone = interface.getNode(args.dest, **getNode_kwargs).get_ringtone() + print(f"ringtone:{ringtone}") if args.info: print("") @@ -1097,6 +1107,8 @@ def export_config(interface) -> str: owner_short = interface.getShortName() channel_url = interface.localNode.getURL() myinfo = interface.getMyNodeInfo() + canned_messages = interface.getCannedMessage() + ringtone = interface.getRingtone() pos = myinfo.get("position") lat = None lon = None @@ -1115,6 +1127,10 @@ def export_config(interface) -> str: configObj["channelUrl"] = channel_url else: configObj["channel_url"] = channel_url + if canned_messages: + configObj["canned_messages"] = canned_messages + if ringtone: + configObj["ringtone"] = ringtone # lat and lon don't make much sense without the other (so fill with 0s), and alt isn't meaningful without both if lat or lon: configObj["location"] = {"lat": lat or float(0), "lon": lon or float(0)} diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index cf9009ce..16ec9758 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -1077,6 +1077,20 @@ def getPublicKey(self): return user.get("publicKey", None) return None + def getCannedMessage(self): + """Get canned message""" + node = self.localNode + if node is not None: + return node.get_canned_message() + return None + + def getRingtone(self): + """Get ringtone""" + node = self.localNode + if node is not None: + return node.get_ringtone() + return None + def _waitConnected(self, timeout=30.0): """Block until the initial node db download is complete, or timeout and raise an exception""" diff --git a/meshtastic/node.py b/meshtastic/node.py index d006075f..deb8b7bc 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -454,7 +454,6 @@ def get_ringtone(self): if self.ringtonePart: self.ringtone += self.ringtonePart - print(f"ringtone:{self.ringtone}") logging.debug(f"ringtone:{self.ringtone}") return self.ringtone @@ -530,7 +529,6 @@ def get_canned_message(self): if self.cannedPluginMessageMessages: self.cannedPluginMessage += self.cannedPluginMessageMessages - print(f"canned_plugin_message:{self.cannedPluginMessage}") logging.debug(f"canned_plugin_message:{self.cannedPluginMessage}") return self.cannedPluginMessage diff --git a/meshtastic/tests/test_main.py b/meshtastic/tests/test_main.py index 235829d4..32447e9b 100644 --- a/meshtastic/tests/test_main.py +++ b/meshtastic/tests/test_main.py @@ -494,6 +494,44 @@ def test_main_get_canned_messages(capsys, caplog, iface_with_nodes): assert err == "" mo.assert_called() +@pytest.mark.unit +@pytest.mark.usefixtures("reset_mt_config") +def test_main_set_ringtone(capsys): + """Test --set-ringtone""" + sys.argv = ["", "--set-ringtone", "foo,bar"] + 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"Setting ringtone to foo,bar", out, re.MULTILINE) + assert err == "" + mo.assert_called() + +@pytest.mark.unit +@pytest.mark.usefixtures("reset_mt_config") +def test_main_get_ringtone(capsys, caplog, iface_with_nodes): + """Test --get-ringtone""" + sys.argv = ["", "--get-ringtone"] + mt_config.args = sys.argv + + iface = iface_with_nodes + iface.devPath = "bar" + + mocked_node = MagicMock(autospec=Node) + mocked_node.get_ringtone.return_value = "foo,bar" + iface.localNode = mocked_node + + with caplog.at_level(logging.DEBUG): + 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"ringtone:foo,bar", out, re.MULTILINE) + assert err == "" + mo.assert_called() @pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") @@ -1724,6 +1762,8 @@ def test_main_export_config(capsys): mo.getLongName.return_value = "foo" mo.getShortName.return_value = "oof" mo.localNode.getURL.return_value = "bar" + mo.getCannedMessage.return_value = "foo|bar" + mo.getRingtone.return_value = "24:d=32,o=5" mo.getMyNodeInfo().get.return_value = { "latitudeI": 1100000000, "longitudeI": 1200000000, diff --git a/meshtastic/tests/test_mesh_interface.py b/meshtastic/tests/test_mesh_interface.py index 65c0725f..c561ab20 100644 --- a/meshtastic/tests/test_mesh_interface.py +++ b/meshtastic/tests/test_mesh_interface.py @@ -525,6 +525,28 @@ def test_getMyNodeInfo(): myinfo = iface.getMyNodeInfo() assert myinfo == anode +@pytest.mark.unit +@pytest.mark.usefixtures("reset_mt_config") +def test_getCannedMessage(): + """Test MeshInterface.getCannedMessage()""" + iface = MeshInterface(noProto=True) + node = MagicMock() + node.get_canned_message.return_value = "Hi|Bye|Yes" + iface.localNode = node + result = iface.getCannedMessage() + assert result == "Hi|Bye|Yes" + + +@pytest.mark.unit +@pytest.mark.usefixtures("reset_mt_config") +def test_getRingtone(): + """Test MeshInterface.getRingtone()""" + iface = MeshInterface(noProto=True) + node = MagicMock() + node.get_ringtone.return_value = "foo,bar" + iface.localNode = node + result = iface.getRingtone() + assert result == "foo,bar" @pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") @@ -543,7 +565,6 @@ def test_generatePacketId(capsys): assert err == "" assert pytest_wrapped_e.type == MeshInterface.MeshInterfaceError - @pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") def test_fixupPosition_empty_pos():