From 701165560b559749608ad76f33dc5ae56ad59f54 Mon Sep 17 00:00:00 2001 From: geeksville Date: Mon, 27 Apr 2020 16:44:41 -0700 Subject: [PATCH] raw serial reading works --- *.pyc | 1 + TODO.md | 24 --------------------- bin/run.sh | 1 + meshtastic/.gitignore | 1 + meshtastic/__init__.py | 2 +- meshtastic/__main__.py | 4 ++-- meshtastic/interface.py | 48 ++++++++++++++++++++++++++++++++++++++--- 7 files changed, 51 insertions(+), 30 deletions(-) create mode 100644 *.pyc create mode 100755 bin/run.sh create mode 100644 meshtastic/.gitignore diff --git a/*.pyc b/*.pyc new file mode 100644 index 0000000..0d20b64 --- /dev/null +++ b/*.pyc @@ -0,0 +1 @@ +*.pyc diff --git a/TODO.md b/TODO.md index 4ee77cd..654f212 100644 --- a/TODO.md +++ b/TODO.md @@ -5,30 +5,6 @@ ## Primary API: MeshInterface -Contains a reader thread that is always trying to read on the serial port. - -methods: - -- constructor(serialPort) -- send(meshPacket) - throws errors if we have errors talking to the device -- close() - shuts down the interface -- init() - starts the enumeration process to download NodeDB etc... - we will not publish to topics until this enumeration completes -- radioConfig -- nodeDB -- myNodeInfo -- myNodeId - -## PubSub topics - -Use a pubsub model to communicate events [https://pypubsub.readthedocs.io/en/v4.0.3/ ] - -- meshtastic.send(MeshPacket) - Not implemented, instead call send(packet) on MeshInterface -- meshtastic.connection.established - published once we've successfully connected to the radio and downloaded the node DB -- meshtastic.connection.lost - published once we've lost our link to the radio -- meshtastic.receive.position(MeshPacket) -- meshtastic.receive.user(MeshPacket) -- meshtastic.receive.data(MeshPacket) -- meshtastic.debug(string) ## Wire encoding diff --git a/bin/run.sh b/bin/run.sh new file mode 100755 index 0000000..f35148d --- /dev/null +++ b/bin/run.sh @@ -0,0 +1 @@ +python3 -m meshtastic diff --git a/meshtastic/.gitignore b/meshtastic/.gitignore new file mode 100644 index 0000000..bee8a64 --- /dev/null +++ b/meshtastic/.gitignore @@ -0,0 +1 @@ +__pycache__ diff --git a/meshtastic/__init__.py b/meshtastic/__init__.py index d2d61e2..f916634 100644 --- a/meshtastic/__init__.py +++ b/meshtastic/__init__.py @@ -1,4 +1,4 @@ """API for Meshtastic devices""" -from .interface import MeshInterface +from .interface import StreamInterface diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 02ae007..a013491 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -1,7 +1,7 @@ #!python3 import argparse -from .interface import MeshInterface +from .interface import StreamInterface import logging @@ -35,7 +35,7 @@ def main(): args = parser.parse_args() logging.basicConfig(level=logging.DEBUG if args.debug else logging.INFO) - client = MeshInterface("/dev/ttyUSB0") + client = StreamInterface("/dev/ttyUSB0") if __name__ == "__main__": diff --git a/meshtastic/interface.py b/meshtastic/interface.py index 7c91be2..1e79172 100644 --- a/meshtastic/interface.py +++ b/meshtastic/interface.py @@ -9,16 +9,58 @@ import sys TODO: * use port enumeration to find ports https://pyserial.readthedocs.io/en/latest/shortintro.html + +Contains a reader thread that is always trying to read on the serial port. + +methods: + +- constructor(serialPort) +- sendData(destinationId, bytes, variant) +- sendPacket(destinationId, meshPacket) - throws errors if we have errors talking to the device +- close() - shuts down the interface +- init() - starts the enumeration process to download NodeDB etc... - we will not publish to topics until this enumeration completes +- radioConfig - getter/setter syntax: https://www.python-course.eu/python3_properties.php +- nodes - the database of received nodes +- myNodeInfo +- myNodeId + +## PubSub topics + +Use a pubsub model to communicate events [https://pypubsub.readthedocs.io/en/v4.0.3/ ] + +- meshtastic.send(MeshPacket) - Not implemented, instead call send(packet) on MeshInterface +- meshtastic.connection.established - published once we've successfully connected to the radio and downloaded the node DB +- meshtastic.connection.lost - published once we've lost our link to the radio +- meshtastic.receive.position(MeshPacket) +- meshtastic.receive.user(MeshPacket) +- meshtastic.receive.data(MeshPacket) +- meshtastic.node.updated(NodeInfo) - published when a node in the DB changes (appears, location changed, username changed, etc...) +- meshtastic.debug(string) + """ class MeshInterface: """Interface class for meshtastic devices""" + def __init__(self): + self.debugOut = sys.stdout + self.nodes = None # FIXME + + def __handleReceived(fromradio): + """ + Handle a packet that arrived from the radio (update model and publish events) + + Called by subclasses.""" + + +class StreamInterface(MeshInterface): + """Interface class for meshtastic devices over a stream link (serial, TCP, etc)""" + def __init__(self, devPath): """Constructor, opens a connection to a specified serial port""" + MeshInterface.__init__(self) 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=()) @@ -30,5 +72,5 @@ class MeshInterface: def __reader(self): """The reader thread that reads bytes from our stream""" while True: - b = read(1) - self.debugOut.write(b) + b = self.stream.read(1) + self.debugOut.write(b.decode("utf-8"))