Databricks にて Azure IoT Hub に対して Cloud-to-device messages を送受信する方法

## 概要

Databricks にて Azure IoT Hub に対して Cloud-to-device messages を送受信する方法を紹介します。本記事で詳細する方法は、検証目的で実行する方法です。

## 事前準備

### 環境構築

- Azure IoT Hub の構築 （本手順は Free tier で実施）
- Databricks （本手順は Serveless ではなく汎用コンピュートで実行）

### デバイスの作成と接続文字列の取得

Azure IoT Hub のリソース画面にて、`デバイス`タブを選択後、`+ デバイスの追加`を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/32708e89-0264-4b64-b5f2-494be974a7d4.png)

`デバイス ID`に任意の値を入力し、`保存`を選択してデバイスを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/37ac238e-cbd3-48d6-82f5-68cf9038354e.png)

作成したデバイスを表示して、`プライマリ接続文字列`の`コピー済み`を選択して値をコピーします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/4f8d5549-6a72-4ff4-9e10-0e23214201f6.png)

### 組み込みのエンドポイントの接続文字列を取得

Azure IoT Hub のリソース画面にて、`組み込みのエンドポイント`タブを選択して、`イベントハブ互換エンドポイント`の値をコピーします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/0d7b0ebb-998d-473d-8ee6-cbee3af3bbed.png)

### Azure IoT Hub の接続文字列を取得

Azure IoT Hub のリソース画面にて、`共有アクセス ポリシー`タブ -> `iothubowner`ポリシーを選択して、`プライマリ接続文字列`の値をコピーします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/ac063b7d-54f5-4dbd-a27a-92cde4a1a04a.png)

## Cloud-to-device messages を送信する方法

Databricks にて下記のコードを実行して、Cloud-to-device messages を送信します。

```python
%pip install azure-iot-device==2.9.0 -q
dbutils.library.restartPython()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/93cd3f59-1fab-4034-b411-15404add89eb.png)

```python
iot_conn_str = "HostName=iot-hub-test-001.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey=FUum/tiOgEuhye/JqAb+XXXXX="
device_id = "qiita_test_01"
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/7806cc00-63b8-43aa-bc63-5042683e0894.png)


```python
from azure.iot.hub import IoTHubRegistryManager
import uuid, json

payload = json.dumps({"command": "blink", "interval": 1})
rm = IoTHubRegistryManager.from_connection_string(iot_conn_str)
message = {"messageId": str(uuid.uuid4()), "priority": "high"}
rm.send_c2d_message(
    device_id,
    payload.encode(),
    properties=message,
)
print("送信完了")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/6c4f07a9-1c03-40ea-aac8-2b7b9f589541.png)


## Cloud-to-device messages を受信する方法

Databricks にて別のノートブックを作成して、下記のコードを実行して、Cloud-to-device messages を受信します。

```python
%pip install azure-iot-device -q
dbutils.library.restartPython()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/960a1f56-4112-415b-9e70-c73a8fa946ca.png)

```python
device_conn_str = "HostName=iot-hub-test-001.azure-devices.net;DeviceId=qiita_test_01;SharedAccessKey=r2fxXUdn/4w9iNJdhqnIJZ+h0qxxxxx="
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/b0202865-e234-405d-a884-2bcd86ce0746.png)


```python
import time, json
from azure.iot.device import IoTHubDeviceClient


client = IoTHubDeviceClient.create_from_connection_string(
    device_conn_str,
    websockets=True,
)

client.connect()

def handler(msg):
    print("受信:", msg.data.decode())
    print("Props:", msg.custom_properties)

client.on_message_received = handler

# 一定時間待機後に停止
time.sleep(60)
client.shutdown()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/ff1d77d9-5b44-4d48-930c-0c45b7cd155b.png)