Miyp が 2021年05月13日16時03分14秒 に編集
コメント無し
本文の変更
+ Obniz IoTコンテスト2021
## やりたいこと コロナで自宅にいる時間が増えているので自宅のスマートホーム化を計画しました。 いきなり難しいことはできないため、まずはそれぞれの部屋の温度・湿度を取得して履歴の取得と 携帯からそれぞれの部屋の状態を確認できるシステムを構築しました。 ## デモ画面 @[Youtube](https://youtu.be/Hzoxv2gYD9w) ## システム構成 ![キャプションを入力できます](https://camo.elchika.com/30b1bf0e6969eb7747586420a640db031953c0da/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f62333035636636342d663637382d343862632d613034662d6637356432323565633864372f33313630653834342d313664612d346631652d626463312d666132376561333933383732/)
## ハードウェア 今回は買い物だけではんだ付けは不要です。 |No|名称|機能|入手先| |:--|:--|:--|:--|
|1|obniz|BLE通信を使いGoveeから温湿度情報を取得し、Ambientにデータを出力します|[Amazon](https://www.amazon.co.jp/dp/B07DD6FK8G/)やSWITCHSCIENSなど|
|1|obniz|BLE通信を使いGoveeから温湿度情報を取得、Ambientにデータを出力します|[Amazon](https://www.amazon.co.jp/dp/B07DD6FK8G/)やSWITCHSCIENSなど|
|2|Govee|BLE温湿度計|[Amazon](https://www.amazon.co.jp/dp/B083348J3X/)など|
|3|Raspberrypi4|ダッシュボード表示用のWebサーバ|[Amazon]()など|
No.3のRaspberrypiはHtml+Javascriptファイルを公開するためのWebサーバです。 obnizIDを書いたファイルを公開したくなかったので自宅内にWebサーバを立てましたが、上手く管理する方法があればCloud上にあるサービスを使って公開するのもよいかと思います。
## ソフトウェア
## ①履歴取得 obnizのサーバレス機能を使い、10分間隔で温湿度の取得。取得したデータをAmbientへ書き込みを行います
### 事前準備:Ambientのユーザ登録とチャンネル登録 [Ambient](https://ambidata.io/)はIoTデータの可視化サービスです。8チャンネルまでなら無料で使用できるため、個人のIoT用途にぴったりです。 ユーザ登録をして、今回のプロダクト用にチャンネルの作成をしてください。
```html :サーバレスイベント
### ①履歴取得 obnizのサーバレス機能を使い10分間隔で温湿度の取得します。取得したデータをAmbientへ書き込みを行います。プログラムはAmbientから提供されているJavascriptライブラリ「[Ambient-lib](https://ambidata.io/refs/js/)」を利用してデータの書込みます。 JavascriptプログラムもAmbientの[サンプル](https://ambidata.io/samples/devices/obniz2/)とほぼ一緒です。下記プログラムをobniz開発者コンソールのリポジトリに登録し、サーバレスイベントとして実行させています。 サーバレスイベントの制限が「各イベントの実行は1日に150回まで」となっているので、イベントのトリガーは10分間隔(144回/日)としています。 各自の環境に合わせてプログラム定数を書き換えてください。 ```js:各自の環境に応じて書き換える部分 const ambientID = Your Channel key;//Ambientのユーザチャネルキー const ambientRKey = "Your Read Key";//Ambient読込用のキー const ambientWKey = "Your Write Key";//Ambient書込用のキー const obnizID = "Your obniz ID";//ObnizのID ``` Goveeの温湿度計は温度・湿度情報をBLE通信のAdvertised Dataとして送信します。 仕様は[ここ]()で解説されていますが、 ```js:アドバタイズドデータから温度・湿度を計算する部分 const buf = peripheral.adv_data[26] * Math.pow(16, 4) + peripheral.adv_data[27] * Math.pow(16, 2) + peripheral.adv_data[28] let temperature = Math.floor(buf / 1000) / 10; let humidity = (buf % 1000) / 10; let power=peripheral.adv_data[29]; ``` ```html:プログラム全体(サーバレスイベント)
<html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" /> <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script> <script src="https://unpkg.com/obniz@3.x/obniz.js" crossorigin="anonymous" ></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/qs/6.10.1/qs.min.js" integrity="sha512-aTKlYRb1QfU1jlF3k+aS4AqTpnTXci4R79mkdie/bp6Xm51O5O3ESAYhvg6zoicj/PD6VYY0XrYwsWLcvGiKZQ==" crossorigin="anonymous"></script> <script src="https://unpkg.com/ambient-lib@1.0.3/lib/ambient-lib.js"></script> </head> <body> <script> // インストールされたデバイス情報に書き換わる
const ambientID=Your Channel key; //
const ambientID=Your Channel key;
const ambientRKey="Your Read Key"; const ambientWKey="Your Write Key";
//const gvhName= "GVH5075_XXXX";
const obnizID="Your obniz ID" var obniz = new Obniz(obnizID); obniz.onconnect = async function () { await obniz.ble.initWait(); var target = {
//localName:gvhName,
localNamePrefix:"GVH5075" }; var setting = { duration: 60, // 60 sec } obniz.ble.scan.onfind = async function (peripheral) { let name=peripheral.localName; console.log("Name:"+name); const buf = peripheral.adv_data[26] * Math.pow(16, 4) + peripheral.adv_data[27] * Math.pow(16, 2) + peripheral.adv_data[28] let temperature = Math.floor(buf / 1000) / 10; let humidity = (buf % 1000) / 10; let power=peripheral.adv_data[29]; //console.log(buf); //console.log("RSSI:"+peripheral.rssi); console.log("Temp:"+temperature); console.log("Humi:"+humidity); console.log("Power:"+power); am = new Ambient(ambientID,ambientWKey); am.send({d1: temperature, d2: humidity,d3:power}, function(response) { console.log(response.status); }); if (Obniz.App.isCloudRunning()) { Obniz.App.done({ status: 'success', text: `Worked` }) } else { alert("Done.") } }; obniz.ble.scan.onfinish = async function (peripherals, error) { //console.log("scan again") await obniz.ble.scan.startWait(target, setting); }; await obniz.ble.scan.startWait(target, setting); }; obniz.onclose = async function() { }; </script> </body> </html> ```
obnizでサーバレスイベントを設定した手順は以下になります。 - 開発者コンソールにアクセス - リポジトリをクリック - 新規作成でタイプをBlockProgram、ファイル名入力し作成ボタンをクリック - プログラムを作成 して保存
## ②ダッシュボード
### ②ダッシュボード
30秒間隔で温湿度計のデータを取得。取得したデータをダッシュボードに表示しています。
温湿度計は複数個に対応しています。obnizの制限で最大4台まで対応します。
温湿度計は複数個に対応しています。
開発環境にはビジュアルプログラミングツールNoodlを使い、SPAのダッシュボードを作成します。
Noodlプロジェクトを[Github]()にアップしていますので、Noodl2.2.4以上で読込んで使用してください。
### NoodlでUI・アプリの作成 4つのコンポーネントを作成しました。
|No|名称|機能| |:--|:--|:--| |1|obniz|BLE通信を使いGoveeから温湿度情報を取得、Ambientにデータを出力します| |2|Govee|BLE温湿度計| |3|Raspberrypi4|ダッシュボード表示用のWebサーバ| |4|XXXX|XXXXXXXXXXXXXXX| Javascriptノード内のプログラムは下記となります。
```js:Javascriptノードの中身 Node.Inputs = { ObnizID: 'string', } Node.Outputs = { temperature: "number", humidity: "number", power:"number", rssi: "number", name: "string", } Node.Signals.ScriptLoaded = function () { var obniz = new Obniz(Node.Inputs.ObnizID); obniz.onconnect = async function () { await obniz.ble.initWait(); var target = {
//localName: "GVH5075_BAFD",
//localName: "GVH5075_XXXX",
localNamePrefix:"GVH5075" }; obniz.ble.scan.onfind = async function (peripheral) { Node.Outputs.name=peripheral.localName; console.log("Name:"+peripheral.localName); const buf = peripheral.adv_data[26] * Math.pow(16, 4) + peripheral.adv_data[27] * Math.pow(16, 2) + peripheral.adv_data[28] Node.Outputs.temperature = Math.floor(buf / 1000) / 10; Node.Outputs.humidity = (buf % 1000) / 10; Node.Outputs.power=peripheral.adv_data[29]; Node.Outputs.rssi=peripheral.rssi; //console.log(buf); //console.log(temperature); //console.log(pressure); //console.log("RSSI:"+peripheral.rssi); }; obniz.ble.scan.onfinish = async function (peripherals, error) { console.log("scan again") await obniz.ble.scan.startWait(target); }; await obniz.ble.scan.startWait(target); }; }
```
## 動作確認 準備ができたので動作確認をしてみました。
実際に設定した手順は以下になります。
**注 ①②はともに同じobnizに接続しに行くため同時には利用できません。** **そのため②のダッシュボードを表示している間は10分間隔で起動する①の履歴送信ができなくなります。**
開発者コンソールにアクセス リポジトリをクリック 新規作成でタイプをBlockProgram、ファイル名入力し作成ボタンをクリック プログラムを作成 して保存 ほぼサンプルプログラムと同じですが、以下のプログラムを作成しました。 ## 動作確認 準備ができたので、動作確認をしてみました。 機能②で紹介したzabbixのアクションにて、軽度以上の障害が発生した際に、以下のようにcurlコマンドでwebhookのURLにアクセスするように設定しました。
## まとめ
また、時間ができたらリベンジしてみます。 obnizとJavaScriptの経験が浅いので、間違っている実装もあると思いますがその点はご了承ください。
これで各部屋の温湿度を取得できるようになりました。今回はBLE通信を使ったので半田付けも不要でお手軽にIoTを始められる方法だと思います。 今後はこのデータを使ってLINEへの通知や空いているobnizのIOポートを使った出力を行い、スマートホーム化をさらに進めていきたいです。
## 参考資料 - [bluetooth 温度・湿度計を読んでインターフェイスする。](https://qiita.com/hiratarich/items/3f7991d4164e5f0ecc62)
-[Obnizでセンサデータを取得しAmbientに送る](https://ambidata.io/samples/devices/obniz2/)
- [Obnizでセンサデータを取得しAmbientに送る](https://ambidata.io/samples/devices/obniz2/)