「Python」でRaspberry PiをAlibaba Cloud IoTプラットフォームに接続する


この記事では、MVPのLiu Hongfeng氏が、Alibaba Cloud IoT Platformを使ってRaspberry Piデバイスをクラウドに接続した体験談を紹介しています。

本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。

下記アリババクラウドMVPのHongfeng Liu氏が執筆しました。

私はAlibaba Cloud MVPとして、Alibaba Cloud IoT Platformをユーザー目線でテストした最初の一人という光栄に浴しています。私はAlibaba Cloud IoT Platformを熟知しており、当初からFeifeng Platform(ワンストップ開発プラットフォームであるLink Developの前身)のハードウェアアクセス作業にいくつか参加させていただく機会を得ました。また、アリババクラウドのIoTチームが数十人から数百人へと急速に拡大していく様子も目の当たりにしました。そのIoTプラットフォームでホストされているコンテンツも同様に急速に拡大し、IoT開発キットの基本版「飛燕」、ワンストップ開発プラットフォーム「Link Develop」、IoT開発キットの上級版「飛燕」、「飛翔」、「City Brain」、「Agricultural Brain」、「Industrial Interconnection Platform」などがありました。そのため、Alibaba Cloudの各IoT製品に追いつき、完全に理解することが課題となっています。

最初はMCUのシングルチップ+.NET MFプラットフォームを使用し、Alibaba Cloud Platformを接続するための関連コードをMQTTプロトコルを直接使用して実装しました。IoTプラットフォームも構成に応じて柔軟に接続することができますが、WEB、AI、クラウド開発者の中にはまだ慣れていない人もいます。こうした要件があるため、JSやJava、Pythonなどの先進言語がハードウェア開発に参入し、MCUチップ上で直接実行できるようになったことで、クラウドとIoTデバイスの接続が大幅に高速化されました。

本記事では、先進言語であるPythonを使って、Raspberry PiをベースにクラウドとIoTデバイスを接続してみました。前回の記事では、Node.jsを使って実行する方法を紹介しました。

以下はAlibaba Cloudチームが納品したテストハードウェアです。

1、Wi-FiとBluetoothを搭載したRaspberry Pi 3B
2、DHT11温湿度モジュール
3、LEDモジュール

ステップ1: Raspberry Pi用のOSをインストールする

Raspberry Pi用のオペレーティングシステムをインストールする必要があります。

Raspbian ファームウェアをインストールしていますが、ここで提供されている手順に従ってインストールすることができます:https://www.yuque.com/cloud-dev/iot-tech/ig269q

ステップ2: Python SDKのインストール

アリババクラウドプラットフォーム用のPython SDKをインストールする

以下のコマンドを実行します。

pip install aliyun-python-sdk-iot-client

ステップ3: コードを書く

Raspbian ファームウェアと Python SDK をインストールした後、プロジェクトを実行するためのコードを Python で書く必要があります。サンプルコードはAlibaba Cloud Platformのドキュメント(https://www.yuque.com/cloud-dev/iot-tech/rz6fpl )に既に提供されていますが、機能は比較的シンプルで、2つの乱数をクラウドに送信するだけです。

センサーデータをクラウドに送信し、クラウドからコマンドを送信して関連機器を制御できるように、まず双方向通信を実現するという比較的複雑なシナリオを設計しています。

データのアップロードには、温度と湿度の値を取得できる実物のセンサーDHT11を選択しています。また、クラウドから送られてくるコマンドでライトの点灯・消灯状態を制御するLEDモジュールも用意されています。

Raspberry Piのピン定義図は以下の通り。

DHT11 モジュールは、シングルバス通信に属する 3 本のラインで構成されています。電源ラインは 5V-4pin、グランドラインは GND-6pin、通信ピンは GPIO16-36pin に接続しています。LEDモジュールも3本のラインで構成されています。電源ラインを 3V3-1pin、グランドラインを GND-9pin、制御ラインを GPIO4-7pin に接続しています。

ピンのハイレベルとローレベルを制御するだけで、比較的簡単にLED制御を実現することができます。

led_pin = 4 //GPIO is 4
 GPIO.setmode(GPIO.BCM) //GPIO definition of BCM 
 GPIO.setup(led_pin, GPIO.OUT) //Set to output mode

ライトをつける:

GPIO.output(led_pin, GPIO.HIGH)
Turn off the light:
GPIO.output(led_pin, GPIO.LOW)

DHT11は比較的複雑です。詳しくは、2010年に書いたブログ記事を参照してください(関連リンク:https://blog.csdn.net/yfiot/article/details/5996524)

コード量が多いので、温度(T)と湿度(H)の2つの値を同時に返す関数としてパッケージ化しています。

インターネット上のPythonを使った例の多くは、温度と湿度を1回読み込んでいます。連続して読み取る場合は、時間間隔を3秒程度にしなければならず、そうしないと簡単に失敗してしまいます。Linux はリアルタイムではないので、時間間隔を 3 秒にしても正しく温湿度の値を取得できないことがあり、検証をパスした誤った値を取得してしまうことがあることがわかりました。

DHT11のデータピンはGPIO16に接続されているので、以下のようにピンコードを定義しています。

dht_pin =16
The code that encapsulates the function is as follows:
def GetDTH(): 
 data = []
 j = 0 
 GPIO.setup(dht_pin, GPIO.OUT)
 GPIO.output(dht_pin, GPIO.LOW)
 time.sleep(0.02)
 GPIO.output(dht_pin, GPIO.HIGH)
 GPIO.setup(dht_pin, GPIO.IN)

 while GPIO.input(dht_pin) == GPIO.LOW:
  continue
 while GPIO.input(dht_pin) == GPIO.HIGH:
  continue

 while j < 40:
  k = 0
  while GPIO.input(dht_pin) == GPIO.LOW:
  continue
  while GPIO.input(dht_pin) == GPIO.HIGH:
  k += 1
  if k > 100:
  break
  if k < 8:
  data.append(0)
  else:
  data.append(1)  
  j += 1

 humidity_bit = data[0:8]
 humidity_point_bit = data[8:16]
 temperature_bit = data[16:24]
 temperature_point_bit = data[24:32]
 check_bit = data[32:40]

 humidity = 0
 humidity_point = 0
 temperature = 0
 temperature_point = 0
 check = 0

 for i in range(8):
  humidity += humidity_bit[i] * 2 ** (7-i)
  humidity_point += humidity_point_bit[i] * 2 ** (7-i)
  temperature += temperature_bit[i] * 2 ** (7-i)
  temperature_point += temperature_point_bit[i] * 2 ** (7-i)
  check += check_bit[i] * 2 ** (7-i)

 tmp = humidity + humidity_point + temperature + temperature_point
 if check == tmp:
  return temperature,humidity
 else:
  print "wrong"
  return 0,0 

これらの準備が完了したら、関連する製品やデバイスをクラウド上で定義していくことになります。アリババクラウドが提供している公式サンプルとは異なり、読み書きが可能な属性LEDを追加し、0が消灯、1が点灯を示す列挙変数を使用しています。

これらの準備が完了したら、関連する製品やデバイスをクラウド上で定義していくことになります。アリババクラウドが提供している公式サンプルとは異なり、読み書きが可能な属性LEDを追加し、0が消灯、1が点灯を示す列挙変数を使用しています。

client.on_message = on_message

つまり、クラウドからプッシュされた情報を得ることができるということです。

クラウドがプッシュする情報内容は以下の通りです。

{"method":"thing.service.property.set","id":"169885527","params":{"LED":1},"version":"1.0.0"}

LEDの値を取得する必要があるので、on_message関数に何かを追加する必要があります。

 setjson = json.loads(msg.payload)
 led = setjson['params']['LED']
 GPIO.output(led_pin,(GPIO.HIGH if led==1 else GPIO.LOW ))

LEDの値を元に点灯・消灯を行います。

関連するコードを修正したら、次の図のようにRaspberry Piデバイスにアップロードして実行を開始します。

この時、クラウド機器の状態を確認すると、正常にクラウドにデータがアップロードされていることがわかります。

クラウド製品のオンラインデバッグパネルでデータ配布テストを実施しています。

0や1を送ると、LEDが消灯しているか点灯しているかがわかります。

一般的に、IoTのコードはおなじみのPython言語を使って簡単に書けることがわかります。

アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ