ステートの登録処理

Thing は、ステートを Thing Interaction Framework に登録します。ステートが登録されるのは、初期化の際に指定した時間間隔または、すべてのアクションを処理し終わった直後です。

Thing-IF SDK は、ステートの登録処理が必要になると、ステートハンドラーを呼び出します。ステートハンドラーは引数の KII_THING_IF_WRITER を使って、JSON 形式で表現されたステートの文字列を書き出します。ステートハンドラーが成功として返ると、Thing-IF SDK はステートを Thing Interaction Framework に送信します。

ステートの情報の取得

Hello Thing-IF でステートとして扱われる情報は、LED ライトの状態とモーションセンサーの値です。次のようなプログラムによって、それぞれ smartlightmotion に取得します。

static kii_bool_t state_handler(
        kii_t* kii,
        KII_THING_IF_WRITER writer)
{
  ......

  int motion;
  prv_smartlight_t smartlight;
  memset(&smartlight, 0x00, sizeof(smartlight));
  if (prv_get_smartlight_info(&smartlight) == KII_FALSE) {
    printf("Failed to lock/unlock mutex.\n");
    return KII_FALSE;
  }
  if (prv_get_motion_sensor(&motion) == KII_FALSE) {
    printf("Failed to lock/unlock mutex.\n");
    return KII_FALSE;
  }

  ......

  return KII_TRUE;
}

prv_get_motion_sensor は、アクションハンドラーの説明の際 ハンドラー間の値の共有 に示したとおりです。グローバル変数に保存されている prv_smartlight_t 構造体の値をミューテックスで同期して返すものです。

prg_get_motion_sensor() はグローバル変数 m_motion の値を取得すると同時に、値をインクリメントする関数です。

static pthread_mutex_t m_mutex;
static int m_motion = 0;

static kii_bool_t prv_get_motion_sensor(int *motion)
{
  if (pthread_mutex_lock(&m_mutex) != 0) {
    return KII_FALSE;
  }
  m_motion = (m_motion + 1) % 11;
  *motion = m_motion;
  if (pthread_mutex_unlock(&m_mutex) != 0) {
    return KII_FALSE;
  }
  return KII_TRUE;
}

なお、prv_get_motion_sensor()m_motion = m_motion + 1 は、MQTT 受信スレッドと、ステート定期更新スレッドの 2 つから同時に実行される可能性があります。Hello Thing-IF では、値が変化するだけでよいため、正しくカウントアップされなくても問題にはなりませんが、一般的には上記のようにミューテックスなどで同期処理を行うのが適切な処理方法です。

ステートの書き出し

ステートとして書き出す情報が準備できたら、KII_THING_IF_WRITER にステートの JSON 文字列を書き出します。

KII_THING_IF_WRITER の第 1 引数には、ステートハンドラーに渡された kii_t をそのまま指定します。第 2 引数には出力したい文字列を指定します。出力に成功した場合は KII_TRUE を返します。

Hello Thing-IF では、以下のような JSON を出力します。

{"power":true,"brightness":100,"motion":10}

出力する処理は以下のとおりです。

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

  ......

  if ((*writer)(kii, "{\"power\":") == KII_FALSE) {
    return KII_FALSE;
  }
  if ((*writer)(kii, smartlight.power == KII_JSON_TRUE
                  ? "true," : "false,") == KII_FALSE) {
    return KII_FALSE;
  }

  if ((*writer)(kii, "\"brightness\":") == KII_FALSE) {
    return KII_FALSE;
  }
  sprintf(buf, "%d,", smartlight.brightness);
  if ((*writer)(kii, buf) == KII_FALSE) {
    return KII_FALSE;
  }

  if ((*writer)(kii, "\"motion\":") == KII_FALSE) {
    return KII_FALSE;
  }
  sprintf(buf, "%d}", motion);
  if ((*writer)(kii, buf) == KII_FALSE) {
    return KII_FALSE;
  }

  printf("Sending the state\n");

  return KII_TRUE;
}

ここでは KII_THING_IF_WRITER の効果を説明するために少しずつ書き出していますが、実際のプログラムではバッファーに全体を書き出して、それを KII_THING_WRITER に渡すような実装すると、よりシンプルな実装にできます。


次は...

以上で Hello Thing-IF の実装の説明は完了です。次に、Thing の実装時に問題が発生した際のヒントのため、トラブルシューティングについて説明します。

トラブルシューティング に移動してください。

より詳しく学びたい方へ