switchbotの温湿度計を購入したので、node.jsでデータを取得し、s3にアップロードしてみた。
データの取得
データの取得にはnobleを使用した。
nodeのv9以降では動かないようなので、v8系をインストールすること。
nobleの使い方は割愛。
microbotの開発元?のOpenWonderLabsがAPI仕様を公開しているので、それを参照しながらデータを読み取る。
https://github.com/OpenWonderLabs/python-host/wiki/Meter-BLE-open-API
ビットの操作はとっても苦手なので、苦労した。
例えば、4バイト目の後ろ7ビットには温度のデータが入っているようなので、このようにして取得。
consttemperature=data.readUInt8(4)&0x7f;
&(ビット演算子)で0x7f(1111111)をビットANDして、後ろ7桁を切り出すらしい。
前3桁が欲しかったら、こんな感じで0xE0(11100000)をビットANDして、
さらにシフト演算子 >>>
(0埋めバージョン)で後ろ5桁を溢れさせる。
vara=data.readUInt8(4)&0xE0>>>5
web開発ばっかりやってた人間としては、このあたりはとっても苦手な領域。
データが取れたら fs
でファイルに書き出す。
後で扱いやすいように moment.js
を使って日時分秒をファイル名にした。
↓ソース全体(scan.js)
'use strict';constnoble=require('noble');constfs=require('fs');constmoment=require('moment');// living swithbotconstMAC="xxxxxxx";// switchbotのmacアドレスconsttmpDir="/var/tmp/envdata/";// データを保存したいディレクトリnoble.on('stateChange',(state)=>{if(noble.state==='poweredOn'){noble.startScanning();}else{noble.on('stateChange',scanStart);}});noble.on('scanStart',()=>{console.log('start scanning');});noble.on('scanStop',()=>{console.log('stop scanning');process.exit(0);});noble.on('discover',(peripheral)=>{if(peripheral.uuid===MAC){noble.stopScanning();constdata=peripheral.advertisement.serviceData[0].data;constdeviceType=data.slice(0,1).toString('ascii');constbattery=data.readUInt8(2)&0x7f;consttemperature=data.readUInt8(4)&0x7f;consthumidity=data.readUInt8(5)&0x7f;consttime=moment().format('YYYY-MM-DD_HH:mm:ss');constjsonData={"datetime":time,"battery":battery,"temperature":temperature,"humidity":humidity};// write to filefs.writeFileSync(tmpDir+time+'.log',JSON.stringify(jsonData));noble.stopScanning();}});
s3へのアップロード
s3へのアップロードはいたって簡単です。
下準備
aws-sdk
のライブラリを npm install
する。
AWSのIAMでアップロード用のユーザ作ってAmazonS3FullAccess
のポリシー(uploadだけだったら権限絞ったポリシーで良い気もする)付けて、そのcredential情報をjsonファイルに書き出しておく。
{"accessKeyId":"xxxxxxxxxxxxx","secretAccessKey":"xxxxxxxxxx"}
こんな具合。
S3への接続
こんな感じでs3オブジェクトをセットアップ。
AWS.config.loadFromPath('/home/pi/.aws/credential.json');// 保存したcredentialファイルのパスを指定AWS.config.update({region:'ap-northeast-1'});consts3=newAWS.S3();
あとはアップロードしたいファイルの情報を整えて s3.putObject()
でアップロード。
↓ソース(upload.js)
constAWS=require('aws-sdk');constfs=require('fs');AWS.config.loadFromPath('/home/pi/.aws/credential.json');AWS.config.update({region:'ap-northeast-1'});consts3=newAWS.S3();consttmpdir='/var/tmp/envdata/';fs.readdir(tmpdir,(err,files)=>{if(err)throwerr;files.forEach((file)=>{varparams={Bucket:'switchbot-room',Key:file};params.Body=fs.readFileSync(tmpdir+file);s3.putObject(params,(err,data)=>{if(err)throwerr;fs.unlinkSync(tmpdir+file,(err)=>{if(err)throwerr;});});});});
自動起動設定
cron設定するだけ。
*/5 **** /usr/local/bin/node /home/pi/swithbot/scan.js
*/5 **** /usr/local/bin/node /home/pi/swithbot/upload.js
5分間隔でデータを取得して、アップロード。
今のところ問題なくデータが上がってます。
NextAction
次は、上がったデータを可視化したい。
QuickSight, Mackerel, ES + Kibana どれでやろうか検討中。chart.js使って自分で作ってもいいけど、
一番費用が掛からない方法がいいな。