diff --git a/.gitignore b/.gitignore index 8ee1a8e..74d237b 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,7 @@ nanopb-0.4.4 .coverage *.py-E venv/ +*pyc +.DS_Store +__pycache__ +examples/__pycache__ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..aa8f164 --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +# unit test +test: + pytest + +# local install +install: + pip install . + +# lint the codebase +lint: + pylint meshtastic + +cov: + pytest --cov-report html --cov=meshtastic + # on mac, this will open the coverage report in a browser + open htmlcov/index.html + +# run cli examples +examples: FORCE + pytest -mexamples + +FORCE: ; diff --git a/examples/hello_world_serial.py b/examples/hello_world_serial.py new file mode 100644 index 0000000..5c0b0b6 --- /dev/null +++ b/examples/hello_world_serial.py @@ -0,0 +1,18 @@ +"""Simple program to demo how to use meshtastic library. + To run: python examples/hello_world_serial.py +""" + +import sys +import meshtastic +import meshtastic.serial_interface + +# simple arg check +if len(sys.argv) < 2: + print(f"usage: {sys.argv[0]} message") + sys.exit(3) + +# By default will try to find a meshtastic device, +# otherwise provide a device path like /dev/ttyUSB0 +iface = meshtastic.serial_interface.SerialInterface() +iface.sendText(sys.argv[1]) +iface.close() diff --git a/examples/pub_sub_example.py b/examples/pub_sub_example.py new file mode 100644 index 0000000..a58d83a --- /dev/null +++ b/examples/pub_sub_example.py @@ -0,0 +1,26 @@ +"""Simple program to demo how to use meshtastic library. + To run: python examples/pub_sub_example.py +""" + +import sys +from pubsub import pub + +import meshtastic +import meshtastic.tcp_interface + +# simple arg check +if len(sys.argv) < 2: + print(f"usage: {sys.argv[0]} host") + sys.exit(1) + +def onConnection(interface, topic=pub.AUTO_TOPIC): + """This is called when we (re)connect to the radio.""" + print(interface.myInfo) + interface.close() +pub.subscribe(onConnection, "meshtastic.connection.established") + +try: + iface = meshtastic.tcp_interface.TCPInterface(sys.argv[1]) +except: + print(f"Error: Could not connect to {sys.argv[1]}") + sys.exit(1) diff --git a/examples/pub_sub_example2.py b/examples/pub_sub_example2.py new file mode 100644 index 0000000..b8ee60b --- /dev/null +++ b/examples/pub_sub_example2.py @@ -0,0 +1,35 @@ +"""Simple program to demo how to use meshtastic library. + To run: python examples/pub_sub_example2.py +""" + +import sys +import time +from pubsub import pub + +import meshtastic +import meshtastic.tcp_interface + +# simple arg check +if len(sys.argv) < 2: + print(f"usage: {sys.argv[0]} host") + sys.exit(1) + +def onReceive(packet, interface): + """called when a packet arrives""" + print(f"Received: {packet}") + +def onConnection(interface, topic=pub.AUTO_TOPIC): + """called when we (re)connect to the radio""" + # defaults to broadcast, specify a destination ID if you wish + interface.sendText("hello mesh") + +pub.subscribe(onReceive, "meshtastic.receive") +pub.subscribe(onConnection, "meshtastic.connection.established") +try: + iface = meshtastic.tcp_interface.TCPInterface(hostname=sys.argv[1]) + while True: + time.sleep(1000) + iface.close() +except(Exception) as ex: + print(f"Error: Could not connect to {sys.argv[1]} {ex}") + sys.exit(1) diff --git a/meshtastic/tests/test_examples.py b/meshtastic/tests/test_examples.py new file mode 100644 index 0000000..9f162d4 --- /dev/null +++ b/meshtastic/tests/test_examples.py @@ -0,0 +1,24 @@ +"""Meshtastic test that the examples run as expected. + We assume you have a python virtual environment in current directory. + If not, you need to run: "python3 -m venv venv", "source venv/bin/activate", "pip install ." +""" +import subprocess + +import pytest + +@pytest.mark.examples +def test_examples_hello_world_serial_no_arg(): + """Test hello_world_serial without any args""" + return_value, _ = subprocess.getstatusoutput('source venv/bin/activate; python3 examples/hello_world_serial.py') + assert return_value == 3 + + +@pytest.mark.examples +def test_examples_hello_world_serial_with_arg(capsys): + """Test hello_world_serial with arg""" + return_value, _ = subprocess.getstatusoutput('source venv/bin/activate; python3 examples/hello_world_serial.py hello') + assert return_value == 1 + _, err = capsys.readouterr() + assert err == '' + # TODO: Why does this not work? + # assert out == 'Warning: No Meshtastic devices detected.' diff --git a/pytest.ini b/pytest.ini index 62e2a7b..315962e 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,6 +1,6 @@ [pytest] -addopts = -m "not smoke1 and not smoke2 and not smokewifi" +addopts = -m "not smoke1 and not smoke2 and not smokewifi and not examples" markers = unit: marks tests as unit tests @@ -8,3 +8,4 @@ markers = smoke1: runs smoke tests on a single device connected via USB smoke2: runs smoke tests on a two devices connected via USB smokewifi: runs smoke test on an esp32 device setup with wifi + examples: runs the examples tests which validates the library