もうかれこれ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); }