運用上、倉庫の出入りを管理したいことがあります。
○分前に人の出入りがあったか?を確認しようとすると、設置した監視カメラの映像を使うことが一般的かもしれませんが、確認に時間がかかります。
そんなとき、入退室の時間を何かのデータベースに登録しておき、その情報を簡単に確認できるとうれしいです。
そこで、kintoneと、MESHの人感ブロック・LEDブロック・ボタンブロックを組み合わせて、倉庫の出入り状況を確認できるしくみを作ってみました。
MESHについては
MESH公式サイト
を確認してください。
このカスタマイズでは次のことを行います。
- MESHの人感ブロックを使って、「エリア内に人がいるか?」をチェックします。チェック結果はkintoneのアプリに登録します。
- MESHのボタンを押して、直近5分以内に人がいたか(該当するレコードがあるか)をkintoneに問い合わせします。
- 人がいた場合:MESHのLEDブロックは赤に点灯します。
- 人がいなかった場合:MESHのLEDブロックは緑に点灯します。
MESHとMESHを接続しているモバイルはBluetoothの範囲内としてください。
kintoneの設定
固定リンクがコピーされました
下記手順で作成するkintoneアプリのIDとAPIトークンは、MESHの設定で利用するので控えておいてください。
アプリIDは、アプリのURLで確認できます。
例:URLがhttps://sample.cybozu.com/k/10/の場合、「10」がアプリIDです。
kintoneアプリの作成
固定リンクがコピーされました
次のフィールドをフォームに設置します。
フィールド名 |
フィールドタイプ |
フィールドコード |
初期値 |
備考 |
日時 |
日時 |
DateTime |
レコード登録時の時刻を初期値にする |
人感センサで人を感知した時間です。 |
ステータス |
数値 |
Status |
ー |
人感センサの値です。 ただし登録するのみで、プログラム内で利用はしません。 |
APIトークンの生成
固定リンクがコピーされました
「レコード閲覧」「レコード追加」権限のあるAPIトークンを生成します。
APIトークンの生成方法は「
APIトークンを生成する
」を参照してください。
MESH SDKは、MESHアプリのレシピで利用するカスタムブロック(ソフトウェアブロック)を作成するツールです。
カスタムブロックでは、JavaScriptを使って、複雑な処理やさまざまなWebサービスとの連携ができます。
以下の手順にしたがって、MESHのカスタムブロックを2つ作成します。
作成するカスタムブロックは以下の「入退室(登録)ブロック」「入退室(取得)ブロック」です。
- 入退室(登録)ブロック:人感センサのチェック結果をkintoneに登録するブロックです。
- 入退室(取得)ブロック:kintoneに問い合わせしてLEDブロックを点灯させるブロック
-
[Create New Block]をクリックし、新規ブロックを作成します。
-
[Import]タブを選択します。
-
エディタ部分に、後述する「
入退室(登録)
」および「
入退室(取得)
」のJSONの内容をそれぞれ貼り付けます。
[Load JSON]をクリックすると、上書きの確認ダイアログが表示されるので[OK]ボタンをクリックし、インポートします。
-
インポート後、下記PropertyのDafault Valueを書き換えます。
PropertyのDefault Valueは、レシピにブロックを配置する際、初期値として設定されます。
Propertyの値は、MESHアプリのレシピからも変更できます。
-
[Save]をクリックし、保存します。
MESHアプリでは、Bluetoothで接続したMESHブロックや、MESH SDKで作成したカスタムブロックを「レシピ」のキャンバス上に配置し、処理フローを作成します。
-
[+新しいレシピ]をタップし、レシピを作成します。
-
MESHブロックを接続します。
- 人感ブロック
- ボタンブロック
- LEDブロック2つ。
MESHブロックの接続
-
接続したMESHタグを、ドラッグ&ドロップでキャンバスに配置し、設定します。
ブロック |
設定 |
人感センサ |
|
ボタンブロック |
|
LEDブロック |
1つめのブロック
- 点滅する
- 色:オレンジ
- 明るさ:1
- 時間(秒):5秒
- 周期(秒):1秒
2つめのブロック
- 点滅する
- 色:ミント
- 明るさ:1
- 時間(秒):5秒
- 周期(秒):1秒
|
-
MESH SDKにサインインします。
MESH SDKのサインイン
-
カスタムの[追加]をタップし、MESH SDKで作った2つのカスタムブロックを追加します。
カスタムブロックの追加
-
追加したカスタムブロックを、ドラッグ&ドロップでキャンバスに配置します。
MESH SDKでブロックを作成したときのDefault Valueが初期値に設定されます。
変更する場合は、対象のブロックをタップして表示される画面で変更してください。
-
配置したブロックをそれぞれ次のように接続します。
「入退室(取得)」ブロックの出力コネクタについては、次のように接続してください。
- 1つめのコネクタ(confusion):色をオレンジに設定したLEDブロック
- 2つめのコネクタ(vacant):色をミントに設定したLEDブロック
- 人感ブロックの前に立って感知されたら、kintoneにレコードが登録されます。
- ボタンブロックのボタンを押して、LEDブロックが光ります。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
{
"formatVersion": "1.0",
"tagData": {
"name": "入退室(登録)",
"icon": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAADc0lEQVRoQ+2a3VEbMRCAd3UugFQAVIBTQUwHoQOoIPLp3jHv1nFUEFIBJWAqwB3EHcR5t24z65E85+MMuh+JhIlm/OCxfvbTrla7KyN8kIYfhAP+gwyhSSnlRAjxBREnAHBiPzz1GgCWiLjcbDY/iqJYvrXeu2iEAZIkuQYABvBpC2PMTVEUi0Odo4JIKY+EENeIKH2kr/dBxGKz2TAQa2yveYNIKcdCiG88uixLnmzVRhgp5cloNHogonGbcQ0wbG4X9fW9QbIsmxDRI09sjDl/Tc31xVkTo9HosS+Em9eeHZZhp5koIGma3nY1p4NnArGYz+fTHZyvmrtqpDrOdy3fflXLCK4RpRSbo6938mVw/RZa63P+EhSEHUSSJM9tpWvT32klKMh0Oi2cp2sjXJu+RHST5/lsD8S62Eb3KIQ4JqKZXeSOiBpv27Isl+4mDmxWe+a1B5Km6QwR+cbt3NwO8QRKqV8AcNR5Mr+BK631aWgQ8pOlXy+tNdZNi3evcQeFEBNE/G6XvDDGHArk1u6iUkq9D8hr+9LlHlFK/axEtP22/fDotdb6U1Cv9W6HfWiNZFk2I6JezsNDjXdaaxlUIyHDEwdojPnM7j4oiHXB/36IwiAhtdIpaLTZ3VcWrizLRZvESilVAMA2KRuwbc+Gm8/btPoIwJuQJAmbWK/ssCLD0mqjfWLVB4THcqqbJMnDADAM0T3V7QtiYVgzHHh2NbM7Y8ysV/FhCBA3h3UArcpBiHgzn8//jnJQfTNs4nUJAGfW5FycxxWaFSI+AcDiNYCoh72qCQC4JaIVET1x7sICH/KA9lyNiYirkGdckTTGXDVVcKJ4LQfyRsZYr5Ox8C8aEd3neX5V/yEqSJZlzwPUttbGmNP6gY8GYs2Ew/reralAGA0kTdPLSmLWF2ZXBop+2JVSfBluQ5wB2gvziqaRoQsRRHSV5/l9VI0EioD3zCuKRkIV6owxn5z3igIykNttulOmeZ5ziuBf++16QId0uw0ytC9idwUZ2O2+EMOZV3DTGtjtHjSvGCCh679b8woKEsjtNppXUJBQbrdOwi8AQUEi1X6ZaxEUxD0c2b9ouCywqwOsj+Ok7IkfnLg8FRSkvrJ9bx+XZTlGRE6cju0zRvV/KG4Yl3q2HxYWEX9boXcvYtX5o4IMpYqmeT4MyB+14EAP6Tq37QAAAABJRU5ErkJggg==",
"description": "",
"functions": [
{
"id": "function_0",
"name": "postKintoneApp",
"connector": { "inputs": [{ "label": "motion" }], "outputs": [] },
"properties": [
{
"name": "ドメイン",
"referenceName": "domain",
"type": "string",
"defaultValue": "example.cybozu.com"
},
{
"name": "アプリケーションID",
"referenceName": "appId",
"type": "number",
"defaultValue": "1"
},
{
"name": "APIトークン",
"referenceName": "apiToken",
"type": "string",
"defaultValue": "TOKEN"
}
],
"extension": {
"initialize": "",
"receive": "",
"execute": "/*\n * MESH program\n * Copyright (c) 2019 Cybozu\n *\n * Licensed under the MIT License\n */\nconst url = `https://${properties.domain}/k/v1/record.json`;\nconst data = {\n app: properties.appId,\n record: {\n DateTime: { value: new Date() },\n Status: { value: messageValues.stateValue }\n }\n};\n\najax ({\n url: url,\n data: JSON.stringify(data),\n type: 'POST',\n contentType: 'application/json',\n dataType: 'json',\n timeout: 5000,\n headers: { 'X-Cybozu-API-Token': properties.apiToken },\n success: (contents) => {\n log('success');\n },\n error: (request, errorMessage ) => {\n log('error');\n log(request.responseText);\n log(errorMessage);\n }\n});\n\nreturn {\n resultType: 'pause'\n};\n",
"result": ""
}
}
]
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
{
"formatVersion": "1.0",
"tagData": {
"name": "入退室(取得)",
"icon": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAD9klEQVRoQ+1a0VHbQBC9PbkAqCBQAVBBoINQQaCCyD79A9/4hKggpALoAFMB7iBOBXH+ddrMc04eWZbkO1sSDJOb8fDh9e2+3ber3RUkPsihD4JD/AfSRiTDMDyVUn4molMhxIH94Oq5EGJKRNM0TX8kSTLdpO9NIgIAQRBcCSEAwOVMjDE3SZJM6oSdgIRhuGe9hb9zFw9VKcQ9UsorIgpdrC/LEFGSpikAIWIrpxHIaDS6IKKvFZ7DRU/WSzMXo8IwPBgMBo/MfOwiX+v5f3Q7T5JkRW8lECgNguC7Q+hnxpiz8qVlIxCJwWDwvCuI/F6bO9C7jMwakBqlE2aeEdEejCEiJGZ+JlrrsyYvj0aju23p1BCZZDweD5fgarh8HAQBPDiXUl6Ox+NlkgFoEASPxWgZY/areIu7oyg6ZebnXehU91vLhoVttTkCekGgijZKqS9CCIDJz4HW+leVQqUUQLhWJ1+8SzY4Va3y7bYIIIcWR2tdl2uI7KuvdT7yeVS8gYRhCOMQjUXEmPkmjuPrKuXD4TCRUn7zMcxXNtfvBUQpBaNgNJ4njSDwfce0Wik2zkCiKLpi5tzzc2YexnH80ORBpdTvHLSvpz3kZ1rrQycgpZyYW15u7H+UUuxh0NaiyFEnIEWK2EgkLlrfK5BFchtjLpuatyJApdTPQkfrgn0bmbnWet8pItvc/m6TfRswURRdMzPa9S7PvdY6dIqIUgoPvwshxExKeX57e7sx0WF5l+1J7hljzAnGio1AKtqRjU1iKU/eR4tSbkcwgmqtT1y50mVUnJrG3FA71b0WWvdzrfWTKxCb9CjXbbcqi9zI7dhIrVwQnk3TdFrXrjcBs60/KLbTdFjQMbXRqB+sfDztI2unTjSbu4IBCLdR18dAH1kbGfRr29Ls3hhz7b188DHSR9YWAK91EBHdFCfVsj7nHPEx1FXWzjZ4Ph1Zyi3GAzyv8CGiFyHEpAmAd7K7Gtckh0gIIe6wyGDmlyzL8GCd1W1hbF4dMzP6vCNsJOt6vV4jsmFiLO/HipuapX+Y+SGO48s3pVYURa8t7LYwDx2WE763iFiaoK3f+RSf6L3nSEWrswugtX6vt4gopfAwxD6sjbNGrz6BtLqIYObL4vKjFyAddcAr9OoFSFeLuuLOuRcgLZXdtdwqbnQ6B9Jm2a2oErstsX3KTstld011Tq/OI9Jy2a2lVx9AWi27dfTqFEhHZbeSXp0C6arslpHgHUmnQHra/QLXpFMgmACllHgLjIEqnwJ9il6TLIayF2aeZlnWLZCyFfbV93GWZfkr7k/2RVDx/1Dyn2HVs/jAWCL6Y43GSmptZdtpRNpyvcs9HwbIXwb2Gg9ECfJDAAAAAElFTkSuQmCC",
"description": "",
"functions": [
{
"id": "function_0",
"name": "getKintoneApp",
"connector": {
"inputs": [{ "label": "button" }],
"outputs": [{ "label": "confusion" }, { "label": "vacant" }]
},
"properties": [
{
"name": "ドメイン",
"referenceName": "domain",
"type": "string",
"defaultValue": "example.cybozu.com"
},
{
"name": "アプリケーションID",
"referenceName": "appId",
"type": "number",
"defaultValue": "1"
},
{
"name": "APIトークン",
"referenceName": "apiToken",
"type": "string",
"defaultValue": "TOKEN"
},
{
"name": "間隔(分)",
"referenceName": "interval",
"type": "number",
"defaultValue": "5"
}
],
"extension": {
"initialize": "",
"receive": "",
"execute": "/*\n * MESH sample program\n * Copyright (c) 2019 Cybozu\n *\n * Licensed under the MIT License\n */\n\nconst query = 'order by 作成日時 desc limit 1';\nconst url = `https://${properties.domain}/k/v1/records.json?app=${properties.appId}&query=${encodeURIComponent(query)}`;\n\najax({\n url: url,\n type: 'GET',\n dataType: 'json',\n timeout: 5000,\n headers: {\n 'X-Cybozu-API-Token': properties.apiToken\n \t},\n success: (contents) => {\n log('get: success');\n const records = contents.records;\n let outputIndex = 1;\n if(records.length > 0) {\n const current = new Date();\n const latest = new Date(records[0].DateTime.value);\n const diff = current.getTime() - latest.getTime();\n if(diff < (properties.interval * 60 *1000)) {\n outputIndex = 0;\n }\n }\n runtimeValues.outputIndex = outputIndex;\n callbackSuccess({\n resultType : 'continue',\n runtimeValues : runtimeValues\n });\n },\n error: (request, errorMessage) => {\n log('get: error');\n log(request.responseText);\n log(errorMessage);\n callbackSuccess({\n resultType : 'continue',\n runtimeValues : runtimeValues\n });\n }\n});\n\nreturn {\n resultType : 'pause'\n};\n",
"result": "return {\n indexes: [ runtimeValues.outputIndex ],\n resultType : 'continue'\n};"
}
}
]
}
}
|
サンプルコードの解説
固定リンクがコピーされました
今回作成したMESHカスタムブロックのポイントを解説します。
MESH SDKの詳細は、
MESH SDKリファレンスマニュアル
を参照してください。
入退室(登録)ブロック
固定リンクがコピーされました
人感センサの結果をkintoneに登録する
人感センサブロックは、人を感知したときに次のブロックへ信号を伝えるように設定しています。
Code
入退室(取得)ブロック
固定リンクがコピーされました
レコードの取得結果に応じて出力先を変える
「5分以内に人がいたか?」に応じてLEDの色を変更させるため、2つのLEDブロックを配置しています。
カスタムブロックで、レコードがなければ1つめのコネクタに接続したブロックへ信号を送り、レコードがあれば2つめのコネクタに接続したブロックへ信号を送っています。
出力コネクタを分岐させるには、次のように設定します。
Connector
Code
-
Initializeメソッド
Function内で共有できる変数runtimeValues
を定義します。
-
Executeメソッド
runtimeValues
のプロパティに、出力先コネクタの番号を指定します。
1つめのコネクタのコネクタ番号は0、2つめのコネクタのコネクタ番号は1です。
デフォルトでは、2つめのコネクタに出力するようにしています。
所定の時間以内のレコードがなければ、1つめのコネクタに出力します。
処理が終わったらcallbackSucces()
メソッドでResultメソッドに渡します。
-
Resultメソッド
Executeメソッドから渡されたruntimeValues
の値をindexes
プロパティに設定することで、Output Connectorに出力します。
今回の記事では、「5分以内に」人がいるか?をチェックしました。
チェックタイミングを「○時までに」とすると、指定時刻までに入室(または退室)が必要な業務において、入退室を管理できます。
また、cybozu developer networkでは、他にもkintoneとMESHを連携した記事を紹介しています。
ぜひこれらの記事も参照してみてください。