New and Updated Libraries

Big roll-out of library updates and additions today, folks.

New
Initial State 1.0.0 — Provides data posting access to the Initial State online service
Mnubo 1.0.0 — Provides data saving access to the Mnubo online service
Promise 1.0.0 — Provides a promise handling mechanism; required by the Mnubo library

Updated
Twitter 1.2.1 — Improved Twitter error handling
Loggly 1.1.0 — Addition of an optional callback to the flush() method
Onewire 1.0.1 — Minor bug fix
TheThingsAPI 1.0.1 — Minor bug fix
Bullwinkle 2.0.1 — Added server.error() message for unhandled NACKs

On trying out the Initial State library I ran into a situation where I was evidently having my data throttled. It seems 30 events/second is too much for the service. Whatever, the library didn’t handle it too gracefully - my first hint that something was wrong was the error
[Agent] ERROR: too many active timers (20)
It took me a little while to figure out where this error was coming from, along with some puzzling
[Agent] 429 -
Looking at the library code on GitHub, 429 turned out to be the clue to the problem as it’s
the resp.statuscode for throttling.
Pity I can’t use it as it’s quite a neat service apart from the bandwidth issue.

Tried batching the events and sending them with a single sendEvents() call?

I couldn’t figure out how to do that. The Initial State api doc. says

JSON events can be sent as either a single object as the root of the http body, or inside an array of events with the root of the HTTP body being an array
That seemed to be asking for something like this:
`function testis(){
    is.sendEvents([
            [{"key": "p1", "value": 1},{"key": "p2", "value": 5}],
            [{"key": "p1", "value": 2},{"key": "p2", "value": 6}],
            [{"key": "p1", "value": 3},{"key": "p2", "value": 7}],
            [{"key": "p1", "value": 4},{"key": "p2", "value": 8}]
     ], function(err, data) {
        if (err != null) server.error("Error: " + err);
    });
}`

but nothing happened when calling (no errors, no show on IS dashboard). It looked a bit gross too, so I tried sending in the values as an array:
{"key": "p1", "value": [1,2,3,4,]},{"key": "p2", "value": [5,6,7,8]}
but while this was accepted, it didn’t seem to plot - it just appeared in the table view as

2015-12-28T10:44:59.680097Z,p1,"1,2,3,4" 2015-12-28T10:44:59.681640Z,p2,"5,6,7,8"

I think you’re nesting your array more deeply than is required - ie, remove the square brackets that surround each entry and try again. I’m guessing it just iterates over the data.

Have asked someone from IS to look at this thread, though.

@iceled I’m the author of the library. Thanks for pointing out that the error handling wasn’t sufficient. I’ll make notes to try and get this updated in a future version.
Since this library is making HTTPS calls, we do limit users to 5 requests/sec. To be efficient with Internet traffic, you should batch calls and use the sendEvents() function of the library. sendEvent() is meant for low frequency data like sending once every 300+ms.

The “value” property/parameter of both sendEvent and sendEvents functions currently accept simple data types as values i.e. string, number, bool.

So, you would send data like this (using your example):

function testis(){ // note, sending a batch of events like this with multiple values for the same keys // may ultimately not make sense without overriding when the event actually happened // i.e. providing an epoch timestamp. is.sendEvents([ {"key": "p1", "value": 1},{"key": "p2", "value": 5}, {"key": "p1", "value": 2},{"key": "p2", "value": 6}, {"key": "p1", "value": 3},{"key": "p2", "value": 7}, {"key": "p1", "value": 4},{"key": "p2", "value": 8} ], function(err, data) { if (err != null) server.error("Error: " + err); }); }

Note, the sendEvents function takes a single dimension array of objects. These objects need at least a “key” and a “value” property and can optionally include an “epoch” to override the timestamp of the event. Here is some more information on throttling and bandwidth use as well as docs on how the Initial State API should be consumed.

This is a first pass at an Electric Imp library, so feedback is welcome! Additionally, the library is open source and improvements/enhancements are very welcome through github pull requests. Likewise, if you have any feature requests for the library or for Initial State, feel free to file them at support.initialstate.com

Cheers! Hope this helps.

OK I get it now. Thanks for all the help here. One problem I still have to overcome is generating the timestamp from the device due to the date().usecs you use in the Library not being supported on the device side. I’m sure I can work something out in its place!

Thanks for the extra info, @davidsulpy. I’ve added it to the library documentation.