ペペロン頭脳

ソフトウェアエンジニアのメモ的なアレ。

Raspberry Pi でおうちモニター

システム全体の様子

(2年もブログ放置してたぜ!)

夏休みの工作でやってみましたIoT。
この手のやつは作ってる人たくさんいて取り立てて技術的に新しい点は何もないのだが、いろいろ未経験だったのでいい勉強になった。 github.com

概要

  • 自宅の室温・湿度・気圧を遠隔監視できる
  • 赤外線リモコンの信号を遠隔発信できる
  • カメラを通じて自宅内の様子を確認できる

つまり「部屋暑いな。帰る前にエアコン入れとこ」ができる。 「ほんとにエアコン入ったかな?」をカメラで確認できる。

iPhoneからWebUIを開いた状態

材料

  • 去年勢いで買って腐らせていたラズパイ3
  • ずっと使ってなくて埃を被っていたWebカメラ
  • BME280センサー搭載モジュール(新規購入)
  • IRKit(新規購入)
  • ほかブレッドボードとか小物

おおまかな構成

下記セットを一つのリポジトリにまとめてあります。

  • APIサーバー兼Webサーバー
    • Node.js製
    • アプリフレームワークにExpress, 認証ミドルウェアにPassportを採用
    • /api以下に定義されたエンドポイントを通じて、センサーやリモコン、Webカメラにアクセスする
    • ログイン時にJWT(JSON Web Token)を発行、以後各APIへのアクセス時にトークンを要求・検証する
  • フロントエンドUI
    • Vue.js製のSPA
    • 上記Webサーバーから配信される

作った感想など

久々に半田ごてを持って緊張した

BME280のモジュールはピンヘッダが付いてない状態で買ったので 自分で付ける必要があったのです。普通そういうものかな。 部品小っちゃいし、下手くそなので熱しすぎたりしないか怖かった。 (実際熱しすぎてしまった気がする...) ピンアサインとかGPIOとの接続については情報が多く、苦労せずに済んでよかったよかった。

オールJavaScriptで作れた

APIサーバーもNode.jsで動いており100%JavaScriptなシステムになっています。 npmのパッケージ群が充実しまくってるおかげですね。 BME280センサーから値を取るモジュールも、WebカメラのMJPEGストリームをプロキシするモジュールも、全部npmにある。

npmは便利な一方で↓みたいな危険もあるけどまあそれは。 gfx.hatenablog.com

あとES2015でゴリゴリ書けて楽しかった(一部しか機能使ってないけど)。

Vue.jsの手触りがよい

フロントエンド側はVue.jsで書きました。
(フレームワークいらないくらいの規模ではあるが)

前はBackbone使ってたけどもうメインストリームじゃないし、
Angularはボリューム的に学ぼうという気がまったく起きないし、
Reactは本体の学習コスト低いらしいけど他のコンポーネントを組み合わせて使う前提でそっちの学習コストどうなの。
とにかく手っ取り早く小さいSPA書きたい!けどjQueryには戻りたくない!モダンなのがいい!という場合にVue.jsはいい感じです。

コンポーネント単位で.vueにHTML/JS/CSSをまとめて書いたり、HTMLに独自ディレクティブを埋め込んじゃうスタイル、 最初は気持ち悪いと思ってたけど、スコープがバシッと切れてて◎でした。

あとデータバインディングが無い世界にはもう戻りたくない。

モダーンなフロントエンドJSは当然ビルドしなきゃいけないわけですけど、その辺のサポートも整ってるので苦労しませんでした。 vue-cliでセットアップすれば、ホットリロードしつつ随時Lint掛けてくれる開発サーバーは立ち上がるし、リリースビルドもコマンド一発だしで至れり尽くせり。何かハマったときにもwebpackのconfig類が比較的読みやすくて対処しやすかったです。

No-IP便利, Let's Encrypt便利

外から自宅に繋ぐため、ダイナミックDNSとしてNo-IPを利用。
HTTPS化必須でしょ。ということでLet's Encryptを利用。
どちらも実に簡単に導入できて素晴らしい時代ですね。

そういやトークン平文で流してるって「艦これ」が騒ぎになってましたね。 blog.livedoor.jp

IRKitちょっと不安定かも & 罠

公式サイトには

IRKitデバイスは、Bonjourを使ってIPアドレスを求めることができます。

って書いてあるんですが、自分の環境だとどうにもうまくいかず。ルーター側でDHCP固定割当したらアクセスできなくなったりとかも。この辺を掘り下げるにはネットワークの知識が足りない…

あとリクエスト投げるときにX-Requested-Withヘッダ付けろと書いてあるんですが、実際はそれだけじゃ足りなくてContent-Lengthもちゃんと載っけてやらないといけない。 例にあるcurlだと気にする必要ないけど、他の手段で明示的にヘッダを書く場合は注意が必要。(ちなみにパケット分割が発生しないサイズなら無くてもOKなのを確認済)

カメラの必要性

妻には「それカメラ必要ある?リビング写す必要ある?覗き趣味なの?変態なの?」と10回くらい聞かれたので
「覗かれたくないときは何かかぶせてカメラ塞いでください」と20回くらい返した。

絶対無いといけないわけでもないし…
セキュリティ的には無いに越したことはないし…
あと今ストリーミングの制御を一切してないので、LTE経由でうっかり開いたままにすると容易にパケ死ギガが減る
ちゃんとコントロールするか、カメラいっそやめてしまうか……
うーむ。