🍿

快適な作業環境を評価するIoTシステムを構築してラズパイで組んだKubernetesクラスタに載せる(総論)

2024/02/25に公開

概要

リモートなどで自宅で作業していると頻繁に温度調節をしていて、作業環境を一定に保つのが結構大変なので自動化したいと思い、温度などを監視して快適度を評価するIoTシステムを構築しました。ここでは構成や快適度の計算などの全体の話をメインとして、バックエンドやフロントエンドの技術的な詳細などは別の記事にまとめていきます。

開発背景

室内環境の快適度を一定に保つのは結構難しいです。まず人間が体温を持っている時点で何もしなければ少しづつ部屋の温度は上昇していくため快適性は破れます。
エアコンなどを導入するとなるべく一定の温度にしてくれますが遮蔽物があると循環が十分に機能せず、温度ムラが発生します。作業机付近の快適度を中心にして適切に周辺のものを制御するのがあるべき姿としてこの問題を捉えます。
まず、最適化には何をしたら良いのかというのを考えるために、暑いな~と感じたときどのような行動選択をするかを考えてみましょう。
暑いときの行動分岐

最初に窓を開けるかどうかというところがあります。これは外の温度状態を知らなければ選択できないですね。次に、冷房か除湿かというところですがいつも気分によって選択しがちなので湿度によって適切に評価したほうが良いと思います。
いきなり制御まで手をつけるのは大変なので、今回はまず、自分が不快だと思う状況を定量的に知ることを最初の目標として考えます。不快である状態を知らなければ、適切にフィードバックを行うことができませんからね。

構成

常にモニタリングするシステムを作るために構成は下記のように取りました。おおまかにセンサ周り、バックエンドとフロントエンドの3セクションあります。ここでは概略を述べるに留めて、それぞれの技術的な詳細は別の記事にまとめていきたいと思います。
構成

1.センサ周り

温度センサはBosch製のBME280です。秋月にあったのでこれにしました。温度と(相対)湿度と大気圧まで測れるのでとても便利ですね。最終的にこの3つの指標を使って快適度を計算するのですが、CO2濃度とかそこらへんもあると評価の仕方もごちゃっとしてきてより面白いなという気がしています。
温度を測るコードは基本的に資料を見て行いましたが、備忘録のため別の記事にまとめていきます。

2.バックエンド周り(AWS)

バックエンドはほとんどAWSを使用しました。データベースはローカルにおいても良いと思いますが、AWS IoT Coreを使ってみたかったので、合わせてDynamoDBを使って完結させました。IoT CoreからDynamoDBにデータを流すようにして、API Gatewayでフロントエンドからのリクエストを受け付けます。これも別の記事に詳細をまとめていきたいと思います。

3.フロントエンド周り

フロントエンド周りはタイトルにもあるようにラズパイ3台をKubernetesクラスタを組んでいるので、そこにnginxを積んでビルドしたReactアプリを載っけました。
自宅のネットワークからしかアクセスしないのと、せっかくKubernetsクラスタを飼っているのでここになにか実用的なpodを載っけて運用してみたかったのでちょうど良いですね。将来的には耐障害試験とかもしてみたいと考えてます。
実際のUI
上から快適度、温度、大気圧、湿度を過去24hで表示しています。実際は計測開始から15分刻みで記録し続けているのでクエリを変えれば他の時間帯も見ることができます。快適度は100点満点で現在どの程度快適に感じるかということを自分自身の感覚と合わせこんでキャリブレーションしてそこそこ正確な値がでています。
この快適度という指標をどのように計算するかということが今回のメインです。

(参考) 実際の写真

ラズパイと実際のUIの写真フロントエンド側のラズパイのKubernetesクラスタと温度センサの実際の写真は下図になります。

ラックなどはAmazonで購入して、k8sノードは少し性能が欲しかったので新しいラズパイ4を3台買ってやってみました。温度を測っているラズパイは元々別の用途で使ってたものなので消費電力と取り回しの観点からpicoやarduinoなどに代用したいなと思ってます。

快適度をどう測るか(本題)

さて、ここからがようやく本題です。上図の快適度をどう計算して評価するか?というのがこのシステムの1番の問題です。例えば、温度が20℃から23℃に上がるのと、27℃から30℃に上がるとき、暑いと感じる量は同じかどうか?ということを考えなければなりません。これは私の感覚では同じではないように思います。
これには先人の知恵としてウェーブハフナーの法則というのが知られています。
https://ja.wikipedia.org/wiki/ヴェーバー‐フェヒナーの法則
これは、人間の感覚は対数スケールに従うというもので、例えば、デシベルという音の単位は人間が2倍音が大きくなったと感じるには音圧pを10倍にしなければならないというものです。

しかし、温度や湿度に対してこれだけでは少し大雑把な気がするのでこの知見を参考に評価値の計算式を私なりに考案してみることにします。

理想値と許容範囲を設定する

日々、不快だったり快適だなとタイミングでこの温度と湿度と大気圧を確認するようにして自分の理想的な状態や許容範囲を定量的に把握することにしました。
これによって主に下記のような値を得ました。ここで、温度T、湿度M、大気圧Pとして許容値をdとしています。

T_{ideal} = 25 \mathrm{\, °C}, d_T = \pm3 \mathrm{\, °C} \\ M_{ideal} = 50 \mathrm{\,\%}, d_M = \pm10 \mathrm{\,\%} \\ P_{ideal} = 1013 \mathrm{\,hPa}, d_P = -10 \mathrm{\,hPa} \\

実際に見てみると不快だなと思うタイミングの温度はだいぶわかりやすくて私の場合は28℃くらいが上限でした。湿度は40-60%くらいに保てばになるとウイルスを抑えられるらしい記事があったのと、大気圧は一度、頭が痛くなった時があって1000hPaくらいだったのでその時を参考に許容値を設定してみました。
https://www.condair.jp/humidity-for/humidity-at-40-60rh-reduces-airborne-viruses

評価値を計算する

上記の理想状態と、許容値を使って評価インデックスIを測定量Sを使用して下記のように考案してみました。

I_S = \Bigg(\frac{|S-S_{ideal}|}{|d_S|}\Bigg)^{\alpha_S}

括弧の中について先に説明します。まず、分子では観測値と理想状態の差分の絶対値を取っています。それを許容値dで割ると、1以内は許容値内、1以上は許容値外となり値を正規化できます。
正規化

これに加え、指数を導入することで感覚の非線形性を表現します。括弧の中身が1を超過する、つまり許容値を超えた場合は急激に値が大きくなり、逆に1を以内、つまり許容値内の場合は緩やかな上昇具合になります。
指数\alphaが1を超過した場合は下に凸のグラフになる一方で、1より小さいといきなり1に近づきます。この\alphaに関しては温度、大気圧、湿度で微調整することで各インデックスの上昇具合を制御できます。

指数の特性

つまり、それぞれのインデックスを示すと下記のようになります。

I_T = \Bigg(\frac{|T-T_{ideal}|}{|d_T|}\Bigg)^{\alpha_T} \\ I_M = \Bigg(\frac{|M-M_{ideal}|}{|d_M|}\Bigg)^{\alpha_M} \\ I_P = \Bigg(\frac{|P-P_{ideal}|}{|d_P|}\Bigg)^{\alpha_P} \\

理想温度や許容値、指数を微調整してあげることで個人差を表現できます。これらをシステムが推定することも将来的には必要になりそうですね。
いずれせよ、上記の3つのIは0~1なら許容内、1を超えたら許容値外であるという状態は変わりません。そのため、総合値としてI'を下記のように定義します。

I' = I_T + I_M + I_P

このI'は0に近いほど快適で、3を超えるとどれかのインデックスが必ず1を超えていて作業環境として許容できない状態であることが予想されます。なのでわかりやすく、I"=0→3となるのをI=100→0と変換をして完成です。

I = -\frac{100}{3}I' + 100

上記を踏まえて改めて確認すると、わりかしいい感じの数字がでます。観察している感じだと60点を下回ると少し不快だなと感じるくらいで結構正確にできました。

今後は、この快適度を中心にエアコンや窓を開けさせたりフィードバックした制御を行えるようにしていければと考えています。ここまでお付き合いいただきありがとうございました!

Discussion