起床エンジニアリング


社会人1年目に立ちはだかる[^1]大いなる壁。**それは布団。**

はじめまして。[Retty Inc. Advent Calendar 2018](https://qiita.com/advent-calendar/2018/retty) 7日目の記事はエンジニアの @pikatenor がお送りします。

昨日は @resessh さんの [PRごとにCIでStorybookをビルドしてデザイナーとインタラクションまで作っていく話](https://qiita.com/resessh/items/38ef6492d0cf21facec8) でした。CircleCI による Storybook ビルドの方法解説もさることながら、エンジニア&デザイナーのワークフローの考察から CI を目的達成のために的確に活用しているあたりが美しい記事だと感じました。
RettyAC2018 は今後も力作ぞろいを予感させるテーマ群が並んでいますが、生憎自分は CI じゃなく狂言しか回せないので、今日の記事はアホ記事としてお気軽に読み飛ばしていただければ幸いです。

# 序
さて、今年4月に新社会人として入社した僕ですが、日々の堕落が積み重なり朝の起床に苦労する日々です。
しかし、技術をもってして問題解決にあたるエンジニアという職を選んだからには、やはりエンジニアリングで課題解決に挑んでいかねばならないと思いました。
そこで今回は、自宅の現行構成である、**アラームアプリとともに部屋の電気とTVがついて幸せな音楽が流れ出す** というのをご紹介します。

家の構成は人それぞれだと思いますので、個々の設定の詳細については概要に留め、こういうのを組み合わせるとこういうのができるよ、という話を中心にやっていきます。

# 構成技術

![The_Big_Irasutoya.png](https://qiita-image-store.s3.amazonaws.com/0/72321/df83641a-4513-1521-e756-77b9b3c224a3.png)


流れとしては
 1. アラームアプリが openHAB の rule をキック
 2-1. openHAB が電気つけるマシーンを起動
 2-2. 電気つけるマシーンが電気をつける
 3-1-1. openHAB が 別ホストの lircd を叩く
 3-1-2. LIRC でテレビを起動
 3-2-1. openHAB が adb 経由で Fire TV Stick の Plex アプリを起動
 3-2-2. openHAB が Plex Server 経由で Fire TV Stick を操作
 3-2-3. TV に接続された Fire TV Stick が音楽を再生

という感じの動きをします。

## openHAB
今回の実装で割と要になっているのが [openHAB](https://www.openhab.org/) です。これはスマートホーム向けサーバーソフトウェアで、各種 [Bindings](https://www.openhab.org/addons/) を用いて様々な機器の制御を統合できます。また、[Rules](https://www.openhab.org/docs/tutorial/rules.html) を用いることで、機器から取得した状態を元に別の機器を操作することも可能です。 [openHABian](https://www.openhab.org/docs/installation/openhabian.html) という Raspbian 派生のディストリビューションがあり、Raspberry Pi へのインストールは非常に簡単にできます。

起床にあたっては [HTTP Binding](https://www.openhab.org/addons/bindings/http1/#http-binding)、[LIRC Binding](https://www.openhab.org/addons/bindings/lirc/#lirc-binding) と [Exec Binding](https://www.openhab.org/addons/bindings/exec/#exec-binding) を使って Rule を定義しています。

## LIRC
Linux で赤外線リモコンを学習・発射するときの定番ですね。
前述の openHAB を置いた Raspberry Pi とは別に、テレビの受光センサを狙える位置に Raspberry Pi Zero WH を貼り付け、ネットワーク経由で lircd を叩きます。

<img src="https://qiita-image-store.s3.amazonaws.com/0/72321/9a1e74a8-4126-2891-21a3-e097484def6a.jpeg" width="400">


GPIO から赤外線LED [OSI5FU5111C-40](http://akizukidenshi.com/catalog/g/gI-03261/) のドライブには [2N7000](http://akizukidenshi.com/catalog/g/gI-09723/) が便利です。パルスなら割と電流流しても大丈夫そう。

## Plex
[Plex Media Server](https://www.plex.tv/) はメディアライブラリ管理サーバーです。Web UI をはじめとして各種プラットフォーム向けにクライアントアプリもあり、アプリ側を[リモートプレイヤー](https://support.plex.tv/articles/201358263-controlling-the-remote-player/)としてサーバーに通知することで他クライアントからの操作も可能になります。
起床では Fire TV Stick 上の Plex アプリを立ち上げ、リモートからの操作を受け付ける状態にしています。

一点問題になったこととしては、openHAB には [Plex Binding](https://www.openhab.org/addons/bindings/plex1/#plex-binding) もあるのですが、あくまでリモコン的な使い方しかできず指定の曲を流すなどは無理そうだったので、Plex サーバーの HTTP API を直接叩くことで曲を再生させています。ざっくり GET パラメーターについた `X-Plex-Token` と `X-Plex-Client-Identifier` があっていれば `/player/playback/playMedia` を叩けばいいという雰囲気。詳しくは [ドキュメントある](https://github.com/plexinc/plex-media-player/wiki/Remote-control-API)。


## Fire TV Stick と ADB
Plex App は起動していないとリモートプレイヤーとして認識されないので、Fire TV Stick の方も操作していく必要があります。Fire OS はまあ Android なので、[adb が使え、ネットワーク経由で shell にアタッチできます](https://developer.amazon.com/ja/docs/fire-tv/connecting-adb-to-device.html)。
起床ではスリープの解除に `input` コマンドを使ってリモコンのエミュレーション、アプリの起動に `am start` コマンドという感じで、

```
adb connect {hostname of fire}
sleep 10 # 早すぎると adb が device を認識してくれないしテレビもついてない
adb shell input keyevent KEYCODE_WAKEUP
adb shell am start -n com.plexapp.android/com.plexapp.plex.activities.SplashActivity
adb kill-server
```

とすると Plex アプリが起動できます。これを Exec Binding で openHAB の Item 定義に持っていきます。

## 電気つけるマシーン
部屋の電気のスイッチが1箇所しかなく[^2]、電球を Hue に変えるとかも不可能なタイプの部屋だったので、ちょうどうってつけのマイクロサーボが余っていたこともあり、スイッチを押すマシーンは自作しました。
<img src="https://qiita-image-store.s3.amazonaws.com/0/72321/35ae6588-ec73-7c9d-05ae-0de613496eeb.jpeg" width="400">

サーボ [SG-90](http://akizukidenshi.com/catalog/g/gM-08761/)[^3] を ESP-WROOM-02 で駆動させるものです。
ESP-WROOM-02(ESP8266) といえば、Wi-Fi モジュール内蔵で Arduino 互換プログラムが動くｽｺﾞｲﾔｽｲﾁｯﾌﾟとして有名ですね。そういうわけでこれは HTTP サーバーとして外部からの操作を受け付ける Arduino スケッチを書いて動かしています。画像を見て*大いなる察し*があると思われますが、主に壁に穴を開けずに固定するために苦労しました。

## 目覚ましアプリ
当然ですがこれらは目覚ましに反応しないと一切動かないので、最後に肝心要の目覚ましアプリのご紹介です。僕のイチオシは [Sleep as Android](https://play.google.com/store/apps/details?id=com.urbandroid.sleep&hl=ja) です。
非常に高機能なアプリで、睡眠の解析とスマートウェイクアップ（眠りが浅いタイミングで起こす）、起床確認など、ねぼすけのための機能が豊富にそろっています。Tasker 連携もあるので、これを使って openHAB の REST API を操作し、起床 rule のトリガーとしています。

# 〆
このようなピタゴラスイッチの組み合わせにより、快適な起床が可能になりました。**Google Home でいいじゃん。** そうだね。

なんだか思ったよりアホな記事になってしまい恐縮ですが、弊社 Tech Blog の方では「Retty新卒エンジニアの入社半年間の振り返り」と題して今年入社の同期が振り返りブログを書いております。

[Retty新卒エンジニアの入社半年間の振り返り〜Part.1〜](https://engineer.retty.me/entry/2018/10/25/113000)（アプリ: 山田）
[Retty新卒エンジニアの入社半年間の振り返り〜Part.2〜](https://engineer.retty.me/entry/2018/11/19/111849)（フロントエンド: 諏訪）
[Retty新卒エンジニアの入社半年間の振り返り〜Part.3〜](https://engineer.retty.me/entry/2018/12/05/113542)（アドテク: 堤）

当然僕も新卒として振り返りブログに参加することになっているのですが、そちらの記事が上がらないまま[^4]うっかり登録したACの日が先に来てしまいました。

新卒振り返りブログの方では普段取り組んでいる検索の品質改善や基盤の取り組み等について真面目な口調でご紹介できればと思いますので、よろしければそちらの方もご覧ください。よろしくお願いします。~~原稿がんばります。~~

# 余談

1度アラームアプリがフリーズするという不具合により起床システム全体が起動せず寝坊するという Incident があり、アプリが SPOF であることが明らかになりました。その際先輩方から頂いたありがたいご提案がこちらです。

![DrNjDtCU4AASFk6.jpg](https://qiita-image-store.s3.amazonaws.com/0/72321/949a6c63-dabc-94d5-de4b-0cecdb015461.jpeg)


**人の耐起床障害性が十分に高ければ目覚ましなど不要。**
なおまだ全然ダメ人間なので Chaos 起床 Engineering やっていく宣言は出せそうにありません。

# 追記

動いている様子の動画が観たい、というお声を社外の方から頂いたと伺いました。ありがたい限りです。
部屋の全景や TV 周辺は~~汚い~~プライバシーの理由により撮影を差し控えさせていただくのですが、電気つけるマシーンでよければご覧ください。
ESP-WROOM02 単独でも操作できるようお気持ち程度の Web UI を実装しており、これはそこから操作した様子です。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">様子 <a href="https://t.co/35aU2ZDMIv">pic.twitter.com/35aU2ZDMIv</a></p>&mdash; 関西生まれのピカチュウ(60Hz) (@pikatenor) <a href="https://twitter.com/pikatenor/status/1071033962443632641?ref_src=twsrc%5Etfw">2018年12月7日</a></blockquote>

[^1]: 毎朝
[^2]: 厳密には2箇所あったが家具の配置の都合で操作不能になった
[^3]: 後に1番上のスイッチだけ裏のツメの配置が悪く出力不足が頻発したので SG-92 に交換した
[^4]: トリになったのは完全に自分のせい。ご迷惑をおかけしています……