すべてのプロダクト
Search
ドキュメントセンター

IoT Platform:例:

最終更新日:Apr 09, 2025

デバイスジョブを実装し。/demos/task_posix_demo.cサンプルコードファイルを使用します。

背景情報

  • デバイスジョブの詳細については、「概要」をご参照ください。

  • 概要

ステップ1: クライアントの初期化

  1. ヘッダーファイルの追加

    ...
    ...
    
    # 「aiot_task_api.h」
    を含む
  2. 基になる依存関係を追加し、ログ出力機能を設定します。

    aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile);
        aiot_state_set_logcb(demo_state_logcb); 
  3. aiot_task_init() 操作を呼び出して、タスクを作成します

    task_handle = aiot_task_init();
        if (task_handle == NULL) {
            demo_mqtt_stop(&mqtt_handle);
            printf("aiot_task_init failed\n");
            return -1;
        }

ステップ2: 機能の設定

aiot_task_setopt() 操作を呼び出して、次の項目を設定します。

  1. MQTT接続ハンドルに関連付けます。

    重要

    デバイスジョブ固有のパラメーターを設定する前に、デバイス認証情報が指定されていることを確認してください。 詳細については、「」をご参照ください。

    • aiot_task_setopt(task_handle、AIOT_TASKOPT_MQTT_HANDLE、mqtt_handle);
    • パラメーター

      説明

      AIOT_TASKOPT_MQTT_HANDLE

      mqtt_handle

      MQTT接続を確立する必要があります。 このパラメータは、MQTT接続ハンドルに関連付けるために使用されます。

  2. メッセージコールバックの設定

    • aiot_task_setopt(task_handle、AIOT_TASKOPT_RECV_HANDLER、demo_task_recv_handler);
    • パラメーター

      説明

      AIOT_TASKOPT_RECV_HANDLER

      demo_task_recv_handler

      デバイスジョブ固有のメッセージが受信されると、この関数が呼び出される。

ステップ3: ダウンストリームジョブ通知の受信

デバイスがオンラインのときにIoT Platformがジョブ通知を送信する場合、次の手順を実行して通知を処理します。

  1. IoT Platformコンソールにログインし、デバイスジョブを作成します。

  2. デバイスジョブを作成すると、IoT Platformはデバイスに通知を送信します。 デバイスが通知を受信すると、demo_task_recv_handlerコールバックが呼び出されます。

    コールバックの処理ロジックを指定する場合は、次の項目に注意してください。

    • aiot_task_recv_tはコールバックの入力パラメーターです。 このパラメーターは、データ形式を示します。

    • AIOT_TASKRECV_NOTIFYはメッセージタイプを示します。

    • 次の表に、通知例と通知のAlinkデータ形式を示します。

      Alinkデータ形式

      説明

      {
          "task": {
              "taskId": "i5Ks6 *** pF010101" 、
              "status": "SENT" 、
              "jobDocument": {
      
              },
              "jobFile": {
                  "signMethod": "Md5" 、
                  "sign": "wssxff56dhdsd ***" 、
                  "fileUrl": "https:// iotx-*** .aliyuncs.com/***.zip"
              }
          }
      }
      {
        "id": "7542940" 、
        "version": "1.0"、
          "params": {
              "task": {
                  "taskId": "i5Ks6 *** pF010101" 、
                  "status": "SENT" 、
                  "jobDocument": {
                    },
            "jobFile":{
               "signMethod":"Md5" 、
               "sign":"wssxff56dhdsd ***" 、
               "fileUrl": "https:// iotx-*** .aliyuncs.com/***.zip"
            }
              }
          }
      }

      メッセージの内容はJSON形式です。 コンテンツは、Alinkデータのparamsパラメーターの値です。

    • デバイスはジョブの下にタスクを実装し、タスクのステータスをIoT Platformに送信します。 タスクを更新する方法の詳細については、「手順5: ジョブのタスクのステータスを更新する」をご参照ください。

    • この例では、タスクを実装するロジックは提供されていません。 ビジネスニーズに基づいて処理ロジックを指定する必要があります。

      void demo_task_recv_handler(void * handle, const aiot_task_recv_t * packet, void * userdata)
      {
          switch (packet->type) {
              ケースAIOT_TASKRECV_NOTIFY: {
                  const task_desc_t * in_desc = &(packet->data.notify);
      
                  printf("revice task notify, task_id:[% s],status:[% d],job_document[% s],document_file_url:[% s],\
                  sign_method:[% s],sign[% s]\r\n ",
                         in_desc->task_id、in_desc->status、in_desc->job_document、
                         in_desc->document_file_url、in_desc->sign_method、in_desc->sign);
      
                  /* 1. ハンドルにジョブレコードが存在しない場合、IoT Platformによって送信されたジョブをハンドルのdefault_task_descフィールドに保存します。 */
                  if (NULL == g_local_task_desc) {
                      demo_copy_task_to_local_task(&g_local_task_desc、in_desc);
                      /* ジョブを開始します。 この例では、ジョブ情報が印刷される。 ビジネスニーズに基づいてロジックを指定できます。 */
                      int res = pthread_create(&g_task_thread, NULL, demo_task_thread, g_local_task_desc);
                      if (res != 0) {
                          printf("pthread_create demo_task_thread failed: % d\r\n", res);
                      } else {
                          /* デタッチするダウンロードスレッドのタイプを設定します。 ファームウェアが取得されると、ダウンロードスレッドは自動的に終了します。 */
                          pthread_detach(g_task_thread);
                      }
                      /* ジョブのステータスを変更します。TODO: 次のコードは参照用です。 ジョブが完了したら、ステータスをAIOT_TASK_STATUS_SUCCEEDEDに設定する必要があります。 */
                      g_local_task_desc->status = AIOT_TASK_STATUS_IN_PROGRESS;
                      aiot_task_update (ハンドル、g_local_task_desc);
                      demo_free_local_task(&g_local_task_desc);
                      break;
                  }
      
                  /* 2. IoT Platformによってジョブステータスが最終ステータスに設定されている場合、ローカルジョブはクリアされます。 */
                  if (in_desc->status == AIOT_TASK_STATUS_CANCELLED | | in_desc->status ==AIOT_TASK_STATUS_REMOED
                      | | in_desc->status == AIOT_TASK_STATUS_TIMED_OUT) {
                      /* TODO: ローカルジョブをクリアし、スレッドを停止します。 */
                      /* ジョブがハンドルに記録されているデフォルトのジョブの場合は、ジョブのメモリをクリアします。 それ以外の場合は、ジョブのメモリを維持する必要があります。 */
                      if (NULL != g_local_task_desc&0 == strcmp(in_desc->task_id, g_local_task_desc->task_id)) {
                          /* ローカルジョブのメモリを解放します。 */
                          demo_free_local_task(&g_local_task_desc);
                      }
                      break;
                  }
      
                  /* 3.ローカルジョブがすでに存在する場合、IoT Platformはジョブの説明を更新します。 更新された説明を確認する必要があります。 */
                  if (in_desc->status == AIOT_TASK_STATUS_IN_PROGRESS) {
                      if (NULL != g_local_task_desc&0 == strcmp(in_desc->task_id, g_local_task_desc->task_id)) {
                          /* TODO: ローカルジョブの説明を更新します。 ビジネスニーズに基づいて、現在のジョブを一時停止できます。 * /
                          break;
                      }
                  }
      
                  /* 4. その他の場合は、受信したジョブを新規ジョブと判定する。 ジョブが実行中で、新しいジョブを受信した場合は、main() 関数でリストを作成できます。 */
                  /* リストをuserdataパラメータとして渡し、このリストのすべてのジョブをメンテナンス用に記録します。 */
                  break;
              }
      ……
      ... 
      }

ステップ4: デバイスジョブを要求する

デバイスがオンラインになったら、デバイスジョブをリクエストできます。

  1. aiot_task_get_task_detail操作を呼び出して、IoT Platformにリクエストを送信します。 パラメーターをNULLに設定すると、パラメーターに関する情報を取得できます。 第一 実装されていないジョブ。

    説明

    IoT Platformが複数のデバイスジョブをデバイスにプッシュする場合、ジョブ通知を受信する前にaiot_task_get_task_list操作を呼び出してデバイスジョブを照会できます。 次に、各デバイスジョブに関する情報を照会できます。

    res = aiot_task_get_task_detail(task_handle、NULL);
        if (res < STATE_SUCCESS) {
            aiot_task_deinit(&task_handle);
            demo_mqtt_stop(&mqtt_handle);
            return -1;
        }
                            
  2. IoT Platformがリクエストを受信すると、IoT Platformは作成したデバイスジョブ情報をデバイスに返します。

  3. デバイスがジョブ通知を受信すると、demo_task_recv_handlerコールバックが呼び出されます。

    コールバックの処理ロジックを指定する場合は、次の項目に注意してください。

    • aiot_task_recv_tはコールバックの入力パラメーターです。 このパラメーターは、データ形式を示します。

    • AIOT_TASKRECV_GET_DETAIL_REPLYはメッセージタイプを示します。

    • 次の表に、通知例と通知のAlinkデータ形式を示します。

      Alinkデータ形式

      説明

      {
                "taskId": "i5Ks *** F010101" 、
                "status": "IN_PROGRESS" 、
                "jobDocument": {
             },
               "jobFile":{
                    "signMethod":"Md5" 、
                    "sign":"wssxff56dhdsd ***" 、
                    "fileUrl": "https:// iotx-*** .aliyuncs.com/***.zip"
            }
      }
      {
        "id": "1234" 、
        "code": 200,
        "data": {
          "taskId": "$next" 、
          "task":{
                "taskId": "i5Ks *** F010101" 、
                "status": "IN_PROGRESS" 、
                "jobDocument": {
             },
               "jobFile":{
                    "signMethod":"Md5" 、
                    "sign":"wssxff56dhdsd ***" 、
                    "fileUrl": "https:// iotx-*** .aliyuncs.com/***.zip"
            }
           }
          }
      }

      メッセージの内容はJSON形式です。 コンテンツは、Alinkデータのparamsパラメーターの値です。

    • デバイスはジョブの下にタスクを実装し、タスクのステータスをIoT Platformに送信します。 タスクを更新する方法の詳細については、「手順5: ジョブのタスクのステータスを更新する」をご参照ください。

    • この例では、タスクを実装するロジックは提供されていません。 ビジネスニーズに基づいて処理ロジックを指定する必要があります。

      void demo_task_recv_handler(void * handle, const aiot_task_recv_t * packet, void * userdata)
      {
          switch (packet->type) {
      ...
      ... 
              case AIOT_TASKRECV_GET_DETAIL_REPLY: {
                  const task_get_detail_reply_t * in_reply = &(packet->data.get_detail_reply);
                  printf("revice task get detail, code:[% d]\r\n", in_reply->code);
                  if (200 == in_reply->code) {
                      printf("revice task get detail reply, task_id:[% s],status:[% d]\r\n",
                             in_reply->task.task_id, in_reply->task.status);
                      if (in_reply->task.status != AIOT_TASK_STATUS_NOT_FOUND) {
                          printf("job_document[% s],document_file_url:[% s], sign_method:[% s], sign[% s]\r\n",
                                 in_reply->task.job_document, in_reply->task.doc ument_file_url,
                                 in_reply->task.sign_method, in_reply->task.sign);
                          task_desc_tタスク;
                          memset(&task, 0, sizeof(task));
                          memcpy(&task, &(in_reply->task), sizeof(task));
                          /* TODO: スレッドを起動してジョブを実装します。 */
      
                          /* ジョブのステータスを変更します。 TODO: 次のコードは参考用です。 ビジネスニーズに基づいてロジックを指定できます。 タスクが完了したら、ステータスをAIOT_TASK_STATUS_SUCCEEDEDに設定します。 */
                          task.status = AIOT_TASK_STATUS_IN_PROGRESS;
                          task.progress = 88;
                          aiot_task_update (ハンドル、タスク);
                      }
                  }
                  break;
              }
      ……
      ... 
      }

ステップ5: ジョブ配下のタスクのステータスを更新する

デバイスがジョブ情報を取得し、ジョブの下にタスクを実装した後、デバイスはタスクステータスをIoT Platformに送信する必要があります。

  1. aiot_task_update操作を呼び出して、タスクステータスをIoT Platformに送信します。

    タスクのステータスを送信するときは、次の項目に注意してください。

    • task_desc_tはデータ形式を示します。

    • aiot_task_updateはAPI操作を示します。

    • Alink形式のメッセージの例を次に示します。

      説明

      メッセージの内容はJSON形式です。 コンテンツは、Alinkデータのparamsパラメーターの値です。

      {
          "id": "123",
          &quot;version&quot;: &quot;1.0&quot;、
          "params": {
              "taskId": "i5Ks *** F010101" 、
              "status": "IN_PROGRESS" 、
              "statusDetails": {
                  "キー": "値"
              },
              "progress": 50
          }
      }

      メッセージの内容はJSON形式です。 コンテンツは、Alinkデータのparamsパラメーターの値です。メッセージの内容はJSON形式です。 内容は、Alinkデータのparamsパラメーターの値です。注メッセージの内容はJSON形式です。 コンテンツは、Alinkデータのparamsパラメーターの値です。 メッセージの内容はJSON形式です。 コンテンツは、Alinkデータのparamsパラメーターの値です。

    • この例では、AIOT_TASK_STATUS_IN_PROGRESSステータスが送信されています。 実際のビジネスシナリオでタスクのステータスを取得し、ステータスを送信する必要があります。

      • ステップ3のサンプルコード

        g_local_task_desc->status = AIOT_TASK_STATUS_IN_PROGRESS;
                        aiot_task_update (ハンドル、g_local_task_desc);
                        demo_free_local_task(&g_local_task_desc); 
      • ステップ4のサンプルコード

        task.status = AIOT_TASK_STATUS_IN_PROGRESS;
                            task.progress = 88;
                            aiot_task_update (ハンドル、タスク); 
  2. タスクステータスが送信されると、IoT Platformは応答メッセージを返します。 この場合、demo_task_recv_handlerコールバックが呼び出されます。

    コールバックの処理ロジックを指定する場合は、次の項目に注意してください。

    • aiot_task_recv_tはコールバックの入力パラメーターです。 このパラメーターは、データ形式を示します。

    • AIOT_TASKRECV_UPDATE_REPLYはメッセージタイプを示します。

    • この例では、タスクを実装するロジックは提供されていません。 ビジネスニーズに基づいて処理ロジックを指定する必要があります。

      void demo_task_recv_handler(void * handle, const aiot_task_recv_t * packet, void * userdata)
      {
          switch (packet->type) {
      ...
      ... 
              case AIOT_TASKRECV_UPDATE_REPLY: {
                  const task_update_reply_t * update_reply = &(packet->data.update_reply);
                  printf("revice task update reply, code:[% d]\r\n", update_reply->code);
      
                  if (200 == update_reply->code) {
                      printf("revice task update reply, task_id:[% s]\r\n", update_reply->task_id);
                  }
      
                  if (71012 == update_reply->code) {
                      printf("aiot_task_updateタスクのstatus_details値はjson format\r\n" でなければなりません);
                  }
                  /* TODO * /
                  break;
              }
      ……
      ... 
      }

ステップ6: プログラムを終了する

aiot_task_deinit() 操作を呼び出して、タスクを破棄します。

res = aiot_task_deinit(&task_handle);
    if (res < STATE_SUCCESS) {
        demo_mqtt_stop(&mqtt_handle);
        printf("aiot_task_deinit failed: -0x % 04X\n" 、-res);
        return -1;
    }

ステップ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;
    }

次のステップ

  • この例では、。/output/task_posix_demo実行ファイルが生成されます。

    詳細については、「環境の準備」をご参照ください。

  • [ログの表示]します。