更新日:
ORUYOFirebaseNuxtこんにちは。YUKIです。
今回はBLEビーコンを用いた人・モノ検知のデータの活用方法の一つとして、BLEビーコンをセンサーで検知し、Webでその結果をリアルタイムに表示方法をご紹介します。
今回のシステムの全体構造は以下の通りです。
サンプルレポジトリはこちら
今回はフロントエンドのフレームワーク/代表的なライブラリとしてとして以下を利用します。
・NuxtJS (https://ja.nuxtjs.org/)
・Vuetify (https://vuetifyjs.com/ja/)
・Vuexfire (https://vuefire.vuejs.org/vuexfire/)
今回は簡易ではありますがWebシステムを構築することになりますので、前提としてJavascriptおよびHTMLの知識が必要となります。
また以下が用意さていることを前提とします。
・Googleアカウント
・yarn(もしくはnpm)が利用できる環境が用意されていること
今回はデータの格納先としてCloud Firestore、APIの作成用にCloud Functions for Firebaseを利用します。
FirebaseのコンソールにアクセスしGoogleアカウントで認証を行います。
https://console.firebase.google.com/?hl=ja
Firebaseのコンソールから「+プロジェクトの追加」をクリック、任意のプロジェクト名を入力後、「続行」をクリックします。
Google アナリティクスの設定は今回は使用しないので、「有効」、「無効」どちらでも構いません。
「プロジェクトを作成」をクリックし、プロジェクトを作成します。
プロジェクト画面のサイドバーから「Database」をクリックし、「データベースの作成」をクリックします。
通常はセキュリティ設定を行いますが、今回はお試しとして「テストモードで開始」を選択し、「次へ」をクリックします。
※今回は省略しますが、実際のプロジェクトとして利用する場合は、セキュリティルールを必ず適切に設定してください。
ロケーションの設定では「asia-northeast1」を選択して完了を選択します。
※ロケーションによってレイテンシや料金が異なります。実際のプロジェクトではプロジェクトの特性に応じてロケーションを設定してください。
「Project Overview」隣の歯車をクリックし、「プロジェクトの設定」をクリックしSettings画面を表示します。
「全般」タブでプロジェクトIDを確認します。
※後程使用します。
一旦Firebaseの設定はここまでです。
Cloud Functions for FirebaseにORUYOからWebhookを受け付けるAPIのエンドポイントを作成します。
ターミナルからFirebaseにログインします。
$ npm install -g firebase-tools
$ firebase login
Cloud Functions for Firebaseの初期化を行います。
$ firebase init
(中略)
? Are you ready to proceed? (Y/n) ⇒ Y
? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confirm your choices.
( ) Database: Deploy Firebase Realtime Database Rules
( ) Firestore: Deploy rules and create indexes for Firestore
>(*) Functions: Configure and deploy Cloud Functions
( ) Hosting: Configure and deploy Firebase Hosting sites
( ) Storage: Deploy Cloud Storage security rules
( ) Emulators: Set up local emulators for Firebase features
(中略)
? Please select an option: Use an existing project ← 既存のプロジェクトを使用
? Select a default Firebase project for this directory: (Use arrow keys)
ここで先ほど作成したFirebaseのプロジェクトを選択
(中略)
? What language would you like to use to write Cloud Functions? JavaScript
? Do you want to use ESLint to catch probable bugs and enforce style? Yes
(中略)
? Do you want to install dependencies with npm now? Yes
ご利用の環境のNodeJSのバージョンに併せてfunctions/package.json
のengines
を修正します。
functions/package.json
"engines": {
"node": "10"
},
これで、Functions(エンドポイント(API))の作成準備が完了しました。
APIのメインとなるロジックを作成します。
functions/index.js
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const db = admin.firestore();
// エンドポイント関数の作成
exports.endpoint = functions
.region("asia-northeast1")
.https.onRequest(async (req, res) => {
// HTTPリクエストメソッドをPOST以外はエラーとする
if (req.method !== "POST") {
return res.status(405).json({
message: "Method Not Allowed"
});
}
// beaconIdをキーとするため、beaconIdがないとエラー
if (!req.body.beaconId) res.status(400);
// beaconIdをキーとしてFirestoreに情報を格納
await db
.collection("detectData")
.doc(req.body.beaconId)
.set(req.body);
// レスポンスを返却
return res.status(200).json(req.body);
});
functionを作成したら、Firebaseにデプロイします。
$ firebase deploy --only functions
(中略)
+ functions[endpoint(asia-northeast1)]: Successful create operation.
Function URL (endpoint): https://asia-northeast1-oruyo-realtime-sample.cloudfunctions.net/endpoint
↑このURLをWebhookURLとして使用
+ Deploy complete!
ORUYOに先ほど作成したエンドポイントをWebhookの通知先として登録します。
Webhookの通知先の基本的な登録方法はこちらをご覧ください。
通知先の追加は通知先を設定したいワークエリアの「通知先」タブを開き、「通知先設定を追加」をクリックします。
「通知方法」を「Webhook」に設定し、「Method」は「POST」を選択します。
「Webhook URL」には先ほど作成したエンドポイントを設定します。
パラメータを以下の通り追加します。
パラメータ名 | 値種別 |
---|---|
sensorId | センサーID |
beaconId | ビーコンID |
beaconName | ビーコン名 |
detectDate | 検知日時 |
入力が完了したら「テスト」を実施します。
テストが正常に完了したらFirebaseコンソールの「Database」タブからテストで送信したデータが格納されていることを確認します。
正常にテストデータが格納されていればORUYO → Cloud Fucntions for Firebase → Firestore連携は完了です。
ここからはFirestoreからデータを取得して表示するWebアプリケーションを作成します。
基本的にはこちらを参考に進めます。
設定としては以下の通りです。
$ yarn create nuxt-app app
(中略)
? Choose the package manager Yarn
? Choose UI framework Vuetify.js
? Choose custom server framework None (Recommended)
? Choose Nuxt.js modules DotEnv
? Choose linting tools ESLint, Prettier, Lint staged files, StyleLint
? Choose test framework None
? Choose rendering mode Universal (SSR)
? Choose development tools jsconfig.json (Recommended for VS Code)
firebaseに接続するためのパッケージとvuexfireをインストールします。
$ cd app
$ yarn add firebase vuexfire core-js@2
app/pluginsディレクトリの下にFirebase連携用のファイルを作成します。
app/plugins/firebase.js
import firebase from 'firebase/app'
import 'firebase/firestore'
// firebaseの初期化処理
if (!firebase.apps.length) {
firebase.initializeApp({
projectId: process.env.PROJECTID
})
// firebase.analytics()
}
export default firebase
export const db = firebase.firestore()
// コレクション'detectData'を参照するための設定
export const bindDetectDataRef = db.collection('detectData')
環境変数を設定します。
.envにFirebaseのプロジェクトIDを設定します。
app/.env
PROJECTID='{FirebaseのプロジェクトIDを設定}'
Nuxtではデータの状態の管理を行うVuexストアが利用できます。
Vuexストアについてはこちらを参照ください。
VuexfireはVuexストアにデータを格納するので、Vuexストアでの参照データの管理設定を行います。
Vuexストアはapp/storeディレクトリ配下で設定します。
app/store/index.js
import { vuexfireMutations } from 'vuexfire'
export const strict = false
export const mutations = {
...vuexfireMutations
}
app/store/firestore/detectData.js
import { firestoreAction, firestoreOptions } from 'vuexfire'
import { bindDetectDataRef } from '@/plugins/firebase'
// always wait for bindings to be resolved
firestoreOptions.wait = true
export const state = () => ({
list: []
})
export const getters = {
list: (state) => state.list
}
export const actions = {
bindList: firestoreAction(({ bindFirestoreRef }) => {
return bindFirestoreRef('list', bindDetectDataRef)
})
}
ページの設定はapp/pagesディレクトリ配下で設定します。
sensorListはORUYOコンソールのセンサー一覧画面から「SensorID」と「表示名」を取得し、リストにします。
app/pages/index.vue
<template>
<v-container fluid>
<v-data-iterator :items="detectDataTree" hide-default-footer>
<template v-slot:default="props">
<v-row>
<v-col
v-for="sensor in props.items"
:key="sensor.id"
cols="12"
lg="6"
>
<v-card min-height="20vh">
<v-card-title class="subheading font-weight-bold">
{{ sensor.name }}({{ sensor.id }})
</v-card-title>
<v-divider></v-divider>
<v-list dense>
<v-list-item
v-for="beacon in sensor.children"
:key="beacon.beaconId"
>
<v-list-item-content>
{{ beacon.beaconName }}
</v-list-item-content>
<v-list-item-content class="align-end">
検知日時:
{{ new Date(beacon.detectDate).toLocaleString() }}
</v-list-item-content>
</v-list-item>
</v-list>
</v-card>
</v-col>
</v-row>
</template>
</v-data-iterator>
</v-container>
</template>
<script>
export default {
data: () => ({
sensorList: [
{
sensorId: 'dev-0001',
sensorName: 'センサー#1'
},
{
sensorId: 'dev-0002',
sensorName: 'センサー#2'
}
]
}),
computed: {
// FireStoreのデータを取得
detectDataList() {
return this.$store.getters['firestore/detectData/list']
},
// 画面表示用に加工
detectDataTree() {
const output = []
// データをセンサーでグルーピング
this.sensorList.map((sensorObj) => {
// センサーIDが一致するものを取得
const detectDataList = this.detectDataList.filter(
(detectData) => detectData.sensorId === sensorObj.sensorId
)
// センサー毎に情報を格納
output.push({
id: sensorObj.sensorId,
name: sensorObj.sensorName,
children: detectDataList
})
})
return output
}
},
created() {
// StoreにFirestoreのデータを読込
this.$store.dispatch('firestore/detectData/bindList')
}
}
</script>
作成したアプリケーションを起動します。
appフォルダ配下で以下を実行します。
yarn dev
起動後 http://localhost:3000 にアクセスすると画面が表示されます。
これで画面を表示しっぱなしでもビーコンが検知される度に情報が更新され、ほぼリアルタイムに検知状況を表示できるようになりました。
今回はORUYOとFirebaseの連携を行いリアルタイムに検知状態を表示するアプリケーションを作成する方法をご紹介しました。
これを応用することで様々な用途に対応できるアプリケーションが作成可能です。
例として以下の様な活用事例がございます。
<備品管理システム>
センサー名に位置、管理備品にビーコンを付与することで管理備品が
どのセンサーの近くにあるかリアルタイムに管理
<在室管理システム>
誰がどの場所にいるかをリアルタイムに管理
ビーコンの活用方法についてのご相談はぜひこちらからお問合せください。
土井工芸株式会社ビジネスイノベーション事業部