もうかれこれ5年も前の2013年2月5日に、「PC-OP-RS1」を利用して照明をPCから制御する仕掛けの最終稿を記述したが、この度、アイリスオーヤマのシーリングライトを自分の部屋に設置したので、それのリモコン対応についても記録しておく。
先ずは以前の仕掛けをそのまま利用して、シーリングライトの制御を追加した制御用HP。
HTMLからCGIを呼び出すにはフォームを利用している。
しかしこの方法だとプルダウンメニューでアクションを選択し、プッシュボタンを押してCGIを起動するため、選択肢が多くなると煩わしくなる。
そこで直感的に対象の指定とアクションを行える「クリッカブルマップ」という手法を取り入れることにした。
HTMLのイメージは以下の図のようになる。
プロトタイプは、点灯/消灯したい照明にマウスポインタを置き、クリックするだけ。
HTML記述は以下のとおり。
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<title>リモコン・サーバ(By Kouya.Tatsumi)</title>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-JP" />
</head>
<body>
<center><font size=4>リモート制御</font></center><p>
<img src="lighting.png" usemap="#ImageMap" alt="" />
<map name="ImageMap">
<area shape="circle" coords="84,116,49" href="../cgi-bin/irrc.cgi?Seiling=B1" alt="メモリ点灯" />
<area shape="rect" coords="38,194,122,265" href="../cgi-bin/irrc.cgi?Seiling=B2" alt="明るい" />
<area shape="rect" coords="38,267,122,335" href="../cgi-bin/irrc.cgi?Seiling=B3" alt="暗い" />
<area shape="rect" coords="38,368,122,450" href="../cgi-bin/irrc.cgi?Seiling=B4" alt="メモリ設定" />
<area shape="rect" coords="38,470,122,553" href="../cgi-bin/irrc.cgi?Seiling=B5" alt="30%節電" />
<area shape="rect" coords="157,66,240,102" href="../cgi-bin/irrc.cgi?Seiling=B6" alt="全灯" />
<area shape="rect" coords="157,124,240,160" href="../cgi-bin/irrc.cgi?Seiling=B7" alt="消灯" />
<area shape="rect" coords="157,195,240,265" href="../cgi-bin/irrc.cgi?Seiling=B8" alt="常夜灯明" />
<area shape="rect" coords="157,265,240,336" href="../cgi-bin/irrc.cgi?Seiling=B99" alt="常夜灯暗" />
<area shape="rect" coords="157,368,240,451" href="../cgi-bin/irrc.cgi?Seiling=C1" alt="おやすみ" />
<area shape="rect" coords="157,468,240,553" href="../cgi-bin/irrc.cgi?Seiling=C2" alt="50%節電" />
<area shape="circle" coords="360,179,43" href="../cgi-bin/irrc.cgi?SpotLight=P1" alt="LED1" />
<area shape="circle" coords="455,179,43" href="../cgi-bin/irrc.cgi?SpotLight=P2" alt="LED2" />
<area shape="circle" coords="553,179,43" href="../cgi-bin/irrc.cgi?SpotLight=P3" alt="LED3" />
</map>
</body>
</html>
上のHTMLから呼び出すCGIは以下の内容となっている。
#!/usr/local/bin/perl
#
# 2013/01/15 by Kouya.Tatsumi
#
use strict;
use warnings;
use Device::SerialPort;
use Getopt::Std;
my %Ir;
$Ir{'P1'} = [
pack("H*", "ffffffffffffffffffffff0300000000801ffce0073ef0811ffc00003ef00100fc00003f00c00f00e00300f801007ef00300f8c00f00f0831f00c0073ef0831ff800003ef00300fcc00700f00100fc00003f00c00f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffff0100001f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
];
$Ir{'P2'} = [
pack("H*", "ffffffffffffffffffffff0300000000801ffce0073ef0811ffc00003ef00100fc00003f00c00f00e00300f801007ef00300f800007e00801ffc00003ef0811ffcc0073ef00300fcc00700f00100fc00003f00c00f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffff0100001f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
];
$Ir{'P3'} = [
pack("H*", "ffffffffffffffffffffff0300000000801ffce0073ef0831ffc00003ef00100fc00003f00800f00e00300f801007ef00300f8c00f7e00801f00c0077ef0831ff800007e00801ffcc00700f00100fc00003f00c00f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffff0100001f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
];
$Ir{'L1'} = [
pack("H*", "ffff1fc0ffffffffffff1f80ff3ff8ff830f3ef8e0830f3ef8e0ff0ffeffe0830f3ef8e0ff0f3ef8ff830f3ef8e0830f3ef8e0830f3ef8e0830f3ef8ff830ffeffe0ff0ffeffe083ff3ff8ffc30f000000000000000000000000f8ffffffffffff01f8ff87ff3ff8e0831f7ef8e1871ffeffe1ff1f7ef8e1871ffeffe187ff7ff8e1871f7ef8e1871f7ef0c1071f7cf0c107ff7ff0c1ff1ffcffc1ff1f7ef8ff87ff7ff800000000000000000000000080ffffffffffff3f00ff7ff0ff071f7cf0c1071f7cf0c1ff1ffcffc1071f7cf0c1ff1f7cf0ff071f7cf0c1071f7cf0c1071ffcf0c30f3ffcf0ff0f3ffcffc3ff"),
];
$Ir{'L2'} = [
pack("H*", "ffff1fc0ffffffffffff1f80ff3ff8ff830f3ef8e0830f3ef8e0ff0ffeffe0830f3ef8e0ff0f3ef8e0830f3ef8e0ff0f3ef8e0830f3ef8e0871f7ef8ff87ff3ff8ff83ff3ff8ff830f3ef8ff830f000000000000000000000000f8ffffffffffff03f0ff07ff7ff0c1071f7cf0c1071ffcffc1ff1f7cf0c1071ffcffc1071f7cf0c1071ffcffc1071f7cf0c10f3ffcf0c30ffffff0ff0ffffff0ff07ff7ff0c107ff7ff001000000000000000000000000ffffffffffff7f00feffe0ff0f3ef8e0830f3ef8e083ff3ff8ff830f3ef8e083ff3ff8e0830f3ef8e187ff7ff8e1871f7ef8e1071f7cf0c1ff1ffcffc1ff1f"),
];
$Ir{'L3'} = [
pack("H*", "ffff1fc0ffffffffffff1f80ff3ff8ffc30f3ef8e0830f3ef8e0ff0ffeffe0830f3ef8e0ff0f3ef8e0830f3ef8e083ff3ff8e0830f3ef8e0871f7ef8ff87ff3ff8ff83ff3ff8ff830ffeffe0830f000000000000000000000000f8ffffffffffff03f0ff07ff7ff0c1071f7cf0c1071ffcffc1ff1f7cf0c1071ffcffc1071f7cf0c1071f7cf0ff071f7cf0c1071ffcf0c30ffffff0ff07ff7ff0ff07ff7ff0c1ff1f7cf001000000000000000000000000ffffffffffff7f00feffe0ff0f3ef8e0830f3ef8e083ff3ff8ff830f3ef8e083ff3ff8e0830f3ef8e0830ffeffe0830f3ef8e0871f7ef8e1ff1ffeffe1ff0f"),
];
$Ir{'L4'} = [
pack("H*", "ffff1fc0ffffffffffff1f80ff3ff8ff830f3ef8e0830f3ef8e0ff0ffeffe0830f3ef8e0ff0f3ef8e0830f3ef8e0830ffeffe0830f3ef8e0871f7ef8e1ff1ffeffe0ff0ffeffe083ff3ff8ff830f000000000000000000000000f8ffffffffffff03f0ff07ff7ff8e1871f7cf0c1071ffcffc1ff1f7cf0c1071ffcffc1071f7cf0c1071f7cf0c1ff1f7cf0c1071f7cf0c1071ffcffc1ff1ffcffc1ff1f7cf0ff07ff7ff801000000000000000000000000ffffffffffff3f00fffff0ff071f7cf0c30f3ffcf0c3ff3ffcffc30f3ffcf0c3ff3ffcf0c30f3ffce0830f3ef8ff830f3ef8e0830f3ef8e083ff3ff8ff83ff"),
];
$Ir{'L5'} = [
pack("H*", "ffff1fc0ffffffffffff1f80ff3ff8ff830f3ef8e0830f3ef8e0ff0ffeffe0830f3ef8e0ff0f3ef8e0830f3ef8e0830f3ef8e187ff7ff8e0871f7ef8ff87ff3ff8ff830ffeffe083ff3ff8ff830f000000000000000000000000f8ffffffffffff03f0ff07ff7ff0c1071f7cf0c1071ffcffc1ff1f7cf0c1071ffcffc1071f7cf0c1071f7cf0c1071f7cf0ff071f7cf0c10fff7ff0ff07ff7ff0c1ff1f7cf0ff07ff7ff001000000000000000000000000ffffffffffff7f00feffe0ff0f3ffce0830f3ef8e083ff3ff8ff830f3ef8e083ff3ff8e0830f3ef8e0830f3ef8e0830ffeffe0830f3ef8e0ff0ffeffe0ff0f"),
];
$Ir{'R1'} = [
pack("H*", "ffff1fc0ffffffffffff1f80ff3ff8ffc30f3ef8e0830f3ef8e0ff0ffeffe0830f3ef8e0ff0f3ef8e0ff0f3ef8e0830f3ef8e0830f3ef8e0830f3ef8ff83ff3ff8e0ff0ffeffe083ff3ff8ffc30f000000000000000000000000f8ffffffffffff01f8ff83ff3ff8e0830f3ef8e0871ffeffe1ff0f3ef8e0831ffeffe0831ffeffe0830f7ef8e1871f7ef8e1871f7cf0c107ff7ff0ff871ffcffe1ff1f7ef8ff83ff3ff800000000000000000000000080ffffffffffff3f00ff7ff0ff071f7cf0c1071f7cf0c1ff1ffcffc1071f7cf0c1ff1f7cf0c1ff1f7cf0c1071f7cf0c1071f7cf0c1071f7cf0ff07ff7ff0c1ff"),
];
$Ir{'R2'} = [
pack("H*", "ffff1fc0ffffffffffff1f80ff3ff8ffc30f3ff8e0830f3ef8e0ff0ffeffe0830f3ef8e0ff0ffefff0830f3ef8e0830f3ef8e0830f3ef8e0830f3ef8e0ff0ffeffe0ff0ffeffe083ff3ff8ffc30f000000000000000000000000f8ffffffffffff01f8ff83ff3ff8e0830f3ef8e0871ffeffe0ff0f3ef8e0831ffeffe0ff0f3ef8e0830f7ef8e1871f7ef8e1871f7cf0c1071ffcffc1ff1ffeffe1ff1f7ef8ff83ff3ff800000000000000000000000080ffffffffffff3f00ff7ff0ff071f7cf0c1071f7cf0c1ff1ffcffc1071f7cf0c1ff1ffcffc1071f7cf0c1071f7cf0c1071f7cf0c1071f7cf0c1ff1ffcffc1ff"),
];
$Ir{'R3'} = [
pack("H*", "ffff1fc0ffffffffffff1f80ff3ff8ff830f3ef8e0830f3ef8e0ff0ffeffe0830f3ef8e0ff0f3ef8e0830f3ef8ff830f3ef8e0830f7ef8e1871f7ef8ff87ff7ff8ff83ff3ff8ff83ff3ff8ff83ff3ff800000000000000000000000080ffffffffffff3f00ff7ff8ff871f7ef8c1071f7cf0c1ff1ffcffc1071f7cf0c1ff1f7cf0c1071f7cf0ff071f7cf0c1071f7cf0c1071ffcf0ff07ff7ff0ff07ff7ff0ff07ff7ff0ff07ff7ff801000000000000000000000000ffffffffffff7f00fffff0ff0f3ffcf0c30f3ef8e083ff3ff8ff830f3ef8e083ff3ff8e0830f3ef8e0ff0f3ef8e0830f3ef8e0830f7ef8e1ff1f"),
];
$Ir{'R4'} = [
pack("H*", "ffff1fc0ffffffffffff1f80ff3ff8ff830f3ef8e0830f3ef8e0ff0ffeffe0830f3ef8e0ff0f3ef8e0830ffeffe0830f3ef8e0830f7ef8e1871f7ef8ff87ff7ff8ff83ff3ff8e083ff3ff8ff830f000000000000000000000000f8ffffffffffff03f0ff07ff7ff0c1071f7cf0c1071ffcffc1ff1f7cf0c1071ffcffc1071f7cf0c1ff1f7cf0c1071f7cf0c10f3ffcf0c30ffffff0ff0fff7ff0ff071f7cf0ff07ff7ff001000000000000000000000000ffffffffffff7f00feffe0ff0f3ef8e0830f3ef8e083ff3ff8ff830f3ef8e083ff3ff8e0830f3ef8ff830f3ef8e0830f3ef8e0871f7ef8e1ff1ffeffe1ff0f"),
];
$Ir{'R5'} = [
pack("H*", "ffff1fc0ffffffffffff1f80ff3ff8ffc30f3ef8e0830f3ef8e0ff0ffeffe0830f3ef8e0ff0f3ef8e083ff3ff8e0830f3ef8e0830f3ef8e0830f7ef8ff83ff3ff8ff830ffeffe083ff3ff8ff830f000000000000000000000000f8ffffffffffff03f0ff87ff7ff8e1871f7ef0c1071ffcffc1ff1f7ef0c1071ffcffc1071f7cf0ff071f7cf0c1071f7cf0c1071f7cf0c107ff7ff0ff07ff7ff0c1ff1f7cf0ff07ff7ff801000000000000000000000000ffffffffffff3f00fffff0ff071ffcf0c30f3ffcf0c3ff3ffcffc30f3ffcf0c3ff3ffcf0c30ffefff0c30f3ff8e0830f3ef8e0830f3ef8e0ff0ffeffe0ff0f"),
];
$Ir{'R6'} = [
pack("H*", "ffff1fc0ffffffffffff1f80ff3ff8ff830f3ef8e0830f3ef8e0ff0ffeffe0830f3ef8e0ff0f3ef8e0830f3ef8e0830f3ef8e0830ffeffe0830f7ef8ff83ff3ff8ff83ff3ff8e083ff3ff8ff830f000000000000000000000000f8ffffffffffff03f0ff87ff7ff8e1871f7ef0c1071ffcffc1ff1f7ef0c1071ffcffc1071f7cf0c1071f7cf0c1071f7cf0c1ff1f7cf0c107ff7ff0ff07ff7ff0ff071f7cf0ff07ff7ff801000000000000000000000000ffffffffffff3f00fffff0ff071ffcf0c30f3ffcf0c3ff3ffcffc30f3ffcf0c3ff3ffcf0c30f3ff8e0830f3ef8e0830f3ef8ff830f3ef8e0ff0ffeffe0ff0f"),
];
my $url = "http://blue.runrun.dip.jp:7000/index.html";
my $device = "/dev/ttyU0";
my $ch = 1;
my $port = &openDev;
&sendData($port, "69"); # LED command
&expect("4f", &readData($port, 1));
my $buffer="";
if ($ENV{'REQUEST_METHOD'} eq "POST"){
read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'});
}
else {
$buffer = $ENV{'QUERY_STRING'};
}
my @pairs = split(/&/,$buffer);
foreach my $pair (@pairs){
(my $name,my $value) = split(/=/,$pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
if ($name eq 'SpotLight'){
$ch = 1;
} else {
$ch = 2;
}
if (defined $Ir{$value}) {
for my $ir (@{$Ir{$value}}) {
&transmit($port, $ch, $ir);
}
}
}
print "Location: $url\n\n";
sub openDev {
my $port = new Device::SerialPort($device) || die;
$port->user_msg(1);
$port->error_msg(1);
$port->baudrate(115200);
$port->databits(8);
$port->parity("none");
$port->stopbits(1);
$port->handshake("none");
$port->read_const_time(100); # 0.1 sec
$port->read_char_time(5);
$port;
}
sub transmit {
my ($port, $ch, $data) = @_;
&sendData($port, "74"); # transmit
&expect("59", &readData($port, 1));
&sendData($port, sprintf("3%d", $ch % 10));
&expect("59", &readData($port, 1));
$port->write($data) || die;
&expect("45", &readData($port, 1));
}
sub sendData {
my ($port, $str) = @_;
$port->write(pack("H*", $str)) || die;
}
sub readData {
my ($port, $len, $timeout) = @_;
my $i = 0;
my $j = 0;
my $data;
while ($i < $len) { my ($l, $d) = $port->read(1);
if ($l > 0) {
$data .= $d;
$i += $l;
$j = 0;
} else {
$j++;
}
}
$data;
}
sub expect {
my ($ex, $d) = @_;
my $str = unpack("H*", $d);
}