NatureRemoのセンサー情報をElasticSearchにぶち込みダッシュボード化

echo dotとNatureRemoを購入

スマートスピーカーとスマートリモコンが使いたくなり、echo dotとNature Remoを購入した。

以降に書く内容とはなんの関係もないが、スマートスピーカーは休みに引きこもって声を出さない人には、発声する機会になって非常に良いと思う。

休日は誰とも喋らない人や引きこもりの人におすすめである。



スマートリモコンも色々種類があるが、Nature Remoを選択したのはAPIを叩けばセンサー情報が取得できるからである。

Nature Remoには気温、湿度、照度、騒音、人感センサーがあり、気温、湿度、照度に関してはAPIでかんたんに取得できる。

Nature Remoのアプリでもセンサー情報確認できるし、NatureRemoアプリ単体で「気温が何度以上になったらエアコンON」とか「何時くらいに照度が下がったら証明ON」とか普通にできるのでおすすめな製品。

Nature Remoのセンサー情報をAPIで取得

※筆者、ElaticSearchとかJSON APIとかあんまり分かってない人なので間違ったこと書いてたらご容赦ください

細かい内容はNature Remo の Remote API を実行してセンサー情報をとってみたNature Remoの公式APIの使い方を参考にしていただければいいのだが、Global APIにアクセスするための認証トークンを取得して、curlでアクセスすればセンサー情報がJSON形式で得られる。

余談だが、Nature RemoのローカルIPが分かればLocal APIを叩いて直近に学習したリモコンの情報が取得でき、そのJSONをPOSTすれば学習した信号を送ることができるのだが、学習した直後じゃないとAPI叩いても値が帰ってこないので注意したい。
筆者、見事にハマった。

JSON形式で取得できるならElasticSearchにぶち込んで部屋のセンサー情報をグラフ化してしまおう!と思い立つ。

ElasticSearchのインストール

UbuntuをKVMの仮想環境に入れてElasticSearchの公式サイトからElasticSearchのdebとグラフ化するためのkibanaのdebを入れて終了!
(ここはホンマに何も書くことがない)

ElasticSearchにセンサーデータをPOST

GlobalAPIを叩いて取得した値をElasticSearchにぶち込むところがゴール。

GlobalAPIを叩いてセンサー情報を取得。
curl -X GET "https://api.nature.global/1/devices" -H "accept: application/json" -k --header "Authorization: Bearer <トークン>"

下記のような値が返ってくる。(XXXのところは固有情報のためマスク)
[{"name":"XXX","id":"XXXX","created_at":"2019-05-22T13:48:40Z","updated_at":"2019-06-11T00:23:13Z","mac_address":"XXX","serial_number":"XXX","firmware_version":"XXX","temperature_offset":0,"humidity_offset":0,"users":[{"id":"XXX","nickname":"XXX","superuser":true}],"newest_events":{"hu":{"val":40,"created_at":"2019-06-11T00:34:09Z"},"il":{"val":249.39,"created_at":"2019-06-11T00:23:36Z"},"te":{"val":27.79,"created_at":"2019-06-10T23:59:02Z"}}}]

上記を直接投入しようとしたが、"["と"]"が邪魔でElasticSearchに怒られるのでsedで除去する。

もっとオシャンティーなやり方があると思うのだが、自分の持てる残念なスキルを活かして、sedで除去した結果を一時ファイルに吐き出す。

sedで"["と"]"を除去する場合は特殊文字になるようで、「sed -e s/[][]//g 」のように書くらしい。

吐き出したファイルをElasticSearchにPOSTして投入する。
とりあえず「natureremo」っていうインデックスで登録していく。
IDは自動採番。難しいことはとりあえずしない←。

結果、以下のようなシェルが完成。
#!/bin/bash
# get sensor data from cloud api
curl -X GET "https://api.nature.global/1/devices" -H "accept: application/json" -k --header "Authorization: Bearer <トークン>"  | sed -e s/[][]//g > ${HOME}/sensor.json
# put new record into elasticsearch
curl -XPOST localhost:9200/natureremo/_doc/ -H "Content-Type: application/json" -d @${HOME}/sensor.json

GlobalAPIは5分以内に30回以上叩くとリクエスト制限がかかる&実はそんなにセンサー情報が更新されていない疑惑があるので、5分に1回リクエストを投げてElasticSearchに登録するよう、crontabにシェルを登録。
*/5 * * * * /opt/natureremo_get.sh


これで5分に一回センサー情報を取得してElasticSearchに投入することができた。

Canvasでダッシュボードを作成

データためただけだとつまらないので、ElasticSearchの付属ツールであるKibanaで気温の状態がわかるダッシュボードを作成してみる。

先に完成形を上げるとこんな感じ。
左側に直近2日分のセンサーグラフ、右側に最新のセンサー値を表示させるダッシュボード。

溜め込んだセンサー情報の取得方法については、筆者がSQLなら分かる(luceneのクエリ勉強中…)ので、ぱぱっとSQL文で書いてみた。

newest_events.te.createdとnewest_events.te.valが温度の取得時間と温度(セルシウス度)になる。te(tempature)のところが湿度はhu(humidity)、照度はil(illuminance)になるので読み替え。

  • 最新の気温情報の取得
とりあえずデータも大した量にならないので、時系列でDESCで降順ソートして、一番最初のデータを取得するという野蛮な方法で取得。
SELECT 
newest_events.te.created_at,round(newest_events.te.val) as tempature
FROM "natureremo"
where newest_events.te.created_at is not null
order by newest_events.te.created_at DESC
LIMIT 1

  • 2日前までの気温情報の取得

ElasticSearchのSQLで期間を指定する方法を参照しつつ、2日前までのセンサー情報を取得する。
SELECT  newest_events.te.created_at ,newest_events.te.val FROM "natureremo" 
where newest_events.te.created_at is not null
and newest_events.te.created_at > today() - interval 2 day
order by newest_events.te.created_at 

あとは作りたいグラフなどのエレメントのデータソースに上記のようなSQLを指定してやればOK。

リフレッシュ間隔を指定してやれば定期的にアップデートされるので、部屋の状況が変わると値も自動で変わってくれる。

あとはCanvasのURLを指定したら自動でいわゆるキオスクモードとか自動リフレッシュの間隔をURLで指定できると便利だなーと思っていたら、同じこと思う人がいっぱいいるみたいで対応中らしいので、今後に期待。

大雑把な感想

これでセンサー情報を蓄えて表示するというIoT的なことが実現できた。

ElasticSearch、JSON直接投入できて便利だし、SQLを書けるというところがDBオジサンにとって嬉しい点。

redash使ってみようと思ったのもSQL書けばグラフができるからだし、SQLのスキルが活かせるのはとっつきが良くていい。(Lucene勉強します…)

センサーの情報みたいならminiじゃないやつ。


スマートリモコンが使いたくて、温度だけで良ければmini


買ってみるとスマートスピーカーは割と楽しい



コメント

このブログの人気の投稿

ヤマダ電機の安心会員住所変更をした

JP1の定義をドキュメント化するjp1ajs2.jobdocが超便利

curlでADのドメインユーザーでプロキシを超える