
I love it when device manufacturers realize that they can do well by selling a device with documented interfaces, in the hopes that a nebulous community of hackers will invent cool new things for it. So I was pretty happy when the Radio Thermostat Company of America announced that they had an API available for their wifi thermostats (such as the 3M-50 at Home Depot or the CT-30 [amzn] at Amazon). The API docs are currently available under a link on their “latest news” page. The API describes a JSON interface to the thermostat, so you can retrieve or send information using http. For example:
$ curl http://thermostat1/tstat
{"temp":67.50,"tmode":1,"fmode":0,"override":0,"hold":0,
"t_heat":62.00,"time""{"day":1,"hour":9,"minute":47},
"t_type_post":0}
We can get current temperature, set point, mode (heating, cooling, or off), humidity (on some models) etc. And it’s not just a read-only interface; you can set parameters like target temp, schedules, etc, as well as display some information on the screen (4 digits on the CT-30 [amzn] , alphanumeric on the CT-80
[amzn])
There’s a Windows tool out there called “Set Your Thermostat” which seems to have gotten the most press, and there’s a 3rd party iPhone app called Thermostapp which likely uses this API as well. So far all I’ve done with it at home is to query the devices every 5 minutes for setpoint and current temperature, so I can graph stuff out, like in the graph above. At the end if this post is a basic & ugly perl script to gather that information from the thermostat; I process this a little with a bash script and use MRTG to graph it out.
I think there’s a lot more that could be done, such as:
- Display of household electricity data, or thermostat run time, on the display
- Use of indoor & outdoor temps to start heating/cooling in time to hit setpoint at desired time
- Better graphing than MRTG can provide, maybe with Cacti or PCP.
- Addition of X10 or similar occupancy sensors for automatic setback
- Automatic coordination of two zones to minimize boiler firing cycles
I’ll leave you with my simple perl script to gather some basic data from a thermostat:
#!/usr/bin/perl
use LWP::UserAgent;
use MIME::Lite;
use MIME::Base64;
use Getopt::Std;
use JSON;
use strict;
use vars qw/ %opt /;
my $debug = 0;
my $host = "thermostat2";
my $tempurl = "http://$host/tstat";
my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(GET => $tempurl);
my $res = $ua->request($req);
if (! $res->is_success) {
exit;
}
my $scalar = from_json($res->content);
# target isn't there if not in heat mode
my $t_heat = 0;
$t_heat = $scalar->{ 't_heat' } if $scalar->{ 't_heat' };
print "Temp is " . $scalar->{ 'temp' } . "\n";
print "Target temp is " . $t_heat . "\n";
print "Mode is " . $scalar->{ 'tstate' } . "\n";

Which one do you have?
The CT-30/80 don’t have the best reviews on Amazon. I’d probably end up going with the CT-30, because then at least I won’t be out too much money is there are any problems.
-Bryan
I have the 3M/Filtret 3M-50 which is basically the CT-30, and also the CT-80, which – full disclosure – I got gratis from the company a year or so ago for testing & review.
One of the bad CT80 reviews is actually complaining about a different thermostat made by Rite Temp, and upset that Radio Thermostat didn’t help him with it – they may be similar thermostats and have the same parent company but still, you have to at least try to complain to the right people.
The CT-30 got 4.5 stars average, so that’s not too bad.
The screen on the 3M-50 / CT-30 isn’t the best, honestly; the touch screen is a little twitchy. The CT-80 is nicer, but yeah, it’s really on the pricey end. Both of them are a little fiddly to set up & install. Maybe I’ll do a full review of them at some point.
I wish these had the style & build of my Lux thermostat, which looks and works well, with the addition of the WiFi interface, which is really neat.
I wonder if the thermostats your way are compatible with those here — they should be, at least while now I have some Italian-brand (which I didn’t even know before getting them in, they are specialised in heater-related hardware, rather than more general electrical stuff that I’m most aware of), what I had beforehand, for over twenty years, was a Honeywell.
I have been complaining with my mother about our current stupid (and wasteful!) thermostat setup for as long as we have had it. And honestly a munin plugin for the thermostats would be just too nerd not to have ;)
I’m just honestly scared of custom duties of getting two of those my side of the pond.
Pingback: Siri meets wifi thermostat | Eric's Blog
That looks pretty cool, it’s nice to see something that is so hackable from the start. I need to replace the thermostat in my house to get some better control of the heating so I was looking into getting one. Unfortunately after contacting them I discovered they don’t currently have a European licensed WiFi module – so I shall have to wait or find something else for the UK market. So far I haven’t been very impressed with the options.
It is pretty cool, though I wish it were just a little more polished. A combination of my Lux TX9000TS touch screen thermostat’s aesthetic & build plus a wifi interface would make a really slick product. The actual thermostat on the wall is no great shakes, but that’s pretty much made up for by the handy network interface. I should do an actual review some time I suppose.
(Hm maybe a display-less version for even cheaper would be cool, and just rely on the many connected devices everyone carries around by now…)
I’d like to play around with this but I ran the script and saw no output. I replaced the hostname with my themostats name.
Hrm, does something as simple as:
$ curl http://thermostatname/tstatwork for you? I have a local nameserver to translate the name to an IP address; maybe substituting IP address for the name will do the trick?
Ya that works
curl 192.168.1.6/tstat
{“temp”:69.50,”tmode”:1,”fmode”:0,”override”:1,”hold”:1,”t_heat”:70.00,”tstate”:0,”fstate”:0,”time”:{“day”:2,”hour”:22,”minute”:40},”t_type_post”:0}
I tried with the ip instead of the name.. same thing it runs with no error and no output. It should print the Temp, Target and Mode to the console right?
Sorry, my quick and dirty perl sucks!
If it’s not printing anything it must be exiting early. Try adding a print of the status line on failure:
if (! $res->is_success) {print $res->status_line, "\n";
exit;
}
to get a reason for the early exit.
400 URL must be absolute
Weird. Maybe a typo in these lines:
my $host = "thermostat2";my $tempurl = "http://$host/tstat";
Can you paste what you’ve got?
Also, sorry it has no error checking :)
ok I changed ot to:
my $host = “192.168.1.6″;
my $tempurl = “http://$host/tstat”;
and it worked! Thanks! this is fun!
oooh I need me one of these ….
but I was looking at doing something like: http://mcmicken.ca/tag/arduino-thermostat/
even though it might take me forever
Yeah I’d considered DIY but for $99 … I figured what the heck. ;)
I need to do a full review of it at some point; it has its rough spots but in general I’m pretty happy with it.
Got mine installed and I have been polling data once a day on mine. Tried your script in my router running linux but hit this error. Could be limited on my routers openwrt linux running perl.
Can’t locate LWP/UserAgent.pm in @INC (@INC contains: /usr/lib/perl5/5.10 .) at ./tstatperl line 3.
BEGIN failed–compilation aborted at ./tstatperl line 3.
root@OpenWrt:/home/julian#
Here is what I am collecting if its any interest to anyone. I pole this using a crontab daily to get an idea of how much my a/c is running day to day. Again, Im running this through my Tplink router.
# My first script
date >> accompare
curl http://192.168.0.196/tstat/datalog > dataloginfo
cut -d: -f 1,6,7,8,13,14,15 dataloginfo >> accompare
my output looks like this
{“today”:{“hour”:0,”minute”:30}},”yesterday”:{“hour”:5,”minute”:10}}}
Wed May 9 15:16:19 CDT 2012
{“today”:{“hour”:0,”minute”:12}},”yesterday”:{“hour”:1,”minute”:9}}}
Wed May 9 16:01:29 CDT 2012
{“today”:{“hour”:0,”minute”:25}},”yesterday”:{“hour”:1,”minute”:9}}}
Thu May 10 15:38:13 CDT 2012
{“today”:{“hour”:0,”minute”:17}},”yesterday”:{“hour”:2,”minute”:52}}}
Thu May 10 15:42:08 CDT 2012
{“today”:{“hour”:0,”minute”:17}},”yesterday”:{“hour”:2,”minute”:52}}}
Thu May 10 21:42:45 CDT 2012
As you can tell, we had a cold front blow in.
Just need the LWP::UserAgent module installed on the system, then it should work – but whatever works is cool ;)
I’ve lately started sending mine to pachube.com too: https://pachube.com/feeds/47922
Thanks for the info on pachube. One problem I am running against is that I am running this perl on OpenWrt which doesnt seem to have any precompiled modules ready like JSON. Might have to look at building a miniATX or something small that will support a bigger linux install.