AnsibleでおうちIoT

# はじめに
この記事は[Ansible Advent Calendar 2019](https://qiita.com/advent-calendar/2019/ansible)と[おうちハック Advent Calendar 2019](https://qiita.com/advent-calendar/2019/ouch-hack)の8日目です。

# 概要
こんな感じの構成を作ります。
![Untitled Diagram.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/f46f7c2b-e679-9209-945c-b072e4523219.jpeg)

今回はAWS IoTをSubscribeするためにRaspberry Pi Zero、赤外線リモコンとしてbroadlink RM mini3を使いましたが、目的が果たせれば何でもよいです。


# AWS IoT設定
AWS IoTのコンソールからモノの登録をします。
![スクリーンショット 2019-12-07 20.14.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/5129fc04-78cb-9828-697e-2242d3c87c5e.png)

「単一のAWS IoT モノの登録」を選び、名前だけ入力し作成を進めます。
![スクリーンショット 2019-12-07 20.15.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/38a3dfad-9b07-d699-a0b5-e151f740222d.png)

「1-Click 証明書作成」を選ぶと以下のように証明書が作成されるので、全てダウンロードし「有効化」をクリックします。
ルートCA証明書は[コレ](https://www.amazontrust.com/repository/AmazonRootCA1.pem)をダウンロードしておきます。
![スクリーンショット 2019-12-07 20.31.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/c2a55e47-7e2f-3cdc-8351-ddac13a24318.png)

ポリシーを作りますが…
![スクリーンショット 2019-12-07 20.40.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/9cf16f7e-36c4-c3ee-a5d2-01dfabcc38aa.png)

アクションを「aws:\*」、リソースARNを「*」と雑に作ってしまいます。
本格的に使う場合はそれなりに考えましょう。
![スクリーンショット 2019-12-07 20.40.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/0b014307-10b1-b36e-8d22-cf4aad530839.png)

ポリシーを作ったら、先ほどモノを登録した時に作られた証明書にアタッチします。
![スクリーンショット 2019-12-07 20.41.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/6a29fef3-2b6a-d745-1f0e-1f5e88eb0ce1.png)

左のメニューから「設定」を開き、エンドポイントのURLを控えておきます。

# サブスクライバの準備
AWSのGithubで公開されている[サンプルのPythonスクリプト](https://github.com/aws/aws-iot-device-sdk-python/blob/master/samples/basicPubSub/basicPubSub.py)を利用します。
pipでパッケージをインストールし、

```bash
$ pip3 install AWSIoTPythonSDK
```
以下のようにスクリプトを起動しておきます。

```bash
$ python3 basicPubSub.py -e <エンドポイントのURL> -r <ルートCA証明書のパス> -c <モノの証明書ファイルのパス> -k <プライベートキーファイルのパス> -t myTopic -m subscribe
```

AWSコンソールのテストのページからmyTopicに発行を行い、標準出力にメッセージが出力されることを確認しておきます。

# スクリプト変更
問題なくサブスクライブができていたら、メッセージを受けたらコマンドを実行するようスクリプトを改変します。
customCallback関数を以下のように変更。

```basicPubSub.py
def customCallback(client, userdata, message):
    payload = json.loads(message.payload)
    print(payload["deviceName"])
    print(payload["name"])
    print(payload["value"])    
    if payload["deviceName"] == "RoomLight" and payload["name"] == "powerState":
        if payload["value"] == "ON":
            subprocess.call(<照明をつけるコマンド>)
        elif payload["value"] == "OFF":
            subprocess.call(<照明を消すコマンド>)
        else:
            print("Unknow Value:" + payload["value"])
```
編集後、再度スクリプトを起動しておきます。

#Playbook作成（この記事唯一のAnsible要素）
AWS IoTにPublishするために、Ansibleの[mqttモジュール](https://docs.ansible.com/ansible/latest/modules/mqtt_module.html)を利用します。
[paho-mqtt](https://pypi.org/project/paho-mqtt/)が必要になるのでインストールしておきます。

```bash
pip install paho-mqtt
```

Playbookは以下のような感じで書きます。

```mqtt.py
---
- hosts: localhost
  become: no
  tasks:
  - name: Light On
    mqtt:
      topic: 'myTopic'
      payload: '{"deviceName": "RoomLight", "name": "powerState", "value": "ON"}'
      qos: 0
      server: <エンドポイントURL>
      port: 8883
      ca_cert: <ルートCA証明書ファイルのパス>
      client_cert: <モノの証明書ファイルのパス>
      client_key: <プライベートキーファイルのパス>
```
実行すると…

```bash
$ ansible-playbook mqtt.yml 
```

![VID_20191208_005218a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/6ac353de-880a-1121-afdb-67db8c0affd9.gif)
できました。

# おわりに
Ansibleアドベントカレンダー登録したものの、ネタが思いつかず…。
AnsibleでMQTT扱いたい人の参考になれば幸いです。