3M-50 thermostat module / best way to communicaten via HTTP

I’m writing a plugin for my (three) Wifi 3M-50 thermostat’s. The thermostat API uses HTTP GET and POST requests that return JSON responses. The API seems fairly straightforward, with the limitation that the thermostat web server is single threaded. (so I’m assuming that if I keep a persistent TCP connection open to the thermostat that it would block other requests.)

As this is my first time doing any Luup development, I’ve got a handful of “Luup 101” questions that weren’t clearly answerable from the docs / example code. If anyone could give me a helping hand to get started, it would be greatly appreciated.

First, from reading the Luup docs and browsing the code, it appears there are several strategies for communicating via HTTP from a luup plugin:

  1. Using luup.io.read/write to talk to a socket connection. However, it’s not clear from the doc what is the lifecycle of a socket connection. As there’s no luup.io.close, I’m assuming it’s persistent which rules it out due to the single threaded nature of the thermostat.

  2. Call os.execute (“curl …”). This appears to be easiest to implement for me (easy to test communications using curl on command line :slight_smile: and curl implements a high-level HTTP protocol stack. However, this obviously incurs a lot of overhead due to starting a whole new process and I’m not sure how much of an impact this would be to the vera device.

  3. Call luup.inet.wget. (i.e. like Guessed’s weather plugin) Looks like a nice option, but wget seems to only support GET not POST. (I believe the thermostat requires POSTS for some requests, but I need to check to see if I can “get way” with using a GET with a query string)

  4. Using the lua socket.http library. (i.e. like the Sonos Wireless HiFi Music Systems plugin).

Any suggestions on which of these might be the best option for communicating with the thermostat via HTTP? Also, what’s the best way to “robustly” parse JSON in Luup without reinventing the wheel?

Second, does anyone have suggestions on places to look for some example / boilerplate code that might get me started more easily writing this sort of module that implements a standard UPnP interface? One thing I’m a little confused about at the moment is which code is absolutely necessary to bootstrap / initialize the module, and what that code actually does. (i.e. why does everyone’s module include the same child finding code, and what does that do)

Thanks in advance!

If I were writing the Weather device today, I’d use the same techniques that the Sonos Plugin uses, mostly to avoid having to startup a Linux process (which is true of both 2 and 3, under the covers)

It would require a bit of testing though, just to ensure that there was no leakage going on (etc), and that all of the error handling is solid for the various failure cases.

In doing a T-Stat implementation, you’re about to embark down the same road that @TimAlls is on. It’s a different device, under the covers, but the overall process will be the same. There’s opportunity for you both to share efforts and avoid some pain.

See these discussions here:

The comments will be related, except you don’t need to deal with the Binary that he has to handle. There will be a lot of sharable code between these implementations, and certainly a lot of shared “bits” (JSON, etc) that don’t need to be done twice.

Guessed, thanks for the help… it saved me a lot of time researching options.

I did, however, burn a lot of time (grrrrrr…) trying to figure out why a simple require(“json.lua”) wouldn’t load a third party json parser library. It looks like a UI5 bug with lzo files handling that’s only been fixed in the private Beta.

Anyway, the screenshot below shows the progress I’m making. The thermostats are displaying live status information pulled via HTTP/JSON from my 3M-50 thermostats. Should only be a little more work to get this module “Alpha” ready.

Considering I only bought my Vera Lite a couple of days ago, it’s not too bad. :slight_smile:


Great stuff, always fun when you hit milestone in your experiments…