LoginSignup
5
5

More than 5 years have passed since last update.

ようやく始める Azure IoT Hub

Last updated at Posted at 2018-03-12

レファレンス

まずはいろんな記事を参考にしていきます。2018年3月11日現在、Azure IoT Hubで検索したところ、71件見つかりました。同じようにチュートリアルをやっていた(しかも1か月前に!)記事はしっかり確認しました。

ただ、Raspberry Piはなかったので、そこをどうしようかと・・。

チュートリアル開始!

ということで、シミュレートしたデバイスでチュートリアル開始。

準備

このチュートリアルではPythonを使いますが、なんとかVisual Studio内で実現できるよう、いろいろ準備をしました。というか、「Azure の開発」「Python 開発」をインストールしました。

Azureの開発、Python開発をインストール

Azure IoT Hubの作成

「無料試用版」サブスクリプションで、他のリソースは全て削除した状態で始めます。まずはリソースの作成から。

図2.png

次に、F1 - Free(デフォルトではS1が選択されている)に変更して、リソース名、リソースグループを設定、場所も西日本に変更して作成します。

図3.png

こちらが作成中の画面。

図4.png

で、こちらが作成完了した画面。

図5.png

その後、以下のように進み、接続文字列をコピーします。これは後々、ソースコード内で使用します。(ソースコードを作ってから・・)

プロジェクトの作成

空のPythonアプリケーションプロジェクトを作成し、azure-iothub-device-clientazure-iothub-service-clientを入れておきます。2018年3月11日時点では1.3.0が最新でした。

image.png

デバイスIDの作成

追加新しい項目から空の Python ファイルCreateDeviceIdentity.pyとして追加します。CONNECTION_STRINGは先ほどの接続文字列です。

で、実行して成功すると、次のような画面がでます。

image.png

CreateDeviceIdentity.py
import sys
import iothub_service_client
from iothub_service_client import IoTHubRegistryManager, IoTHubRegistryManagerAuthMethod
from iothub_service_client import IoTHubDeviceStatus, IoTHubError

### TODO:ここは変える!
CONNECTION_STRING = "<接続文字列>"
DEVICE_ID = "MyFirstPythonDevice"

def print_device_info(title, iothub_device):
    print ( title + ":" )
    print ( "iothubDevice.deviceId                    = {0}".format(iothub_device.deviceId) )
    print ( "iothubDevice.primaryKey                  = {0}".format(iothub_device.primaryKey) )
    print ( "iothubDevice.secondaryKey                = {0}".format(iothub_device.secondaryKey) )
    print ( "iothubDevice.connectionState             = {0}".format(iothub_device.connectionState) )
    print ( "iothubDevice.status                      = {0}".format(iothub_device.status) )
    print ( "iothubDevice.lastActivityTime            = {0}".format(iothub_device.lastActivityTime) )
    print ( "iothubDevice.cloudToDeviceMessageCount   = {0}".format(iothub_device.cloudToDeviceMessageCount) )
    print ( "iothubDevice.isManaged                   = {0}".format(iothub_device.isManaged) )
    print ( "iothubDevice.authMethod                  = {0}".format(iothub_device.authMethod) )
    print ( "" )

def iothub_createdevice():
    try:
        iothub_registry_manager = IoTHubRegistryManager(CONNECTION_STRING)
        auth_method = IoTHubRegistryManagerAuthMethod.SHARED_PRIVATE_KEY
        new_device = iothub_registry_manager.create_device(DEVICE_ID, "", "", auth_method)
        print_device_info("CreateDevice", new_device)

    except IoTHubError as iothub_error:
        print ( "Unexpected error {0}".format(iothub_error) )
        return
    except KeyboardInterrupt:
        print ( "iothub_createdevice stopped" )

if __name__ == '__main__':
    print ( "" )
    print ( "Python {0}".format(sys.version) )
    print ( "Creating device using the Azure IoT Hub Service SDK for Python" )
    print ( "" )
    print ( "    Connection string = {0}".format(CONNECTION_STRING) )
    print ( "    Device ID         = {0}".format(DEVICE_ID) )

    iothub_createdevice()

シミュレーション対象デバイス アプリの作成

Pythonコードの用意

[IoTHub Device Connection String]は、上記の例だとHostName=akr-hub.azure-devices.net;DeviceId=MyFirstPythonDevice;SharedAccessKey=84NkAiOeObqRmfHXyYmIRdRA9BF5ruQIoa5ifNcjZbY=みたいな感じになります。

SimulatedDevice.py

import random
import time
import sys
import iothub_client
from iothub_client import IoTHubClient, IoTHubClientError, IoTHubTransportProvider, IoTHubClientResult
from iothub_client import IoTHubMessage, IoTHubMessageDispositionResult, IoTHubError, DeviceMethodReturnValue

# ここ、変えるよ!
CONNECTION_STRING = "[IoTHub Device Connection String]"
# choose HTTP, AMQP or MQTT as transport protocol
PROTOCOL = IoTHubTransportProvider.MQTT
MESSAGE_TIMEOUT = 10000
AVG_WIND_SPEED = 10.0
SEND_CALLBACKS = 0
MSG_TXT = "{\"deviceId\": \"MyFirstPythonDevice\",\"windSpeed\": %.2f}"

def send_confirmation_callback(message, result, user_context):
    global SEND_CALLBACKS
    print ( "Confirmation[%d] received for message with result = %s" % (user_context, result) )
    map_properties = message.properties()
    print ( "    message_id: %s" % message.message_id )
    print ( "    correlation_id: %s" % message.correlation_id )
    key_value_pair = map_properties.get_internals()
    print ( "    Properties: %s" % key_value_pair )
    SEND_CALLBACKS += 1
    print ( "    Total calls confirmed: %d" % SEND_CALLBACKS )

def iothub_client_init():
    # prepare iothub client
    client = IoTHubClient(CONNECTION_STRING, PROTOCOL)
    # set the time until a message times out
    client.set_option("messageTimeout", MESSAGE_TIMEOUT)
    client.set_option("logtrace", 0)
    client.set_option("product_info", "HappyPath_Simulated-Python")
    return client

def iothub_client_telemetry_sample_run():

    try:
        client = iothub_client_init()
        print ( "IoT Hub device sending periodic messages, press Ctrl-C to exit" )
        message_counter = 0

        while True:
            msg_txt_formatted = MSG_TXT % (AVG_WIND_SPEED + (random.random() * 4 + 2))
            # messages can be encoded as string or bytearray
            if (message_counter & 1) == 1:
                message = IoTHubMessage(bytearray(msg_txt_formatted, 'utf8'))
            else:
                message = IoTHubMessage(msg_txt_formatted)
            # optional: assign ids
            message.message_id = "message_%d" % message_counter
            message.correlation_id = "correlation_%d" % message_counter
            # optional: assign properties
            prop_map = message.properties()
            prop_text = "PropMsg_%d" % message_counter
            prop_map.add("Property", prop_text)

            client.send_event_async(message, send_confirmation_callback, message_counter)
            print ( "IoTHubClient.send_event_async accepted message [%d] for transmission to IoT Hub." % message_counter )

            status = client.get_send_status()
            print ( "Send status: %s" % status )
            time.sleep(30)

            status = client.get_send_status()
            print ( "Send status: %s" % status )

            message_counter += 1

    except IoTHubError as iothub_error:
        print ( "Unexpected error %s from IoTHub" % iothub_error )
        return
    except KeyboardInterrupt:
        print ( "IoTHubClient sample stopped" )

if __name__ == '__main__':
    print ( "Simulating a device using the Azure IoT Hub Device SDK for Python" )
    print ( "    Protocol %s" % PROTOCOL )
    print ( "    Connection string=%s" % CONNECTION_STRING )

    iothub_client_telemetry_sample_run()

nodeプロジェクトの用意

iothub-explorerをnodeプロジェクトに入れて、プロジェクトから立ち上げようとしたけど失敗。

なんか色々もう・・。
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Web\External(ワークロードからNode.js開発をインストールするとデフォルトで入る)にPATH張って、コマンドプロンプトを管理者権限で立ち上げて、npm install -g iothub-explorerいれました。ごめんなさい。

総仕上げ

iothub-explorer monitor-events MyFirstPythonDevice --login "<接続文字列>"で受け口作ります。

Visual Studio側からSimulatedDevice.pyを起動します。

そしたら、なんかいい感じになります(たぶん)。

image.png

あと、ポータルからみても動いてて楽しい。

image.png

参考

ちなみに、Python用のバックグラウンドアプリケーション(IoT)を使ってみようと奮戦したのですが、うまくいきませんでした。

何をやってもno module namedだとか、ImportError: DLL load failed: %1 is not a valid Win32だとか色々怒られます・・。

たぶん、実行時のPythonが特殊なものを使っているので、ライブラリを正しく読めていないのか、多重で読んでしまっているのか・・。はたまたターゲットを正しく設定してあげないといけないのか・・。正直、うまくいきませんでした。残念。

終わりに

運用環境のコードでは、一時的な障害処理に関する MSDN の記事で推奨されているように、再試行ポリシー (指数関数的バックオフなど) を実装することをお勧めします。

とのことです。とりあえずは終わり。
リソースグループごと削除するのを忘れないようにしてください(忘れてもいいようにFreeにしたけども)。

以上。

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5