diff --git a/meshtastic/__init__.py b/meshtastic/__init__.py index 1b82fca..d5a6095 100644 --- a/meshtastic/__init__.py +++ b/meshtastic/__init__.py @@ -135,7 +135,7 @@ class MeshInterface: meshPacket.decoded.position.altitude = int(altitude) if timeSec == 0: - timeSec = time.time() # returns unix timestamp in seconds + timeSec = time.time() # returns unix timestamp in seconds meshPacket.decoded.position.time = int(timeSec) meshPacket.decoded.want_response = wantResponse @@ -306,6 +306,12 @@ class MeshInterface: if meshPacket.decoded.HasField("data"): topic = "meshtastic.receive.data" + + # OPAQUE is the default protobuf typ value, and therefore if not set it will not be populated at all + # to make API usage easier, set it to prevent confusion + if not "typ" in asDict["decoded"]["data"]: + asDict["decoded"]["data"]["typ"] = "OPAQUE" + # For text messages, we go ahead and decode the text to ascii for our users if asDict["decoded"]["data"]["typ"] == "CLEAR_TEXT": asDict["decoded"]["data"]["text"] = meshPacket.decoded.data.payload.decode( @@ -361,7 +367,7 @@ class BLEInterface(MeshInterface): class StreamInterface(MeshInterface): """Interface class for meshtastic devices over a stream link (serial, TCP, etc)""" - def __init__(self, devPath=None, debugOut=None, noProto=False): + def __init__(self, devPath=None, debugOut=None, noProto=False, connectNow=True): """Constructor, opens a connection to a specified serial port, or if unspecified try to find one Meshtastic device by probing @@ -392,14 +398,24 @@ class StreamInterface(MeshInterface): devPath, 921600, exclusive=True, timeout=0.5) self._rxThread = threading.Thread(target=self.__reader, args=()) + MeshInterface.__init__(self, debugOut=debugOut, noProto=noProto) + + # Start the reader thread after superclass constructor completes init + if connectNow: + self.connect() + + def connect(self): + """Connect to our radio + + Normally this is called automatically by the constructor, but if you passed in connectNow=False you can manually + start the reading thread later. + """ + # Send some bogus UART characters to force a sleeping device to wake self.stream.write(bytes([START1, START1, START1, START1])) self.stream.flush() time.sleep(0.1) # wait 100ms to give device time to start running - MeshInterface.__init__(self, debugOut=debugOut, noProto=noProto) - - # Start the reader thread after superclass constructor completes init self._rxThread.start() def _sendToRadio(self, toRadio): diff --git a/meshtastic/test.py b/meshtastic/test.py index 42945e2..c80906a 100644 --- a/meshtastic/test.py +++ b/meshtastic/test.py @@ -39,7 +39,7 @@ def subscribe(): pub.subscribe(onNode, "meshtastic.node") -def testSend(fromInterface, toInterface, isBroadcast=False): +def testSend(fromInterface, toInterface, isBroadcast=False, asBinary=False): """ Sends one test packet between two nodes and then returns success or failure @@ -60,7 +60,12 @@ def testSend(fromInterface, toInterface, isBroadcast=False): toNode = toInterface.myInfo.my_node_num logging.info(f"Sending test packet from {fromNode} to {toNode}") - fromInterface.sendText(f"Test {testNumber}", toNode, wantAck=True) + wantAck = True + if not asBinary: + fromInterface.sendText(f"Test {testNumber}", toNode, wantAck=wantAck) + else: + fromInterface.sendData((f"Binary {testNumber}").encode( + "utf-8"), toNode, wantAck=wantAck) time.sleep(45) return (len(receivedPackets) >= 1) @@ -73,7 +78,8 @@ def testThread(numTests=50): global testNumber testNumber = testNumber + 1 isBroadcast = True - success = testSend(interfaces[0], interfaces[1], isBroadcast) + success = testSend( + interfaces[0], interfaces[1], isBroadcast, asBinary=(i % 2 == 0)) if not success: numFail = numFail + 1 logging.error( @@ -95,6 +101,7 @@ def onConnection(topic=pub.AUTO_TOPIC): print(f"Connection changed: {topic.getName()}") global testsRunning + global interfaces if (all(iface.isConnected for iface in interfaces) and not testsRunning): testsRunning = True t = threading.Thread(target=testThread, args=()) @@ -122,5 +129,8 @@ def testAll(): pub.subscribe(onReceive, "meshtastic.receive") global interfaces interfaces = list(map(lambda port: StreamInterface( - port, debugOut=openDebugLog(port)), ports)) + port, debugOut=openDebugLog(port), connectNow=False), ports)) + for i in interfaces: + i.connect() + logging.info("Ports opened, waiting for device to complete connection")