Saturday, February 7, 2015

The Q API

I wrote about the Q and my thoughts about it at a general level recently.  I've also been tinkering with making it actually do interesting things via the API that it exposes.

The API is part of a beta firmware update, and it shows.  For example, right now the command to get a list of connected light bulbs locks up the device and requires a reboot.  I'm sure that will get fixed, and fortunately I can just read the serial numbers off of the physical bulbs themselves in the meantime.  But it does mean that it's basically impossible to write a consumer application to the API right now.

The API


The API that the Q exposes is pretty simple: it listens on a UDP port for messages in JSON.  It then returns nothing, a string, or JSON data.  It's a bit warty; anything communicating with it needs to expect different formatted data depending on the action.  I'd prefer to see it always return JSON, including when it doesn't understand the request.  Unfortunately, it never returns anything if there is an error and some commands don't get a success confirmation or even acknowledgement.  So it's possible that you think something has failed when it has succeeded or vice-versa.   I really hope that changes.

It's also not as well documented yet as I'd like.  There are fields that are entirely explained right now.  For example, the API to control the lights themselves contains fields like "effect", "matchValue", and "iswitch" which are undocumented.  So far I've determined that setting effect to "9" makes the bulb do what you say, a few other values (e.g. "8") makes it turn white no matter what color is specified, and anything else seems to have no effect at all but receives an "ok cmd!" response from the Q station.

Tinkering quickly


While it's possible to write a C, Python, Perl, etc. program as a harness to play with the Q, that's more work than I wanted to go through to just poke at it.  Plus I'm lazy and want to just do things from Bash wherever I can.

Since the Q just expects JSON messages on a given UDP port, it's possible to use netcat to do this without writing anything extra.  As an example, this will simply ping the unit and determine if it is working:

$ echo '{ ping" }' | nc -u 10.1.10.182 11600 -q 1
belled,MQ1AC43700000669,172.16.0.1,1

(This is using my Q's IP address.  You'll want to replace 10.1.10.182 with your unit's IP address.)

The "-q 1" parameter to nc tells it to disconnect after nothing is sent for one second.  Once I had this in my command history, it was a bit more convenient than hitting ^C to end the connection.

I've also used this to change a bulb's color:

$ echo '{ "cmd":"light_ctrl", "r":"155", "g":"20", "b":"255", "bright":"100", "sn_list":[ { "sn":"MD1AC44200001127" } ], "iswitch":"1", "matchValue":"0", "effect":"9"}' | nc -u 10.1.10.182 11600 -q 1
ok cmd!

(Again, my Q's IP address and my light bulb's serial number won't work for you, so be sure to change those.)

netcat allows simple interaction with the Q to interactively play with the API without having to bother with writing a full script and deal with sockets yourself.

No comments:

Post a Comment