ok - I need it anyways for stress testing a bunch of nodes (and seeing if I ever drop packets etc…) So I just did the device side code for the ‘easy’ python API. There should be something you can use in a couple of weeks.
Ok - a first cut of the python client API is out: https://pypi.org/project/meshtastic/
Any feedback appreciated. You’ll need to run device software version 0.6.0 or later.
It includes a “meshtastic” command line app which should work on windows, os-x and linux and it lets you see all of the messages the radios send to the host. Soon you’ll also be able to use this commandline tool to change all the various device options that the android app doesn’t have a GUI for yet.
New version of the python API released. Includes more documentation and examples.
Also - the associated command line tool lets you set all the options of the devices (including options that don’t yet have a spot in the Android GUI).
This is very nice. For range testing i connect one device to my computer and run this script on it:
import meshtastic import time interface = meshtastic.StreamInterface() while 1: str = time.strftime("%a, %H:%M:%S", time.gmtime()) interface.sendText(str) time.sleep(60)
Each minute i get a notification on the device i bring on my walk. It is easy to see when you get out of range. So far i have only been 1 km out and had no missed messages.
btw - received Snr is included in the packets provided to the API, so you could log that as well.
Also, there is a want_response bool which can be set in those text message packets which will cause the receiving device to reply with its position and implicitly you will get snr there so you can log it if you wish. The python api doesn’t have a way to set that flag right now, but I’ll add that today.
In case it is useful for your efforts:
@claesg Nice script!
As @geeksville updates the want_response to the code, you could not only get the SNR’s logged on the stationary node, but you could also make your stationary node send the SNR and timestamp, inside your str notification, to your mobile node, of your last response from your mobile node. This might also work with want_ack flag (although you loose position information).
0.6.7 - minor update to make the python library ready for the last bit of device firmware changes (coming next week)
0.9.2 released to fix:
1.0.2 has been released to cleanly exit if the serial/USB port is simply unplugged
1.0.3 contains fixes to the example and minor changes to exceptions to make errors clearer.
1.1.7 of the python app and API is released. These changes are entirely thanks to @isinglass!
- Add a --setowner option to set owner info
- Fix meshtastic.node.updated not being published.
- Add a setURL() method for setting channel settings
1.1.20 of the python API & tool have been released.
This release contains a number of small bug fixes and changes to support the new remote GPIO API and the new cleaned-up on device API. It should be backwards compatible with old device firmware, newer firmwares will tell you that this library must be updated (with “pip3 install --upgrade meshtastic”)
I’ll write more fully about this when I release the device and android code later today.
1.1.23 of the python api/command line tool has been released. Anyone using Windows should upgrate. (Apparently on windows the hw flow control signals have been causing boards to reboot when the API connects - which was not the intent)
pip3 install --upgrade meshtastic
I was hoping this would fix the same problem on MacOS where the device would reset under the same circumstances. Alas, nope.
Hmm can you try turning off the code to restore cts in the _disconnect() call? It might fix macos.
I couldn’t find a restore of cts but found one of rts in _disconnected(self). I commented out these two:
if platform.system() != 'Linux': self.stream.rts = True # Return RTS high, so that the reset button still works
The initial set worked but the subsequent --info hang.
jmcasler@Ma> c-mini meshtastic % meshtastic --port /dev/cu.SLAB_USBtoUART --set ls_secs 301
Connected to radio
Setting ls_secs to 301
Writing modified preferences to device
jmcasler@Mac-mini meshtastic % meshtastic --port /dev/cu.SLAB_USBtoUART --info
Traceback (most recent call last):
File “/usr/local/bin/meshtastic”, line 8, in
File “/usr/local/lib/python3.9/site-packages/meshtastic/main.py”, line 407, in main
client = SerialInterface(
File “/usr/local/lib/python3.9/site-packages/meshtastic/init.py”, line 731, in init
File “/usr/local/lib/python3.9/site-packages/meshtastic/init.py”, line 588, in init
File “/usr/local/lib/python3.9/site-packages/meshtastic/init.py”, line 603, in connect
File “/usr/local/lib/python3.9/site-packages/meshtastic/init.py”, line 314, in _waitConnected
raise Exception(“Timed out waiting for connection completion”)
Exception: Timed out waiting for connection completion
It wouldn’t come back until I reset the device.
ooh! the latest pyserial has an ability to turn of rtscts support (I think - wasn’t needed in linux). Can you try changing the constructor call:
self.stream = serial.Serial( None, 921600, exclusive=True, timeout=0.5, dtrrtr=False, rtscts=False)
And removing my manual driving of rts (both places)?
I have pySerial 3.4 on my Windows system, and I couldn’t get this to work. It looks like the defaults are supposed to be False for both of these settings(assuming you meant dsrdtr=False).
hmm - I bet the person who posted about “timeout waiting for device” on connection might be seeing the same thing (assuming RTS is getting asserted by Windows when the port is opened, thus resetting the TBEAM).
Based on reading this pyserial bug:
# Note: we provide None for port here, because we will be opening it later self.stream = serial.Serial( None, 921600, exclusive=True, timeout=0.5, dsrdtr=False, rtscts=False) # rts=False Needed to prevent TBEAMs resetting on OSX, because rts is connected to reset self.stream.port = devPath self.stream.dtr = True self.stream.rts = False self.stream.open() StreamInterface.__init__( self, debugOut=debugOut, noProto=noProto, connectNow=connectNow) def _disconnected(self): """We override the superclass implementation to close our port""" StreamInterface._disconnected(self)