Azure IoT Hubから送られたメッセージをIoTデバイスで受信する

はじめに

Azure IoT Hubにおいては、デバイス側からIoT Hub側にメッセージを送るという、デバイス→IoT Hubという方向のデータ送信がほとんどですが、稀にデバイス側でIoT Hub側からのメッセージを受信したい事があります。

今回は、Raspberry pi 3BへインストールしたIoT Hub ClientでIoT Hub側からのメッセージを受信する方法について、具体的な例を示した記事があまりないので、ここに記載します。

 

Raspberry Pi 3へIoT Clientの導入

 

まずはRaspberry Pi 3にIoT Hub clientを導入します。

Pythonでデバイスをハンドリングするので、pipを用いて以下のパッケージをインストールします。

pip install azure-iothub-device-client
pip install azure-iothub-service-client

 

IoT Hubへデバイスの登録

IoT Hubへメッセージを送りたいデバイスを登録します。
このあたりの詳細は、Microsoftの公式ページを参照してください。

 

IoT Hubからのメッセージを受けるプログラムの作成

 

IoT Hubからメッセージを受けられるようにプログラムを書きます。

基本的にはIoT Hubにメッセージを送る際と同様、iothub_clientをimportして、必要なdefを書いていくのですが、メッセージを受ける場合に必要となるのが、receive_message_callbackです。IoT Hubからのメッセージを受信すると、このコールバックが呼び出されるので、ここに必要な処理を書いていきます。

以下は、トイレIoT用に書いたプログラムからの抜粋です。
Azure IoT Hub側からのメッセージを受けて、Raspberry PiのGPIOをOn/Offさせるプログラムになっています。

 

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Program name: hc_connect.py
# Copyright by Inteligence Business Solutions Inc.
# Programed by Hideaki Maruno
# Ver 1.1 2017-09-13
# coding: UTF-8
import iothub_client

~略~

def receive_message_callback(message, counter):
    global receive_callbacks
    # connection IDとGPIO ポートの変換テーブル
    io_table =
{'1':'35','2':'36','3':'37','4':'38','5':'40','6':'37','7':'38','8':'40'}
    dt = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    buffer = message.get_bytearray()
    size = len(buffer)
    logfile = open('hc_connect.log','a')
    print >> logfile, ("    %s Received Message [%d]:" % (dt, counter))
    message_data = buffer[:size].decode('utf-8')
    print >> logfile, ("    %s Data: <<<%s>>> & Size=%d" % (dt, message_data, size))
    map_properties = message.properties()
    key_value_pair = map_properties.get_internals()
    if message_data == 'TimeUpdate':
    # 経過時間による通知
        try:
            hall_computer_name = key_value_pair["HallComputerName"]
            connection_id = key_value_pair["ConnectionID"]
            iothub_ack = key_value_pair["iothub-ack"]
            print >> logfile, (u"   %s hc_connect.py: %s" % (dt, message_data))
            print >> logfile, (u"   %s hc_connect.py: HallComputerName: %s") % (dt, hall_computer_name)
            print >> logfile, (u"   %s hc_connect.py: ConnectionID: %s") % (dt, connection_id)
            print >> logfile, (u"   %s hc_connect.py: iothub-ack: %s") % (dt,iothub_ack)
            print >> logfile, (u"   %s hc_connect.py: subprocess start" % (dt))
            proc = subprocess.Popen(['python','./gpio_switch.py',io_table[connection_id],'1'])
        except:
            print ("    %s hc_connect.py: Properties not correct. \"%s\"") % (dt, key_value_pair)
            print >> logfile, (u"   %s hc_connect.py: Properties not correct. \"%s\"") % (dt, key_value_pair)
    elif message_data == 'CountUpdate':
    # 利用回数による通知
        try:
            area_id = key_value_pair["AreaID"]
            hall_computer_name = key_value_pair["HallComputerName"]
            connection_id = key_value_pair["ConnectionID"]
            iothub_ack = key_value_pair["iothub-ack"]
            print >> logfile, (u"   %s hc_connect.py: %s" % (dt, message_data))
            print >> logfile, (u"   %s hc_connect.py: AreaID: %s") % (dt,area_id)
            print >> logfile, (u"   %s hc_connect.py: HallComputerName: %s") % (dt, hall_computer_name)
            print >> logfile, (u"   %s hc_connect.py: ConnectionID: %s") % (dt, connection_id)
            print >> logfile, (u"   %s hc_connect.py: iothub-ack: %s") % (dt, iothub_ack)
            print >> logfile, (u"   %s hc_connect.py: subprocess start" % (dt))
            proc = subprocess.Popen(['python','./gpio_switch.py',io_table[connection_id],'1'])
        except:
            print ("    %s hc_connect.py: Properties not correct. \"%s\"") % (dt, key_value_pair)
            print >> logfile, ("    %s hc_connect.py: Properties not correct. \"%s\"") % (dt, key_value_pair)
    else:
    # 未知の通知
        print ("    %s hc_connect.py: Message \"%s\" is not supported. \"%s\"") % (dt, message_data, key_value_pair)
        print >> logfile, ("    %s hc_connect.py: Message \"%s\" not supported. \"%s\"") % (dt, message_data, key_value_pair)
        print >> logfile, ("    %s hc_connect.py: Error" % (dt))
    counter += 1
    receive_callbacks += 1
    print >> logfile, ("    %s Total calls received: %d" % (dt,receive_callbacks))
    logfile.close()

    return IoTHubMessageDispositionResult.ACCEPTED

補足

  • デバイスへのメッセージ送信は、Freeプランでもサポートされているので簡単に実験できます。
  • このサンプルプログラムでは、実際のGPIOの操作は外部プログラムを呼んで行っています。この部分をほかのプログラムに差し替えれば、Raspberry Pi 上で動作するどんなプログラムでも実行できるので、様々応用できると思います
いいね (←参考になった場合はハートマークを押して評価お願いします)
読み込み中...

注意事項・免責事項

※技術情報につきましては投稿日時点の情報となります。投稿日以降に仕様等が変更されていることがありますのでご了承ください。

※公式な技術情報の紹介の他、当社による検証結果および経験に基づく独自の見解が含まれている場合がございます。

※これらの技術情報によって被ったいかなる損害についても、当社は一切責任を負わないものといたします。十分な確認・検証の上、ご活用お願いたします。

※当サイトはマイクロソフト社によるサポートページではございません。パーソルプロセス&テクノロジー株式会社が運営しているサイトのため、マイクロソフト社によるサポートを希望される方は適切な問い合わせ先にご確認ください。
 【重要】マイクロソフト社のサポートをお求めの方は、問い合わせ窓口をご確認ください