ステートの登録処理
Thing は、ステートを Thing Interaction Framework に登録します。ステートが登録されるのは、初期化の際に指定した時間間隔または、すべてのアクションを処理し終わった直後です。
Thing-IF SDK は、ステートの登録処理が必要になると、ステートハンドラーを呼び出します。ステートハンドラーは引数の KII_THING_IF_WRITER
を使って、JSON 形式で表現されたステートの文字列を書き出します。ステートハンドラーが成功として返ると、Thing-IF SDK はステートを Thing Interaction Framework に送信します。
ステートの情報の取得
Hello Thing-IF でステートとして扱われる情報は、LED ライトの状態とモーションセンサーの値です。次のようなプログラムによって、それぞれ smartlight
と motion
に取得します。
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 の実装時に問題が発生した際のヒントのため、トラブルシューティングについて説明します。
トラブルシューティング に移動してください。
より詳しく学びたい方へ
- ステートの送信方法の詳細は ステートの更新 を参照してください。