良い睡眠を取るために
みなさん、良い睡眠は取れていますか? ?
私は 1 日に夜 8 時間睡眠+日中仮眠を数回取らないと夕方にはクタクタになってしまいます。
毎日 8 時間睡眠を取るのはなかなか難しいので、睡眠の質を上げていきたいわけです。
その一環として、前回の記事(よく風邪を引くのでちょうどいい布団を教えてくれるLINE BOT作った)でちらっと紹介しましたが、今回は寝床内気象にフォーカスを当てたいと思います。
寝床内気象とは?
寝床内気象でググるといろんなサイトがヒットします。
寝床内気象とは、快適な眠りに関わる条件のうち、布団内の温度・湿度のことを指すようです。
(「寝室環境・寝床内の研究 ぐっすり眠るために最適な温度や湿度は?」より引用)
日本睡眠化学研究所さんの研究によると、
理想的な寝床内温度・湿度を明らかにするために数々の実験を重ね、その結果、「温度33±1℃」「湿度50±5%RH」という数値を導きだしました。
とのこと。
つまり、良い睡眠を得るためには、布団の温度を湿度が適切な値になっている必要があるようです。
手元に Obniz と温度センサーがあったので、早速温度を測る準備を始めましょう(湿度はまた今度)
ところで寝床内気象って何て読むんでしょうか…ねどこないきしょう? しんしょうないきしょう?
アプリイメージ
システムイメージ
- マイコンの知識がないので、お手軽に使える Obniz を使用。
- Lambda を使って、Obniz からの温度取得と DynamoDB への保存を行う。
- 上記処理を Cron 実行させるため、CloudWatchEvents を使用
回路イメージ
今回は Obniz でお手軽に実装するため、ObnizのJSパーツライブラリで対象となっている温度センサーを使用していきます。
Obniz
Obniz とは、
obniz(オブナイズ)は、ON/OFFやUART通信などのIO制御をクラウドのAPI経由で行える仕組みです。センサーやアクチュエーター、既存機器をネットワーク経由で直接操作でき、クラウド中心のIoT開発が可能です。
とのこと。青色のかわいいやつです。
公式サイト→ https://obniz.io/ja/
使用した素子
- 温度センサー:LM35DZ (http://akizukidenshi.com/catalog/g/gI-00116/)
- gnd: io0, output: io1, vcc: io2 に接続します。
- 青色 LED(デバッグ用) (http://akizukidenshi.com/catalog/g/gI-06247/)
- anode: io3, cathode: io4 に接続します。
処理の流れ
Lambda関数
大まかな処理の流れは、
(1)Obniz から温度取得
(2)DynamoDB への保存
です。
ソースをピックアップして説明します。
- Obniz に接続、LM35DZ から温度を取得する。
Obniz JSパーツライブラリのドキュメントがとても分かりやすいので、こちらを一読するのをオススメします。
const Obniz = require('obniz');
const obniz = new Obniz(process.env.OBNIZ_ID);
const getTemperature = async () => {
await obniz.connectWait(); // 接続を試し、接続するまで待つ
const tempsens = obniz.wired("LM35DZ", { gnd:0 , output:1, vcc:2});
return await tempsens.getWait(); // センサーの温度を取得
}
getTemperature().then((temperature) => {
console.log(`${temperature}度`);
})
- 取得した値を DynamoDB に保存する。
DynamoDB の操作には、DocumentClient(公式ドキュメント)を使います。
const AWS = require('aws-sdk');
const documentClient = new AWS.DynamoDB.DocumentClient();
const uuidv4 = require('uuid/v4');
const dayjs = require('dayjs');
documentClient.put({ // putメソッドでDynamoDBにアイテムを作成
TableName: 'BedSensorTable',
Item: {
dataId: uuidv4(), // パーティションキー。UUIDを入れる。
created: dayjs().unix(), // ソートキー。現時刻のUNIX時間を入れる。
temperature: temperatureValue // 上記で取得した温度を入れる。
}
}).promise();
CloudWatchEvents
上記で作成した Lambda 関数を 5 分に 1 回実行するようにルールを設定する。
AWSコンソール > CloudWatch > ルール > ルールの作成
から適当にルールを作る。
これで完成!
早速設置し、寝てみる
ベッドに設置してみた。
うん。なかなかシュールだ。
シーツをかけると見た目は普通のベッドになりました。
実際に寝てみる。ベッドが柔らかいおかげか、意外と気にならなかった。
布団に入ると内部の温度が上昇し、40±2℃くらいで推移しているようです。
体感ではちょうど良い温度だったのですが、33℃前後って少し寒いのでは…?
改善したいこと
- 意外と気にならないとは言っても、無意識にセンサーを避けて寝ていた。また、寝ていて Obniz の熱を感じる。
Obniz の熱+温度センサーが近い=温度が高めに取得されている?
どちらにせよ壊れるのはいやなので、Obniz とセンサーの間にケーブルを入れて、Obniz はベッドの外に出したほうがよさそう。 - Obniz 直挿しだと素子がすぐ抜けてしまう。ちゃんとやるならはんだ付けなどをしないと。
- 温度の見える化。時間の関係で、見える化にまでは至らなかった。LINE LIFFの v2 が公開されたらしいので使ってみたい。
- 記事書きました。(2019/11/28 更新)
- →https://qiita.com/tmisuo0423/items/1044e4ee96e6868ae17e
詰まったところ
Obniz接続時のエラー(Error: ad 1 is not valid io)
Obniz を使って温度センサーの値を取得しようとすると以下のようなエラーが出てきた。
const Obniz = require('obniz');
const obniz = new Obniz(process.env.OBNIZ_ID);
const tempsens = this.obniz.wired("LM35DZ", { gnd:0 , output:1, vcc:2});
const result = await tempsens.getWait();
console.log(result);
{
"errorType": "Error",
"errorMessage": "ad 1 is not valid io",
"trace": [
"Error: ad 1 is not valid io",
" at Obniz.getAD (/var/task/node_modules/obniz/obniz/ObnizComponents.js:200:13)",
" at LM35DZ.wired (/var/task/node_modules/obniz/parts/TemperatureSensor/analog/AnalogTemperatureSensor.js:11:21)",
" at Obniz.wired (/var/task/node_modules/obniz/obniz/ObnizParts.js:54:17)",
" at Runtime.exports.handler (/var/task/index.js:5:26)",
" at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)",
" at process._tickCallback (internal/process/next_tick.js:68:7)"
]
}
ドキュメントをちゃんと見ると、onconnect のコールバックとして温度取得の処理を入れないといけないらしい。
const Obniz = require('obniz');
const obniz = new Obniz(process.env.OBNIZ_ID);
obniz.onconnect = async function() { // 追加
const tempsens = this.obniz.wired("LM35DZ", { gnd:0 , output:1, vcc:2});
const result = await tempsens.getWait();
console.log(result);
}
なんか書きにくいなぁと思いながらドキュメントを眺めていると、connectWait関数
なる関数を発見。
const Obniz = require('obniz');
const obniz = new Obniz(process.env.OBNIZ_ID);
obniz.connectWait().then(async () => { // connectWaitに変更
const tempsens = obniz.wired("LM35DZ", { gnd:0 , output:1, vcc:2});
const result = await tempsens.getWait();
console.log(result);
});
最終的に、温度を 1 回分取得する関数として以下のように落ち着いた。
const Obniz = require('obniz');
const obniz = new Obniz(process.env.OBNIZ_ID);
// きれいになった
const getTemperature = async () => {
await obniz.connectWait();
const tempsens = obniz.wired("LM35DZ", { gnd:0 , output:1, vcc:2});
return await tempsens.getWait();
}
// 使うときはこんな感じ。async/awaitで書いてもよい。
getTemperature().then((temp) => {
console.log(temp);
})