Hack and / - Temper Temper

 in
A $15 USB thermometer and some spare parts are all I needed to control my refrigerator with Linux.
Install Libraries and Perl Modules

I've always considered Debian as the distribution with the most packaged CPAN modules, but even it didn't have many of the modules I needed for the TEMPer thermometer, so I had to install them from scratch. I'll warn you in advance, this process is a bit tedious, and it reminded me of what it was like to install programs on Linux more than a decade ago. It's amazing how much we take the hard work of package maintainers for granted. At least the first dependencies I had (headers for libusb and a build environment to compile the Perl modules) were available with packages:

$ sudo apt-get install libusb-dev build-essentials

Next I needed to install a few Perl modules with the cpan program. What you'll find is that many of these modules have their own set of dependencies, so when you are prompted to install dependencies, just tell the cpan program “yes”. Also, the first time you run cpan, you might have to go through the initial setup program. If so, just accept the defaults, and you should be fine. Here are the different cpan commands you need to run in order to install the various modules:

$ sudo cpan Bundle::CPAN
$ sudo cpan ExtUtils::MakeMaker
$ sudo cpan Inline::MakeMaker
$ sudo cpan Device::USB
$ sudo cpan Device::USB::PCSensor::HidTEMPer

Next I downloaded a Perl script from www.cs.unc.edu/~hays/dev/bash/temper/temper_mon.pl and made it executable. When run, the script will print the temperature from the thermometer. In my case, I modified it so it output in Fahrenheit instead of Celsius:

#!/usr/bin/perl

use 5.010;
use strict;
use warnings;
use Carp;
use Device::USB;
use Device::USB::PCSensor::HidTEMPer::Device;
use Device::USB::PCSensor::HidTEMPer::NTC;
use Device::USB::PCSensor::HidTEMPer::TEMPer; 
use lib;
use Device::USB::PCSensor::HidTEMPer;

my $pcsensor  = Device::USB::PCSensor::HidTEMPer->new();
my @devices   = $pcsensor->list_devices();
  
foreach my $device ( @devices ){
   say $device->internal()->fahrenheit();
}

I stored the script in /usr/local/sbin/temper_mon.pl and ran it a few times to make sure it output the correct temperature. Then I connected the thermometer to a USB extension cord that was long enough to reach inside the fridge.

My Custom Fridge Script

The final step in the process was to write a script that would pull the temperature and control the power to my fridge based on whether it was within the proper maximum and minimum temperature ranges I had set. I decided to separate the max and min by two degrees so that the compressor wouldn't kick on too much. I also wanted to write the results to a log so I could monitor how well the fridge maintained the temperature. Plus, I thought it would be cool to ssh in to my laptop from anywhere in the world and check on the temperature.

When I first set this up, the weather was cool in the evenings, so I discovered that my fridge would dive down way below the minimum! My solution was to buy a $15 electric heating pad from the drugstore, connect it to another X10 outlet, and put it in the bottom of the fridge. I figured the heat would be gentle enough to maintain the temperature at night without the risks that a proper space heater would have. I set up the script so that it would turn on the heater only if the temperature dipped down one degree below the minimum. I saved my script in /usr/local/sbin/temper.pl:


#!/usr/bin/perl

use 5.010;
use strict;
use warnings;
use Carp;
use Device::USB;
use Device::USB::PCSensor::HidTEMPer::Device;
use Device::USB::PCSensor::HidTEMPer::NTC;
use Device::USB::PCSensor::HidTEMPer::TEMPer;
use lib;
use Device::USB::PCSensor::HidTEMPer;

my $pcsensor  = Device::USB::PCSensor::HidTEMPer->new();
my @devices   = $pcsensor->list_devices();
my $temp_min  = 71;
my $temp_max  = 73;
my $logfile   = '/var/log/temper.log';
my $time      = localtime();
my $temperature;

foreach my $device ( @devices ){
   $temperature = $device->internal()->fahrenheit();
}

open LOG, ">> $logfile" or die "Can't open $logfile: $!\n";

# B4 = Fridge power, B5 = Heater power

# turn on heater if I'm 1F below the low temp
if($temperature < ($temp_min - 1)){
   system('br --port /dev/ttyS0 B5 ON');
   print LOG "$time\t$temperature\tHON\n";
}
elsif($temperature < $temp_min){
   system('br --port /dev/ttyS0 B4 OFF');
   system('br --port /dev/ttyS0 B5 OFF');
   print LOG "$time\t$temperature\tOFF\n";
}
elsif($temperature > $temp_max){
   system('br --port /dev/ttyS0 B4 ON');
   print LOG "$time\t$temperature\tCON\n";
}
else{
   print LOG "$time\t$temperature\t\n";
}

close LOG;

The way the logic of the script works, it allows the temperature to drop or rise naturally while the compressor or heater is on, respectively. It changes the power state of my X10 devices with the br command only when the temperature is outside the preset ranges. I set this script to run every minute with cron, and because I log all of the power states, it's easy to watch the temperature float between extremes. I did a bit of tuning at the beginning with the various ranges, and with the current script, the temperature floats between 1°F below the minimum temperature and 1°F above the maximum temperature, which is good enough for me. If I wanted more accuracy, I always could set $min and $max to be closer to each other.

Since the system has been in place, I've been able to maintain the temperature successfully for the first batch of beer I put in the fridge. If you look closely at Figure 2, you can see the little thermometer on the right-hand shelf. Even though my laptop is old, it has plenty of horsepower to spare, so eventually I will graph all of the temperature data and serve it out over Apache. If Bill were here, I'm sure he'd tell me to tweet the temperature.

Figure 2. A West Coast-Style Red Ale in My Linux-Powered Fridge

______________________

Kyle Rankin is a director of engineering operations in the San Francisco Bay Area, the author of a number of books including DevOps Troubleshooting and The Official Ubuntu Server Book, and is a columnist for Linux Journal.

Webinar
One Click, Universal Protection: Implementing Centralized Security Policies on Linux Systems

As Linux continues to play an ever increasing role in corporate data centers and institutions, ensuring the integrity and protection of these systems must be a priority. With 60% of the world's websites and an increasing share of organization's mission-critical workloads running on Linux, failing to stop malware and other advanced threats on Linux can increasingly impact an organization's reputation and bottom line.

Learn More

Sponsored by Bit9

Webinar
Linux Backup and Recovery Webinar

Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.

In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.

Learn More

Sponsored by Storix