Dynamic language library API usability

We’re considering adding implementations of our library to these platforms:

  • Python (2 & 3)
  • Node.js

As always - those will be cross-platform, extensible and hackable :slight_smile:
It’s going to support:

  • Raspberry Pi, Intel Edison
  • Windows, Linux, OS X
  • WiPy, PyBoard
  • Espruino

Now the main question I have is about providing best usability and user experience.
For example, in Arduino library we allow user to create BLYNK_READ and BLYNK_WRITE functions.

In dynamic languages, it doesn’t look great :smile:

We could:

  1. Add separate blynk.onVirtualRead(pin, callback) and blynk.onVirtualWrite(pin, callback) functions
  2. Add a combined blynk.onVirtual(callback). In this case the callback will get pin#, type (read or write) and values if needed
  3. In JS, it can be like: blynk.on('vread1', function(){}) and blynk.on('vwrite5', function(param){})
  4. Or, maybe even:
blynk.on('V1', {
    read: function(){...},
    write: function(param){ ... }
});

There are many other approaches, for example one that was implemented for the WiPy:
https://github.com/danicampora/wipy/blob/master/lib/blynk/blynk.py

So we have a big variety of choices. Which do you like most?
Do you have any ideas?
Please show us some (Python-, JS-, pseudo-) code examples of the desired functionality.

P.S. Please note, this is not an announcement yet and we don’t provide any estimates…

Hello Blynkers!

I just wanted to jump in an explain a bit more about the WiPy’s API for Blynk. Here is the example that is included at the top of the Python module:

import blynk

blk = blynk.Blynk('e7c0a812347f12345f6ae8403abcdefg')

# to register virtual pins first define a handler
def vrhandler (request):
    if request.type == blynk.VrRequest.READ:
        # do some stuff

# create the virtual pin and register it
vrpin = blynk.VrPin(0, vrhandler)
blk.register_virtual_pin(vrpin)

# a user task the will be called periodically can also be registered
def my_user_task():
    # do any non-blocking operations

# register the task and specify the period which
# must be a multiple of 50 ms
blk.register_user_task(my_user_task, period_multiple_of_50_ms)

# start Blynk (this call should never return)
blk.run()

The request object passed to the virtual handler contains the following attributes:
- pin: the pin number
- type: can be either VrRequest.READ or VrRequest.WRITE
- args: list of arguments passed to a virtual write, equals None in the case of a virtual read.

The public API is as follows:

  • blynk.Blynk(token, server=‘cloud.blynk.cc’, port=8442, connect=True, enable_wdt=True)
    Create a new instance of Blynk. Requires a token string. If connect is True, then a connection to the Blynk server is attempted when run() is called. If enable_wdt is True, then the WDT will be enabled and kicked periodically by the library.

  • blynk.tweet(msg)
    Send a tweet.

  • email(to, subject, body)
    Send an email.

  • register_virtual_pin(pin)
    Register a new virtual pin. Pin must be an instance of the blynk.VrPin class.

  • register_user_task(task, ms_period)
    Register the user task which will be called at ms_period. The user task must be a function that receives no arguments and returns None. The period must be a multiple of 50ms.

  • connect()
    Connect to the Blynk server.

  • disconnect()
    Disconnect from the Blynk server.

  • *run(self)
    Runs Blynk. This method never returns.

Feedback is very much appreciated. We’ve tried to allow advanced users to have full control over the board while at the same time retaining the simplicity and beauty of Blynk.

Cheers,
Daniel

It’s very cool. I find the wdt option in your API. Can we control this in Arduino ? Just find that annoying to get restarted due to wdt …

Well, the WDT is a good thing, if you are restarted by it is because things went south. Ideally the WDT should never reset the board (if the hardware and software were perfect).
In the case of the Blynk library for the WiPy, when the WDT is active it is kicked periodically under the hood, so the user doesn’t need to worry about it. If an unhandled exception occurs, or the board hangs, the WDT will trigger a reset to start from scratch.

@danicampora,
Do you think using asyncio/uasyncio could simplify things for the user?
Is it stable enough in the micropython implementation?

For node, what about something like:

var V5 = new blynk.virtualPin(5);
var V7 = new blynk.virtualPin(7);

V5.on('read', function () {});
V7.on('write', function (param) {});

Are reads and writes both allowed on the same virtual pin, or are they exclusive?

1 Like

hey! yes, this looks very nice :smile:
didn’t think about this.

reads and writes are both allowed on the same pin.

Hi all, here is some basic JavaScript (Node.js/Espruino) support:

it would be great if someone can do code review, point to the problems (I’m not a JS coder :smile: mostly)
Thx @dougal for the VirtualPin object idea…

@lawII, @horchler, your attention please…

1 Like