はじめに
この記事はIoTLTオンラインで登壇した話の補足です。登壇資料はこちらからご覧ください。
今回は5分で収まりきらなかったIBM Cloud FunctionsでSens'itのデータを溜め込むまでの詳細なお話をします。
用意するもの
- IBM Cloud(ライトアカウントでもOK)
- SORACOMユーザーコンソール
- Sens'it(SORACOM IoTストアから購入したもの)
事前にSens'itのセットアップを済ませてSORACOM harvestでデータが表示出来る状態とします。
SORACOM Beamからのデータを受け取ってみる
Cloudantの用意
まずはデータを溜め込むためにデータベースを用意します。今回は、データの保存先としてCloudantを使います。CloudantはIBM Cloudが提供しているDBaaSです。NoSQLデータベースでIoTのデータを溜め込むにはうってつけのサービスです。Node-REDをIBM Cloudで使っている方はフローの保存にCloudantが使われているので、これをそのまま使ってもOKです。もし、Cloudantがリソースリストにない場合は、Cloudantのリソースを作成しておきます。Cloudantのリソース画面に移動したら、サービスの資格情報
から新規資格情報
を選択してCloudantの接続情報を作成しておきます。
役割はManagerを選択しておきます。資格情報が作成されたらそこに表示されているusername
とpassword
、url
をどこかにメモしておきます。
次にSens'itのデータを貯めるためのデータベースを用意します。管理を選択し、そこからLaunch DashboardをクリックしてCloudantのダッシュボードにアクセスします。
ダッシュボードの右側のCreate Database
を選択して、データベース名をsensit_data
とし、パーティションはNon Partitioned
を選択してCreate
をクリックします。
SigfoxデバイスIDを確認
続いて使用するSens'itのデバイスIDを確認します。SORACOMコンソールからSORACOM Air for Sigfox
の中のデバイスの管理を選択し、使用しているSens'itのデバイスIDをメモしておきます。合わせて、SORACOMのユーザーコンソールにログインするときに使っているメールアドレスとパスワードもメモしておきます。
アクションの用意
最後にIBM Cloud Functionsのアクションを作成します。IBM Cloud Functionsのトップページに移動し、作成の開始
を選択します。そこからActionsを選択したらお好きなアクション名を設定してRuntimeをPython3.7
にしてCreateをクリックしてください。作成できたら以下のコードをアクションのエディタにコピペします。
import json
import requests
from cloudant.client import Cloudant
from cloudant.query import Query
from cloudant.adapters import Replay429Adapter
def main(args):
auths = getToken(args["SORACOM_EMAIL"], args["SORACOM_PASSWORD"])
# Get current soracom sens'it data
timestamp = args["__ow_headers"]["x-soracom-timestamp"]
headers = {
'Accept': 'application/json',
'X-Soracom-API-Key': auths["apiKey"],
'X-Soracom-Token': auths["token"],
}
params = {
'from': timestamp,
'sort': 'asc'
}
response = requests.get('https://api.soracom.io/v1/sigfox_devices/{}/data'.format(args["DEVICE_ID"]),
headers=headers,
params=params)
print(response.json())
data = json.loads(response.json()[0]["content"])
# Cloudantに接続
client = Cloudant(args["USERNAME"], args["PASSWORD"], url=args["URL"],
adapter=Replay429Adapter(retries=10, initialBackoff=0.01)
)
client.connect()
userdb = client["sensit_data"]
#リクエストデータを登録(timestampをIDとする)
data = {
"_id": data["time"],
"time": data["time"],
"battery": data["battery"],
"tempC": data["tempC"],
"tempF": data["tempF"],
"humidity": data["humidity"]
}
resistDocument = userdb.create_document(data)
if resistDocument.exists():
print("SUCCESS!")
# Cloudantを切断
client.disconnect()
return { 'status': 200 }
def getToken(email, password):
body = {
"email": email,
"password": password
}
response = requests.post("https://api.soracom.io/v1/auth", json=body)
return response.json()
簡単にソースコードの解説をすると、SORACOM Beamから受け取るデータにはセンサーの情報が何も入ってませんでした。Beamの設定ではアクセスポイントぐらいしか設定項目がなかったので、特に送信するデータを自分で自由に設定できるわけではなさそうです(もし送信するデータを設定する方法を知っている方がいたら教えてほしいです…)。ただ、データを送信したときのタイムスタンプはリクエストデータから取得することができました。そこで、SORACOMのAPIリファレンスに紹介されていたSigfoxのAPIを使って最新のセンサーデータを取得しています。また、序盤でアクセストークンをAPIで取得しているのは、アクセストークンが一定時間立つと無効になってしまうので、ユーザーネームとパスワードからアクセストークンを取得しています。あとは、データを整形してCloudantに送信するという仕組みです。
パラメータの用意
アクションを用意できたらアクションを動かすためにパラメータを用意します。パラメータは先程メモしたアクセストークンなどをここで設定します。アクションのエディタ画面からParameters
を選択し、各パラメータを設定します。今回設定するパラメータは以下の通りです。
Parameter Name | Parameter Value |
---|---|
SORACOM_EMAIL | SORACOMユーザーコンソールのメールアドレス |
SORACOM_PASSWORD | SORASOMユーザーコンソールのパスワード |
PASSWORD | Cloudantのパスワード |
USERNAME | Cloudantのユーザーネーム |
URL | CloudantのURL |
APIエンドポイントの設定
それでは、最後にこのアクションを呼び出すためにAPIエンドポイントを設定します。Functionsのトップページに移動し、左のメニューからAPIを選択します。
APIの作成からAPI名とエンドポイントを設定して、操作の作成をクリックします。
操作の作成では、以下のようになります。パス名は自由に設定ていいですが、後で使うのでメモしておきましょう(スラッシュはパス名を入れると自動でつきます)。VerbにはPOSTを選択し、アクションは先程作成したアクションを選択します。応答コンテンツはapplication/jsonのままでいいです。入力を終えたら「作成」をクリックして作成します。途中で「Webアクションが自動的に有効になります」的な警告が出てきたらそのまま次にすすみます。
作成が終わると以下のAPI設定画面が出てくるので、この中のルート
に書かれてるURLに先程のパスを合わせたものがSORACOM Beamで設定するエンドポイントURLになりますのでメモしておきましょう。
SORACOM Beamの設定
続いて先程用意したエンドポイントをSORACOM Beamで設定します(本当はSORACOM Funkから呼び出せると嬉しい…)。SORACOM Air for Sigfoxの中のSigfoxグループの中からSens'itが登録しているグループを選択します。+ボタンを押してエンドポイントを追加します。
設定方法としては先程メモしたエンドポイントURLのうち、×××.us-south.apigw.appdomain.cloud
がホスト名となり、/以下のパスはパスに設定します。ポート番号は何も書かなくていいです。記入し終えたら、下にスクロールして保存
をクリックします。
動作確認
これでIBM Cloud Functionsで値を受け取ることが出来る状態になります。1時間おきにデータが送信されて、Cloudantのデータベースを確認するとこのように温湿度のデータやバッテリーの残量をを溜め込むことができます。
おまけ
今回Soracomのキャンペーンで記事を投稿してSens'itを入手しました。
その時書いた記事はコチラ↓
ソラコムの【あのボタン】で勤怠打刻してみた(その1)
ソラコムの【あのボタン】で勤怠打刻してみた(その2)