前回の記事では、PLCnext Control から Azure IoT Hub へ MQTT でデータを送信する方法がいくつかあることを解説しました。
この記事では、Python と Azure 専用ライブラリ azure.iot.device モジュールを用いて PLCnext Control から Azure IoT Hub へ MQTT 通信を行うための詳細な実装手順を紹介します。
Azure IoT Hub の準備
まず、Azure の IoT Hub サービスを利用するための準備が必要です。
- Azure アカウントの作成とIoT Hub サービスの設定 (デバイス登録)
- Azure 管理ツール (通信のモニタリング用)
Azure アカウントの作成と IoT Hub サービスの設定 (デバイス登録)
Azure のアカウントをまだ持っていなければ、30日間 USD$200 分のクレジットを無料で利用可能な無料アカウントの作成をお勧めします。
Azure のアカウントが出来たら、IoT Hub にデバイスを登録する必要があります。
デバイス名は任意で構いません。
Azure アカウント作成からデバイス登録までの手順は、以下の記事をご参照ください。
[リンク] PLCnext コントローラ-クラウド間データ転送実験の準備:Azure IoT Hubの設定
管理ツール Azure CLI (通信のモニタリング用)
MQTT による送受信などが実際に成功しているかは、Azure の管理ツールである「Azure CLI」を使うと簡単に確認できるので、利用できるようにあらかじめ環境を準備しておきましょう。
Linux、macOS、または Windows コンピューターへローカルインストールするか、ブラウザから Azure Cloud Shell 経由で利用、もしくは Docker コンテナ版を利用することが出来ます。
以下の記事では Azure CLI を Windows コンピューターへローカルインストールする方法について紹介していますので、ご参照ください。
[リンク] クラウド受信データのモニタツール:Azure CLI
デバイス側の Python 環境の準備
クラウドに接続するので、PLCnext Control をインターネットへ接続できるようにします。
また、Azure 専用ライブラリである azure.iot.device モジュールを使用するので、pip コマンドでインストールします。
PLCnext Control をインターネットへ接続
以下の記事を参考に、PLCnext Control がインターネットへ接続できるようにしてください。
[リンク] AXC F 1152/2152/3152をインターネットへ接続する
root パスワードの準備
PLCnext Control では、後述の pip コマンドのインストール等に root ユーザ用のパスワードが必要になります。
(デフォルトでは root ユーザ用パスワードは設定されておらず、su コマンドが使用できません)
まだ root ユーザ用パスワードを設定していない場合は、以下の記事を参考に設定を行ってください。
pip コマンドの準備
PLCnext Control には Python3 がインストールされていますが、pip コマンドは入っていないので、以下のサイトの手順を参考に pip コマンドをインストールしてください。その際も、PLCnext Control がインターネットに接続されている必要があります。
azure.iot.device モジュールのインストール
Teraterm, Putty 等のターミナルソフトを用いて PLCnext Control に接続し、以下の様に pip コマンドで azure.iot.device モジュールをインストールしてください。
su
<root パスワードを入力>
pip install azure.iot.device
MQTT 送信プログラム
デバイスの接続文字列を Azure サイト上で取得
Azure へ MQTT でデータを送信するには、デバイスの接続文字列が必要になります。
接続文字列には接続先のURLやデバイスの情報などが含まれているので、Azure IoT Hub への MQTT 送信時に必要な接続情報はこの1行だけで済みます。
Azure のサイト上で以下の様に接続文字列を取得してください。
送信するデータの種類
以下のデータを JSON 形式で Azure へ送信することとします。
JSON キー名 | 説明 |
---|---|
DEVICE_NAME | データ送信元のデバイスが何なのかわかりやすいように定義した任意の文字列。 このサンプルでは「PHOENIX CONTACT PLCnext Control」としています。 |
COUNT | デバッグ用情報。データ送信が行われる毎に 1 を加算します。 |
TEMPERATURE | 気温:本来は温度センサで取得する値ですが、このサンプルでは単純化のため、10秒ごとに 1 ℃ずつ加算されていく値としています。 |
TEMP_WARN_H | 高温警報閾値※ |
TEMP_WARN_L | 低温警報閾値※ |
HUMIDITY | 湿度:本来は湿度センサで取得する値ですが、このサンプルでは単純化のため、10秒ごとに 5% ずつ加算されていく値としています。 |
HUM_WARN_H | 多湿警報閾値※ |
HUM_WARN_L | 乾燥警報閾値※ |
POWER | 消費電力:本来は電力計で取得する値ですが、このサンプルでは単純化のため、10秒ごとに 5W ずつ加算されていく値としています。 |
PWR_WARN_H | 高電力警報閾値※ |
PWR_WARN_L | 低電力警報閾値※ |
VOLTAGE | 電圧:本来は電力計で取得する値ですが、このサンプルでは単純化のため、常に 100.0 V の定数値としています。 |
CURRENT | 電流:本来は電力計で取得する値ですが、このサンプルでは単純化のため、POWER ÷ VOLTAGE の値としています。 |
※本来は GUI 等からユーザが設定すべき値ですが、このサンプルでは単純化のため、プログラム内で決め打ちにした定数値としています。
実際に送信される JSON 文字列は以下の様になります。
{ "DEVICE_NAME": "PHOENIX CONTACT PLCnext Control", "COUNT": 1, "TEMPERATURE": 1.00, "TEMP_WARN_H": 30.00, "TEMP_WARN_L": 15.00, "HUMIDITY": 5.00, "HUM_WARN_H": 60.00, "HUM_WARN_L": 20.00, "POWER": 80.00, "PWR_WARN_H": 50.00, "PWR_WARN_L": 15.00, "VOLTAGE": 100.00, "CURRENT": 0.80, "TIMESTAMP": "2024-07-31 18:32:52" }
Python のプログラムファイルを作成
以下のプログラムを「sample_to_send.py」というファイル名で作成してください。
IOT_HUB_CON_STR 変数の部分は、先ほど取得した実際のデバイスの接続文字列を入力してください。
ファイルをパソコン上で作成した場合は、WinSCP 等のファイル転送ソフトを用いて PLCnext Control の任意のディレクトリ※へ配置してください。(※推奨ディレクトリは後述します)
(※ターミナルソフトから SSH で PLCnext Control にログインして nano エディターなどで直接書いても構いません。)
from time import sleep
from datetime import datetime, timedelta, timezone
from azure.iot.device import IoTHubDeviceClient, Message
import random
import uuid
# ========= 定数値 =========
# 接続文字列
IOT_HUB_CON_STR = "****************************************************************************************************************"
# ペイロード用メッセージを作成
DEVICE_NAME = "PHOENIX CONTACT PLCnext Control"
TEMP_MIN = 0.0 # 気温最低値用定数
TEMP_MAX = 50.0 # 気温最高値用定数
HUM_MIN = 0.0 # 湿度最低値用定数
HUM_MAX = 100.0 # 湿度最高値用定数
POW_MIN = 80.0 # 電力最低値用定数
POW_MAX = 5.0 # 電力最高値用定数
# ========= 変数初期値設定 =========
count = 1
temperature = TEMP_MIN # 気温
humidity = HUM_MIN # 湿度
power = POW_MIN # 電力
voltage = 100.0 # 電圧 (一定)
current = 0.0 # 電流 (後で算出:power / voltage)
temp_warn_h = 30.0 # 高温警報閾値 (一定)
temp_warn_l = 15.0 # 低温警報閾値 (一定)
hum_warn_h = 60.0 # 多湿警報閾値 (一定)
hum_warn_l = 20.0 # 乾燥警報閾値 (一定)
pwr_warn_h = 50.0 # 高電力警報閾値 (一定)
pwr_warn_l = 15.0 # 低電力警報閾値 (一定)
# ========= メインループ =========
while True:
# ========= Azure IoT Hub Client準備 =========
client = IoTHubDeviceClient.create_from_connection_string(IOT_HUB_CON_STR)
try:
while(1):
# タイムスタンプ取得
timestamp_utc = datetime.now(timezone.utc) # 現在のUTCのタイムスタンプを取得
timestamp_jst = timestamp_utc + timedelta(hours=9) # 9時間を加算
readable_time_jst = timestamp_jst.strftime('%Y-%m-%d %H:%M:%S') # 人間が読みやすい形式に変換
# センサ計測値値生成 (本来はセンサからの出力値を取り込むべき部分)
temperature = temperature + 1.0
temperature = TEMP_MIN if temperature > TEMP_MAX else temperature
humidity = humidity + 5.0
humidity = HUM_MIN if humidity > HUM_MAX else humidity
power = power + 5.0
power = POW_MIN if power > POW_MAX else power
current = power / voltage
# json 文字列作成
# ---- 気温, 湿度, 電力, 電圧
json_temp = f'"TEMPERATURE": {temperature:.2f}, "TEMP_WARN_H": {temp_warn_h:.2f}, "TEMP_WARN_L": {temp_warn_l:.2f}'
json_hum = f'"HUMIDITY": {humidity:.2f}, "HUM_WARN_H": {hum_warn_h:.2f}, "HUM_WARN_L": {hum_warn_l:.2f}'
json_pwr = f'"POWER": {power:.2f}, "PWR_WARN_H": {pwr_warn_h:.2f}, "PWR_WARN_L": {pwr_warn_l:.2f}'
json_vol_cur = f'"VOLTAGE": {voltage:.2f}, "CURRENT": {current:.2f}'
# ---- 全て結合
json_final = f'{{ "DEVICE_NAME": "{DEVICE_NAME}", "COUNT": {count}, {json_temp}, {json_hum}, {json_pwr}, {json_vol_cur}, "TIMESTAMP": "{readable_time_jst}" }}'
# Azure のメッセージオブジェクト作成
message = Message(json_final)
# ---- json プロパティを設定
message.message_id = uuid.uuid4()
message.content_encoding = "utf-8"
message.content_type = "application/json"
# メッセージを送信
print(f"メッセージを送信中: {json_final}", flush = True)
client.send_message(message)
print("メッセージが送信されました", flush = True)
# カウントアップ
count = count + 1
# 待機
sleep(10)
except Exception as e:
print(f"送信中にエラーが発生しました: {e}", flush = True)
finally:
# クライアントの終了
client.shutdown()
print("client.shutdown()実行", flush = True)
プログラムファイルを PLCnext Control 上へ配置
パソコン上で作成したプログラムファイルを、WinsSCP 等の SCP/SFTP ソフトを使用して PLCnext Control 上のディレクトリに配置してください。
ファイル名 | PLCnext Control 上の配置パス (推奨) |
---|---|
sample_to_send.py | /opt/plcnext/ |
プログラムの実行
PLCnext Control へターミナルソフトから SSH ログインし、以下のコマンドを入力して Python のプログラムを実行してください。
python3 sample_to_send.py
成功すると、以下の様なメッセージが表示されます。
admin@axcf2152:~$ python3 sample_to_send.py
メッセージを送信中: { "DEVICE_NAME": "PHOENIX CONTACT PLCnext Control", "COUNT": 1, "TEMPERATURE": 1.00, "TEMP_WARN_H": 30.00, "TEMP_WARN_L": 15.00, "HUMIDITY": 5.00, "HUM_WARN_H": 60.00, "HUM_WARN_L": 20.00, "POWER": 80.00, "PWR_WARN_H": 50.00, "PWR_WARN_L": 15.00, "VOLTAGE": 100.00, "CURRENT": 0.80, "TIMESTAMP": "2024-07-31 18:32:52" }
メッセージが送信されました
メッセージを送信中: { "DEVICE_NAME": "PHOENIX CONTACT PLCnext Control", "COUNT": 2, "TEMPERATURE": 2.00, "TEMP_WARN_H": 30.00, "TEMP_WARN_L": 15.00, "HUMIDITY": 10.00, "HUM_WARN_H": 60.00, "HUM_WARN_L": 20.00, "POWER": 80.00, "PWR_WARN_H": 50.00, "PWR_WARN_L": 15.00, "VOLTAGE": 100.00, "CURRENT": 0.80, "TIMESTAMP": "2024-07-31 18:33:02" }
メッセージが送信されました
Azure CLI による通信確認
Windows パソコンにローカルインストールした Azure CLI で Azure IoT Hub に対する通信の内容を確認する手順を解説します。
Azure CLI をブラウザから Azure Cloud Shell 経由で利用したり Docker コンテナ版を利用する方法については、インターネット上の Azure の解説サイト等をご参照ください。
Azure へログイン
パソコンでコマンドプロンプトを開き、以下のコマンドで Azure にログインします。
az login
そうするとブラウザが立ち上がりアカウントの選択を求められるので、Azure へのログインに使用するアカウントを選択してください。
上記の画面になったらログインは完了です。ブラウザは閉じて構いません。
IoT Hub 上のイベントをモニタ
パソコンでコマンドプロンプトで以下のコマンドを実行すると、指定した IoT Hub 上の指定したデバイスで発生しているイベントをモニタすることが出来ます。
az iot hub monitor-events --hub-name <IoT Hub 名> --device-id <デバイス名>
上記の通り、Azure IoT Hub がデバイスから送信されたメッセージを受信していることがわかります。
デバイスから送信された JSON データは、”payload” の値に反映されています。
デバイスから Azure IoT Hub へデータ送信を送信する手順は以上で完了です。
Azure IoT Hub で受信したデータをクラウド上で利用するには、クラウド上のストレージやデータベース等にいったん格納する必要があります。
「データベース」というと一見ハードルが高そうに響きますが、当記事の例のような文字/数値データをクラウド上で扱う際には普通のストレージよりも操作が容易になります。