luup: a Chicken Scheme extension for MiOS home automation gateways.
This Chicken Scheme extension, named
luup, provides support for
communicating with MiOS devices, such as the Mi Casa Verde Vera home
MiOS gateways expose two network APIs: UPnP, and an RFC 3986-compliant URI query interface that is essentially just an HTTP request wrapper around their Luup (Lua-UPnP) scripting and plug-in environment. This extension uses the simpler HTTP interface, which is documented here.
I want to remotely control my Vera gateway using simple command-line
utilities that can be incorporated into more complex shell scripts,
AppleScripts, etc. Because MiOS gateways expose an HTTP control
interface, it’s certainly possible to build these simple utilities
wget; but short of hard-coding device
numbers, scene IDs, and the like, you really need to be able to
parse the MiOS gateway’s JSON responses in order to create a
flexible and maintainable system. This extension provides a
mechanism for building these utilities using Chicken Scheme, while
also hiding the (frankly, rather ugly) details of the MiOS HTTP
- A Luup-enabled MiOS gateway (tested with a Mi Casa Verde Vera running UI4 1.1.1047).
- Chicken Scheme 4.x (tested on 4.6.0)
data-structuresChicken Scheme extensions.
The luup extension is distributed under the MIT license.
Building the extension
The distribution comes with a Makefile, so a simple
should suffice to build the extension and install it into your
Chicken Scheme extension repository, assuming your paths and
permissions are set properly. If you need to use an alternate
installation path, or specify any other options, you can run
chicken-install by hand in the extension source code directory.
During the build process, the extension’s setup file should automatically install all the necessary Chicken Scheme extension dependencies.
Currently, only a very limited amount of Luup HTTP functionality is covered by this extension - basically, just the bits that I can test in my extremely small home Z-Wave environment. Over time, as I add more devices, I plan to add more functionality to the extension.
I will assume you’re familiar with the basic behavior and terminology of a MiOS gateway: scenes, devices, actions, etc.
Any s-expressions returned by the extension’s functions are, unless otherwise stated, a direct Scheme representation of the MiOS gateway’s JSON response to a request. JSON objects returned in the gateway’s HTTP reply are returned to the caller as Scheme alists, and JSON arrays in the reply are returned as Scheme lists. Other JSON types are represented in Scheme as you’d expect (strings, numbers, booleans, etc.).
This function returns an s-expression that corresponds to the JSON returned by the MiOS gateway in response to a lu_status request. It’s not particularly useful on its own, but the extension uses this function internally to discover the gateway’s scenes, and I decided to expose it so that people could poke around and see the gateway’s state.
Returns a list of scenes. Each scene in the list is, in turn, an alist containing the scene’s properties: its name, its status, etc.
Find a scene by name.
NAME is a string whose value is the name of a
scene you’ve defined using the MiOS gateway’s “scene wizard” user
Returns the scene as an alist, or
#f if there’s no scene by that
name. Typically, you will use the returned scene as an argument to
other scene-related functions.
Returns the numeric ID of
SCENE (a scene alist as returned by,
find-scene). This is not a particularly useful function at
SCENE (a scene alist) is active, otherwise
Run the scene specified by
SCENE, a scene alist.
Note that there is no “stop scene” functionality in MiOS. If you want to deactivate a scene, you’ll either need to activate an “opposite” scene that you’ve defined in the MiOS scene wizard (e.g., define both a “TV on” and a “TV off” scene); or you can change the state of a device that’s used in the scene, which appears to deactivate the scene. (The latter functionality is not yet exposed by this extension’s API.)
Even if you’ve created both a scene and its opposite in the gateway’s web UI, there’s no straightforward way to determine programmatically the relationship between two scenes using just the MiOS gateway’s scene information, so any sort of “run opposite scene” functionality is too configuration-dependent to embed in a general API like this one. However, you should find it relatively easy to use this extension to implement something like this that’s customized to your particular scene configuration.
This extension ships with two command-line executables:
run-scenetakes a scene name argument and tells the MiOS gateway to run that scene. (If the scene is already active, the command is effectively ignored.)
run-sceneexits with status 0 if the command was successful, otherwise it prints an error message to stderr and exits with status 1.
scene-statustakes a scene name argument. If a scene with that name exists on the MiOS gateway,
scene-statusprints “active” to stdout if the scene is active, or prints “inactive” if the scene is inactive; and then exits with status 0. If there’s an error (e.g., no such scene exists), it prints an error message to stderr and exits with status 1.
(Note that with a bit of scripting (bash, AppleScript, etc.), you could easily create a “scene toggle” command using these two executables and some knowledge of your scene configuration.)
Known issues and bugs
- Err… the base URI of the MiOS gateway is set to the hostname of the Vera gateway on my home network, and there’s currently no way to change it without modifying the source code!
- The API is currently very limited.
- Functions should check for unexpected results and raise exceptions when these occur.
- Parameterize the base URI value.
- Add support for some sort of rc-file to the bundled command-line executables, so that the user can specify a default base URI value.
- Add actions for individual devices. Currently the extension really only works at the scene level, but it would be nice to have fine-grained control over devices, too. Device control probably entails creating commands that are specific to the device classes supported by MiOS: simple on/off switches, dimmers, thermostats, etc.
Feel free to contact me with questions or concerns here.