Quantcast
Channel: 仙石浩明の日記
Viewing all articles
Browse latest Browse all 47

IFTTT に登録できないのでお蔵入りになってた Eco Plugs RC-028W & CT-065W が、UDP パケットを送るだけでコントロールできた!

$
0
0

IoT 機器の多くが、 専用のスマホアプリだけでなく Googleアシスタントや Amazonアレクサからコントロールできる。 しかし、 いちいち音声でコントロールするのはメンドクサイ (なぜ音声以外の方法でもコントロールできるようにしないのか?)。 出かけるときに毎回 「行ってきま〜す」 などと Googleアシスタントに呼び掛けるのは、 いかがなものかと思う。 外出を勝手に検知して家電を適切にコントロール (例えば電気ポットの電源を切る) してくれるほうがずっといい。

IoT 機器を IFTTT に登録すると、 自前のプログラムからコントロールできるようになる。 IoT 機器は Googleアシスタントでコントロールするより、 自前のプログラムでコントロールするに限る。 例えば自宅の Wi-Fi LAN にスマホが繋がっているかプログラムで監視し、 繋がってるスマホがいなくなったら留守になったと判断して、 自動的に電気ポットの電源を切れば、 電気ポットのコンセントを抜いたかどうか出先で心配せずに済む。 あるいはコンセントを抜くのを忘れて寝てしまい、 翌朝電気ポットのお湯が熱いままなのを見て愕然とするより (先月の電気使用量が 600kWh だったので驚いた)、 部屋が暗いときは自動的に電源が切れている方がいい (これはプログラムを書かなくても IFTTT だけで実現できる)。

というわけで持ってる IoT 機器を片っ端から IFTTT に登録したのだけど、 IFTTT に登録できない IoT 機器も残念ながら若干ある。 いまどき IFTTT に登録できない IoT 機器に何の意味があるのだろう? (今なら絶対に買わない) と思うのだけど、 IFTTT の便利さを知る前に買ってしまったのだから後悔先に立たず。 IFTTT の便利さを知ってからは、 お蔵入りになっていた。

Eco Plugs もそんな「使えない」IoT 機器の一つ。 当時としては安価だった (今ならもっと安い) ので Walmart で購入してしまった。 Googleアシスタントや Amazonアレクサには登録できるのに、 肝心の IFTTT に登録できない。

といって通信プロトコルを解析しようにも、 いまどきの IoT 機器はクラウド (ベンダが運用するサーバ) と https で通信するので調べる取っ掛かりがない。 最後の手段、 分解するしかないのか?

ところがググっていると、 Eco Plugs は平文で通信しているという投稿を見つけた。 Eco Plugs はクラウドに登録しなくても、 同一 LAN セグメントならスマホアプリでコントロールできるが、 同一 LAN 内では平文の UDP パケットを飛ばしているらしい。

ありがたいことに Eco Plugs をコントロールする JavaScript プログラムが GitHub に公開されていた。 JavaScript は文法もロクに知らない (^^; のだけど、 見よう見まねで perl で書き直してみる:

#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Std;
use IO::Socket::INET;
our ($opt_v);
(getopts('v') && @ARGV == 3) || &help;
my ($ip, $id, $on) = @ARGV;

my $state = 0x0100;
$state = 0x0101 if $on eq "on";
my $buf = pack("H260", 0);
# Byte 0:3 - Command 0x16000500 = Write, 0x17000500 = Read
substr($buf, 0, 4) = pack("N", 0x16000500);
# Byte 4:7 - Command sequence num - looks random
substr($buf, 4, 4) = pack("N", rand(0xffffffff));
# Byte 8:9 - Not sure what this field is - 0x0200 = Write, 0x0000 = Read
substr($buf, 8, 2) = pack("n", 0x0200);
# Byte 16:31 - ECO Plugs ID ASCII Encoded - <ECO-xxxxxxxx>
substr($buf, 16, 16) = $id;
# Byte 116:119 - The current epoch time in Little Endian
substr($buf, 116, 4) = pack("L", time());
# Byte 124:127 - Not sure what this field is - this value works, but i've seen others 0xCDB8422A
substr($buf, 124, 4) = pack("N", 0xCDB8422A);
# Byte 128:129 - Power state (only for writes)
substr($buf, 128, 2) = pack("n", $state);

my $sock = IO::Socket::INET->new(PeerAddr => $ip, PeerPort => 80,
    Proto => 'udp', Timeout => 1) || die;
my $flags;
print unpack("H*", $buf) . "\n" if $opt_v;
print $sock $buf;
$sock->recv($buf, 1024, $flags);
print unpack("H*", $buf) . "\n" if $opt_v;

# Byte 10:14 - ASCII encoded FW Version - Set in readback only?
my $fwver = substr($buf, 10, 5);
# Byte 48:79 - ECO Plugs name as set in app
my $name = substr($buf, 48, 32);
$name =~ s/\0*$//;
printf("%s (ver %s)\n", $name, $fwver);

sub help {
    print <<EOF;
Usage: ecoplugs <opt> <IP> <ID> <on/off>
opt:   -v           ; verbose
EOF
    exit 1;
} 

長さ 130 バイトの UDP パケット (変数 $buf) を作って Eco Plugs へ送信している (print $sock $buf;) だけなので、 いたってシンプル。 ユーザ認証もないので LAN 内なら誰でもコントロールできる。

Eco Plugs の IP アドレス (第1引数) と、 Eco Plugs の ID 「ECO-XXXXXXXX」(第2引数, XXXXXXXX は MACアドレスの第3〜6オクテット, ただし 16進数の A〜F は大文字限定)、 および「on」あるいは「off」の 3引数を付けて、 この perl プログラムを実行すると、 該当 Eco Plugs をオン/オフし、 Eco Plugs の名前 (スマホアプリで設定できる。以下の例では 「potplug」) と、 ファームウェアのバージョン (以下の例では 「1.6.3」) を表示する。

senri:~ $ ecoplugs -v 192.168.15.123 ECO-01234567 on
16000500940c163b020000000000000045434f2d303132333435363700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a625df5d00000000cdb8422a0101
160005000000163b0000312e362e330045434f2d30313233343536370000000000000000000000000000000000000000706f74706c7567000000000000000000000000000000000000000000000000003031323334353637000000000000000000000000000000000000000000000000a8e23b7ea625df5d00000000cdb8422a
potplug (ver 1.6.3) 

「-v」オプションを付けた場合、 最初に表示される行が Eco Plugs へ送った長さ 130バイトの UDP パケット (260桁の 16進数)、 2行目が Eco Plugs から返ってきた長さ 128バイトの UDP パケット (256桁の 16進数)。 第1引数で指定した IP アドレスが Eco Plugs のものでなかった場合、 あるいは第2引数で指定した ID が間違っている場合など、 応答が返ってこない時は待ち続ける。 ID の 16進数において A〜F が小文字だと応答しないので注意。

Eco PlugsRC-028W (屋外用) および CT-065W (屋内用) で動作を確認したが、 おそらく同シリーズの他の機器でも使えるだろう。 Woods の WiON (スマホアプリが Eco Plugs そっくり) でも使えるらしい。


Viewing all articles
Browse latest Browse all 47

Trending Articles