$$self{cool_start} = $::Time;

Creating the object:

   $thermostat = new RCSsTR40;
   die "rcs init failed\n" unless $thermostat;

Use internet weather temperature to automatically update the outside temperature on the display. If you have a physical external temp monitor hooked up to the unit, then this will have no effect. If you have a weather station or an iButton, just change the reference from \$Weather{TempInternet} to something else and stop running 'Get internet weather data' every hour.

   if ($Startup or $Reload) {
   if ($New_Hour or $Startup) {
      run_voice_cmd 'Get internet weather data';

Watch for temperature changes (can do the same with outside_temp_change if you have a physical outside temperature monitor hooked up to the TR40).

   if (state_now $thermostat eq 'temp_change') {
      my $temp = $thermostat->get_temp();
      print "Got new thermostat temperature: $temp\n";

Watch for other changes such as fan mode, system mode, etc. I only currently watch for vacation mode (enabled/disabled by holding down the HOLD button for 3 seconds) and use this to enable/disable the Misterhouse vacation mode. This module looks for the temperatures to change to 66 and 80 at the same time to detect this. This is what my unit does when you place it into vacation mode. You can change the temperatures (locally or remotely) after it goes into vacation mode and the mode will still remain active until turned off on the control panel.

   $mode_vacation = new Generic_Item;
   $mode_vacation->set_states('all', 'one', 'nobody');

   if ($state = state_changed $thermostat) {
      print "Got new thermostat state: $state\n";
      if ($state eq 'vacation') {
         set $mode_vacation 'all';
      } elsif ($state eq 'no_vacation') {
         set $mode_vacation 'nobody';

And, you can set the temperature and mode at will...

   if (state_changed $mode_vacation eq 'all') {

All of the states that may be set:

   temp_change: inside temperature changed (call get_temp() to get value)
   outside_temp_change: outside temperature changed (call
      get_outside_temp() to get value)
   heat_sp_change: Heat setpoint was changed from the control pad
      (call get_heat_sp() to get value).
   cool_sp_change: Cool setpoint was changed from the control pad
      (call get_cool_sp() to get value).
   off: System mode set to 'off'
   heat: System mode set to 'heat'
   cool: System mode set to 'cool'
   auto: System mode set to 'auto'
   emerg_heat: System mode set to emergency heat (only with heat pumps?)
   invalid: Controlled failed to communicate with the control pad
   fan_on: Fan was turned on
   fan_auto: Fan was set to auto mode
   hold: Program hold was activated by user
   run: Program mode was resumed by user
   vacation: Vacation mode was enabled by user
   no_vacation: Vacation mode was turned off by user


Control RCS serial (rs232/rs485) TR40 model thermostats. This will probably need some enhancement to work with rs485, or at least if you want to put multiple units on the same drop.

I created a new module because I don't have a full understanding of the compatibility issues with older/other models. My new module *should* be usable with multiple thermostats and could be expanded to support some of the more advanced RCS thermostat modules.


PS - I don't know if I'm just stupid or what, but I could not send anything to the TR40 through either minicom (Linux) or HypterTerminal (Windows), but I could receive messages (i.e. when the TR40 was powered up). I thought it was broken, but it turns out that this module talked to it fine. Who knows.

I don't know why they don't mention this in the manual... maybe it is common knowledge? But I went to Radio Shack and bought a female, 9-pin serial connector and use that to wire into the TR40 control unit. These pin-outs worked for me:

   Cable            Controller
                    +V (not connected)
   Pin 5 (SG)       G (Gnd)
   Pin 2 (receive)  T+ (transmit)
   Pin 3 (transmit) R- (receive)


I recommend enabling auto-send either in the configuration menu or by calling (once) the function: set_variable(74,1); I don't like having to leave the thermostat in "hold" mode, so instead I clear out the schedule (just once using the clear_schedule() command).


The get_heat_run_time() and get_cool_run_time() functions are not always accurate... I must still have some bugs there.





Clears all runtime data


Returns # of seconds of heating since last reset


Returns # of seconds of cooling since last reset


Sets system mode to argument: 'off', 'heat', 'cool', 'auto', or 'emerg_heat' (if available)


Sets fan to 'on' or 'off'


Sets schedule control to 'hold' or 'run'. Note that this has no effect if there is no scehdule defined.


Locks the TR40 display.


Unlocks the TR40 display.


Creates a schedule entry. Parameters are:

  1) day of week (1=Sunday, ..., 7=Saturday)
  2) entry # (1 through 4)
  3) hour (00-23)
  4) minute (00-59)
  5) heat setpoint
  6) cool setpoint

A convenience function that can be used to clear out the entire schedule. This is permanent so it only has to be run once. I use this so that Misterhouse can completely control the thermostat.


Sets an arbitrary variable to an arbitrary value. First argument is the variable number (from back of programming manual) and the second argument is the value.


Clears all text messages from the system


Sends an arbitrary text message to the display. The TR40 automatically timestamps the message. Max length is 80 characters and the double-quotes character (") is not allowed.

Use carriage returns (\r) for new lines


Sets a new cool setpoint.


Sets a new heat setpoint.


Sets the displayed outside temp. Only works if no external temperature sensor is connected to the TR40.


Sets a remote temperature that will be average with the internal temperature sensor when determining the actual current temperature. Does not work if you actually have a remote temperature sensor connected.


Sends Misterhouse's current date/time to the TR40. Note that the module automatically calls this once per hour.


Pass in a scalar reference to this function and it will automatically set the displayed outside temperature whenever the scalar changes. See above for an example.


Returns the current inside temperature.


Returns the current outside temperature.


Returns the current heat setpoint.


Returns the current cool setpoint.


Returns the current mode (off, auto, heat, cool, emerg_heat)


Returns the current fan mode (fan_on or fan_auto)


Returns the current schedule mode ('hold' or 'run'). Note that this will always return 'hold' if there is no schedule defined.


Returns either 'vacation' or 'no_vacation'. Vacation mode is (de)activated by pressing and holding the away button for 3 seconds.

set_heat_limits(min, max)

Specify minimum and maximum heat setpoints

set_cool_limits(min, max)

Specify minimum and maximum cool setpoints


RCSsTR40_serial_port=/dev/ttyS4 RCSsTR40_baudrate=9600 RCSsTR40_address=1 to 255 (for mutiple thermostats on a 422 interface) May be omitted (or 1) if using RS232.


Initial version created by Chris Witte <cwitte@xmlhq.com> Expanded for TR40 by Kirk Bauer <kirk@kaybee.org>




This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.