color_kurenawiのアイコン画像
color_kurenawi 2021年05月05日作成 (2021年05月05日更新)
セットアップや使用方法 セットアップや使用方法 閲覧数 1364
color_kurenawi 2021年05月05日作成 (2021年05月05日更新) セットアップや使用方法 セットアップや使用方法 閲覧数 1364

obniz x LINE NotifyでCO2濃度通知システムを作ってみた

デモ動画

ここに動画が表示されます

つくった背景

新型コロナウイルス禍の近頃,空間の密閉対策として換気の重要性が叫ばれています.換気を行う目安としては,CO2濃度計が使われることが多いと思います.しかし,精度が高く,多機能なCO2濃度計は一般的に高価であり,一般家庭で使うにはハードルが高いものになっています.

そこで,精度を少し犠牲にすることで,安価にも関わらず通知機能を持ったCO2濃度計を作ってみることにしました.

部品と費用

品目 数量 価格(円)
obniz Board 1Y 1 6,930
CCS811 1 526
合計 - 7,456

設計図

以下の通りに接続する

品目 接続
obniz Board 1Y 2:SCL, 3:SDA
CCS811 VCC:3.3V, GND:GND, SCL:SCL, SDA:SDA, WAK:GND

完成図

ソースコード

Node.jsで書いています.また,通知にはLINE Notifyを利用しています.

app.js

const fs = require("fs"), request = require("request"), Obniz = require("obniz"), { createCanvas } = require("canvas"); // LINE APIのトークンはLINE_API_TOKEN.txtに記載しておく const LINE_NOTIFY_URL = "https://notify-api.line.me/api/notify"; let LINE_API_TOKEN = fs.readFileSync("LINE_API_TOKEN.txt", "utf-8"); console.log("LINE API token :", LINE_API_TOKEN); // 通知するCO2の閾値を設定 const CO2_THOREHOLD = 1200; const MESSAGE = "CO2濃度が閾値を超えました.換気をしましょう."; // 通知の最小間隔を秒で指定 const NOTIFY_INTERVAL = 300; let last_notify_time = 0; const HEADERS = { "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Bearer " + LINE_API_TOKEN }; const OPTIONS = { url: LINE_NOTIFY_URL, method: "POST", headers: HEADERS, json: true, form: { message: MESSAGE } } let obniz = new Obniz("OBNIZ_ID_HERE"); obniz.onconnect = async function () { obniz.display.clear(); const canvas = createCanvas(128, 64); const ctx = canvas.getContext('2d'); ctx.fillStyle = "white"; ctx.font = "15px Avenir"; ctx.fillText('hello world!', 0, 26); obniz.display.draw(ctx); let sensor = obniz.wired("CCS811", {scl:2, sda:3, address:0x5a}); await sensor.configWait(); obniz.repeat(async()=>{ if (await sensor.checkAvailableDataWait()) { var data = await sensor.readAlgorithmResultsWait(); console.log(data); obniz.display.clear(); ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillText("eCO2 " + data.eCO2 + " ppm", 0, 26); ctx.fillText("TVOC " + data.TVOC + " ppb", 0, 52); obniz.display.draw(ctx); if(data.eCO2 < CO2_THOREHOLD){ return; } if(calElaspedTime(last_notify_time) > NOTIFY_INTERVAL){ request(OPTIONS, async(error, response, body) => { console.log(body); last_notify_time = (new Date()).getTime(); if(error){ console.log(error); } }); } } }) } function calElaspedTime(last_notify_time){ let now = (new Date()).getTime(); elapsed_time = (now - last_notify_time)/1000; return elapsed_time; }

参考にした記事

ログインしてコメントを投稿する