🍀

Cosmos DBで確認:ラズパイに繋いだセンサーで温度を取得してみた

2023/02/27に公開

はじめに

前回のブログにてLINEから温度が確認できたので、今回は温度センサーの値をMicrosoft Azure(以下 Azure)のCosmos DBに格納していきたいと思います。

システム構成

以下のようなシステム構成で構築を進めていきます。

Azureリソースの作成

IoT Hubの作成

まずはAzure IoT Hub(以下 IoT Hub)の作成から進めていきます。以下のように選択し、作成ボタンを押下します。

リソースの作成:IoT Hubを選択



次画面では以下のように入力し、確認および作成ボタンを押下します。

リソースグループ:作成したリソースグループ
IoT Hub 名:任意の値
領域名:適切なリージョン名



次にデバイスの作成を行います。以下のように入力し、保存ボタンを押下します。

デバイスID:任意の値
自動生成キー:チェックオン
このデバイスをIoTハブに接続する:有効化を選択



これでIoT Hubの作成は完了です。

Stream Analyticsの作成

次にAzure Stream Analytics(以下 Stream Analytics)を作成します。
リソースの作成よりStream Analyticsを選択し、作成をクリックし、「新しいStream Analyticsジョブ」画面を表示します。
以下の値を入力し、確認と作成ボタンよりリソースを作成します。

リソースグループ:今回使用するリソースグループ名
名前:任意の値
リージョン:任意のリージョンを選択
ホスティング環境:クラウド
ストリーミングユニット:1 ※このストリーミングユニットの数だけ課金されるので今回は1つにします。

IoT HubとCosmos DBを連携する必要がありますが、こちらはCosmos DBを作成後に実施します。



Cosmos DBの作成

次にCosmos DBを作成します。
リソースの作成よりCosmos DBを選択し、プランに「Azure Cosmos DB」を選択し、作成ボタンを押下します。



APIオプションの選択画面が表示されるので、「コア(SQL)-推奨」内の作成ボタンを押下します。



アカウント作成画面にて、以下の値を入力し、レビュー+作成ボタンを押下し、リソースを作成します。

リソースグループ:今回使用するリソースグループ
アカウント名:任意の値
場所:任意のリージョンを選択



次にコンテナを作成します。
画面左上の「New Container」を押下すると、画面右にNew Containerのポップアップが表示されるので、以下の値を入力し、OKボタンを押下します。

Database id:任意の値
Container id:任意の値



これで一旦必要なリソースの作成ができました。

IoT HubからStream Analyticsを経由しCosmos DBにデータストアする設定

次にIoT Hubで受信したセンサーデータをCosmos DBへストアするための設定を記述します。
まずは先程作成したStream Analyticsのリソースを開きます。
画面左ペインの「ジョブトポロジ」→「入力」を押下し、「ストリーム入力」の「IoT Hub」を選択します。



IoT Hubを選択すると画面右に「新規入力」のポップアップが開きます。
以下の値を入力し、保存ボタンを押下します。

入力のエイリアス:任意の値
Iot Hub:先程作成したIoT Hubのリソース
その他:デフォルト値のまま



次に画面左ペインの「ジョブトポロジ」→「出力」を押下し、「追加」ボタンからCosmos DBを選択します。



IoT Hubを選択すると画面右に「新規入力」のポップアップが開きます。
以下の値を入力し、保存ボタンを押下します。

出力のエイリアス:任意の値
アカウントID:先程作成したCosmos DBのデータベースを選択
コンテナ名:先程作成したコンテナ名
認証モード:接続文字列
アカウントキー:任意の値



以上で設定は全て完了です。

センサーデータをDBに格納するプログラムを動かしてみる

プログラムを作成し、温度センサーからCosmos DBに格納されるまでを実装

今回はPythonを使って、温度センサーの値をIoT Hub経由でCosmos DBに格納するプログラムを作成しました。
一定間隔で温度センサー値を取得し、IoT Hub経由でCosmos DBに書き込む実装をしています。
IoT HubからCosmos DBへの連携は、上記で設定した情報で接続しています。

send_temperature.py

import os
import glob
import time
import datetime
import asyncio
import RPi.GPIO as GPIO
import time
from azure.iot.device.aio import IoTHubDeviceClient
 
GPIO.setmode(GPIO.BCM)
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

# 温度センサーデバイスへの接続情報
base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'

# IoT-Hubの接続文字列(環境変数より取得)
conn_str = process.env.IOTHUB_ACCESS_TOKEN

async def main():

    #Azureに接続
    device_client = IoTHubDeviceClient.create_from_connection_string(conn_str)
    await device_client.connect()

    # 開始メッセージ送信
    print("処理開始")
    await device_client.send_message("This is a message that is being sent")
    
    # 一定間隔でメッセージを送り続ける
    while True:
        temp = await read_temp()
        # メッセージ送信
        await device_client.send_message('{\"temperature\":%3.1f,\"ins_datetime\":\"%s\"}'% (temp, datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
        
        time.sleep(10)
    
# 温度センサーの読み取りとメッセージの整形
async def read_temp():
    lines = await read_temp_raw()
    while lines[0].strip()[-3:] != 'YES':
        time.sleep(0.2)
        print(lines)
        lines = await read_temp_raw()
    equals_pos = lines[1].find('t=')
    if equals_pos != -1:
        temp_string = lines[1][equals_pos+2:]
        temp = float(temp_string) / 1000.0
        return temp

# 温度センサー1行分読み取り
async def read_temp_raw():
    f = open(device_file, 'r')
    lines = f.readlines()
    f.close()
    return lines

if __name__ == "__main__":
    asyncio.run(main())

このプログラムが正しく動いているか以下のコマンドで実行してみます。

python3 send_temperature.py

温度データがDBにストアされているか確認

Cosmos DBのデータエクスプローラーよりデータを確認します。
itemsよりデータを参照するとデータが格納されていることが確認できます。



1件データを開いてみると、温度とタイムスタンプが記録されていることが確認できました。



以上でIoTデバイスを使って、温度センサーをCosmos DBにストアする仕組みの構築は完了です。
次回以降もIoTデバイスを使って、色々試していきたいと思います。

Discussion