2016年2月11日

【FHC】コーヒー入れておいて。的なシステムを作ってみた【WATCH BOOT】

コーヒーは濃ゆいのが好きな城間直裕です。
時代はIoTが盛んな昨今、僕もその流れに便乗し、タイトルの通りFHCからコーヒーメーカーを操作するシステムを作ってみました。



■きっかけ

今までコーヒーは自分でドリップして飲んでいたのですが、先日食器を洗っているときにうっかりコーヒーサーバーを落として割ってしまったことが始まり。

こんな感じのフラスコみたいなの

直接コーヒーカップにドリップしてもいいのですが、自分の場合2~3杯分まとめてドリップすることが多いので、新たなコーヒーサーバーを購入しなければなりません。

ただ、朝とか忙しいからコーヒーメーカー欲しいんだよなぁ…とも前々から感じていたところ。

この際だからコーヒーメーカー導入してしまおうか!せっかくだからFHCから遠隔操作できるような製品がないかしら!
…という流れで、良さ気なコーヒーメーカーが無いか探しに秋葉原へ。

ヨドバシに向かう途中、ジャンク通りを通っていたら面白いものを発見。

明京電機製リブーター WATCH BOOT mini RPC-T4H

LANから電源をON/OFFできるアダプタです。

へぇLANから操作するってのもあるのかーコンソールポートもついてるからシリアル通信もできそうだなぁ。と思いながらこのときは特に何も考えずに素通り。

ヨドバシでコーヒーメーカーを物色し、あんまりパッとしたものが見つからなかったので、購入をあきらめようかと思っていたところ。



思い立ったが吉日で、4000円程度の比較的安いコーヒーメーカーに加え、先ほど見つけた電源アダプタをいそいそと購入しました。

■WATCH BOOT mini RPC-T4H

帰宅後、購入してきた製品をネットで確認。

WATCH BOOT mini RPC-T4H 取扱説明書(リンク先:PDF)

おぉ、思ったよりもしっかりした製品だ。telnet、シリアルだけじゃなく、WebUI、Windows専用ツールなんかもある。SNMP Trapも投げられるみたいだし、モデム回線があればサーバのシャットダウン制御なんかもできるみたいだ。
ちゃんとしたマニュアルもあるし、これが4800円なら安いと思いました。

(そういえばUSBから操作できる電源アダプタも持ってるのだけど、こっち使ってもよかったかもな…)

WATCH BOOT mini 前面
前面は左からLANポート、コンソールポート、モデムポート、DIPスイッチが並んでいます。
ちなみにLANは10Base-Tです。Telnetするくらいなのでこれで十分ですね。

WATCH BOOT mini 背面
背面は電源とモデムポートが4ポートずつあります。
モデムポートは今回使いませんが、UPSのシャットダウンメッセージを模してサーバーに送ってくれるそうです。

■初期設定

マニュアルに沿って初期設定をします。
最初はコンソールで設定しようとしてたのですが、PCとWATCH BOOTそれぞれCOMポートがオス端子で、持ってるケーブルが オス-メス だけだったのであきらめました。
初期値として192.168.10.1/24が設定されているようなので、ノートPC側のIPを設定してtelnetにて接続

TELNETから電源1を停止/起動している
(設定済みなのでホスト名/アドレスなどが異なります)
コマンドなど独自のものを使用していますが、操作感はほかのネットワーク機器と同じ感じです。
コマンドを入力して電源をON/OFFすることができます。

■電源ON/OFF操作するためのスクリプトを書く

FHCから電源をON/OFFできるように、bashでスクリプトを書きます。
別の製品だとCURLからコマンドを打てるみたいですが、この製品にはそれがないようです。
潔く諦めてtelnetからの操作を自動化するスクリプトを作成したいと思います。

telnetのように、CUIにおける対話式の操作を自動化するコマンドとして、Linuxにはexpectというものが存在します。

Linuxの対話がめんどくさい?そんな時こそ自動化だ!-expect編- 

僕は普段業務でTeratermマクロで対話式操作を自動化するスクリプトはよく書いているので、expectは比較的すんなり組むことができました。
(改行コードがLFだったり、エスケープのタイミングが間違えていてプチ躓きをしましたが。

処理の流れとしては 何かコマンドを打つ→特定のメッセージが出力されたら次のコマンドを打つ
の流れを延々と繰り返すだけです。簡単ですね。

で、書いたスクリプトが以下。

#!/bin/bash

PW="magic"
ADDR="192.168.2.10"
HOST="YKHP21"

set_power() {
        expect -c "
                log_file \"expect.log\"
                set timeout 3
                log_user 0
                spawn env LANG=C /usr/bin/telnet ${ADDR}
                expect \"server ready.\"
                send \" \r\"
                expect -regexp \"\[Pp\]assword:\"
                send \"${PW}\r\"
                expect \"${HOST}>\"
                send \"${CMD}\r\"
                expect \"${HOST}>\"
                log_user 1
                send \"exit\r\"
        "
}

get_power() {
        expect -c "
                log_file \"expect.log\"
                set timeout 3
                log_user 0
                spawn env LANG=C /usr/bin/telnet ${ADDR}
                expect \"server ready.\"
                send \" \r\"
                expect -regexp \"\[Pp\]assword:\"
                send \"${PW}\r\"
                expect \"${HOST}>\"
                send \"${CMD}\r\"
                expect -regexp \"${CMD} ((\[01\])(\[01\])(\[01\])(\[01\]))\r\n?.*${HOST}>\"
                puts \"\$expect_out(${INDEX},string)\"
                log_user 1
                send \"exit\r\"
        "
}

if [ $1 = "on" ] ; then
        MODE="PON"
elif [ $1 = "off" ] ; then
        MODE="POF"
elif [ $1 = "status" ] ; then
        MODE="POS"
else
        echo "usage: ./fucking_coffee.sh [on|off|status] [0-4]"
        exit 0
fi

if [ $2 -ge 1 -a $2 -le 4 ] ; then
        PORT="${2}"
elif [ -z $2 -o $2 -eq 0 ] ; then
        TARGET="M"
else
        echo "usage: ./fucking_coffee.sh [on|off|status] [0-4]"
        exit 0
fi

if [ $MODE = "POS" ] ; then
        case $PORT in
                1 | 2 | 3 | 4)
                        INDEX=`expr $PORT + 1` ;;
                *)
                        INDEX=1 ;;
        esac
        CMD=$MODE
        get_power
else
        CMD="${TARGET}${MODE}${PORT}"
        set_power
fi



ちなみにスクリプト名はこちらを参考にしています。とてもCoolです。

引数で操作方法と電源を指定します。

# ./fucking-coffee.sh [on|off|status] [0-4]

第1引数で操作方法[電源ON/電源OFF/電源状態]を指定し、第2引数でポート番号(0で全ポート)を指定します。

なお、FHCは初期でexpectが入っていないようなので自分でビルドしました。依存パッケージとしてtcl/tkも必要です。

■FHCに組み込む


先ほど作成したスクリプトを呼び出すためのスクリプトを作ります。
「設定」→「コマンド設定を行う」→「新しいスクリプトを新規作成」

///@args1@must@動作@on | off@text
///@args2@must@ポート番号@1-4@number
function main(mode, port)
{
  result = kernel_execute_local("/home/sshuser/fucking-coffee.sh " + mode + " " + port);
  if(result.substring(0, 4) == "usage"){
    arr = {"result": false, "message": "引数が無効です"};
  }else if(result.length == 5){
    arr = {"result": true,
           "status": [ result.charAt(0), result.charAt(1), result.charAt(2), result.charAt(3) ]
          };
  }else if(result.length == 2){
    arr = {"result": true,
           "status": [ result.charAt(0) ]
          };
  }else{
    arr = {"result": true,
           "status": [ "ok" ]
          };
  }
  //alert(arr);
  return arr;
}



ホントは上記スクリプトにsetTimeoutを設定して30分後に勝手に消えるようにしたかったんですけど、FHCの仕様でコマンド設定の方のスクリプトには入れられないそうで…残念。

■完成品がこちら

コーヒーメーカーはラックの横に設置
機器の設定が済んだのでラックに搭載します。
ついでなのでラック裏の煩雑になっていたケーブル周りを綺麗にしたりとか。

ちょっと不満があるとすれば、WATCH BOOTの前面からLANケーブルが飛び出してしまうのが気になってしまうところとかでしょうか。構造上仕方ないので目をつむりますが。

あと今回購入したコーヒーメーカーですが、サーバーが設置されていない状態で電源を入れてもお湯が零れないようにする基本的な仕組みがあるみたいですが。

微妙に残念な感じのコーヒーメーカー
奥の黒いのを押していないと抽出口から出てくるのをせき止められるだけの仕組みなので、上のドリッパー部からは普通にお湯がドバドバ流れます。
なので、せき止められてるからといって、しばらくするとコーヒーが溢れてくる糞仕様です。

そこで、ココもそのうち手を加えようかなぁとおもいます。
ズバリ黒いレバーの裏にスイッチを組み込んでコーヒーメーカーが動作できる状態にあるか取得できるようにしたいですね。
電子工作の分野は微妙に専門外ですが…コレができたらHTCTCP418Errorを返すことも可能ですね!

■終わりに

最近久しぶりにホームコントロール関係の開発意欲がもりもり湧き上がってきている城間直裕です。

今回のコーヒーメーカーもそうですが、もっとFHCを活用するためのデバイスを作ってもいいかな。なんて思っている次第なので、次回を乞うご期待。

…と書いておいて実行に移さないのが僕なんですが…orz