Nature Remoというスマートリモコンがあります。スマホのアプリやGoogle Homeなどから家電を操作できるもので去年くらいから愛用しています。このRemoにはセンサーが積んであり、温度、湿度、照度、人の動きをAPIから取得することができます(Remo miniは温度のみ)。今回、このAPIを叩きデータをためるところまでAzureのSaasを用いてクラウドだけで完結したいと思います。
クラウド上で完結させたかった理由
- メンテナンスが必要ない
- ほぼ無料で構築できる(ストレージアカウントに数円課金される)
- 外出先でもデータが確認可能
ラズパイなどを使ったほうが構築は簡単かと思いましたが、家庭のネットワークが切れることもありますし、外から確認することも考えクラウドでやりました。
使うもの
- Nature Remo / Remo mini
- Remo API
- Azure Functions(以下Functions)
- Azure Consmos DB(以下CosomosDB)
- Python 3系
- VScode
事前準備
今回FunctionsをPythonで使うため、ポータル上でのコードの編集はできません。VVScodeからAzureへデプロイします。そこでVScodeと以下の拡張機能を用意します。
VScode 拡張機能
- Azure Account
- Azure Functions
- Azure CLI Tools
- Azure CosmosDB
Azure Functions Core Tool
https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-run-local?tabs=windows%2Ccsharp%2Cbash
VScodeでAzureにサインイン
上記の拡張機能をインストールしたら、VScode上でF1を押し、Azure: sign in をせんたくします。開いたブラウザ上でサインインするとVScodeでAzureのサインインができます。
Azureのリソースを準備する
CosmosDB
CosmosDBを作成します。これはポータル上から行っても、VScodeからデプロイしてもかまいません。
VScodeで作成する場合
- VScode上でF1を押し、CosmosDB:Create Account...を選択
- Account名に任意の名前を入力します。(グローバルに一意)
- CosomosDBのAPIをCore(SQL)と選択します。
- Apply Free Tier Discountをapplyとします。
- ほかの質問に順に回答してください。
CosmosDBは無料範囲があり、以下のFAQにあるように400RU/秒と5GBのストレージが無料で使えます。
https://azure.microsoft.com/pricing/details/cosmos-db/
Functions
Functionsは今回Pythonで構築するためVScodeから行います。
- VScodeでF1を押す。
- Functionsを検索しAzure Functions: Create New Projectをする。
- ローカルで開発するディレクトリを選択する
- Pythonを選び、ローカルにインストールしているPython本体の実行ファイルを選択します。
- Triggerを選択します。今回はTimerTriggerで行います。
- Functionの名前を入力します。
- TimerTriggerの実行頻度をCRON式で入力する。デフォルトの
0 */5 * * * *
は5分ごとの実行です。
これでローカルにプロジェクトと関数のテンプレートができました。
関数作り
まず普通にPythonでRemoのAPIを叩けることを確認します。以下の記事のPythonのコード用いました。アクセストークンを入手し、ローカルでAPIが叩けることを確認しましょう。この記事中でも注意されいているように、APIkeyを流出させないように気をつけましょう。API経由で家電が他人に操作し放題となります。
https://qiita.com/sohsatoh/items/b710ab3fa05e77ab2b0a
結果は以下のようなjsonが返ってきます。Remo miniを用いたのでnewest_event
においてte
の項目で温度のみ出力されています。
[
{
"name": "Remomini",
"id": <your remo id>,
"created_at": "2019-07-21T13:01:54Z",
"updated_at": "2020-04-29T05:18:05Z",
"mac_address": <your remo mac address>,
"serial_number": <your remo serial number>,
"firmware_version": "Remo-mini/1.0.92-g86d241a",
"temperature_offset": 0,
"humidity_offset": 0,
"users": [
{
"id": <your id>,
"nickname": <your nickname>,
"superuser": true
}
],
"newest_events": {
"te": {
"val": 23,
"created_at": "2020-04-30T05:10:10Z"
}
}
}
]
created_at
がRemoを設定した日時、updated_at
がRemoをアップデートした日時(自動でアップデートされる?)のようです。
今回知りたいのはnewest_event
なので、その中身とAPIを叩いた時間をCosmosDBに送ります。newest_events
はセンサーの値が変化した際に更新される仕様のようなので、このcreated_at
はAPIを叩いた時間とは異なります。
このコードをtimetriggerのテンプレートコードに載せていきます。
__init__.py
import datetime
import logging
import json
import requests
import azure.functions as func
def main(mytimer: func.TimerRequest, doc: func.Out[func.Document]) -> func.HttpResponse:
utc_timestamp = datetime.datetime.utcnow().replace(
tzinfo=datetime.timezone.utc).isoformat()
if mytimer.past_due:
logging.info('The timer is past due!')
apikey= "<your remo API key>"
# get JSON
headers = {
'accept' : 'application/json',
'Authorization' : 'Bearer ' + apikey ,
}
response = requests.get('https://api.nature.global/1/devices', headers= headers, verify=False)
rjson = response.json()
res_json = rjson[0]["newest_events"]["te"]
res_json["request_time"]= utc_timestamp
res_json = json.dumps(res_json,indent=2)
logging.info('Python timer trigger function ran at %s', utc_timestamp)
doc.set(func.Document.from_json(res_json))
mytimer: func.TimerRequest
はazure.functionsのモジュールからのタイマー
、doc: func.Out[func.Document]
はazure.functionsの出力を意味しています。
今設定したdoc
という変数に値をセットすることで出力することができます。doc
という変数は関数作成時に生成されたfunction.json
にCosmosDBへ送る値だということを記述します。
関数アプリの設定
- F1キーでコマンドターミナルを出し、bindingと入力し、Azure Functions: Add bindingを選択します。(サイドバーのAzureロゴからローカルの先ほど作成した関数を右クリックすることでもできます。)
- 先ほど作成した関数を選択します。
- 今回は出力なのでoutを選択します。
- Azure CosmosDBを選択します。
- 関数の中で用いる変数名を入力します。今回は
doc
とします。 - CosmosDB内のデータベース名を入力します。今回は
home
とします。 - データベース内のcollection名を入力します。今回は
temperature
にします。 - DBが存在しない場合に作成するかについて、
true
とします。 - ローカル環境の設定について聞かれるので
Create new local app setting
で作成します。 - データベースのアカウントを聞かれるので、作成した
home
を選択します。 - Partitionkeyは任意なのでスルーします。
! Database名はグローバルに一意でないといけないため、任意の名前としてください
これでfunction.jsonに以下の内容が追加されます。
{
"type": "cosmosDB",
"direction": "out",
"name": "doc",
"databaseName": "home",
"collectionName": "temperature",
"createIfNotExists": "true",
"connectionStringSetting": "cielohome_DOCUMENTDB"
}
これで出力の設定ができました。なおCosmosDBのconnectionStringは同ディレクトリのlocal.settings.json
に記載されています。
"cielohome_DOCUMENTDB": "AccountEndpoint=https://hogehoge.documents.azure.com:443/;AccountKey=fugafuga;"
ローカルでテスト
ローカルでテストするために、必要なモジュールを入手します。今回は必要なモジュールはazure-functions
, requests
なので同ディレクトリのrequirements.txtに記載します。
azure-functions
requests
これをpip install requirements.txt
で入手します。
F5キーを押すとデバッグできます。
Functionsにデプロイする
- F1キーでコマンドターミナルを出し、deployと検索し、
Azure Functions: deploy to function app ....
を選択する。 -
Create new Function App in Azure (Advanced)
を選択 - 任意のリソース名を入力する。(グローバルに一意の名前)
- Python 3.7を選択する。
- Coonsumptionを選択する。従量課金です。Functionsも無料枠があるため5分に一回程度であれば基本的に課金されません。
- リソースグループ選択する。CosmosDBと同じリソースグループとします。違うものでも大丈夫です。リソースグループがLinuxで作っていないとPythonのアプリが動かないので注意する。
- storage accountを選択します。
- Application insightsを選択します。ログを見たりするSaasです。
これでデプロイが完了しています。
CosmosDBでデータを確認する
関数のデプロイができたら、データを見てみましょう。
VScode上からAzureのロゴをクリックしてサイドバーのCosmosDBを確認します。データベースを開くとtemperature
にドキュメントとしてできています。
"val": 24.2,
"created_at": "2020-05-02T13:49:12Z",
"request_time": "2020-05-02T14:00:00.007771+00:00"
これで完成です。
まとめ
これでAzureでFunctionsとCosmosDBを用いてデータを格納することができました。次回はこのデータを可視化してみたいと思います。
参考
https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-integrate-store-unstructured-data-cosmosdb?tabs=javascript
https://docs.microsoft.com/ja-jp/azure/azure-functions/
https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-reference-python
Nature スマートリモコン Nature Remo mini 家電コントロール Amazon Alexa / Google Home / Siri 対応 GPS連携 温度センサー Remo-2W1
おまけ
MicrosoftのPowerBI Desktopというソフトがあるので、それで簡単に簡単に可視化してみるとこんな感じでした。Azureとの連携が簡単なので楽でいいですね。