編集履歴一覧に戻る
inoue2002のアイコン画像

inoue2002 が 2021年05月16日15時00分23秒 に編集

初版

タイトルの変更

+

距離センサー×Notion×LINEを利用した我が家の冷蔵庫監視システム

タグの変更

+

obnizBoard1Y

+

LINE

+

Notion

+

距離センサー

+

HC-SR04

メイン画像の変更

メイン画像が設定されました

本文の変更

+

# 背景 僕はつい意味もなく冷蔵庫を開けてしまう癖があります😓ものの数十分で冷蔵庫の中に新しいものが湧くわけでもないのに。でもなんだか開けてしまうんですよね(笑) でも、ちまちま不必要に冷蔵庫を開けてしまうと、電気代のことや環境のことなどを考えると良くありません。また、5人家族の我が家では1日にどれぐらい冷蔵庫が開け閉めされ、また開いている時間は合計でどれぐらいになるのか興味を持ちました。 冷蔵庫の開け閉めの回数と開いている時間が可視化できれば、僕の冷蔵庫を不必要に開けてしまう癖も少しはおさまるかもしれないと思って開発することにしました。 電子工作も全然やったことないし、今回提供してくださったobnizとたまたま家に転がっていた距離センサーをくっつけてみたら意外とうまく値が取得できたのでこれの組み合わせを使うことにしました。(ちなみにブレットボードを今回の作品で初めて触りました。) 作っているうちに自分の得意分野で拡張していったら、最終的にはLINEBotが完成し、冷蔵庫の情報と一緒に我が家に不足しているものを登録できる機能も開発しました。詳細については後術します。 # このプロダクトのポイント ・2021/5/13についにパブリックベータ版になったnotionAPIをフル活用している ・距離センサーを用いており、冷蔵庫だけでなく汎用性が高い ・フロントエンド・サーバーサイド・電子工作に触れることができる ・冷蔵庫の開き時間が少なくなる # システム構成図 ![構成図](https://camo.elchika.com/8107ea668d12712c2f54a5e2f6071a2ad23fd1dd/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f62613339333662652d333566612d343562372d623638332d6537393063616562613333342f37373866613633392d363061332d343831342d393436652d336364393435343537323865/) # センサー ![センサー](https://camo.elchika.com/c36a94bc40fa2a77d337dfb6ce36d970b2087c3c/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f62613339333662652d333566612d343562372d623638332d6537393063616562613333342f39326439386232652d626432632d346639642d396431392d363066373735383538313138/) # DEMO # 部品 | 品名 | 用途 | 価格 | |:---:|:---| :--- | | [obniz Board 1Y](https://obniz.io/ja/products#deviceComparison) | メインコンピュータ | 6930 | | [ブレッドボードx2 ](https://akizukidenshi.com/catalog/g/gP-05294/) | センサーの回路 | 200x2 | | [ジャンプワイヤ](https://www.amazon.co.jp/dp/B06Y48V9DL/ref=cm_sw_em_r_mt_dp_VYC77WFJTDEBWVA2X47F?_encoding=UTF8&psc=1) | センサーの回路 |990 | | モバイルバッテリー(給電できる場合はいらない) | センサーの回路 | 3000弱 | # ソースコード obniz自体を動かしているnodejsのソースコードは以下です。 ```obniz:index.js "use strict"; require("dotenv").config(); const Obniz = require("obniz"); const axios = require("axios"); const obniz = new Obniz(process.env.OBNIZ_ID); obniz.onconnect = async () => { const hcsr04 = obniz.wired("HC-SR04", { gnd: 0, echo: 1, trigger: 2, vcc: 3, }); let isOpen = false; let startTime; let totalTime; while (true) { let avg = 0; let count = 0; for (let i = 0; i < 3; i++) { // measure three time. and calculate average const val = await hcsr04.measureWait(); if (val) { count++; avg += val; } } if (count > 1) { avg /= count; } console.log(avg, isOpen); if (avg > 100 && isOpen === false) { isOpen = true; startTime = new Date().getTime(); console.log("冷蔵庫があきました!"); } if (avg < 100 && isOpen === true) { //しまった時 isOpen = false; console.log(new Date().getTime()); console.log(startTime); totalTime = new Date().getTime() - startTime; totalTime = totalTime / 1000; const hour = Math.floor(totalTime / 3600); const hour_wari = Math.floor(totalTime % 3600); const min = Math.floor(hour_wari / 60); const min_wari = Math.floor(hour_wari % 60); const sec = min_wari; console.log(`${hour}時間${min}分${sec}秒開いていた`); //totalTimeをAPIに送る axios.post(process.env.API_URL + "/register", { totalTime: Math.floor(totalTime), }); } await obniz.wait(100); } }; ``` [ソースコードの参考にした記事](https://protoout.studio/posts/obniz-nodejs-hcsr04) ハード以外のAPIやLINEBotのソースコードなどはこちらの[リポジトリ](https://github.com/inoue2002/refrigeratormonitoring-obniz)に公開されています # 開発過程 ・NotionAPIの学習 ・ハード開発 ・API開発 ・LINEBot開発 ・設置・検証 ・サーバーに移行し永続化 の順に工夫したポイント・難しいところをまとめていきます ### NotionAPIの学習 NotionAPIは3日ほど前に出たばかりで、全くと言っていいほど知見も記事もありませんでした。ただひたすらに公式の英語ドキュメントを読んで理解しました。最低限の書き出しや特殊な概念(Notion特有の概念)を理解してAPIで操作し、現時点でできることできないことを把握するのに結構時間を取られました。 APIの習得する過程は[こちら](https://scrapbox.io/inouenote/notionAPI%E3%82%92%E3%81%84%E3%81%98%E3%81%84%E3%81%98)の記事にてまとめてあります。 ここではこのプロダクトに利用できた知見のみ共有します。 まず、NotionAPIはJavaScriptのSDKが公開されています。[こちら](https://github.com/makenotion/notion-sdk-js)を使うことで簡単にAPIを利用することができます。 今回使ったAPIはDBから値を取得するものと値を更新するものです。とりあえずこれが使えたらDBとして使うことができるので何かものが作れるかと思います。 nodejsでnpmモジュールを用いてSDKを利用するには以下のように呼び出します ```api:index.js const { Client } = require("@notionhq/client"); // Initializing a client const notion = new Client({ auth: process.env.NOTION_TOKEN, }); ``` データを取得したい場合は以下のようにリクエストを送ります。今回はクエリのAPIを利用していますが、全項目(回数と時間)を取得しているのでクエリ式を入れておりません。 ```api:index.js //今のセンサーのあたいを取得しにいく const request_payload = { path: "databases/" + "データベースのID(databaseId)" + "/query", method: "POST", }; const current_pages = await notion.request(request_payload); console.log(current_pages.results) ``` データを書き込みたい時は以下のようにリクエストを送ります。 ```api/:index.js const = todayCount = { id : "データベースの項目のID(pageId)", count : 2 //更新したい値を入力する } const request_payload = { path: "pages/" + todayCount.id, method: "patch", body: { parent: { database_id: "データベースのID(databaseId)", }, properties: { 冷蔵庫: { title: { text: { content: "本日開いた回数", }, }, ], }, count: { number: todayCount.count, }, id: { rich_text: [ { text: { content: todayCount.id, }, }, ], }, }, }, }; await notion.request(request_payload); ``` このような記述で値の更新を行います。NotionAPIは他にもアクセスしているユーザーの情報を取得したり、項目の新規追加(更新では無い)のようなことも、クエリやソートも柔軟にできるようです。しっかり使いこなすことでもっといろいろな機能を実装することができます。ただ、まだ対応していないブロックなどもあり、パブリックベータ(記事執筆時点)であることを忘れずに使う必要があると感じました。 ### ハードウェアの開発 初めてobnizに電源を入れ、距離センサーなどを繋いだ時のまとめは[こちら](https://scrapbox.io/inouenote/obniz%E3%80%80%E9%9B%BB%E5%AD%90%E5%B7%A5%E4%BD%9C%E5%85%A5%E9%96%80)に書かれています。こちらを参考にし、上記で書いたobnizと距離センサーを接続し、電源を入れインターネットに繋ぐセットアップを行いました。初めはソースコードの開発のところに記したサンプルコードを起動すると簡単に動いたので、特に開発面で難しいことはないと思います。 ①obnizとジャンプワイヤーとブレッドボードと距離センサーを準備 ②公式ドキュメントを参考につなげる ![キャプションを入力できます](https://camo.elchika.com/fcadc938b86918d24469508f888ff3f78becb6e8/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f62613339333662652d333566612d343562372d623638332d6537393063616562613333342f61646133616536302d653536632d346131302d386165352d303837663237626333623763/) ③ソースコードを起動 ④動いた <blockquote class="twitter-tweet"><p lang="ja" dir="ltr">一瞬で距離取得に成功した<br>これはおもろいwwwwww <a href="https://t.co/IEcMJ6JIa2">pic.twitter.com/IEcMJ6JIa2</a></p>&mdash; ようかん / Yosuke Inoue (@inoue2002) <a href="https://twitter.com/inoue2002/status/1387318838027382790?ref_src=twsrc%5Etfw">April 28, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> # 最後に とっても楽しかった! [構成図のツイート](https://twitter.com/inoue2002/status/1393480311313371138?s=20)への反応が多くて嬉しかった! 結構時間なくて締め切り前日に徹夜ハッカソンして開発したのはいい思い出です!