Gravio 4でボタン一つで温度・湿度・気圧・CO2をLINE通知とPollyで音声アナウンスする

仕事をしていると寒いなぁとか換気必要かなとかいろいろ思うことがある。CO2のライトもいいけど、ボタン一つでいろいろ教えてくれると便利と思ってやってみた。

# 使用環境

今回はAmazon Pollyを使うので、安定して動くWindows版のHubKitを動かす。

* Windows 10 20H2 (19042.844)
* Gravio HubKit v4.1.4049.0
* Gravio Studio v4.1.5432.0
* Gravio クライメートセンサー (Gravio Basic以上の契約が必要)
* Gracio CO2センサー (Gravio Standard以上の契約が必要)
* LINENotify/LINE
* Amazon Web Services/Amazon Polly

# 事前準備
* AWSでAmazon Pollyが使えるようなアカウントのアクセスキーとシークレットキー
* LINE通知を行うためのアカウントと、通知するためのLINENotifyのトークン
* 上記ふたつを基本プロパティセットとして登録しておきます

# 手順
## センサーとボタンの登録
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/3732e974-5679-f3c5-f4b8-971263487eff.png)
温度、湿度、気圧、CO2の各レイヤーを作成し、それぞれセンサーをバインドします。温度、湿度、気圧はすべてGravio クライメートセンサーから取得できますので、それぞれのレイヤーに同じセンサーをバインドすればOKです。
また、通知をするためのボタンもペアリング、レイヤー作成し、バインドしておきます。

## アクションの作成

### センサーデータの取得

このような形のアクションを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/ab17b716-c50a-6a74-2579-27ed011ee09a.png)

まず、**Sensor Data DB**コンポーネントで直近の値を１つだけ拾ってきます。ここでは温度を指定しています。
取ってきた値をPost Mappingsでアクション変数を作って代入しておきます。`cvn.`はこのコンポーネントの出力ペイロードです。Post Mappingsでのみ使えます。

```:av.温度
cvn.Payload.Data
```

これを他のデータでも実施します。同様に、湿度、気圧、CO2に対して同じようにコンポーネントを設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/140b9a1e-b48d-d868-8e0b-5660359e85d5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/b06b13ed-5a33-7f66-d91a-15dc956656aa.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/cc5e0c19-68b8-878b-a23c-244684bf69d2.png)

### メッセージの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/1ed8207f-024b-8e7f-e160-ee11359cd6a1.png)

センサーデータが揃ったので、今度は **Template**コンポーネントを使ってメッセージを作成します。
Pre Mapppings等の式で生成してもいいのですが、ここでは **Template**コンポーネントを使います。記述がわかりやすいのと、このあと **LINE Notify**コンポーネントと **Amazon Polly Speech**コンポーネントで同じメッセージを使うためです。
変数の参照は``{{}}``でくくるのと、`av`などの前に`.`を付けるのを忘れずに。マッピングとは異なる記法です。
作ったメッセージは今回もアクション変数に代入しておきます。Templateコンポーネントの出力は合成文字列そのものなのでそのまま代入します。

```:テンプレートプロパティ
現在の温度 {{.av.温度}} 度、湿度 {{.av.湿度}} ％ 、気圧 {{.av.気圧}} hPa 、CO2 {{.av.CO2}} ppmです。
```

### LINE通知

**LINE Notify**コンポーネントのメッセージに作成しておいたアクション変数を渡します。基本プロパティセットには準備しておいたトークンを設定したものを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/cd6f042b-888e-b6d9-e97f-5620886ebc1e.png)

### Pollyで音声アナウンス

**Amazon Polly Speech**コンポーネントのテキストに同じく作成しておいたアクション変数を渡します。基本プロパティセットにはこちらも準備しておいたキーを設定したものを選択します。音声は日本語を再生するので、`Takumi`か`Mizuki`を指定しておきましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/8a3a771d-cc31-6e8a-65ba-3ab2e5dce235.png)

## 実行
アクションを実行するとLINEに通知され、音声で読み上げられました。頑張って記事を書いてたのでCO2が上がってしまったようですｗ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/11bbcac6-1a86-a736-8c11-f54165fba6a4.png)

## トリガーの設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/1126ce23-a35f-9141-f5ab-ac6e276d363e.png)
いつものようにボタンの `Single press`に対してアクションを紐付けておきます。
有効にすると、ボタンを押したタイミングで実行されるようになりました。

# ポイント
* データの取得は**Sensor Data DB**コンポーネントを使って、1レコードだけ取得する
* データはアクション変数に格納しておくと便利。ただし、後述のように注意すべき点も。
* メッセージの合成は**Template**コンポーネントが使える。記述がマッピングの式とは異なるので注意！

# Sensor Data DBの使用上の注意
今回、**Sensor Data DB**は１レコード限定で取得しました。通常利用する場合は、複数レコード取得することがあります。その場合、以降のコンポーネントは各レコード単位で動きます。つまりループのような動きをするので注意が必要です。
そういう意味では、今回は連続するSensor Data DBで１＞１＞１＞１のループが発生しているとなります。仮にどこかのデータが全く取得できていない場合は、例えば１＞１＞１＞０となり後続の処理が実行されないので注意しましょう。

# アクション変数の使用上の注意
アクション変数はアクションスコープの変数ですが、前述のように**Sensor Data DB**のようなループの中で実行してしまうと、各レコードに対する処理は並列で実行される可能性があるので、同時にアクション変数にアクセスする可能性があり、参照のタイミングで期待する値が入っていないことが考えられます。なので、今回は１レコード限定なのでいいですが、利用には十分気をつける必要があります。
マルチスレッド処理で同時に同じグローバル変数にアクセスしているようなものと考えると、わりとイメージが近いと思います。

# 参考
* [Gravio][]
* [Sensor Data DBコンポーネント][Gravio-SensorDataDB]
* [Templateコンポーネント][Gravio-Template]
* [LINE Notifyコンポーネント][Gravio-LINENotify]
* [AmazonPollySpeechコンポーネント][Gravio-AmazonPollySpeech]


[Gravio]:https://www.gravio.com/jp
[Gravio-SensorDataDB]:https://doc.gravio.com/manuals/gravio4/1/ja/topic/sensordb-recent
[Gravio-Template]:https://doc.gravio.com/manuals/gravio4/1/ja/topic/template
[Gravio-LINENotify]:https://doc.gravio.com/manuals/gravio4/1/ja/topic/line-notify-action-component
[Gravio-AmazonPollySpeech]:https://doc.gravio.com/manuals/gravio4/1/ja/topic/amazonpollyspeech-action-component