Mais conteúdo relacionado
Semelhante a kintoneで実践するIoTハンズオン -90分で挑戦!kintone & AWS IoT連携- (20)
kintoneで実践するIoTハンズオン -90分で挑戦!kintone & AWS IoT連携-
- 28. kintoneからAWS各サービスへのアクセス
28
REST API Event REST API
Device
Shadow
SOAP API
①スイッチON/OFF
②API GatewayとLambdaを介して、
Device ShadowのREST APIをコール
③Device Shadowで
Raspberry Piを制御
④Raspberry PiからLAN内の
Wemoにアクセス
⑤家電の電源をON/OFF
- 38. ハンズオン構成(続き)
①BLE CentralからBLE Peripheralの
センサーデータをAWS IoT Device GWへ
MQTT Publish
AWS
Lambda
kintone on cybozu.com
MQTT
AWS IoT
Event
REST
API
IoT Device
BLE
Peripheral
BLE
Central
②AWS IoTルール
エンジンでイベントドライブ
③Lambdaから
kintoneへのレコード操作
AWS IoT/Lambdaからkintoneへの柔軟なデータ取り込みを体験
※今回BLE CentralはRaspberry Piで代用
38
- 40. • kintone
• kintone REST APIをNode.jsでコールする
• レコード操作
• ワークフロー操作(応用編)
• AWS
• AWS Lambdaの設定方法
• AWS IoTの設定方法
• デバイス、ルール、ポリシー、証明書
• IoT Device
• AWS IoT SDKによるMQTT Publishの記述方法
今回のハンズオンに必要とされるスキルセット(目標・成果物)
40
- 41. ハンズオンの手順
①BLE CentralからBLE Peripheralの
センサーデータをAWS IoT Device GWへ
MQTT Publish
AWS
Lambda
IoT Device ← AWS IoT ← Lambda ← kintone
MQTT
AWS IoT
Event
REST
API
IoT Device
BLE
Peripheral
BLE
Central
②AWS IoTルール
エンジンでイベントドライブ
③Lambdaから
kintoneへのレコード操作
データやプロセスの終着点側から設定すると、スムーズに進みます!
41
- 47. kintone REST APIの概要
47
• kintoneアプリのレコードやスペースの操作
kintone REST APIの用途
プロトコル
• HTTPSプロトコル
フォーマット
• JSON
文字コード
• UTF-8
認証認証
• ユーザ認証(パスワード、APIトークン)
• Basic認証
その他
• 同時処理レコード数100件
• API同時アクセス10件
※GET/recordsのみ500件
- 48. kintone REST APIの概要(続き)
48
• https://{subdomain}.cybozu.com/k/v1/{command}.json【通常】
• https://{subdomain}.cybozu.com/k/guest/{space id}/v1/
{command}.json【ゲストスペース】
URI
リクエストヘッダ
• Host: {subdomain}.cybozu.com:443
• Content-Type:application/json
• 認証情報
- 56. AWS IoTの概要
56
引用「AWS IoTの仕組み」
(https://aws.amazon.com/jp/iot/how-it-works/)
• DEVICE GATEWAY
• メッセージブローカー、MQTT/HTTP1.1
• AUTHENTICATION & AUTHORIZATION
• TLS1.2、IAM、SigV4、Cognito
• AWS IoT DEVICE SDK
• Embedded C、JavaScript、Arduino Yún
• RULES ENGINE
• SQLライクな記述、AWSサービスへのアクション
• DEVICE SHADOWS
• オフライン時のメッセージ受信
• REGISTRY
• メタデータ管理参考「Everything You Want to Know About AWS IoT」
(http://www.slideshare.net/AmazonWebServices/mbl205-new-everything-you-want-to-know-about-aws-iot)
- 89. // Libraries
var https = require('https'); // HTTPS request
// constant parameters
const KINTONE_HOST = 'kintone-iot.cybozu.com';
const APP_ID = 3;
const API_TOKEN = 'Tm8C8ziqgf7fUx2XdvAAIu1PJINczwPHVntFj9ON';
イベントコード「kintone_iot.js」の部分解説
89
HTTPSリクエストを行う標準モジュール
Node.jsのモジュール(1行目∼)
設定値(定数)(6行目∼)
アプリ毎の固有の情報(今回の編集対象)
- 90. // get options to access to kintone REST API
var getOptions = function(path, method) {
return {
hostname: KINTONE_HOST,
port: 443,
path: path,
method: method,
secureProtocol: 'SSLv3_method',
headers: {
'X-Cybozu-API-Token': API_TOKEN
}
};
};
イベントコード「kintone_iot.js」の部分解説(続き)
90
ヘッダ情報は認証情報のみセットしておく
(URL渡しのGET/records等以外はContent-
Type: application/jsonを別途付加)
HTTPSリクエスト時に必要な情報を取得する関数(9行目∼)
- 91. // regist record to kintone
var postRecord = function(event, callback) {
console.log('start postRecord');
// set request body
var params = {
"app": APP_ID,
"record": {
"time": {
"value": event.time || event.timestamp || ""
},
"device": {
"value": event.device || "devsumi_device"
},
"temp": {
"value": event.temp || ""
},
"humidity": {
"value": event.humidity || ""
}
}
};
var json = JSON.stringify(params);
// set request headers
var options = getOptions('/k/v1/record.json', 'POST');
options.headers['Content-Type'] = 'application/json';
// access to kintone REST API
var req = https.request(options, function(res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function(chunk) {
console.log('BODY: ' + chunk);
if (res.statusCode === 200) {
callback(null, JSON.parse(chunk));
}
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
callback(e.message);
});
req.write(json);
req.end();
};
イベントコード「kintone_iot.js」の部分解説(続き)
91
eventを処理してレコード登録を行う関数(24行∼)
eventから登録するrecordを作成
「Content-Type: application/json」を
リクエストヘッダに付加
POST/recordをコール
- 120. MQTT Publishの確認(エミュレータの準備・続き)
120
/
┣ AWS IoT Publisher-darwin-x64/ (Mac用)
┃ ┗ AWS IoT Publisher.app (エミュレータアプリ)
┣ AWS IoT Publisher-win32-ia32/ (Windows32bit用)
┃ ┗ AWS IoT Publisher.exe (エミュレータアプリ)
┗ AWS IoT Publisher-win32-x64/ (Windwos64bit用)
┗ AWS IoT Publisher.exe (エミュレータアプリ)
レポジトリの中身(パッケージ済アプリ部分のみ)
③自分の環境に適したアプリを起動
- 121. MQTT Publishの確認(エミュレータによるPublish)
①「Asia Pacific (Tokyo)[ap-northeast-1]」を選択
②先程設定した「devsumi/ginga」を記入
③先程ダウンロードした「rootCA.pem」を選択
④先程ダウンロードした「certificate.pem」を選択
⑤先程ダウンロードした「private.pem」を選択
⑥サンプルの「sample_event.json」
をkey-value形式で入力
⑦「Publish to AWS IoT !」をクリック
121
- 133. IoT Deviceの設定
133
{kintoneのログインID(例: user1)}/
┣ ginga_iot.js (センサーの値を取得してPublishするメインのNode.jsファイル)
┣ node_module/ (Node.jsのモジュール群)
┃ ┣ aws-iot-device-sdk/ (証明書を伴うAWS IoTへのアクセス)
┃ ┣ noble/ (BLE Centralの作成)
┃ ┗ moment/ (日時操作)
┗ cert/ (証明書ファイル群)
┣ rootCA.pem (ルート証明書)
┣ certificate.pem (証明書)
┗ private.pem (秘密鍵)
BLE Centralのフォルダ構成 フォルダ名を「ginga/」からkintoneの
ログインIDに各自修正しておく
- 134. // constant parameters
const DEVICE_NAME = 'dev1';
const TOPIC = "devsumi/ginga"; // MQTT TOPIC
const MY_ADDRESS = "f3:2f:85:98:69:ce"; // MAC Address of BLE peripheral, "GINGA"
const REGION = 'ap-northeast-1';
IoT Deviceの設定
134
ginga_iot.jsの編集箇所(6行目∼)
①Peripheralの「Dev**」を記入
②Peripheralのアドレスを記入
- 136. // libraries
var noble = require('noble'); // BLE central module
var awsIot = require('aws-iot-device-sdk'); // AWS IoT SDK
var moment = require('moment'); // Date library
Centralコード「ginga_iot.js」の部分解説
136
Node.jsのモジュール群(1行目∼)
// constant parameters
const DEVICE_NAME = 'dev1';
const TOPIC = "devsumi/ginga"; // MQTT TOPIC
const MY_ADDRESS = "f3:2f:85:98:69:ce"; // MAC Address of BLE peripheral, "GINGA"
const REGION = 'ap-northeast-1';
設定値(定数)(6行目∼)
AWS IoTルールエンジンで設定したTopicと同じ値
AWS IoTの設定を行った東京リージョン
- 137. // device config.
var device = awsIot.device({
keyPath: './certs/private.pem',
certPath: './certs/certificate.pem',
caPath: './certs/rootCA.pem',
clientId: DEVICE_NAME,
region: REGION
});
Centralコード「ginga_iot.js」の部分解説(続き)
137
AWS IoT Device SDKにおけるdeviceオブジェクトの初期化(12行目∼)
証明書のパス
- 138. // parse & publish temperature/humidity data
function publish_ginga(data) {
// parse temperature data
var t1 = parseInt(data[0]);
var t2 = parseInt(data[1]) / 100;
var temp_value = t1 + t2; // temperature value
// parse humidity data
var h1 = parseInt(data[2]);
var h2 = parseInt(data[3]) / 100;
var humidity_value = h1 + h2; // humidity value
// create & publish message
var message = {
"device": DEVICE_NAME,
"sensor": 'ginga',
"time": moment().format(),
"temp": temp_value,
"humidity": humidity_value
};
message = JSON.stringify(message);
console.log("# Publish: " + message);
device.publish(TOPIC, message); // publish
}
Centralコード「ginga_iot.js」の部分解説(続き)
138
GINGAのデータをパースしてAWS IoTにPublishする関数(48行目∼)
温度をパース
湿度をパース
Publishするメッセージ
AWS IoTへのPublish
- 139. // event for BLE peripheral "discover"
noble.on('discover', function(peripheral) {
noble.stopScanning();
if (MY_ADDRESS == peripheral.address) {
var serviceUUID = peripheral.advertisement.serviceUuids[0];
console.log('# Service UUID: ' + serviceUUID);
peripheral.connect(function(error) {
if (error) console.log('# Connect error: ' + error);
console.log('# Connected to ' + peripheral.uuid);
peripheral.discoverServices([serviceUUID],
function(error, services) {
if (error) console.log('## discoverServices error: ' + error);
console.log('## services.length: ' + services.length);
var service = services[0];
service.discoverCharacteristics(null, function(error, characteristics) {
if (error) console.log('## discoverCharacteristics error: ' + error);
console.log('## characteristics.length: ' + characteristics.length);
characteristics[0].notify(true, function(error) {
if (error) console.log('## notify error: ' + error);
setInterval(function() {
characteristics[0].read(function(error, data) {
if (data) {
// publish_humidity(data); // publish humidity
// publish_temp(data); // publish temperature
publish_ginga(data); // publish GINGA data
}
});
}, 10 * 1000); // per 10sec
});
});
}
);
});
} else {
console.log("# No my device is discovered");
}
});
Centralコード「ginga_iot.js」の部分解説(続き)
139
Peripheralからのadvertisement受信時の処理(80行目∼)
BLE Peripheralからのadvertisementを受けて
データが取れたら、Publishする関数を呼ぶ
nobleモジュールでBLEのadvertisement
を受けた時のイベント
advertisementが指定したアドレスからの
時にはデータ取得のために処理続行
- 141. {kintoneのログインID(例: user1)}/
┣ ginga_iot.js
┣ node_module/
┃ ┣ aws-iot-device-sdk/
┃ ┣ noble/
┃ ┗ moment/
┗ cert/
┣ rootCA.pem
┣ certificate.pem
┗ private.pem
kintoneにファイルセットを保存
141
圧縮して、kintoneの「ユーザー
管理」アプリに保存
BLE Centralのフォルダ
- 142. kintoneに保存したファイルセットをCentralにデプロイ
142
$ curl -X GET "https://kintone-iot.cybozu.com/k/v1/file.json?fileKey={ファイルキー}"
-H "X-Cybozu-Authorization:{「ID:Passwrod」のbase64エンコード値}"
-o ./{kintoneのログインID(例: user1)}.zip
ファイル取得のコマンド
$ unzip ./{kintoneのログインID(例: user1)}.zip
ファイルセットの展開
今回は代表何名か分を実施させていただきますm(__)m