"on device" API now available, feedback requested

Hi ya’ll,

Based on a number of requests over the last yearish and the work of the devs on the project, we now have a supported “on device” API. This will let you (IMO easily) write ‘arduino’ code that sends and receives messages into the mesh to other device nodes, or PCs or phones (and eventually the broader internet).

So if you’ve wanted to use an API like this, it would be super great if:

  • You read the linked (early) tutorial
  • You try to make your idea work, but if you encounter questions or problems you post in this thread so that I can help and we can improve the tutorial/docs as needed.

Good luck! Make something awesome!

5 Likes

Haha, you copy/pasted the code comment I accidentally left in there.

// This is going into the wifidev feature branch
// Only update the WebUI if WiFi is enabled
//#if WiFi_MODE != 0
//  notifyWebUI();
//#endif

I’ll take that out when I’m running again.

Questions:

  • What’s the plan if we exhaust the address space for more application port numbers?
  • The plugins seems to be built around an event, receiving a mesh packet. What if we want something to periodically run in the background or every x-seconds?
  • What’s your guidance if someone would need to import a 3rd party library for use?
2 Likes

re: port numbers
This is a bit like the ‘well known’ port numbers for key UNIX services. We have a full 32 bits to work with so we can keep expanding as needed. In practice I think ‘private’ experimental projects (i.e. stuff never merged upstream into meshtastic) can pick conflicting port numbers without any real problem. But if devs of these third party apps want a guarantee that they don’t conflict they can send in a PR for portnums.proto.

re: threading
Good point! I’ve added an example of how to use threads, and a note about this in the docs: What do you think?

re: 3rd party library
hmm - I don’t know. If people were submitting ‘general’ services upstream that we want to keep in the meshtastic app they can add it to platformio.ini. Beyond that I don’t have any good theories ;-).

More thoughts …

  • re: 3rd party - I don’t have a solution either. the pattern now is to fork 3rd party libraries into the meshtastic repository. that will become a maintenance job for someone to keep it updated.
  • thinking ahead to possible failures, I can imagine that cross platform support of plugins may become a problem if merged into master. Some of our target boards just don’t have as much functionality as others or that functionality may be in a different place. This suggests to me that the available preprocessor definitions should be documented.
  • our plug-in src file system may get a bit messy after a while. May want to introduce some kind of naming conventions now. Maybe:

/src/plugins/core/* - core plugins
/src/plugins/3rdparty/* - 3rd party plugins

May also want to encourage 3rd party (and core?) plugins to put their plug-in into a folder with the port number.

/src/plugins/3rdparty/65-meshPowerTools/*

1 Like

Awesome. I’m really excited to try this.

That’s a question of how abstracted the API is - would it be possible to implement someting like a capability layer, where the plugin code can request/check for certain device capabilities (bluetooth, GPS etc) and change behaviour accordingly? Given that the communication with the specific function like bluetooth is already abstracted from the device hardware, which would mean less hardware-level control for plugins but easier to write compatible code…

Will this concept of plugins allow a minimum sized base code to be easier to install on devices that have very limited available application memory (like watches) ? then dynamically hot load plugins as they seem to be needed ?

Hi! Maybe it´s a little basic, but, by using a RemoteHardwarePlugin, where should I define the GPIOS that i want to be watched? It should be a message from the Python API for example? I´m a little lost using Plugins and they seem to be very usefull for my project. It is just reading some information from sensors and sending them to a base node connected to a computer.

Thanks!!

1 Like

Hi! Alas, I’m not quite ready to support RemoteHardwarePlugin because I want to add multichannel based security first (that should be happening in this next two weeks). Remote GPIO access will be supported then…

I’m happy to help with other plugin questions though.

3 Likes

Thank u! I´ll be waiting…

Another question, how can I implement the Plugins? I´m trying to handle text messages with the TextMessagePlugin handlereceived and I thought that it was already running, but after a little debugging I figured out it don´t.

Thank u again!

1 Like

hmm - the handlereceived should definitely be running, because that’s what draws the message on the OLED screen.

1 Like

@geeksville

Two questions…

  1. I’m working on a plugin and would like to enable configuration of the plugin that would take advantage of the existing config mechanisms that is exposed by the existing API. I need to be able to set two or three bools, a few uint32s and maybe an enum. What’s the best way to do this? I can follow the examples and put into the UserPreferences, but think there could be a name space for plugin configurations rather than putting it in RadioConfig.UserPreferences. Otherwise, as others create plugins, UserPreferences could become unmanageable.

  2. I’ve grabbed port 64 from portnums.proto. How does that change get propagated to the the rest of the applications, python, android, etc? Do I just run “bin/regen-protos.sh” in my local fork and then that gets merged in or is there something you need to do?

This is what I’ve cooked up:

1 Like

good point. For the time being, I’d say "put your preferences into RadioConfig.UserPreferences with a FIXME note. As part of the multi-channel stuff I’m needing to refactor that stuff anyways, because once devices can be part of N channels, RadioConfig becomes too big for a single BLE characteristic. So I’m going to be cleaning up config management as part of that change (in a backwards compatible way).

As part of that change I’ll let plugins have their own separate preferences.

yes, just add an entry in portnums.proto and run regen-protos. That (plus sending in a pull-request for your changes to meshtastic-proto) will take care of the device side. For the python/android/javascript sides, they should initially be fine without even seeing that change. (the port number will appear as its number in debug logs). But the next time anyone has cause to update the protobufs in those apps (by going into the submodule and doing “git pull” and then committing that change they will then know that symbolic name.

1 Like

All easy.

Thanks mate!

1 Like

The Protobufs project isn’t propagating into the device code.

I think the submodule is fixed to a specific version. Is this something you need to update?

Yeah, looks like you need to commit the submodule. Checkout the version of the submodule you want to pin the master repo to and then do “git commit -m’…’ proto” from the root level.

Users will need to do a “git submodule update” from the root level to update their submodules to the new revision.

2 Likes

I’ll google this. Thanks for the pointer.

I’m a git noob.

Command was:

git submodule update --remote

Thanks for your help!

2 Likes

My Mac really does not like nanopb! I got about 3 of 4 dozen security warnings that I had to accept one by one by dismissing several dialogs, go into “Security & Privacy” and then jump back out and run regen-protos only to repeat the whole sequence.

Got it working though. Thanks @geeksville and @isinglass !!

1 Like

I just bought a MacBook Air (pre-owned) first thing I did was install Ubuntu 20.10 on it. Works great. I only bought the air for its compact size. Its a little bigger then my tablet, but I have the keyboard and Linux instead of Android.

1 Like

@geeksville

Writing plugins is actually fairly straight forward and easy. Thanks for this framework!

I’ve begun working on yet another plugin but this one will need to subscribe to multiple ports at the same time. What would be the elegant way of doing this? Would it be to create multiple classes that inherit from SinglePortPlugin or would there be another way?

1 Like