はじめに
enebular developer Meetuup Vol.3 で「enebular InfoMotion を使ってオムロン環境センサー (2JCIE-BL01) を可視化してみた。(仮)」というタイトルで LT する内容の記事です。
Raspberry Piとオムロン環境センサーを使用して測定したデータを可視化する事例やハンズオンはいくつかあるが、データを Firebase へアップロードして、Firebase のデータを enebular InfoMotion で可視化してみた。
- Ambient で可視化 (クラウド)
- オムロン環境センサーからBLE経由でデーターをクラウドに送る
- Grafana で可視化 (ローカル)
- WxBeacon2をRaspberry Pi 3につないで部屋の状態を可視化
- ラズパイでウェザービーコンをハックしてみる~環境作成~
- Raspberry Pi でオムロン環境センサのログをGrafanaで可視化してみる
事前準備
- Raspberry Pi
- Raspberry Pi 3 Model B
- Raspberry Pi 3 Model B+
- Raspberry Pi Zero W
- Raspberry Pi 2 Model B + Bluetooth 4.0 USBアダプタ(CSR V4.0、BT-Micro4 など)
OS は "RASPBIAN STRETCH" Version:June 2018 (Release date:2018-06-27) を使用。
-
オムロン環境センサー (2JCIE-BL01)
センサーの設定をビーコンモードに変更する。(参考) -
enebular 新規登録
"enebular へのサインアップ" 〜 "Project の作成" を実施。 -
Firebase DataSource の作成
"Firebase DataSource の作成" 〜 "DataBase のセットアップ" を実施。
構成
手順
Raspberry Pi
5分毎にデータをFirebaseへアップロードする場合 (Ambient のツールを流用しています)
# ライブラリをインストール
$ sudo apt-get install libglib2.0-dev
$ sudo pip3 install bluepy
$ sudo pip3 install pyrebase
# プログラムを実行
$ sudo nohup python3 omron_firebase.py < /dev/null &
omron_firebase.py プログラムは こちら 。
項目 | 設定値 | |
---|---|---|
config | apiKey | Firebase の apiKey を設定 (必須) |
authDomain | Firebase の authDomain を設定 (必須) | |
databaseURL | Firebase の databaseURL を設定 (必須) | |
storageBucket | Firebase の storageBucket を設定 (必須) | |
Firebase の認証用 ID (必須) | ||
password | Firebase の認証用 Password (必須) | |
address | オムロン環境センサーの BT アドレス (任意) |
# -*- coding: utf-8 -*-
#
from bluepy.btle import Peripheral, DefaultDelegate, Scanner, BTLEException, UUID
import bluepy.btle
import sys
import struct
from datetime import datetime
import argparse
import pyrebase
config = {
"apiKey": "",
"authDomain": "",
"databaseURL": "",
"storageBucket": ""
}
email = ''
password = ''
companyID = 'd502' # OMRON company ID (Bluetooth SIG.)
address = 'FFA511nnnnnn' # BT ADDRESS (replace nnnnnn to own device)
Debugging = False
def DBG(*args):
if Debugging:
msg = " ".join([str(a) for a in args])
print(msg)
sys.stdout.flush()
Verbose = True
def MSG(*args):
if Verbose:
msg = " ".join([str(a) for a in args])
print(msg)
sys.stdout.flush()
def send2firebase(dataRow):
(temp, humid, light, uv, press, noise, accelX, accelY, accelZ, batt) = struct.unpack('<hhhhhhhhhB', bytes.fromhex(dataRow))
MSG(temp/100, humid/100, light, uv/100, press/10, noise/100, (batt+100)/100)
firebase = pyrebase.initialize_app(config)
db = firebase.database()
auth = firebase.auth()
user = auth.sign_in_with_email_and_password(email, password)
now = datetime.now()
dt_s = now.strftime("%s") + str(int(now.microsecond/1000))
data = {
"timestamp": int(dt_s),
"value": {
"created": int(dt_s),
"address": address,
"battery": float((batt+100)/100),
"temperature": float(temp/100),
"humidity": float(humid/100),
"light": float(light),
"uv": float(uv/100),
"pressure": float(press/10),
"noise": float(noise/100)
}
}
MSG(data)
results = db.child("omron").child(address).push(data, user['idToken'])
class ScanDelegate(DefaultDelegate):
def __init__(self):
DefaultDelegate.__init__(self)
self.lastseq = None
self.lasttime = datetime.fromtimestamp(0)
def handleDiscovery(self, dev, isNewDev, isNewData):
if isNewDev or isNewData:
for (adtype, desc, value) in dev.getScanData():
if desc == 'Manufacturer' and value[0:4] == companyID:
delta = datetime.now() - self.lasttime
if value[4:6] != self.lastseq and delta.total_seconds() > 11:
self.lastseq = value[4:6]
self.lasttime = datetime.now()
send2firebase(value[6:])
def main():
parser = argparse.ArgumentParser()
parser.add_argument('-d',action='store_true', help='debug msg on')
args = parser.parse_args(sys.argv[1:])
global Debugging
Debugging = args.d
bluepy.btle.Debugging = args.d
scanner = Scanner().withDelegate(ScanDelegate())
while True:
try:
scanner.scan(5.0)
except BTLEException:
MSG('BTLE Exception while scannning.')
if __name__ == "__main__":
main()
一括でCSVファイルのデータをFirebaseへアップロードする場合 (オムロンのサンプルプログラムが出力するCSVファイルを使用)
# ライブラリをインストール
$ sudo apt-get install python-bluez
$ sudo pip3 install pyrebase
# プログラムを実行
$ python3 omron_csv_firebase.py ./log/env_sensor_log.csv
omron_csv_firebase.py プログラムは こちら 。
項目 | 設定値 | |
---|---|---|
config | apiKey | Firebase の apiKey を設定 (必須) |
authDomain | Firebase の authDomain を設定 (必須) | |
databaseURL | Firebase の databaseURL を設定 (必須) | |
storageBucket | Firebase の storageBucket を設定 (必須) | |
Firebase の認証用 ID (必須) | ||
password | Firebase の認証用 Password (必須) |
import sys
import csv
from datetime import datetime
import pyrebase
config = {
"apiKey": "",
"authDomain": "",
"databaseURL": "",
"storageBucket": ""
}
email = ''
password = ''
arguments = sys.argv
if len(arguments) == 1:
print ("Usage: python omron_csv_firebase.py CSV_FILE")
sys.exit()
csvfile = arguments[1]
def main():
firebase = pyrebase.initialize_app(config)
db = firebase.database()
auth = firebase.auth()
user = auth.sign_in_with_email_and_password(email, password)
## CSV_FILE format
## Time,Gateway,Address,Type,RSSI (dBm),Distance (m),Sequence No.,Battery (mV),Temperature (degC),Humidity (%%RH),Light (lx),UV Index,Pressure (hPa),Noise (dB),Discomfort Index,Heat Stroke Risk,Accel.X (mg),Accel.Y (mg),Accel.Z (mg)
## 2018-09-17 00:04:53.831591,raspberrypi,FFA511nnnnnn,EP,-66,1.77188476275,69,2830.0,22.68,82.6,0,0.01,996.3,34.64,71.4,23.37,0.0,0.0,0.0
f = open(csvfile, 'r')
reader = csv.reader(f)
for row in reader:
if row[0] == 'Time':
continue
dt = datetime.strptime(row[0][0:19], '%Y-%m-%d %H:%M:%S')
dt_s = dt.strftime('%s') + row[0][20:23]
data = {
"timestamp": int(dt_s),
"value": {
"created": int(dt_s),
"address": row[2],
"rssi": float(row[4]),
"distance": float(row[5]),
"battery": float(row[7]),
"temperature": float(row[8]),
"humidity": float(row[9]),
"light": float(row[10]),
"uv": float(row[11]),
"pressure": float(row[12]),
"noise": float(row[13]),
"di": float(row[14]),
"heat": float(row[15])
}
}
## print (data)
results = db.child("omron").child(row[2]).push(data, user['idToken'])
f.close()
return
if __name__ == "__main__":
main()
※ pyrebase をインストールした後、プログラムを実行すると「ImportError: cannot import name 'opentype' 」エラーが出力されるので、google-auth-oauthlib をアップグレードする。
$ sudo pip3 install --upgrade google-auth-oauthlib
Firebase
omron → BT アドレス (FFA511nnnnnn) 配下にデータが格納される。データ構造は以下。
第一階層 | 第二階層 | 値 |
---|---|---|
timestamp | タイムスタンプ Unixtime (ミリ秒) | |
value | address | オムロン環境センサーの BT アドレス |
battery | バッテリー電圧 (mV) | |
created | タイムスタンプ Unixtime (ミリ秒) | |
di | 不快指数 | |
distance | 距離 (m) | |
heat | 熱中症警戒度 | |
humidity | 湿度 (%) | |
light | 照度 (Lm) | |
noise | 騒音 (dBm) | |
pressure | 気圧 (hPa) | |
rssi | 電波強度 (dBm) | |
temperature | 気温 (℃) | |
uv | UV Index |
InfoType
InfoMotion 作成の前に InfoType 作成を実施する必要があるが、InfoType 作成には InfoMotion Tool を導入する必要があるため、今回はサンプルで用意されている linechart をダウンロードして使用することにした。
(参考) https://docs.enebular.com/ja/infomotion/infomotiontool
(参考) https://docs.enebular.com/ja/infomotion/SampleInfoTypes.html
InfoMotion
InfoType と DataSource を指定して InfoMotion ダッシュボードを作成する。(参考)
TYPE に linechart を指定する。
DATASOURCE に Firebase DataSource を指定する。
Label に address データキーを指定する。
Value に 上記の第二階層のデータキーを指定する。(気温であれば temperature を指定する。)