ステートの登録と取得
Thing の状態を表す値をステートとして Thing Interaction Framework に登録し、アプリから参照することができます。これにより、Thing の持つセンサー値や設定値をアプリから様々な形で利用できます。
ステートの概要については ステートの登録と取得 をご参照ください。
REST API では以下の操作が行えます。
ステートの登録
Thing のステートをアップロードする例を以下に挙げます。
curl -v -X PUT \
-H "Authorization: Bearer {ACCESS_TOKEN}" \
-H "X-Kii-AppID: {APP_ID}" \
-H "X-Kii-AppKey: {APP_KEY}" \
-H "Content-Type: application/json" \
"https://api-jp.kii.com/thing-if/apps/{APP_ID}/targets/thing:{THING_ID}/states" \
-d '{
"power":true,
"presetTemperature":25,
"fanspeed":5,
"currentTemperature":28,
"currentHumidity":65
}'
Thing または Thing オーナーのアクセストークンを指定してください。また {THING_ID}
を対象となる Thing の thingID に差し替えてください。上記の例のように、ステートは JSON 形式で表現します。
ステートとして登録可能なデータの最大サイズは、キーと値のペアを JSON 形式で表現した状態で 10 KB までです。
ステートとして入れ子(ネスト)構造になっている JSON データを使うこともできます。この場合、以下の制限が適用されます。
- ステート履歴集計時に フィールド条件 として指定できるのは、ステートのトップレベルのフィールドのみです。
- トリガー実行条件の ステート条件 として指定できるのは、ステートのトップレベルのフィールドのみです。
ステートの登録が成功すると 201 または 204 応答が返されます(初回アップロードの場合は 201、それ以降は 204 が返されます)。
Thing 側でタイムスタンプを付与
登録されたステートにはタイムスタンプが付与されます。タイムスタンプは、基本的には Thing Interaction Framework 側で自動的に付与されますが、Thing 側で明示的にタイムスタンプを付与することもできます。
Thing 側でタイムスタンプを付与する例を以下にあげます。この例のように、"_created" フィールドにタイムスタンプ(UNIX 時間、ミリ秒、UTC)を設定してから、ステートを登録してください。
curl -v -X PUT \
-H "Authorization: Bearer {ACCESS_TOKEN}" \
-H "X-Kii-AppID: {APP_ID}" \
-H "X-Kii-AppKey: {APP_KEY}" \
-H "Content-Type: application/json" \
"https://api-jp.kii.com/thing-if/apps/{APP_ID}/targets/thing:{THING_ID}/states" \
-d '{
"power":true,
"presetTemperature":25,
"fanspeed":5,
"currentTemperature":28,
"currentHumidity":65,
"_created": 1469158821211
}'
なお、Thing 側で設定するタイムスタンプと実際にステート登録が行われた実時間との差には制限があります。詳しくは ステート履歴の管理 をご覧ください。
最新ステートの取得
Thing の最新ステートを参照する例を以下に挙げます。
curl -v -X GET \
-H "Authorization: Bearer {ACCESS_TOKEN}" \
-H "X-Kii-AppID: {APP_ID}" \
-H "X-Kii-AppKey: {APP_KEY}" \
-H "Content-Type: application/json" \
"https://api-jp.kii.com/thing-if/apps/{APP_ID}/targets/thing:{THING_ID}/states"
Thing または Thing オーナーのアクセストークンを指定してください。また {THING_ID}
を対象となる Thing の thingID に差し替えてください。
最新ステートは以下のように 200 応答として返されます。
HTTP/1.1 200 OK
Content-Type: application/json
{
"power":true,
"presetTemperature":25,
"fanspeed":5,
"currentTemperature":28,
"currentHumidity":65
}
「最新」ステートとは最後に登録されたステートのことを指します。特に Thing 側でタイムスタンプを設定する場合、設定したタイムスタンプを元に最新ステートが決定されるわけではない点に注意してください。
ステート履歴の検索および取得
Thing のステート履歴は、Object の取得 と同様に、取得したいステート履歴を検索条件で絞り込んで取得します。
指定可能な検索条件は以下のとおりです。
- 取得するステートの時間範囲(必須)
- 取得するステート履歴のフィールド条件(任意)
検索結果を取得する際には、結果をグループ別にするかしないかが選択できます。グループ別にする場合は、さらにステート履歴自体を取得するか集計値を取得するかが選択可能です。詳しくは 検索結果の取得方法 をご覧ください。
これらの条件を組み合わせて実際にステート履歴を検索・閲覧する具体例は ステート履歴検索例 をご覧ください。
ステート履歴の検索や取得を行うためには、Thing を 初期登録 する際にステート履歴のグループ化の間隔を設定する必要があります。
取得するステートの時間範囲
取得対象とするステート履歴の時間範囲を withinTimeRange 条件で指定します。時間範囲の指定は必須です。
{
"type": "withinTimeRange",
"lowerLimit": 1467000000000,
"upperLimit": 1467003000000
}
lowerLimit と upperLimit に、取得対象とするステート履歴の下限と上限をそれぞれ指定します。指定はタイムスタンプ(UNIX 時間、ミリ秒、UTC)で行います。
なお、実際のステート履歴取得はグループ単位で実行されます。例えば以下の図において時間範囲を A に指定した場合、グループ #1 内のすべてのステート履歴が取得対象となります。同様に時間範囲を B に指定した場合、グループ #1 と #2 内の全てのステート履歴が取得対象となります。
なお上限・下限として指定したタイムスタンプがグループ境界ちょうどの値の場合は、このグループも取得対象となります。
取得対象が 60 グループ以上になる時間範囲は指定できません。指定するとエラーになります。
ステート履歴のタイムスタンプやグループ化の概要は こちら をご参照ください。
取得するステート履歴のフィールド条件
取得するステート履歴を絞り込むフィールド条件が指定できます。フィールド条件の指定は任意です。
絞り込みには Object 検索 と同じ検索条件が利用可能です。ただし GeoBoxClause と GeoDistance 条件は利用できません。
なお、ステートが入れ子(ネスト)構造の JSON データの場合は、トップレベルのフィールドのみが条件として指定可能です。
フィールド条件は、次のように時間範囲と andClause で結合してください。
{
"type": "and",
"clauses": [
{
"type": "range",
"field": "currentTemperature",
"lowerLimit": 32
},
{
"type": "withinTimeRange",
"lowerLimit": 1467000000000,
"upperLimit": 1467003000000
}
]
}
検索結果の取得方法
ステートの履歴は検索結果として返されます。
検索結果の取得形式は、以下より選択できます。
グループごとに取得 | 集計 | ステート履歴の取得方法 |
---|---|---|
しない | しない | 検索条件に合致するステート履歴を取得します。履歴はデフォルトではタイムスタンプで昇順ソートされた形となります。 |
する | しない | 検索条件に合致するステート履歴を、グループごとにまとめた形で取得します。履歴はタイムスタンプで昇順ソートされます。 |
する | する | 検索条件に合致するステート履歴について、グループごとに集計した結果を取得します。 |
グループごとに履歴を取得しない場合
ステート履歴をグループごとに取得しない場合は、Object 検索 と同様に orderBy や descending による履歴の取得順番指定ができます。orderBy の指定がない場合は、タイムスタンプ昇順でステート履歴は返されます。
また、bestEffortLimit や paginationKey を使った ページネーション も利用できます。
グループごとに履歴を取得する場合
ステート履歴をグループごとに取得する場合は、検索時に以下を指定します。
{"grouped": true}
グループごとに取得する場合、ステート履歴の取得順番は常にタイムスタンプ昇順となります。orderBy や descending による取得順番の指定はできません。またページネーションも利用できません。
グループごとに履歴を集計した結果を取得する場合
グループごとにステート履歴を集計した結果を取得する場合は、前記の "grouped": true
の指定に加えて集計ルールを指定します。
集計ルールは、次の例のように aggregations 内に指定します。
{
"aggregations": [
{
"field": "temperature",
"fieldType": "DECIMAL",
"type": "MAX",
"putAggregationInto": "max"
}
]
}
集計ルールは検索ごとに 1 つのみ指定可能です(今後複数指定できるようになる予定です)。
以下の情報を指定します。
- field: 集計対象とするステートのフィールド。
- fieldType: 集計対象フィールドのデータ型。STRING, INTEGER, DECIMAL, BOOLEAN のいずれかが利用可能です。
type: 使用する集計関数。以下のいずれか利用可能です。
- COUNT: 集計対象フィールドの値が null ではないステート履歴の件数。
- SUM: 集計対象フィールドの合計値。
- MAX: 集計対象フィールドの最大値。
- MIN: 集計対象フィールドの最小値。
- MEAN: 集計対象フィールドの平均値。
putAggregationInto: 集計結果につける名前。一例として先ほどの集計ルールの場合、集計値である "temperature" フィールドの最大値は次のように返されます。
{ "aggregations" : [ { "value": 35, "name": "max" } ] }
ステート履歴検索例
ここでは実際にステート履歴を取得する例をいくつかあげます。
時間範囲指定のみ
最初に、取得するステートの時間範囲のみを指定したシンプルな例をあげます。これは機能ガイドの 例 1 の実行例です。
curl -v -X POST \
-H "Authorization: Bearer {ACCESS_TOKEN}" \
-H "X-Kii-AppID: {APP_ID}" \
-H "X-Kii-AppKey: {APP_KEY}" \
-H "Content-Type: application/json" \
"https://api-jp.kii.com/thing-if/apps/{APP_ID}/targets/thing:{THING_ID}/states/query" \
-d '{
"query": {
"clause": {
"type": "withinTimeRange",
"lowerLimit": 1467000000000,
"upperLimit": 1467003000000
},
"grouped": true
}
}'
上記のリクエストでは "grouped": true
により検索結果のグループ化を指定しているため、ステート履歴は次のように返されます。
HTTP/1.1 200 OK
Content-Type: application/json
{
"queryDescription" : "WHERE withinTimeRange(1467000000000, 1467003000000)",
"groupedResults" : [ {
"range" : {
"from" : 1467000000000,
"to" : 1467000900000
},
"objects" : [ {
"currentTemperature" : 32,
"fanspeed" : 5,
"_created" : 1467000010000,
"currentHumidity" : 72,
"presetTemperature" : 25,
"power" : true
}, {
"currentTemperature" : 31,
"fanspeed" : 5,
"_created" : 1467000374001,
"currentHumidity" : 70,
"presetTemperature" : 25,
"power" : true
}, {
"currentTemperature" : 29,
"fanspeed" : 5,
"_created" : 1467000384970,
"currentHumidity" : 72,
"presetTemperature" : 25,
"power" : true
}, {
"currentTemperature" : 32,
"fanspeed" : 5,
"_created" : 1467000460422,
"currentHumidity" : 72,
"presetTemperature" : 25,
"power" : true
} ]
}, {
"range" : {
"from" : 1467000900000,
"to" : 1467001800000
},
"objects" : [ {
"currentTemperature" : 31,
"fanspeed" : 5,
"_created" : 1467001000000,
"currentHumidity" : 72,
"presetTemperature" : 25,
"power" : true
}, {
"currentTemperature" : 31,
"fanspeed" : 5,
"_created" : 1467001221211,
"currentHumidity" : 72,
"presetTemperature" : 25,
"power" : true
} ]
}, {
"range" : {
"from" : 1467001800000,
"to" : 1467002700000
},
"objects" : [ ]
}, {
"range" : {
"from" : 1467002700000,
"to" : 1467003600000
},
"objects" : [ {
"currentTemperature" : 31,
"fanspeed" : 5,
"_created" : 1467003321211,
"currentHumidity" : 72,
"presetTemperature" : 25,
"power" : true
} ]
} ]
}
リクエスト時に "grouped": true
で検索結果のグループ化を指定しなかった場合は、次のようにタイムスタンプ順に昇順ソートされた形でステート履歴が返されます。これは機能ガイドの 例 2 の実行例です。
HTTP/1.1 200 OK
Content-Type: application/json
{
"queryDescription" : "WHERE withinTimeRange(1467000000000, 1467003000000)",
"results" : [ {
"currentTemperature" : 32,
"fanspeed" : 5,
"_created" : 1467000010000,
"currentHumidity" : 72,
"presetTemperature" : 25,
"power" : true
}, {
"currentTemperature" : 31,
"fanspeed" : 5,
"_created" : 1467000374001,
"currentHumidity" : 70,
"presetTemperature" : 25,
"power" : true
}, {
"currentTemperature" : 29,
"fanspeed" : 5,
"_created" : 1467000384970,
"currentHumidity" : 72,
"presetTemperature" : 25,
"power" : true
}, {
"currentTemperature" : 32,
"fanspeed" : 5,
"_created" : 1467000460422,
"currentHumidity" : 72,
"presetTemperature" : 25,
"power" : true
}, {
"currentTemperature" : 31,
"fanspeed" : 5,
"_created" : 1467001000000,
"currentHumidity" : 72,
"presetTemperature" : 25,
"power" : true
}, {
"currentTemperature" : 31,
"fanspeed" : 5,
"_created" : 1467001221211,
"currentHumidity" : 72,
"presetTemperature" : 25,
"power" : true
}, {
"currentTemperature" : 31,
"fanspeed" : 5,
"_created" : 1467003321211,
"currentHumidity" : 72,
"presetTemperature" : 25,
"power" : true
} ]
}
時間範囲指定+フィールド条件(集計なし)
次に、時間範囲指定に加えてフィールド条件を指定する例をあげます。これは機能ガイドの 例 3 の実行例です。
curl -v -X POST \
-H "Authorization: Bearer {ACCESS_TOKEN}" \
-H "X-Kii-AppID: {APP_ID}" \
-H "X-Kii-AppKey: {APP_KEY}" \
-H "Content-Type: application/json" \
"https://api-jp.kii.com/thing-if/apps/{APP_ID}/targets/thing:{THING_ID}/states/query" \
-d '{
"query": {
"clause": {
"type": "and",
"clauses": [
{
"type": "range",
"field": "currentTemperature",
"lowerLimit": 32
},
{
"type": "withinTimeRange",
"lowerLimit": 1467000000000,
"upperLimit": 1467003000000
}
]
},
"grouped": true
}
}'
最初の例と同じ時間範囲条件に加え、今回は「"currentTemperature" フィールドの値が 32 以上」というフィールド条件を追加しています。検索結果のグループ化も指定しているため、次のようにステート履歴が返されます。
HTTP/1.1 200 OK
Content-Type: application/json
{
"queryDescription" : "WHERE ( ( 32 <= currentTemperature ) AND withinTimeRange(1467000000000, 1467003000000) )",
"groupedResults" : [ {
"range" : {
"from" : 1467000000000,
"to" : 1467000900000
},
"objects" : [ {
"currentTemperature" : 32,
"fanspeed" : 5,
"_created" : 1467000010000,
"currentHumidity" : 72,
"presetTemperature" : 25,
"power" : true
}, {
"currentTemperature" : 32,
"fanspeed" : 5,
"_created" : 1467000460422,
"currentHumidity" : 72,
"presetTemperature" : 25,
"power" : true
} ]
}, {
"range" : {
"from" : 1467000900000,
"to" : 1467001800000
},
"objects" : [ ]
}, {
"range" : {
"from" : 1467001800000,
"to" : 1467002700000
},
"objects" : [ ]
}, {
"range" : {
"from" : 1467002700000,
"to" : 1467003600000
},
"objects" : [ ]
} ]
}
時間範囲指定+フィールド条件(集計あり)
最後に、グループごとの集計を行う例を紹介します。
次の例では、先ほどと同じ検索を、今度は集計関数として COUNT を指定して実施しています。これにより "currentTemperature" フィールドの値が 32 以上のステート履歴の件数がカウントされます。これは機能ガイドの 例 4 の実行例です。
curl -v -X POST \
-H "Authorization: Bearer {ACCESS_TOKEN}" \
-H "X-Kii-AppID: {APP_ID}" \
-H "X-Kii-AppKey: {APP_KEY}" \
-H "Content-Type: application/json" \
"https://api-jp.kii.com/thing-if/apps/{APP_ID}/targets/thing:{THING_ID}/states/query" \
-d '{
"query": {
"clause": {
"type": "and",
"clauses": [
{
"type": "range",
"field": "currentTemperature",
"lowerLimit": 32
},
{
"type": "withinTimeRange",
"lowerLimit": 1467000000000,
"upperLimit": 1467003000000
}
]
},
"grouped": true,
"aggregations": [
{
"field": "currentTemperature",
"fieldType": "INTEGER",
"type": "COUNT",
"putAggregationInto": "state_count"
}
]
}
}'
次のように、指定条件に合致するステート履歴の件数がグループごとに集計され返されます。ステート履歴自体は返されない点に注意してください。
HTTP/1.1 200 OK
Content-Type: application/json
{
"queryDescription" : "SELECT count(currentTemperature) as state_count WHERE ( ( 32 <= currentTemperature ) AND withinTimeRange(1467000000000, 1467003000000) )",
"groupedResults" : [ {
"range" : {
"from" : 1467000000000,
"to" : 1467000900000
},
"aggregations" : [ {
"value" : 2,
"name" : "state_count"
} ]
}, {
"range" : {
"from" : 1467000900000,
"to" : 1467001800000
},
"aggregations" : [ { } ]
}, {
"range" : {
"from" : 1467001800000,
"to" : 1467002700000
},
"aggregations" : [ { } ]
}, {
"range" : {
"from" : 1467002700000,
"to" : 1467003600000
},
"aggregations" : [ { } ]
} ]
}
次に、集計関数として MIN を利用した例をあげます。この例ではフィールド条件を指定せず、各グループ内の全ステート履歴の中から最も低い "currentHumidity" の値を集計します。
curl -v -X POST \
-H "Authorization: Bearer {ACCESS_TOKEN}" \
-H "X-Kii-AppID: {APP_ID}" \
-H "X-Kii-AppKey: {APP_KEY}" \
-H "Content-Type: application/json" \
"https://api-jp.kii.com/thing-if/apps/{APP_ID}/targets/thing:{THING_ID}/states/query" \
-d '{
"query": {
"clause": {
"type": "withinTimeRange",
"lowerLimit": 1467000000000,
"upperLimit": 1467003000000
},
"grouped": true,
"aggregations": [
{
"field": "currentHumidity",
"fieldType": "INTEGER",
"type": "MIN",
"putAggregationInto": "minimum_humidity"
}
]
}
}'
結果は次のように返されます。今回の場合、グループ内で最小の "currentHumidity" 値を持つステート履歴が一意に特定されるため、このステート履歴が "object" フィールドの値として返されています。これは機能ガイドの 例 5 の実行例です。
HTTP/1.1 200 OK
Content-Type: application/json
{
"queryDescription" : "SELECT min(currentHumidity) as minimum_humidity WHERE withinTimeRange(1467000000000, 1467003000000)",
"groupedResults" : [ {
"range" : {
"from" : 1467000000000,
"to" : 1467000900000
},
"aggregations" : [ {
"value" : 70,
"name" : "minimum_humidity",
"object" : {
"currentTemperature" : 31,
"fanspeed" : 5,
"_created" : 1467000374001,
"currentHumidity" : 70,
"presetTemperature" : 25,
"power" : true
}
} ]
}, {
"range" : {
"from" : 1467000900000,
"to" : 1467001800000
},
"aggregations" : [ {
"value" : 72,
"name" : "minimum_humidity",
"object" : {
"currentTemperature" : 31,
"fanspeed" : 5,
"_created" : 1467001000000,
"currentHumidity" : 72,
"presetTemperature" : 25,
"power" : true
}
} ]
}, {
"range" : {
"from" : 1467001800000,
"to" : 1467002700000
},
"aggregations" : [ { } ]
}, {
"range" : {
"from" : 1467002700000,
"to" : 1467003600000
},
"aggregations" : [ {
"value" : 72,
"name" : "minimum_humidity",
"object" : {
"currentTemperature" : 31,
"fanspeed" : 5,
"_created" : 1467003321211,
"currentHumidity" : 72,
"presetTemperature" : 25,
"power" : true
}
} ]
} ]
}