Heya, all,
I want to be able to use Snap! to send and receive mqtt messages. My specific desire is to build an interface in Snap so I can send control messages and receive sensor readings from esp8266-based iOT devices (and esp8266 robots!)-- but the sky's the limit with mqtt...
Played with David Ochao's "snap-mqtt gateway", which works well enough for publishing mqtt messages. But, I couldn't figure out a reasonable and manageable and scalable way to subscribe to topics and receive mqtt messages back into Snap.
Then-- in working with websockets (mentioned in a post here or so) to communicate with the gateway-- I realized that it should be possible to build mqtt blocks.
So-- some working mqtt blocks are here. (Is there a way to share a Snap! project so that it doesn't open with the stage maximized?) These blocks utilize the Paho mqtt javascript client library.
I suggest to use the javascript console (in Chrome, dev tools) to see what's going on...
Caveats:
Initialization doesn't work the way I want it to, quite: my intent is that the mqtt library should be loaded when the [init mqtt] block is run, but that loading is skipped if it that library has already been loaded (in other words, if the program has already been run in this instance.) However, instead, first run loads the external libraries (adds as script src in header), then subsequent runs skip that loading and actually create the mqtt client. I'm not sure why it's not working the way I want. I see that other Snap! libraries load external js libraries in different ways, and am open to suggestions!
I'm also not sure that I'm doing "when message received" the best way. At this point, the onMessageArrived js function adds each new message to the end of a "messagequeue" js array, then I have a reporter block that array shifts and returns the oldest message from that messagequeuereturns. (I've set the messagequeue to hold a max of 200 messages- it dumps the oldest when new messages are received after 200. This could easily be changed...) It seems to handle a steady stream of messages pretty well (subscribe to "#" on test.mosquitto.org and watch the javascript console!)
But since "message arrival" is sort of an interrupt-- I wonder if maybe alternatively, it would be good to have a way for the "onMessageArrived" function set a Snap! variable then send a Snap! broadcast so that Snap! could handle the message receipt
Is there such a mechanism-- to make a javascript function set a Snap variable (not as a return, because the function wasn't called per se), and/or to send a Snap broadcast?
This is all just pretty much duct-tape coding, but-- it's functioning and I'm rather proud of that... : )
Please test and give feedback!
Mike