ステートの更新

Thing の状態を表すステートを Thing Interaction Framework にアップロードできます。アップロードが実行されるタイミングには、コマンドの実行完了時と、一定間隔での自動実行の 2 つがあります。ステートはスキーマ(Android, iOS)で定義した形式に基づいて JSON 形式で生成します。これらの機能概要は こちら をご覧ください。

Thing-IF SDK の 初期化 では、ステートを返すコールバック関数(ステートハンドラー)のポインタを 2 件登録します。この関数には、ステートを JSON 文字列の形で組み立てる処理を記述します。初期化処理のサンプルコードでは 2 件とも同じ関数を登録していますが、別の関数を割り当てることもできます。

  • コマンドの実行完了時に対するステートハンドラー

    SDK は MQTT のコマンド受信タスクでコマンドを受信した際、アクションをすべて処理した後でステートハンドラーを呼び出します。コマンド中にアクションが複数個含まれる場合、コマンドの受信ごとに 1 回だけ呼び出します。

  • 一定間隔での自動実行に対するステートハンドラー

    SDK は、内部でステート更新用のタスク(スレッド)を生成し、そのタスクからステートハンドラーを一定間隔で呼び出します。呼び出し間隔は初期化の際に関数ポインタと同時に指定します。

いずれの場合も、ステートの更新のタイミングは、SDK 側が制御しているため、Thing 側のプログラムから自発的に更新することはできません。

コールバック関数内の処理によっては、排他処理の実装が必要になる場合があります。タスクの詳細は こちら をご覧ください。

ステートハンドラー

ステートハンドラーのコールバック関数のプロトタイプは以下のとおりです。

typedef kii_bool_t
  (*KII_THING_IF_STATE_HANDLER)
    (kii_t* kii,
     KII_THING_IF_WRITER writer);

このプロトタイプに基づいて以下のようなステートハンドラーを記述します。SDK の初期化 では、command_handler_resource 構造体の state_handler メンバー、および、state_updater_resource 構造体の state_handler メンバーとしてこのコールバック関数のポインタを渡します。

kii_bool_t state_handler(
        kii_t* kii,
        KII_THING_IF_WRITER writer)
{
  char buf[256];

  /* If the writer failed to write the first key in the JSON string */
  if ((*writer)(kii, "{\"power\":") == KII_FALSE) {
    return KII_FALSE;
  }

  /* If the power is on */
  if (get_power() != 0) {
    /* If the writer failed to write the first value in the JSON string */
    if ((*writer)(kii, "true,") == KII_FALSE) {
      return KII_FALSE;
    }
  } else {
    /* If the writer failed to write the first value in the JSON string */
    if ((*writer)(kii, "false,") == KII_FALSE) {
      return KII_FALSE;
    }
  }

  /* Send the remaining part of the JSON string to the buffer. */
  sprintf(buf,
      "\"presetTemperature\":%d,\"fanSpeed\":%d,\"currentTemperature\":%d,\"currentHumidity\":%d}",
      get_presetTemperature(),
      get_fanspeed(),
      get_currentTemperature(),
      get_currentHumidity());

  /* If the writer failed to write the remaining part of the JSON string */
  if ((*writer)(kii, buf) == KII_FALSE) {
    return KII_FALSE;
  }

  return KII_TRUE;
}

この例では、以下のような JSON 文字列を作成しています。この JSON 文字列は、スキーマ定義でのモバイルアプリ側のステート取得用クラス(Android, iOS)と対応しています。

{"power":true,"presetTemperature":25,"fanspeed":5,"currentTemperature":28,"currentHumidity":65}

コールバック関数の各パラメータの意味は以下のとおりです。

  • kii:ステートの実装に使用する SDK 内部の構造体ポインタです。初期化の際、kii_thing_if_t として初期化した構造体の一部で、下記の writer を使用するために必要です。
  • writer:結果の JSON を出力する際に使用する関数へのポインタです。SDK が提供する文字列出力用 API です。詳細は下記 KII_THING_IF_WRITER をご覧ください。

コールバック関数の実行(ステートの取得)が成功した場合は KII_TRUE を、それ以外の場合は KII_FALSE を戻り値として返します。KII_FALSE を返した場合、ステートの更新(Thing Interaction Framework へのステートのアップロード)は行われません。

KII_THING_IF_WRITER

ステートの更新を行うコールバック関数では、引数に KII_THING_IF_WRITER が渡されます。これは、文字列を書き込むための API です。ステートハンドラーでは、書き込んだ文字列がステートの JSON 文字列として Thing Interaction Framework にアップロードされます。

KII_THING_IF_WRITER のプロトタイプは以下のとおりです。

typedef kii_bool_t (*KII_THING_IF_WRITER)(kii_t* kii, const char* buff);
  • kii:ステートハンドラーに渡された kii をそのまま指定します。ステートの書き込み先を識別するため、KII_THING_IF_WRITER 内部で使用されます。

  • buff:出力したい文字列へのポインタです。

書き込みに成功したときは、戻り値として KII_TRUE を、それ以外は KII_FALSE を返します。

書き込み先のバッファ容量が不足した場合には KII_FALSE を返します。ここでの書き込み先は、SDK の初期化の際に kii_thing_if_state_updater_resource_t 構造体の buffer メンバーで指定したバッファです。

使用例は上記のステートハンドラーの実装例をご覧ください。