C Link SDK のデモファイル ./demos/subdev_basic_demo.c を使用して Link SDK API を呼び出し、ゲートウェイ経由でサブデバイスを IoT Platform に接続します。
背景情報
-
ゲートウェイとサブデバイスに関する詳細については、「概要」をご参照ください。
-
サブデバイスのゲートウェイは、IoT Platform との永続的な接続を維持する必要があります。 接続方法は、直接接続デバイスの場合と同じです。 詳細については、「MQTT 接続の概要」をご参照ください。
この例では、ゲートウェイデバイスの ID 認証情報は次のとおりです。
ProductKey
DeviceName
DeviceSecret
a18wP******
LightSwitchGW
uwMTmVAMnGGHaAkqmeDY6cHxxB******
ステップ 1:初期化
-
ヘッダーファイルを追加します。
…… …… #include "aiot_subdev_api.h" 基になる依存関係を追加し、ログ出力機能を設定します。
aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile); aiot_state_set_logcb(demo_state_logcb);-
aiot_subdev_init を呼び出して
subdevクライアントインスタンスを作成し、デフォルトパラメーターを初期化します。subdev_handle = aiot_subdev_init(); if (subdev_handle == NULL) { printf("aiot_subdev_init failed\n"); demo_mqtt_stop(&mqtt_handle); return -1; }
ステップ 2:機能の設定
aiot_subdev_setopt を呼び出して、次の機能を設定します。
-
MQTT 接続のハンドルを関連付けます。
重要ゲートウェイとサブデバイスの機能パラメーターを設定する前に、ゲートウェイの ID 認証情報を設定したことを確認してください。 詳細については、「MQTT の接続パラメーターの設定」をご参照ください。
-
サンプルコード:
aiot_subdev_setopt(subdev_handle, AIOT_SUBDEVOPT_MQTT_HANDLE, mqtt_handle); -
パラメーター:
設定項目
例
説明
AIOT_SUBDEVOPT_MQTT_HANDLE
mqtt_handle
ゲートウェイとサブデバイスの機能は MQTT 接続に依存します。 この設定項目を使用して、MQTT 接続ハンドルを関連付けます。
-
-
ゲートウェイとサブデバイス機能のメッセージコールバックを設定します。
-
メッセージコールバック関数を設定します。
-
サンプルコード:
aiot_subdev_setopt(subdev_handle, AIOT_SUBDEVOPT_RECV_HANDLER, demo_subdev_recv_handler); -
パラメーター:
設定項目
例
説明
AIOT_SUBDEVOPT_RECV_HANDLER
demo_subdev_recv_handler
デバイスが IoT Platform からゲートウェイまたはサブデバイスのメッセージを受信すると、このコールバック関数が呼び出されてメッセージを処理します。
-
-
メッセージコールバック関数を定義します。
メッセージの Alink データ形式については、「トポロジー関係の管理」および「サブデバイスのオンライン/オフライン状態」をご参照ください。
void demo_subdev_recv_handler(void *handle, const aiot_subdev_recv_t *packet, void *user_data) { switch (packet->type) { case AIOT_SUBDEVRECV_TOPO_ADD_REPLY: case AIOT_SUBDEVRECV_TOPO_DELETE_REPLY: case AIOT_SUBDEVRECV_TOPO_GET_REPLY: case AIOT_SUBDEVRECV_BATCH_LOGIN_REPLY: case AIOT_SUBDEVRECV_BATCH_LOGOUT_REPLY: case AIOT_SUBDEVRECV_SUB_REGISTER_REPLY: case AIOT_SUBDEVRECV_PRODUCT_REGISTER_REPLY: { printf("msgid : %d\n", packet->data.generic_reply.msg_id); printf("code : %d\n", packet->data.generic_reply.code); printf("product key : %s\n", packet->data.generic_reply.product_key); printf("device name : %s\n", packet->data.generic_reply.device_name); printf("message : %s\n", (packet->data.generic_reply.message == NULL)?("NULL"):(packet->data.generic_reply.message)); printf("data : %s\n", packet->data.generic_reply.data); } break; case AIOT_SUBDEVRECV_TOPO_CHANGE_NOTIFY: { printf("msgid : %d\n", packet->data.generic_notify.msg_id); printf("product key : %s\n", packet->data.generic_notify.product_key); printf("device name : %s\n", packet->data.generic_notify.device_name); printf("params : %s\n", packet->data.generic_notify.params); } break; default: { } } }
-
ステップ 3:トポロジー関係の追加
-
サブデバイスの認証情報を取得します。
サブデバイス用にプロダクトとデバイスを作成します。 プロダクトを作成する際、ノードタイプを[ゲートウェイサブデバイス]に設定します。 たとえば、サブデバイスプロダクトを作成し、4 つのサブデバイスを追加します。
製品名
ProductKey
DeviceName
DeviceSecret
ProductSecret
LightSwitchSD
a13FN******
LightSwitch_SubDev_01
768XBgQwgOakz3K4uhOiLeeh9x******
y7GSILD480******
LightSwitch_SubDev_02
iwTZrbjbgNVChfuJkihjE5asek******
LightSwitch_SubDev_03
fdutq35iKMYdcWWBuIINY26hsN******
LightSwitch_SubDev_04
HCKv50YqgwdKhy5cE0Vz4aydmK******
-
サブデバイスの認証情報用の
g_subdev変数を定義します。サンプルコードは、4 つのサブデバイスの認証情報をプリセットします。 本番環境では、サブデバイスの認証情報を取得するために独自のコードを記述してください。 例:
- ゲートウェイは、接続されたサブデバイスを発見した後、ゲートウェイとサブデバイスとの間で定義されたプロトコルに基づいて、サブデバイスの証明書を取得することができる。 プロトコルは、ゲートウェイのプロバイダおよびサブデバイスのプロバイダによって定義される。
- ゲートウェイのプロバイダは、ゲートウェイがサブデバイスに関する証明書情報をプリセットすることを可能にする構成方法を提供する。 この機能は、ゲートウェイのプロバイダによって実装される。
aiot_subdev_dev_t g_subdev[] = { { "a13FN******", "LightSwitch_SubDev_01", "768XBgQwgOakz3K4uhOiLeeh9x******", "y7GSILD480******" }, { "a13FN******", "LightSwitch_SubDev_02", "iwTZrbjbgNVChfuJkihjE5asek******", "y7GSILD480******" }, { "a13FN******", "LightSwitch_SubDev_03", "fdutq35iKMYdcWWBuIINY26hsN******", "y7GSILD480******" }, { "a13FN******", "LightSwitch_SubDev_04", "HCKv50YqgwdKhy5cE0Vz4aydmK******", "y7GSILD480******" } }; -
aiot_subdev_send_topo_add を呼び出して、サブデバイスとゲートウェイデバイス間のトポロジー関係を追加するリクエストを IoT Platform に送信します。
res = aiot_subdev_send_topo_add(subdev_handle, g_subdev, sizeof(g_subdev)/sizeof(aiot_subdev_dev_t)); if (res < STATE_SUCCESS) { printf("aiot_subdev_send_topo_add failed, res: -0x%04X\n", -res); aiot_subdev_deinit(&subdev_handle); demo_mqtt_stop(&mqtt_handle); return -1; } -
オプション: ゲートウェイデバイスがサブデバイスのエージェントとして IoT Platform からのメッセージを受信しなくなった場合は、aiot_subdev_send_topo_delete を呼び出して、サブデバイスとゲートウェイデバイス間のトポロジー関係を削除します。
aiot_subdev_send_topo_delete(subdev_handle, g_subdev, sizeof(g_subdev)/sizeof(aiot_subdev_dev_t)); if (res < STATE_SUCCESS) { printf("aiot_subdev_send_topo_delete failed, res: -0x%04X\n", -res); aiot_subdev_deinit(&subdev_handle); demo_mqtt_stop(&mqtt_handle); return -1; }
ステップ 4:サブデバイスのログイン
-
aiot_subdev_send_batch_login を呼び出してサブデバイスの一括ログインリクエストを IoT Platform に送信すると、サブデバイスは確立されたトポロジー関係を使用してログインし、ステータスが [オンライン] に変更されます。
aiot_subdev_send_batch_login(subdev_handle, g_subdev, sizeof(g_subdev)/sizeof(aiot_subdev_dev_t)); if (res < STATE_SUCCESS) { printf("aiot_subdev_send_batch_login failed, res: -0x%04X\n", -res); aiot_subdev_deinit(&subdev_handle); demo_mqtt_stop(&mqtt_handle); return -1; } -
オプション: サブデバイスをログアウトさせるには、aiot_subdev_send_batch_logout を呼び出してリクエストを IoT Platform に送信します。 IoT Platform がリクエストを受信すると、サブデバイスはオフラインになり、ステータスは [オフライン] に変わります。
重要この API が呼び出されると、IoT Platform はサブデバイスのステータスをオフラインに更新し、ゲートウェイがサブデバイス宛のメッセージを受信するのを防ぎます。
aiot_subdev_send_batch_logout(subdev_handle, g_subdev, sizeof(g_subdev)/sizeof(aiot_subdev_dev_t)); if (res < STATE_SUCCESS) { printf("aiot_subdev_send_batch_logout failed, res: -0x%04X\n", -res); aiot_subdev_deinit(&subdev_handle); demo_mqtt_stop(&mqtt_handle); return -1; }
サブデバイスがログインまたはログアウトした後、IoT Platform はサブデバイスのステータスに基づいてメッセージを処理します。
-
サブデバイスがオフラインの場合、IoT Platform からサブデバイスへの
QoS=0のメッセージはすぐに破棄されます。 -
サブデバイスがオンラインの場合、IoT Platform はサブデバイスのメッセージを対応するゲートウェイに送信し、ゲートウェイはそれらをサブデバイスに転送します。
ステップ 5:サブデバイスのトピックのサブスクライブ
サブデバイスがゲートウェイ経由で IoT Platform に接続した後、aiot_mqtt_sub を呼び出してサブデバイスのトピックをサブスクライブし、そこからメッセージを受信します。
トピックをサブスクライブするときは、サブデバイスとゲートウェイの ProductKey と DeviceName を区別してください。 正しいデバイストピックをサブスクライブしていることを確認してください。
-
サンプルコード:
{ char *sub_topic = "/a13FN******/LightSwitch_SubDev_01/user/get"; res = aiot_mqtt_sub(mqtt_handle, sub_topic, NULL, 1, NULL); if (res < 0) { printf("aiot_mqtt_sub failed, res: -0x%04X\n", -res); return -1; } } -
パラメーター:
パラメーター
例
説明
sub_topic
/a13FN******/LightSwitch_SubDev_01/user/get
サブスクライブ権限があるトピック。 このトピックでは:
-
a13FN******はサブデバイスの ProductKey です。 -
LightSwitch_SubDev_01はサブデバイスの DeviceName です。
この例では、サブデバイスが IoT Platform からメッセージを受信するためのデフォルトのカスタムトピックを使用します。
詳細については、「トピック」をご参照ください。
-
ステップ 6:サブデバイスからのメッセージのパブリッシュ
aiot_mqtt_pub を呼び出して、指定したサブデバイストピックにメッセージをパブリッシュします。
-
サンプルコード:
{ char *pub_topic = "/a13FN******/LightSwitch_SubDev_01/user/update"; char *pub_payload = "{\"id\":\"1\",\"version\":\"1.0\",\"params\":{\"LightSwitch\":0}}"; res = aiot_mqtt_pub(mqtt_handle, pub_topic, (uint8_t *)pub_payload, (uint32_t)strlen(pub_payload), 0); if (res < 0) { printf("aiot_mqtt_pub failed, res: -0x%04X\n", -res); return -1; } } -
パラメーター:
パラメーター
例
説明
pub_topic
/a13FN******/LightSwitch_SubDev_01/user/update
パブリッシュ権限があるトピック。 このトピックでは:
-
a13FN******はサブデバイスの ProductKey です。 -
LightSwitch_SubDev_01はサブデバイスの DeviceName です。
この例では、サブデバイスのデフォルトのカスタムトピックを使用します。 デバイスはこのトピックを使用して、IoT Platform にメッセージをパブリッシュします。
詳細については、「トピック」をご参照ください。
pub_payload
{\"id\":\"1\",\"version\":\"1.0\",\"params\":{\"LightSwitch\":0}}
デバイスがIoT Platformに送信するメッセージの内容。
この例では、カスタムトピックが使用されています。 カスタムメッセージ形式を指定できます。
詳細については、「データ形式」をご参照ください。
-
ステップ 7:ゲートウェイの切断
MQTT接続は、永続的に接続されたままのデバイスに適用されます。 IoT Platformからデバイスを手動で切断できます。
この例では、メインスレッドを使用してパラメータを設定し、接続を確立します。 接続が確立されたら、メインスレッドを一時停止できます。
aiot_mqtt_disconnect操作を呼び出して、デバイスをIoT Platformから切断します。
res = aiot_mqtt_disconnect(mqtt_handle);
if (res < STATE_SUCCESS) {
aiot_mqtt_deinit(&mqtt_handle);
printf("aiot_mqtt_disconnect failed: -0x % 04X\n", -res);
return -1;
}
ステップ 8:プログラムの終了
aiot_subdev_deinit を呼び出して subdev クライアントインスタンスを破棄し、関連リソースを解放します。
res = aiot_subdev_deinit(&subdev_handle);
if (res < STATE_SUCCESS) {
printf("aiot_subdev_deinit failed: -0x%04X\n", -res);
}
次のステップ
-
サンプルファイルを設定した後、コンパイルして実行可能ファイル ./output/subdev-basic-demo を生成します。
詳細については、「環境の準備」をご参照ください。
-
結果の詳細については、「操作ログ」をご参照ください。