diff --git a/meshtastic/__init__.py b/meshtastic/__init__.py new file mode 100644 index 0000000..d2d61e2 --- /dev/null +++ b/meshtastic/__init__.py @@ -0,0 +1,4 @@ + +"""API for Meshtastic devices""" + +from .interface import MeshInterface diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py new file mode 100644 index 0000000..02ae007 --- /dev/null +++ b/meshtastic/__main__.py @@ -0,0 +1,42 @@ +#!python3 + +import argparse +from .interface import MeshInterface +import logging + + +def main(): + """Perform command line meshtastic operations""" + parser = argparse.ArgumentParser() + + # Operations for manufacturing + parser.add_argument("--install", choices=['JR', 'JL', 'JM', 'JO', 'JG', 'JK', 'JY', 'JC', 'JT', 'MB', 'MS'], + help="Install the ezdevice code onto a new device (you must select the board type letter - see README.md)") + parser.add_argument("--readee", action="store_true", + help="Extract the eeprom contents from the device, so it can be programmed onto other boards") + + # Operations for app developers + parser.add_argument( + "--target", help="The device we are controlling given as : (get the secret key at https://www.ezdevice.net/my/devices)") + parser.add_argument( + "--displayfile", help="display a text,html,png,svg or jpeg file on the display") + # parser.add_argument("--displayURL", help="display a text,html,png,svg or jpeg from the web on the device") + parser.add_argument( + "--claim", help="Mark that this device is no longer being used for custom development", action="store_true") + parser.add_argument( + "--release", help="Mark that this device is no longer being used for custom development (i.e. return to joyframe demo app)", action="store_true") + + # Operations for server backend developers + parser.add_argument("--localserve", help="Talk to a development server", + action="store_true") + parser.add_argument("--debug", help="Show debug log message", + action="store_true") + + args = parser.parse_args() + + logging.basicConfig(level=logging.DEBUG if args.debug else logging.INFO) + client = MeshInterface("/dev/ttyUSB0") + + +if __name__ == "__main__": + main() diff --git a/meshtastic/interface.py b/meshtastic/interface.py new file mode 100644 index 0000000..7c91be2 --- /dev/null +++ b/meshtastic/interface.py @@ -0,0 +1,34 @@ + +import serial +import threading +import logging +import sys + +""" + +TODO: +* use port enumeration to find ports https://pyserial.readthedocs.io/en/latest/shortintro.html + +""" + + +class MeshInterface: + """Interface class for meshtastic devices""" + + def __init__(self, devPath): + """Constructor, opens a connection to a specified serial port""" + logging.debug(f"Connecting to {devPath}") + self.debugOut = sys.stdout + self.rxBuf = bytes() # empty + self.stream = serial.Serial(devPath, 921600) + self.rxThread = threading.Thread(target=self.__reader, args=()) + self.rxThread.start() + + def close(self): + self.stream.close() # This will cause our reader thread to exit + + def __reader(self): + """The reader thread that reads bytes from our stream""" + while True: + b = read(1) + self.debugOut.write(b) diff --git a/setup.py b/setup.py index 85f3778..7a39101 100644 --- a/setup.py +++ b/setup.py @@ -25,7 +25,7 @@ setup( ], packages=["meshtastic"], include_package_data=True, - install_requires=["FIXME"], + install_requires=["pyserial"], python_requires='>=3', entry_points={ "console_scripts": [