卵が先か鶏が先か


この記事は[おうちハックAdvent Calendar 2017](https://qiita.com/advent-calendar/2017/ouch-hack) 10日目のエントリーです。

家を建てたからおうちハックをするのか、おうちハックをするために家を建てるのか悩ましい問題ですね。ここをみている人の中には後者がいてもおかしくないかと思います。

自分の持っている技術を使っておうちハックをするのか、おうちハックをするために勉強するのかという、なんか本末転倒な問題もあります。
今回は私のおうちハックことはじめからの数年にわたる本末転倒な迷走と現状を書いてみます。

##おうちハックことはじめ
私の場合は家を建てるときに設備の選択に色々と悩んで面倒くさくなり、取り敢えず後でなんとかすることが出来るように電動化出来る所は全て電動化しておくという場当たり的な対応したことがことの始まりでした。
新居に引っ越して1年位経った頃からボチボチと何かできないか検討を開始しました。取り敢えず壁に取り付けられている設備のコントローラを外して開けて見るところから始まります。

因みにこの頃は本業の方で電子回路の設計からマイコンや組み込みlinuxのソフトの下回り(ドライバーやOSの下のレイヤーですね)を経験していましたが、アプリケーションやOSの上のソフトはあまり触ったことがありませんでした。ましてやクラウドサーバー側のソフトやHTML、javascriptは文字通り雲の上の世界でした。

取っ掛かりとして最初にやった事は家の中の制御したい対象の洗い出しと制御方法の検討です。
電動のシャッターと電動の窓は同じようなスイッチを使ってるのか。開けてみると15V-DCのスイッチでGNDとショートするとスイッチが押されたと認識するらしい。
床暖房、玄関の電気錠、エコキュートの給湯器はHA端子対応、エアコンもHA端子に対応しているらしい。HA端子ってなんだろう.....
エアコンの制御とTV、照明器具は赤外線リモコンだよね。エアコンがついてるかどうかは知りたいよね。
今時の機器はACを直接スイッチで制御しているものはないので、最悪スイッチ部分を改造してFETで制御すれば人がスイッチ押すのと同じことはできるよね。
回路的にはなんとか出来そうな感じ。
でも、新居なので制御回路は壁の中か機器の中に見えないように設置しないと嫁の許可が下りない。。。。
壁の中を工事するのに電気工事士の資格だけとっておくか。
みたいな感じで一人設計妄想会議を頭のなかで行ってスタートしました。

##構成の検討
本体は1つLAN内にサーバーを設置して制御対象機器につける子機とは無線接続かな。
WiFi,BT,ZigBee,etc。WiFiは経験上20個以上あると繋がらない事が多いしBTも3Fと1Fでは繋がらないことがある。
mesh-networkでhopして繋がってくれるZigBeeが使い勝手が良さそうなので当時はメジャーなXBeeを選択。今選ぶならBT5.0とかが選択肢ですね。
マイコンはI/Oの仕様と扱い易さとコストパフォーマンスでArduinoでも使われているAVR328を選択、途中で328Bに乗り換えました。サーバーの本体はlinuxが動けばなんでも良いですがRaspberryPiを選択。
といった感じです。

最終的に出来上がった構成はこんな感じです。
<img width="1363" alt="System2.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/159374/5a9d1ce0-9539-0d4c-1d4d-07f948f416dd.jpeg">


##最初にやったこと
取り敢えず子機を1台ユニバーサル基板で組んでRaspberryPi側のソフトと一緒に作成していきました。
下回りのソフトが本職なので最初に作ったのはXBee越しにAVRのfirmwareをupdateする部分です。AVRのbootコードですね。
後々壁の中に20数個も埋め込んでしまうので、無線経由でupdateできないと毎回取り外して書き込まなくてはならず手間でメンテできなくなって更新されないのが想像つきます。
updateの仕組みさえ作ってしまえば後はソフトをガリガリ書いて試していけます。
次に作ったのはAVR上のコマンドを受けて関数を呼ぶフレームワーク部分です。OSの代わりの簡単なスケジューラーですね。
ここまで準備できると後は必要な機能ごとに作り込んでいくだけになるので単純作業になります。

RaspberryPi側はlinuxのdriverくらいまでは経験していたので、最初に作ったのは子機を管理してコマンドを投げたり定期的にステータスをとって状態管理するdaemonです。これはC++で作っています。
最初の段階ではtelnetでコマンドを叩くと子機が動作してFETを制御して対象機器のスイッチを制御する、HA端子を制御する、機器のステータスを読み取る、センサーの情報を読み取る、複数のXBeeに投げたコマンドとレスポンスの状態を管理して応答がなければリトライ処理をするといったものです。

##赤外線リモコン
次に悩んだのが赤外線リモコンです。世の中に色々な赤外線リモコンの制御のopen sourceがあるのですが、なかなか用途に合うコードが見つかりませんでした。
何が問題かというとAVR328の少ないメモリ(SRAM 2KBの中にstackやXBeeとの通信バッファ、他のI/Oのバッファも必要なので)にXBee越しに赤外線データを投げてエアコン用の長いコード(DAIKINの長めのコードだと500msも続く）を送信、もしくはAVRで受信した赤外線コードをXBee越しにRaspberryPiに投げるということです。これはなんとかInterrupt処理の中にエンコード／デコード処理を押し込んで実現できました。
ここまではそれまでの下回りのソフト開発の経験があったので1ヶ月くらいでプロトタイプが出来ました。

##迷走の始まり
ここから先が未経験の世界で勉強して実装、試作の繰り返しになります。
私の学習の仕方は機会があれば勉強会みたいな所にも出かけて行きますが、基本的にはネットで調べて自分で試してみることを繰り返します。

##基板の設計
２０枚以上の子機をユニバーサル基板で作る根性はなかったのでまず基板設計です。
仕事で回路設計をやって基板は何枚も起こしていたのですがアートワークをした事がなかったので、最初はネットで調べてEAGLEを使いました。その後P板.comの推奨するCADLUSを試してみて、最終的にMacで使えるKiCADに行き着いています。KiCAD使いやすいですね。特にMacでTouchPadとマウスを併用するとサクサク書けます。
基板の製造は最初はP板.com、その後は深圳のelecrowで試作をしています。
実は基板の回路も色々と試しながら変更を加えては試作をして現世代で7世代目に至っています。この間に激しい落雷の影響でI/Oが壊れて窓が勝手に開いてしまったり、ペアリングの仕組みを整えるためにコネクタのピン数が足りなくなったり、色々と実際に組み込んで言った経験上I/Oの構成を変えたりという感じでようやく最近は落ち着いてきました。
elecrowは実装も依頼しています。ネットで見てると当たり外れがあるようなので誰にでも勧められるわけではないですが私はあまりハズレを引いた事はありません。一度だけ試作10pcsでv-cutで3分割30枚を依頼したらルーター切り出しで10枚だけ届いて返金対応してもらったことがあるくらいです。安いのでハズレがきても楽しむくらいの気持ちで付き合うのがコツのようです。
試作を何度か繰り返して出来上がったのがこれです。

<img width="500" alt="System2.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/159374/86b5c2c2-0990-da14-1994-b77ea50716f7.jpeg"> <img width="300" alt="module.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/159374/eb04c017-ad9c-a2b1-87c1-702286e96289.jpeg">
写真は親機と子機で、親機の基板の上に載っている緑色の基板はRaspberryPiです。


##HTMLとjavascript
次に手を付けたのがコントロールするためのwebページです。
家のエアコンをon/offするのにtelnetでコマンドを叩くのは無理があるのでiPhoneアプリを作るかweb pageをRaspberryPiに立てるか考えたのですが、簡単そうなweb pageを試してみました。
最初はapacheでやり始めましたがcgiだらけになって一旦やめて再検討。
ネットで調べてjavascriptを勉強がてらbackendをnode.js、frontendをangular.js(v1) + onsen.ui(v1) + c3.jsにチャレンジしてみました。
node.jsは比較的簡単に使えましたが、angular.jsは中々とっつきにくかったです。結局あとでVue.js + onsen.ui(v2) + c3.jsに変更しています。
勿論、security的に問題のあるtelnetのportはあくまでも開発用で、今は開いていません。

##Cloud Serverの立ち上げとTLS
RaspberryPi上でLAN内では一応制御できるようになったので、次は外出先からのアクセスです。
サーバーは後々色々やりたかったのでOSからインストールできる[さくらインターネットのVPS](https://vps.sakura.ad.jp)にしてみました。
ここで問題になってくるのは暗号通信です。暗号は組み込みlinuxの世界で経験があったので仕組みは理解できてました。
理解のために試しに仕様書読んでSecureWebsocketを一旦実装して見てプロトコルを確認しています。
XBeeとの通信はAES128で暗号化されているので、サーバーとの通信のためにopenSSL(TLS)を使って暗号化して行きます。自宅の鍵なども制御するので自宅ークラウドサーバーー携帯端末間をそれぞれ相互認証をかけていきます。この辺は通信しているパケットの中身がWireSharkでも確認できなくてデバッグに苦労しました。


##管理設定用のページ
次の課題は管理設定用のweb pageです。
最初の頃は設定をテキストのconfigファイルでやっていて、変更の度にRaspberryPiにloginしてviで編集していました。
また、何かセンサーからイベントが上がって来たり時間が来たら実行するようなことをC++のプログラムとして実装していたためメンテナンスが大変で間違いが起きやすくデバッグも大変でした。

そこでRaspberryPi上にnode.jsでサーバーを立てて子機の管理をできるページを作り込んでみました。ここでは流行ってきているとの噂でVue.jsを使ってみました。子機の設定画面はこんな感じです。

<img width="1478" alt="子機管理画面.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/159374/fb70f494-9bf6-12f2-2f15-0b6663a94b9a.jpeg">

子機以外にもHueとかスマートメータとかHAPとかのリンク機器の接続管理やリモコンの登録もできるようにして家全体のシステムを一元管理できるようにしました。

ビジュアルプログラミング環境としてNode−REDを使ってみて使いやすかったのでこれで制御することにしました。

<img width="1473" alt="Node-RED.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/159374/d7e12f89-ef27-8359-ff30-be514216ac44.jpeg">

[Node-RED Advent Calendar 2017](https://qiita.com/advent-calendar/2017/nodered) 18日目　「自宅をまるごとNode-REDで制御」に詳細書きます。
[GitHub](https://github.com/GeckoLink-com/HomeServer)にソースコードを公開しています。
[RaspberryPi用のSDカードイメージ](https://geckolink.com/download)も公開しています。子機を繋がず赤外線リモコンも要らなければRaspberryPi単独でも動作します。

ところで、こういうセットアップページってルーターとかにもありますがGoogleさんがChromeでhttps対応してないページを締め出そうとしてるのにはどう対処したらいいんでしょう？NAT内だとそもそも証明書を取得できないですよね。private addressって対象外にしてもらえてるんでしたっけ？

##Web Site
この頃になると自宅のシステムの話をたまに外で話すようになり、資料を見せたりする必要が出てきてWebページを作ってみました。さらに買いたいといってくれる人たちも現れるようになり、少なくとも買える手段を用意しておかないと話をした時に困るようになってきました。

設定ページの延長線上でWebPageを作ってみたのですが、設定系のページとは違って初期読み込みのデータ量や最初の表示までの時間、UXなどと考えるポイントが違っていて中々苦労しました。
ここの構成はnode.js + Vue.js + Vue-strap + stripeです。
作ったWeb Siteがこちら[https://geckolink.com](https://geckolink.com)になります。いろいろとセットアップの仕方なども書いているのでよろしければ見てください。

##リモート制御のページ
少し経験値が上がってきたので、最初に作って画面遷移が重かった自宅のリモート制御のためのサーバーもnode.js + Vue.js + onsen.ui + c3.jsに作り直しました。最終的にこんな感じのWebApplicationに作ってみました。
実際はiPhoneの画面でスクロールするのですが、全体を見えるようにキャプチャして合成しています。(部屋数が少なくて家の小ささがバレちゃいますね)
だいたいコントロール系はHA端子とFET制御、赤外線リモコン。センサー系はHA端子、温度、湿度、人感、騒音、降雨、電圧、赤外線リモコン、スマートメーターあたりで実現できています。照明はHueと赤外線リモコンの照明と壁スイッチをリモコン対応に付け替えているもので対応しています。開発のために無駄に沢山のセンサーとかがありますが普通ここまでは要らないですね。

<img width="500" alt="WebApplication.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/159374/f41e6d63-4d6b-cc94-37dd-a0df45678123.jpeg">

下のチャートはセンサーデータを表示する画面です。
c3.jsに食わせているデータが3日分の5分おきのセンサーデータx25系統=7200点だったのですが、これの描画がiPhoneだと異常に重くて反応するのに10秒くらいかかってました。これについては[ C3.jsのline-chartをiOSで使ったら重かった(解決済み) ](https://qiita.com/mnakada/items/46d762d63f63ae662aee)に書きました。
(実は、Qiitaは今回初めてアカウントをとって書いているのですが、この記事を書いていてイメージファイルを貼り付けていたらサイズ制限に引っかかってしまいました。先に進めないので慌てて公開記事を1つ書いたのがこれです。)
他にもUIの描画とかに時間を食っているところを修正していって動作がかなり快適になりました。これはAnguler.js+onsen.uiが悪かったわけではなく自分が未熟だっただけです。でもVue.jsは楽ですね。
<img width="700" src="https://qiita-image-store.s3.amazonaws.com/0/159374/b3981461-48ab-825c-b658-c5da1768a9d1.jpeg">

##今の状況と今後の予定
今はどういう状況かというと、少量生産をできるだけ手をかけずにできるようにして少数の在庫で回せるようにしようとしているところです。本体の製造は多少高くつきますが少量でも生産出来ます。
梱包材のほうはオリジナルで作ると最小Lotが多すぎて少量生産に向かないので丁度いい大きさのものを探してみたり取り寄せてみたりしましたが中々うまくいかず、今はトライアルで自分で設計してみてレーザーカッターでダンボール板を切り出して作っています。

一番の問題は、お客さんのところへの取り付けを全部自分で行ってやっていると全然回らないことです。これについては、少しづつ対応を考えているところです。

VoiceUIは既にHomeBridgeは繋いでいるので、これからAmazon EchoやGoogle Homeもつなぎ込む予定です。ここのところ国内発売でQiitaにハック例が沢山出てきているので参考にさせていただきます。

学習リモコンとしてはSonyのHUIS REMOTE CONTROLLERはそのまま使えるのですが、残念ながらうちのリビングのエアコン2台のうち1台が登録できずどうハックしようか悩み中です。どちらも日立製なのですが、それぞれ別々にコントロールしたかったのでリモコンコードを片方切り替えてもらっているので登録できないのです。HUISに別メーカーのエアコンコードを登録して、子機で受けて変換かけて出力し直すか、出来るかどうか判りませんがHUISの中をハックしてリモコンコードのテーブルを直接編集するか。

SonyのMESHもどう繋ぐか思案中です。センサーとして手軽なのですが、いまはMESHアプリにSDKでhttp postをするだけのソフトウェアタグを作って入れて、Node-RED側でhttpで受けて繋ぎこむという回りくどいことをしています。RaspberryPiのHub対応のソフトが公開されたので見てみたのですが、Node.jsで書かれているようなのでもっとシンプルに繋ぎこむパスがあるのではないかと思っています。

その次は機械学習でスイッチを押そうと思った瞬間には勝手に動く自動化かなぁ。それに向けて取り敢えず数年分のログを溜め込んでいます。


##やってみてわかったこと
別に全部自分でやらないといけないと考えているわけではないのですが、やってみないと見えてこない部分もあるなというのが実感です。色々なことを勉強がてら一度経験しておくのもいいかと思ってやっています。一度だけでいいですが。ここに書き切れないほど実は色々なものに手を出して失敗しているのですが、それも経験のうちかと割り切っています。

あとは値付けについてですが、最初は原価＋αくらいで考えていたのですが、故障した場合の返品、交換にかかる費用や送料、いろいろな対応に取られる時間、特に親機に使うRaspberryPiの故障率、サーバーの維持管理、特にセキュリティパッチなどの対応とか考え始めるとあまり安く値付けをするとサービスを維持できないことがわかってきて、それらの費用諸々を含めてつけています。サービスを維持できなくなると本末転倒なので。やはり、個人レベルで扱える量で製造しているとどうしても高くなってしまいます。このへんも追々対応を考えていくべきところですね。

##まとめ
おうちハックを始めてから、迷走しながら色々と学んできた内容を書いてみました。とりとめのない話になってしまいましたが、おうちハックをするために延々いろんなことを学習を続けなくてはならないという、あれ？目的はなんだっけ？何をしたかったんだっけ？なんでQiita書いてるんだっけ？という話でした。

###明日のおうちハックは
@ksasao さんの 機械学習＋おうちハック です。
昨年の [空気を読むUIを作る](https://qiita.com/ksasao/items/4b52ced817c70edc901c)につづいて今年は何が出てくるのか楽しみですね。