DHT22で取得した温湿度データをNode-Red, Azure IoT HubとWeb Appsでリアルタイムグラフ表示するアプリを作る方法【ラズパイ / Azure】

thumbnail

はじめに

今回はRaspberry Pi 4 Model B、DHT22温湿度センサー、Node-RED、Azure IoT HubそしてWeb Appsを使用してセンサーから取得した温湿度データをリアルタイムのグラフとして表示するアプリを作る方法を解説します。

データを保存して表示するというよりは、リアルタイムの数値の変化を見ることができるWebアプリケーションです。次回以降Google スプレッドシートにデータを保存するのも試してみたいと思います。

DHT22センサーとの接続方法はこちらの記事をご参照ください。

完成物

完成すると以下のようなリアルタイムで温湿度のグラフを描画するアプリを作ることができます。

このアプリはマイクロソフトのチュートリアルのコードを使用して作成しています。アプリを開いてからでないとグラフを描画できない、タイムゾーンが日本じゃないなど修正する箇所はいくつもありますが、最低限温度と湿度のリアルタイムの変化を見ることができます。

完成物 | 自室の温湿度のリアルタイムデータ(10分ごと)

システム構成

システムの構成は次の図のようになっています。DHT22センサーから温湿度情報を取得しラズパイに送信する、そして送信されたデータをNode-REDを経由してAzure IoT Hubに送信します。IoT Hubに送信されたデータをWeb Apps上にデプロイされたアプリケーションでグラフ化して表示します。

システム構成図

環境 (Raspberry Pi)

ソフトウェアバージョン
Git2.20.1
Node.js14.18.1
npm6.14.15
Python3.7.3
Raspberry Pi OS10.11
Raspberry Pi上の環境

環境 (Mac)

ソフトウェアバージョン
Azure CLI2.30.0
Git2.30.1
Node.js16.13.0
npm8.1.10
macOS10.11 Monterey 12.0.1
Mac上の環境

Node-REDとは

Node-REDとはフローベースのプログラミングツールです。Node.js上で構築されており、ノードと呼ばれる機能を含むパーツ同士をつなぎ合わせフロー(流れ)を作ります。今回はこれを使って、視覚的にわかりやすくシステムを構築していきます。

Node-REDのインストール方法

ラズパイでLXTerminalを開き、ドキュメントに記載のコマンドを実行する

ターミナルで以下のコマンドを実行します。

bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)
コマンド実行

いくつかの質問が表示されますので”y”と入力して進めましょう。

Node-REDのインストール完了
Node-REDを起動する

Node-REDを起動するには以下の2つの方法があります。どちらの方法でも起動できるので好みの方法で起動してください。

  1. node-red-startコマンドを実行する
  2. ラズパイのメニューから実行する

以下はNode-REDを起動するコマンドです。

node-red-start
Node-REDを起動する
Node-REDの起動

Node-REDにアクセスする

アドレスバーに127.0.0.1:1880と入力してNode-REDにアクセスします。同じネットワーク内ならラズパイからだけでなく、お使いのPCからも(Wi-FiのIPアドレス):1880でアクセスすることができます。

Node-REDへのアクセス

Welcome画面が表示されればアクセスに成功です。かんたんなチュートリアルがあるので進めておきましょう。

DHT22センサーの情報取得

まずはDHT22センサーが正常に動いているかを確認することもかねてNode-REDでDHT22センサーからの温湿度データの取得と表示をおこないます。

DHTセンサー用のノード (rpi-dht22)を追加する

まずはDHT22センサーから温湿度情報を取得します。右上のハンバーガーメニューから「パレットの管理」→「ノードを追加」をクリックし、node-red-contrib-dht-sensorを追加します。

node-red-contrib-dht-sensorの追加

「追加」をクリックします。

rpi-dht22ノードの追加
Injectノード、Debugノードとrpi-dht22ノードをフローに追加する

左側の共通パネルからInjectノード、Debugノードとrpi-dht22ノードをドラッグアンドドロップでフローに追加します。

ノードの追加
ノード間をワイヤーで接続する

ノードのポートをクリックしながらドラッグしてノード同士を接続します。左側からInjectノード、rpi-dht22、そしてDebugノードの順に接続します。

ワイヤー接続

各ノードの構成は次の画像のようになっています。Injectノードの繰り返しの頻度は任意の間隔を設定してください。無料の枠で最大限データを取得するには10分に1回の間隔ぐらいが良さそうです。ちなみに取得できるテレメトリは1ヶ月で8,000メッセージまでになっています。

8,000 メッセージ / 31 日(1ヶ月)≈ 258 メッセージ / 1日 = 258 メッセージ / 24 時間 = 10.75 メッセージ / 1時間 = 10.75 メッセージ / 60 分 ≈ 1 メッセージ / 6 分

になりますので、このあたりで好きな間隔を設定してください。今回は1メッセージ / 10 分で設定しました。

Injectノードの構成
Debugノードの構成
rpi-dht22ノードの構成
デプロイする

この時点ではノードやフローはエディタ上にしか存在しないので サーバにデプロイする必要があります。デプロイボタンをクリックするとサーバにデプロイされます。

デプロイボタンを押したあとはInjectノードの左端をクリックしてフローを実行します。

右側のデバッグコンソールに温湿度が表示されればセンサーは正常に温湿度を取得できています。画像ではpayloadに25.30とあり、これは気温が25.30℃という意味で、humidity: “39.70” となっているところは湿度が39.70%という意味です。(乾燥注意)

フローのデプロイ

以下のJSONコードを読み込むことでフローをインポートすることができます。Pin numberはご自身のものを入力してください。

[
    {
        "id": "2a182b74.7d87c4",
        "type": "tab",
        "label": "フロー 1",
        "disabled": false,
        "info": ""
    },
    {
        "id": "f0a97205.32302",
        "type": "rpi-dht22",
        "z": "2a182b74.7d87c4",
        "name": "",
        "topic": "rpi-dht22",
        "dht": "22",
        "pintype": "0",
        "pin": "4",
        "x": 380,
        "y": 240,
        "wires": [
            [
                "9cce35f3.4c31b8"
            ]
        ]
    },
    {
        "id": "2f9efdeb.2ff4f2",
        "type": "inject",
        "z": "2a182b74.7d87c4",
        "name": "",
        "topic": "",
        "payload": "{\"test\":\"test\"}",
        "payloadType": "json",
        "repeat": "60",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 200,
        "y": 240,
        "wires": [
            [
                "f0a97205.32302"
            ]
        ]
    },
    {
        "id": "9cce35f3.4c31b8",
        "type": "debug",
        "z": "2a182b74.7d87c4",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "x": 550,
        "y": 240,
        "wires": []
    }
]

AzureでのWebアプリ作成

DHT22センサーの稼働を確認できたました。今からはセンサーで取得したデータをAzureに送信し、そのデータをもとにリアルタイムで温湿度のグラフを描画するWebアプリケーションを作成していきます。

Azureの登録方法などは各自検索してください。また、今回作成するWebアプリはすべて無料の範囲でできるものになっています。

手順の大まかな流れは次の通りです。

  1. Azureでリソースグループの作成
  2. AzureでIoT Hubの追加
  3. Node-RED経由でテレメトリ(収集したデータ)を収集・送信するための設定を行う
  4. 公式ドキュメントを参考にWebアプリを作成する
  5. Node-RED経由でテレメトリを送信する
  6. ローカルのWebアプリに温湿度を表示する
  7. WebアプリをApp Serviceにデプロイする

AzureでIoT Hubリソースを作成する

まずはリソースグループを作成します。リソースグループは、デバイスやWebアプリをなどのリソースをまとめて管理するためのグループです。

Azure Portalにアクセスする

Azure Portalにアクセスしてください。https://portal.azure.com

Azure Portal
リソースの作成をクリック

Azureサービスの下にあるリソースの作成をクリックします。

リソースの作成
IoT Hubリソースを追加する

左側のカテゴリからモノのインターネット (IoT)を選択し、”IoT Hub”の下の作成をクリックします。

IoT Hubリソースの作成
リソースグループの詳細を設定する

サブスクリプションを選択し、任意のリソースグループの名前を入力してください(画像の場合はAgriTech)

インスタンスの詳細の設定

基本の設定が終わったら「次へ:ネットワーク」をクリックします。

ネットワークの選択

ネットワークタブの接続の構成でパブリックアクセスを選択します。

ネットワークの設定

「次へ:管理」をクリックします。

管理の設定

管理タブでスケーリングベルトユニット、ロールベースのアクセス制御 (RBAC)とスケーリングを設定します。設定は以下のように行ってください。

スケーリングとユニット→F1 Free レベルを選択

Defender for IoT→オフ

ロールベースのアクセス制御→共有アクセスポリシー・RBAC

IoTハブデータ共有作成者ロールに自分を割り当てる→チェックをつける

管理の設定 1/2
管理の設定 2/2

「次へ:タグ」をクリックします。

タグの設定

次はタグの設定です。今回はタグの設定をしませんので、そのままで「次へ:確認および作成」をクリックします。

タグの設定
確認と作成

確認および作成タブで設定が正しく行われているかを確認し、作成ボタンを押します。

確認と作成

デプロイの進行が始まると右上に通知がポップアップしますので、それをクリックします。もしくは、右上のベルマークアイコンをクリックします。

デプロイ進行中

デプロイが完了すると、「展開が完了しました」とポップアップが右上に表示されます。ポップアップの「リソースに移動」をクリックして、リソースに移動します。

デプロイ完了

IoT HubのTempAndHumidリソースに移動したらデバイス管理メニューの中からデバイスを選択します。

次のステップではIoT Hubに温湿度センサーを登録します。

デバイスの追加

デバイスの追加

左側のパネルのデバイス管理をクリックしたら、デバイスの追加をクリックします。

デバイスの追加
デバイスの作成

デバイスの作成では以下のように設定します。

デバイスIDを→DHT22

認証の種類→対称キー

自動生成キー→チェックする

このデバイスをIoTハブに接続する→有効化

デバイスの作成

一通り設定が終わったら保存ボタンをクリックします。

デバイスが正常に追加されるとデバイスの一覧に追加したDHT22が表示されます。

デバイス作成の確認

Node-REDでIoT Hubにテレメトリを送信する設定をおこなう

次はNode-REDからIoT Hubにテレメトリを送信するための設定をおこないます。IoT Hubにテレメトリを送信するにはnode-red-contrib-azure-iot-hubノードが必要です。

Azure IoT Hubノードを追加する

Node-REDを起動し、右上のハンバーガーメニューからパレットの管理をクリックします。左側のメニューからパレットを選択し、node-red-contrib-azure-iot-hubノード(以下IoT Hubノードと呼びます)を追加します。

node-red-contrib-azure-iot-hubの追加

ポップアップが出たら追加をクリックします。

ノードの追加
functionノードとIoT Hubノードをフローに追加する

左側のノード一覧からfunctionノードとIoT Hubノードをフローに追加して以下の画像のようにワイヤーで接続します。

フローの変更

functionノードの設定

functionノードをダブルクリックし次のコードのように設定します。デバイスIDは前のステップで設定したDHT22を、主キーはデバイスID (DHT22)をクリックした画面から確認することができます。

const data =
{
  "messageId":0,
  "deviceId":"デバイスID",
  "temperature":msg.payload,
  "humidity":msg.humidity
}
msg.payload = {
  "deviceId":"デバイスID",
  "key":"主キー",
  "protocol":"amqp",
  "data":data
};
return msg;
主キー
functionノードの設定

IoT Hubノードをダブルクリックして以下のように設定します。

Name → Azure IoT Hub

Protocol → amqp

Hostname → IoT Hub内の

IoT Hubノードの設定
ホスト名

以下のJSONコードを読み込むことでフローをインポートすることができます。主キーとHostnameはご自身のものを入力してください。

[
    {
        "id": "2a182b74.7d87c4",
        "type": "tab",
        "label": "フロー 1",
        "disabled": false,
        "info": ""
    },
    {
        "id": "f0a97205.32302",
        "type": "rpi-dht22",
        "z": "2a182b74.7d87c4",
        "name": "",
        "topic": "rpi-dht22",
        "dht": "22",
        "pintype": "0",
        "pin": "4",
        "x": 380,
        "y": 240,
        "wires": [
            [
                "9cce35f3.4c31b8",
                "57de7972cbabf99b"
            ]
        ]
    },
    {
        "id": "2f9efdeb.2ff4f2",
        "type": "inject",
        "z": "2a182b74.7d87c4",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "600",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"test\":\"test\"}",
        "payloadType": "json",
        "x": 200,
        "y": 240,
        "wires": [
            [
                "f0a97205.32302"
            ]
        ]
    },
    {
        "id": "9cce35f3.4c31b8",
        "type": "debug",
        "z": "2a182b74.7d87c4",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 570,
        "y": 100,
        "wires": []
    },
    {
        "id": "57de7972cbabf99b",
        "type": "function",
        "z": "2a182b74.7d87c4",
        "name": "",
        "func": "const data =\n{\n  \"messageId\":0,\n  \"deviceId\":\"DHT22\",\n  \"temperature\":msg.payload,\n  \"humidity\":msg.humidity\n}\nmsg.payload = {\n  \"deviceId\":\"DHT22\",\n  \"key\":\"主キー\",\n  \"protocol\":\"amqp\",\n  \"data\":data\n};\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 580,
        "y": 240,
        "wires": [
            [
                "79a4c51a60f8b8fc"
            ]
        ]
    },
    {
        "id": "79a4c51a60f8b8fc",
        "type": "azureiothub",
        "z": "2a182b74.7d87c4",
        "name": "Azure IoT Hub",
        "protocol": "amqp",
        "credentials": {},
        "x": 800,
        "y": 240,
        "wires": [
            []
        ]
    }
]
フローをデプロイする

デプロイボタンをクリックし、Injectノードの左側にあるボタンをクリックします。

デプロイとInject

設定が正しく行われていればIoT Hubでテレメトリの受信を確認することができます。また、Node-REDのデバッグパネルでも同様に温湿度を確認することができます。

テレメトリ受信の確認

Webアプリを作成して温湿度データを視覚化する

ここからのステップでは取得した温湿度データをリアルタイムでグラフ表示するWebアプリの作成方法の説明です。

基本的にはMicrosoftのチュートリアルに沿って説明していきますが、公式のチュートリアルは正直丁寧さにかけていてわかりづらかったり、間違っていたりと大変でしたのでそこらへんを丁寧に説明していきたいと思います。

HomebrewでAzure CLIをインストールする

ターミナルを開き、HomebrewでAzure CLIをインストールします。Homebrewをインストールしていない場合はインストールしてから実行してください。

Azure CLIのインストール
Azure CLIへのログイン

以下のコマンドを実行してAzure CLIにログインします。

az login
Azure CLIへのログイン

使用するアカウントを選択します。

アカウント選択

ログインに成功するとこのような画面が表示されます。

ログイン成功

ターミナルに戻ってもログインできたことが確認できます。

ログイン成功

IoT Hubへのコンシューマーグループの追加

以下のコマンドを実行してIoT Hubへコンシューマーグループを追加します。

az iot hub consumer-group create --hub-name YourIoTHubName --name YourConsumerGroupName

YourIoTHubNameをTempAndHumidに、YourConsumerGroupNameをAgriTechSensorsに設定します。IoTHubNameはIoT Hubリソースを作成したときの名前です。ConsumerGroupNameは任意のものを設定できます。今回はAgriTechSensorsと名付けました。

az iot hub consumer-group create --hub-name TempAndHumid --name AgriTechSensors
コンシューマーグループの追加
IoT Hubのサービス接続文字列を取得する

IoT Hubのサービス接続文字列を取得するには次のコマンドを実行します。

az iot hub connection-string show --hub-name YourIotHub --policy-name service

YourIotHubにはIoT Hub名のTempAndHumidを入力します。

az iot hub connection-string show --hub-name TempAndHumid --policy-name service
サービス接続文字列の取得

接続文字列は以下のようになります。

"HostName={YourIotHubName}.azure-devices.net;SharedAccessKeyName=service;SharedAccessKey={YourSharedAccessKey}"
GitHubからWebアプリのコードをクローンする

任意のディレクトリに移動して下記のコマンドでWebアプリのコードをクローンします。

git clone https://github.com/Azure-Samples/web-apps-node-iot-hub-data-visualization.git
cd web-apps-node-iot-hub-data-visualization

クローンが完了したらクローンしたディレクトリに移動してください。

Webアプリのコードをクローン

Webアプリの環境変数を設定する

ここがドキュメントどおりにコマンドを実行して困ったステップでした。公式のチュートリアルではsetコマンドを使って環境変数を設定していたのですが、何度設定してもうまく行かないためハードコードをしたりググったりと苦労しました。

結論としては公式のチュートリアルはWindows環境での方法で説明されておりmacOS (Linux Shell) ではexportコマンドで環境変数を設定する必要がありました。

環境変数を設定するには以下のコマンドを実行します。

export IotHubConnectionString=YourIoTHubConnectionString
export EventHubConsumerGroup=YourConsumerGroupName

YourIoTHubConnectionStringにはSTEP4で取得した接続文字列を入力します。

YourConsumerGroupNameにはSTEP3で設定した”AgriTechSensors”を入力します。

環境変数の設定
Webアプリの実行

以下のコマンドを実行してWebアプリを実行します。

npm install
npm start

ターミナルでアプリが起動していることを確認できたらhttp://localhost:3000 でアプリにアクセスします。正常にデータが取得できていれば温湿度データが設定時間の間隔でリアルタイムで表示されます。また、ターミナルにも取得されているデータの詳細が表示されます。

取得された温湿度データ

さて、これでローカルでWebアプリを起動し温湿度データを視覚化することができました。しかし、これではアプリを使用したいときに毎回起動しなくてはいけなくめんどくさいです。次のステップではこのWebアプリをApp Service上にホストし、インターネットからアクセスできるようにしていきます。

Webアプリをホストする

Azure App ServiceのWeb Appsは、Web アプリをホストするためのサービスとしてのプラットフォーム (PaaS) を提供しています。この記事では無料で使えるApp Serviceプランを使ってアプリをホストします。

App Serviceプランを作成する

Freeレベル(無料プラン)を使用してApp Serviceプランを作成するには次のコマンドを実行します。

az appservice plan create --name <app service plan name> --resource-group <your resource group name> --sku FREE

<app service plan name>にはApp Serviceの任意の名前をつけます。RealTimeTempAndHumidを入力します。

<your resource group name>にはリソースグループの名前を入力します。AgriTechを入力します。

App Serviceプランの作成
App ServiceでWebアプリをプロビジョニングする

次のコマンドを実行してWebアプリをプロビジョニングします。

az webapp create -n <your web app name> -g <your resource group name> -p <your app service plan name> --runtime "node|14-lts" --deployment-local-git

<your web app name>には任意のWebアプリの名前を入力します。Web アプリ名はグローバルに一意である必要があり、大文字と小文字の英字、数字、およびハイフンを使用できます。 使用している Node.js ランタイムのバージョンに応じて、--runtime パラメーターにノード バージョン 10.6 以降を指定してください。 

<your resource group name>にはリソースグループ名を入力します。AgriTechを入力します。

<your app service plan name>にはApp Service名を入力します。RealTimeTempAndHumidを入力します。

コマンド実行後色々と表示されます。

コマンド実行後
IoT Hub接続文字列とイベントHubコンシューマーグループを指定する環境変数のアプリケーション設定を追加

以下のコマンドを実行して環境変数の設定をおこないます。

az webapp config appsettings set -n <your web app name> -g <your resource group name> --settings EventHubConsumerGroup=<your consumer group> IotHubConnectionString="<your IoT hub connection string>"

<your web app name>にはWebアプリの名前を入力します。CheckTempAndHumidを入力します。

<your resource group name>にはリソースグループの名前を入力します。AgriTechを入力します。

Webソケットプロトコルを有効にし、WebアプリがHTTPSリクエストのみを受信するように設定する

以下のコマンドを実行してWebソケットプロトコルを有効化します。

az webapp config set -n <your web app name> -g <your resource group name> --web-sockets-enabled true

<your web app name>にはWebアプリの名前を入力します。CheckTempAndHumidを入力します。

<your resource group name>にはリソースグループの名前を入力します。AgriTechを入力します。

Webソケットプロトコルの設定

WebアプリがHTTPSリクエストのみを受信するようにするためには次のコマンドを実行します。

az webapp update -n <your web app name> -g <your resource group name> --https-only true

<your web app name>にはWebアプリの名前を入力します。CheckTempAndHumidを入力します。

<your resource group name>にはリソースグループの名前を入力します。AgriTechを入力します。

HTTPSリクエストの設定

ユーザーレベルのデプロイ資格情報を設定する

コードを App Serviceにデプロイするには、ユーザーレベルのデプロイ資格情報を使用します。以前に設定したことがない場合は以下のコマンドを実行して資格情報を設定してください。

az webapp deployment user set --user-name <your deployment user name>

<your deployment user name>には任意のユーザー名を入力します。コマンドを実行するとパスワードの入力も求められますのでパスワードは長さが8文字以上で、文字、数字、記号のうち2つを含む必要があります。

デプロイ資格情報の設定
コードをApp Serviceにプッシュするために使用するGit URLを取得する

Git URLを取得するには以下のコマンドを実行します。

az webapp deployment source config-local-git -n <your web app name> -g <your resource group name>

<your web app name>にはWebアプリ名を入力します。CheckTempAndHumidを入力します。

<your resource group name>にはリソースグループの名前を入力します。AgriTechを入力します。

Git URLの取得
App ServiceのWebアプリのGitリポジトリを参照するリモートをクローンに追加する

App ServiceのWebアプリのGitリポジトリを参照するリモートをクローンに追加するには以下のコマンドを実行します。

git remote add webapp <Git clone URL>

<Git clone URL>にはSTEP7で取得したURLを入力します。

リモートをクローンに追加
作業ディレクトリに注意

作業ディレクトリがクローンしたコードになっていることを確認してください。

App Serviceにコードをプッシュする

App Serviceにコードをプッシュするには以下のコマンドを実行します。公式のチュートリアルとは少し違いますので注意してください。(公式のチュートリアルではmasterではなくmainになっています)

git push webapp master:master
コードのプッシュ

パスワードの入力を求められたら、STEP5で作成したユーザーレベルのデプロイ資格情報を入力します。 必ず、App Serviceリモートのメインブランチにプッシュしてください。

コードのプッシュ
アプリ実行の確認

以下のコマンドを実行してアプリが正常にApp Serviceで実行されているかを確認します。

az webapp show -n <your web app name> -g <your resource group name> --query state

<your resource group name>にはリソースグループの名前を入力します。AgriTechを入力します。

アプリ実行の確認
Webアプリにアクセスする

ブラウザーで https://Webアプリの名前.azurewebsites.net にアクセスします。 Webアプリをローカルで実行したときに表示されたものと同様のWeb ページが表示されるはずです。DHT22センサーが実行中でデータを送信していれば、センサーによって送信された最新の50個の温度と湿度を示す測定値の実行中のプロットが表示されるはずです。

アプリ実行画面

まとめ

Azure IoT HubとNode-REDを使えば比較的簡単にセンサーからデータを取得し、それを視覚化することができました。自分がこの記事と同じ手順でアプリを構築したときは様々なエラーに遭遇しました。エラーに遭遇するたびにググってStack Overflowを見たり、公式チュートリアルのトラブルシューティングを見たりして解決していきました。

このWebアプリは使いやすいとはまだまだ言えないです。例えば、データの表示はアクセスしたときからのものしか表示されなかったり(データベースが必要?)、表示時間がUTC(多分)になっていて把握しづらかったり、メモリの線や縦軸横軸が上下に動くなどまだまだ実用性にはかけています。解決するためにはコードを改修していく必要があります。

ともかく、DHT22センサーをAzureを組み合わせてデータを取得するイメージは掴めたと思います。この記事がお役に立てれば幸いです。

参考ページ

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です