iPhoneから1タップするだけでAWS上のプログラムをON/OFFする方法

#はじめに

常にクラウドでプログラムを走らせておいて、
自分の気の向くままに、どこでもいつでも手軽にプログラムを停止、再起動したい時ってありませんか・・?
私はあります!

わざわざon/offするだけなのに外出先にノートPCを持ち歩きたくない、
**iPhoneひとつで、もしくはAppleWatchからポンと押すだけで実行・停止できる。**
なんかかっこいい、、

**iPhoneや、AppleWatchに「ヘイ Siri! ホゲをつけて」**
と言うだけでAWSプログラムを起動できます。
ナンカ、カッコイイデス。

「したいもの&カッコいいものは作ればいい」ということで早速作ってみました。

##仕様条件
- クラウドはAWSのEC2
- 実行停止するプログラムはNode.js
- 自宅にネット接続されたラズパイが常駐している事
- Apple HomeKit環境を自宅で設定できること
- iPhoneユーザーであること

##概要
早速、ネタバラシします。
AppleにはIoT家電を制御する環境としてHomeKitがあります。
[Apple HomeKitの説明](https://www.apple.com/jp/ios/home/)

家の中はもちろん、外出先からも自宅の家電を操作することができる優れモノですが、その特性を利用します。
まず、Node.jsのライブラリhomebridgeを利用して自宅のラズパイをHomeKitで認識できるIoT家電化させます。
次に、IOT家電化された自宅のラズパイを通して、AWSに接続し、コマンドを要求します。
AWSはラズパイからのコマンドを実行することで、AWSクラウド上のプログラムをON/OFFします。

以上、パチパチパチヽ(｀▽´)/
それでは細かく見ていきます。

##homebridgeをラズパイにセッティング
`homebridge`はNode.jsライブラリで、インストールしてdaemon化することで
ラズパイをHomeKitのブリッジにエミューレートさせることができます。

homebrigeの詳しい説明とセッティングに関しては以前の記事を御覧ください
[Philips_HueをAPI連動！〜ラズパイをHomeKit化する](https://qiita.com/akinko/items/58c650f99f25fc7e3cb5#%E3%83%A9%E3%82%BA%E3%83%91%E3%82%A4%E3%82%92homekit%E5%8C%96%E3%81%99%E3%82%8B)

さて、セッテイングできましたら、
homebrideのconfigにon/offした時に何をさせたいのかコマンドを設定します。
今回は、AWSに命令するshellコマンドをon,offに設定します。

```json:config.json
#以下を該当箇所に追加
#/home/pi/は適宜読み替えてください
  "accessories": [
    {
      "accessory": "CMD",
      "name": "ホゲ",
      "on_cmd": "/home/pi/startAWS.sh",
      "off_cmd": "/home/pi/stopAWS.sh"
    }
　]

```

- `"name":`ボタンの名前になります。Siriに話しかけるので恥ずかしくない名前にしましょうw
- `"on_cmd":`スイッチのON状態、Siriの「つけて」状態で実行されるコマンドです。
- `"off_cmd":`スイッチのOFF状態、Siriの「消して」状態で実行されるコマンドです。


homebridgeのセッティングはひとまず以上となります。

肝心のShellファイルの内容ですが、一旦保留して
shellファイルの命令を受けるAWSのセッティングを先におこないます。

##AWSの準備:foreverをインストール
AWSのEC2サーバーを使用します。
EC2サーバーには事前にNode.js、npmのインストールしておきます。
私はLinuxOSはubuntu18.04LTSで構築、nodebrewでNode.jsをインストールしています。
OSはAmazon Linuxでも、Node.jsのインストールも公式通りで問題ないと思います。
適宜読み替えてください。

AWS上でNode.jsプログラムを常時実行させて再スタート、終了を制御したいので、
今回は使い勝手のよいライブラリ`forever`を使用しました。

foreverは
Node.jsで作られたプログラムをデーモン化して簡単に常駐実行することができます。
ラズパイからAWS上のforeverに命令することで、Node.jsプログラムのON/OFFをするというカラクリです。

AWSにforeverをインストールします。

```sh
npm install -g forever
```

なお、foreverの基本的な使い方は以下のブログが詳しいです。
[foreverの使い方とデーモン化による永続化・自動起動まとめ！](https://www.sejuku.net/blog/81363)

AWS側はひとまずこれだけです。
あっ、当然ですが実際に起動したいNode.jsプログラムもAWSに保存しておきます。

##shellファイルの設置
自宅のラズパイから、AWSにコマンド命令するshellファイルを準備します。

コマンド内容はこれだけです。

- ssh接続
- foreverコマンドでスタート、ストップ

ラズパイからAWSにssh接続するので、事前にラズパイにEC2接続用のpemファイルを保存しておく必要があります。

```sh:startAWS.sh
#!/usr/bin/env bash

#0.0.0.0は任意のEC2のipアドレス
ssh -i ~/.ssh/aws.pem ubuntu@0.0.0.0 <<EOC
/home/ubuntu/.nodebrew/current/bin/node /home/ubuntu/.nodebrew/current/bin/forever start -l hoge.log -a /home/ubuntu/hoge/hoge.js
EOC
```

```sh:stopAWS.sh
#!/usr/bin/env bash

ssh -i ~/.ssh/aws.pem ubuntu@0.0.0.0 <<EOC
/home/ubuntu/.nodebrew/current/bin/node /home/ubuntu/.nodebrew/current/bin/forever stop /home/ubuntu/hoge/hoge.js
EOC
```

startAWS.shをもとに解説

- sshで接続し、コマンドを実行させる
- `aws.pem`はラズパイ上のpemファイル
- `ubuntu@0.0.0.0`はAWS EC2の任意のユーザー名とipアドレスに変更してください
- `/home/ubuntu/.nodebrew/current/bin/node`  
直接コマンドを流し込むのでEC2サーバーのENVが読まれずforeverから始めるとエラーになります。(foreverのshebangが通らない)
foreverを動かすインタプリタとしてnodeを指定する必要があります。  
またENVが読まれないのでフルパスでnodeを指定します。
- `/home/ubuntu/.nodebrew/current/bin/forever`  
上記と同様でフルパスでforeverを指定
- `start` 常時稼働を開始
- `-l hoge.log` ログファイルをhoge.logに指定。
- `-a`は上書きではなく、追記でログを書き込むオプション(Append logs)  
- `/home/ubuntu/hoge/hoge.js`こちらが実際に実行・停止したいプログラム本体です。

上記の、startAWS.shとstopAWS.shをラズパイに保存して
homebridgeのconfigに指定すれば準備完了です。
お疲れさまです:D

##流れを見てみる
それでは全てを踏まえて、もう一度流れを確認します。

1. iPhone,AppleWatchの「ホーム」から該当スイッチをタップ(もしくはSiriに呼びかけ)  
↓
2. AppleHomeKitにより自宅ラズパイでdaemon化したhomebridgeからshellファイルが実行される  
↓
3. shellファイルからAWSにssh接続して、foreverコマンドがAWSに渡される  
↓
4. AWS上のforeverを利用してhoge.jsをrestart,もしくはstopする

こんな感じです。

##おまけ
外出先でハッキリとONされたのを確認したいなら、
予め、プログラムにlineNotifyを仕込んでおくと、スタートされたらLineでpushが来るようにできて分かりやすいです。
[参考:LINE notify を使ってみる](https://qiita.com/iitenkida7/items/576a8226ba6584864d95)

#おわりに
遠隔操作は無数に方法があると思うのですが、**とにかく手軽に**作りたかった。

foreverでなく、ubuntuの`systemctl`で常駐操作しても良かったのですが、
設定ファイルを書くのが面倒くさかったり、手軽に実行ファイルを変更できないので見送りました。
ただ、foreverだとNode.jsに限定されるので
他の言語でカッチリ作りたい場合はsystemctlしてもよいのではないでしょうか。

また、HomeKitの利点は手軽な操作だけでなく、
固定IPにしなくても自宅のラズパイにインバウンドできることでもあります、
この点もすごくお手軽です。

手軽にAWSプログラムをON/OFFしたい方のご参考になれたら嬉しいです。
ここまでお読み頂きありがとうございました。

追伸:
渋谷の人混みの中、AppleWatchに向かって
*「へい、Siri! ホゲを起動して!」*
と大きめの声で言うのは、ちょっと(だいぶ)恥ずかしいですw