黑客与 / - 磨练我的脾气

作者:Kyle Rankin

在我 2010 年 8 月的专栏中,我写了如何使用一台旧笔记本电脑、一些备用的 X10 设备和一个 TEMPer USB 温度计来控制我的冰箱,以便在一个良好的受控环境中发酵啤酒。从那时起,我收到了许多来自 Linux Journal 读者的电子邮件,讨论他们自己创建完美啤酒冰箱的项目。在阅读了关于 Arduino 驱动的冰箱和其他硬件破解解决方案后,我开始感到嫉妒,并开始认为我的笔记本电脑解决方案虽然简单,但还是矫枉过正了。我的硬件破解技能还没有达到 Arduino 的水平,所以我最终决定看看我周围的其他低功耗 Linux 设备(事实证明我有很多),看看我是否能说服其中一台来控制我的冰箱。

我需要的设备必须满足几个标准。第一,它应该能够运行 Linux。第二,理想情况下,它应该至少有一个 USB 端口,我可以用来(必要时使用集线器)连接我的 USB 温度计,如果它没有串行端口,还可以连接一个 USB 串行适配器,这样我就可以使用我的 X10 串行加密狗。对不起,Spykee 机器人,但我的最终选择是一个粉红色的 Pogoplug(图 1)。Pogoplug 是一款漂亮的小型 Linux 驱动设备,允许您连接自己的 USB 硬盘驱动器,然后无论您身在何处,只要您有互联网连接,都可以向您提供数据。可以把它想象成一个个人 Dropbox,只不过您可以完全控制存储和数据。Pogoplug 周围还有一个规模庞大的社区,提供第三方应用程序,甚至还有一个基于 Arch Linux 的自定义 Linux 发行版。

Hack and / - Working on My Temper

图 1. Pogoplug—小巧、粉红、与众不同

Plugbox Linux 安装

对于我的目的来说,Pogoplug 最好的地方在于它体积小、功耗低、有一个带有软件包管理的自定义 Linux 发行版,最重要的是,它有四个 USB 端口。一旦我决定使用它而不是我的笔记本电脑,下一步就是在上面安装基于 Arch Linux 的 Plugbox Linux。这个发行版托管在 www.plugapps.com 上,该站点为 Pogoplug、DockStar 和 SheevaPlug 设备提供各种第三方应用程序和软件包。我只是逐字逐句地按照 Plugbox Linux 的安装文档进行操作,所以在这里就不重新发布了,只需按照 www.plugapps.com/index.php5?title=PlugApps:Pogoplug_Setboot 上的步骤操作即可。请务必遵循关于设置 openntpd 的建议;否则,Plugbox 的时间会非常不准,并且在您尝试安装和编译软件时,您会收到奇怪的警告和错误。

本质上,Plugbox Linux 将自己安装在您提供的外部 USB 驱动器上,然后设置引导加载程序,以便如果插入驱动器,它将尝试从中引导;否则,它将从本地 Pogoplug 固件引导。这提供了一种简单、相对低风险的方式来修改设备以执行您想要的操作,同时仍然能够返回默认设置。虽然我可能已经能够让本地 Linux 安装执行我想要的操作,但 Plugbox 使用 Arch Linux 的 pacman 具有简单的软件包管理,因此我也可以随时返回标准的 Pogoplug 固件。在我的例子中,我使用了一个备用的 1GB U 盘作为操作系统,这似乎已经足够了。

Bottlerocket 轻而易举

Plugbox 安装完成后,我能够引导进入环境并通过 SSH 配置一切。现在,我所需要做的就是重复我的步骤,以获得我的 TEMPer 设备需要的 CPAN 模块,安装 bottlerocket,我就应该完成了。我想我被 Debian 中提供的所有软件包宠坏了,但话说回来,我并没有期望 bottlerocket 会为这个自定义发行版打包。我想我应该能够获得我需要的 CPAN 模块,但真正的问题是我是否能够编译 bottlerocket。没有它,这个项目就将结束。事实证明,这并不太困难。我只是使用 pacman 安装了我的构建环境,然后像过去那样下载并编译了 bottlerocket

# pacman -S gcc make
# wget http://www.linuxha.com/bottlerocket/bottlerocket-current.tar.gz
# tar xvfz bottlerocket-current.tar.gz
# cd bottlerocket-0.04c/
# ./configure
# make
# make install

当我测试 bottlerocket 时,我注意到了一些有趣的事情。我插入的 USB 转串口适配器被检测到并且似乎可以工作;但是,在我第一次运行 bottlerocket 后,任何后续执行都会导致 /dev/ttyUSB0 出现错误。我必须在每次 bottlerocket 执行之间卸载并重新加载该特定的 USB 转串口模块才能使其正常工作。我从经验中得知,并非所有 USB 转串口适配器都是一样的,有些适配器在发送中断信号到您的控制台方面做得更好,所以我认为这只是一个廉价的串口适配器,没有完整的串口支持的情况。我没有简单地忍受每次都重新加载模块的笨拙方法,而是用另一个我知道对中断信号有极好支持并且总体上具有更好兼容性的适配器替换了这个适配器。使用这个新的适配器,我能够毫无问题地打开和关闭我的冰箱电源。

注意:关于 Pacman 的快速抱怨

我不得不承认 Plugbox 是我第一次涉足 Arch Linux 发行版。我知道很多人非常喜欢 Arch,我实际上对发行版本身没有意见,但我想说几句关于 pacman 的话。首先,我喜欢这个名字。其次,是谁想出了命令参数?以我的经验,参数中的大写字母总是保留在您用完小写字母参数时使用(或者,或者,执行与小写字母参数相反的操作),尽管有时参数与您正在执行的操作无关,但至少对于大多数程序来说,最常用的操作是那些具有直观参数的操作。例如,我完全期望 pacman 使用 -i 来安装软件包,或者可能使用长手 --install。它使用的 -S 参数根本没有意义(我知道它代表“Sync”,但这离“install”还很远),而 -Ss 参数来搜索与关键字匹配的软件包就更没有意义了。我知道只需要一秒钟就可以习惯它,但我仍然认为有很多更直观的字母可供选择。

CPAN 是一位严厉的女主人

由于构建 bottlerocket 如此容易,我以为使用 CPAN 安装我需要的所有 Perl 模块也会相对容易。对于那些不是 Perl 黑客的人来说,Perl 在线 www.cpan.org 上提供了一个庞大的额外模块存储库。如果您需要特定的 Perl 模块,您可以使用本地系统上的 cpan 二进制文件来拉取和构建这些模块,就像现代软件包管理器一样。我认为即使 Plugbox 没有包含很多 Perl 模块,我也会识别出我需要的模块并逐个安装它们,就像我在之前的 TEMPer 专栏中那样。现实情况是,虽然 Plugbox 确实包含了 Perl,甚至包含了 cpan 二进制文件,但它并没有包含很多 CPAN 实际工作所需的必要模块。

老实说,一旦我让 CPAN 工作起来,这个项目的其他一切都很简单,但是这个过程花费了最多的时间和精力,它真的让我想起了 Linux 很久以前的样子,那时你会发现 Freshmeat 上有一个很酷的项目,下载源代码,然后花两天时间来追踪所有的依赖项。我终于找到了我需要的软件包和库的神奇列表,在这种情况下,我不得不从 Plugbox 安装一些软件包,并进行手动模块编译

# pacman -S perl-yaml perl-xml-libxml 
# pacman -S perl-text-query perl-text-diff perl-text-reform
# wget http://search.cpan.org/CPAN/authors/id/R/RC/RCLAMP/
 ↪Text-Glob-0.08.tar.gz
# tar xfvz Text-Glob-0.08.tar.gz
# cd Text-Glob-0.08
# perl Build.PL
# perl Build test
# perl Build install

从那时起,我就可以让 cpan 二进制文件正常工作,我可以按照我在上一篇专栏中列出的安装步骤来完成该过程(我很高兴我为自己很好地记录了这一点)。之后,我所要做的就是编辑我的 temper.pl 脚本,以便它引用 /dev/ttyUSB0 而不是本地串口,并创建一个名为 /etc/cron.d/temper 的文件,其中包含以下数据

* *  * * *   /usr/local/sbin/temper.pl

在我重启 cron 后 (/etc/rc.d/crond restart),我能够检查我的日志并看到脚本实际上正在读取温度并像我的笔记本电脑一样控制冰箱。如果您想用您的 Pogoplug 做类似的事情,清单 1 是脚本的当前迭代。

清单 1. 冰箱温度控制脚本

#!/usr/bin/perl

my $temp_min  = 67;
my $temp_max  = 69;

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 $logfile   = '/var/log/temper.log';
my $time      = localtime();
my $temperature;

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

die unless $temperature;

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('/usr/local/bin/br --port /dev/ttyUSB0 B5 ON');
   system('/usr/local/bin/br --port /dev/ttyUSB0 B4 OFF');
   print LOG "$time\t$temperature\tHON\n";
}
elsif($temperature < $temp_min){
   system('/usr/local/bin/br --port /dev/ttyUSB0 B4 OFF');
   system('/usr/local/bin/br --port /dev/ttyUSB0 B5 OFF');
   print LOG "$time\t$temperature\tOFF\n";
}
elsif($temperature > $temp_max){
   system('/usr/local/bin/br --port /dev/ttyUSB0 B4 ON');
   system('/usr/local/bin/br --port /dev/ttyUSB0 B5 OFF');
   print LOG "$time\t$temperature\tCON\n";
}
else{
   print LOG "$time\t$temperature\t\n";
}

close LOG;

现在我已经运行了几周没有问题,我真的很喜欢这个设备是多么安静和低功耗。此外,它在我的冰箱顶部占用的空间也更小。我看到的唯一真正的缺点是设备上没有屏幕。在我的笔记本电脑上,如果我想查看温度,我只需要打开盖子;现在,我必须ssh进入 Pogoplug。虽然我为此使用了 Pogoplug,但我认为您可以将这些步骤转换为许多其他具有 USB 端口的小型 Linux 设备,例如 NSLU2—前提是它包含 Perl 和 gcc 构建环境。现在我可以将我的旧笔记本电脑用于更崇高的追求——比如也许有一天为我的烤肉机供电。

资源

Pogoplug: www.pogoplug.com

Pogoplug 的应用程序,包括 Plugbox: www.plugapps.com

Kyle Rankin 是旧金山湾区的系统架构师,也是许多书籍的作者,包括 The Official Ubuntu Server Book, Knoppix HacksUbuntu Hacks。他目前是北湾 Linux 用户组的主席。

加载 Disqus 评论