コロナ禍をきっかけにほぼ100%在宅勤務となりました。 困ったのは仕事部屋のエアコンが20年ほど昔のもので、 性能がいまいちな上に制御がスカタンで著しく快適性に乏しいです。 例えば暖房で適温に設定するとそのうち暑く感じるようになり、 下げると寒くなる、また上げると暑くなるといった感じで 常にエアコンを操作することになりかなりのストレスでした。 スマートリモコンsRemoを導入することによって解決したので忘れないように記録に残しておきます。
<追記>
後にnature remoに買い替えました。
問題の根本的な原因は、エアコンの室温センサーがどうにもいまいちな場所にあることです。 ほとんどの機種で室温センサーは室内機の吸気口付近にあります。 普通は室内機は天井近くの壁に取り付けられますが、 天井付近の温度環境は人間が普段いる場所とは大きく異なります。 最近買い替えた寝室のエアコンはほぼ調整不要なのですが、 仕事部屋のエアコンではあんまり制御がうまくいってないみたいです。 サーキュレータで攪拌してみたりもしましたがだめでした。
これを解決するひとつの方法はセンサーを人間がいるあたりに移設することです。 実際に室温センサーの配線を延長移設している例を見る限り劇的に改善されるようです。 あと、ひと昔前にサンヨーにリモコンに室温センサーが付いている機種があったようです。 一部の人に評判が良かったようですが、メーカーごと消えました。
この状況に対し、日本の家電メーカーは誤った方向に努力しました。 ハイエンド機に高度なセンサーを追加し 室内の温度分布や人の動きを元により複雑な制御を目指したのです。 私にはテクノロジーの無駄遣いだなあと思えます。
ところがスマートリモコンを使えばセンサーの設置位置にかなり自由度があるので エアコン本体はそのままで安価に解決できる可能性が出てきます。
2021年12月2日ちょっと前のまだsRemoを導入する前のことです。 息子が帰省してきた際にスマートリモコンを持ち帰ってきました。 サークルを引退したときの後輩からのプレゼントだそうです。 一番メジャーと思われるnatureのハイエンド機種remo 3です。 remo 3は温湿度、光度、人感センサーを内蔵しています。
息子は声で一括コントロールできるところを気に入って 自慢するためにわざわざ持ち帰って来たのですが、 以前から気になっていたエアコンの制御を試してみました。 仕事机のそばに設置して、スマホアプリで条件による制御を追加。 結果は極めて良好で、仕事中に気温が気になることはありませんでした。 ちなみにこのときのアプリの設定は以下です。
・室温25℃を上回ったら暖房設定24℃風量1
・室温24.5℃を下回ったら暖房設定26℃風量自動
これに朝夕の自動起動/停止を追加すれば一切リモコンを操作せずに 仕事部屋の温度環境が整います。
アプリではあまり複雑な条件の制御ができないのですが、 APIではかなり色々なことができるようです。 ひととおり試してみましたが実用性ありと判断しました。
ただremo 3は約1万円と、私には高い買い物です。 そこで目を付けたのがsRemoというわけです。 ネットの評判を見ると色々と問題のある機種らしく、 メルカリではかなり安くなっています。 新品同様の最新版R3が送料込み3000円で入手できました。
2021年12月3日sRemoのいいところは安いことです。他はnature remo 3の劣化下位互換と思っていいです。 事前の調べで数ある短所は把握していましたが、工夫で何とかなると判断しました。 どうしようもなければ同じくらいの値段で売ることにします。
nature remo 3では適温に自動制御できましたが、 sRemoは温度センサーに不安があります。 まずは標準アプリの以下設定で実際に使ってみました。
・室温30℃以上で暖房設定24℃風量しずか
・室温29℃以下で暖房設定26℃風量自動
なお、sRemoのセンサーの値-5でだいたい正しい値になります。補正機能は使っていません。 結果は概ね問題ないけどたまに暑さ寒さを感じることがあるという感じです。 ギリギリおまけで合格と言ったところでしょうか。 nature remo 3のときよりon/offぎみの制御になってしまいます。 特に弱に移行したときにコンプレッサーが切れて送風になってしまうケースが増えました。 やはり温度センサーの値が微妙にバラつくのと、計測値が1℃刻みなのが痛いようです。
幸いnature remoの初代モデルならメルカリで3000円程度で出ているので まずはこれでAPIによる制御系を作り込んで、 しばらく運用して不満が出たら買い替えることにしましょう。
2021年12月5日まずはcurlコマンドを使ってsRemoのAPIを実際に叩いてみます。 Linuxで以下のコマンドを順番に実行すると 現在の温度、湿度、光度がJSON形式で返ります。 なお、トークンは事前にサポートサイトで発行しておきます。 識別子もトークン発行メニューの近くで表示できます。
R3=識別子
TOKEN=トークン
JSON=$(curl -s https://uapi1.sremo.net/user_api/$R3/get_thl -H "Authorization: Bearer $TOKEN")
echo $JSON
{"t":29,"h":31,"l":100}
温度と湿度をjqコマンドで取り出して、日時と一緒に出力するとこんな感じ。
TE=$(echo $JSON | jq .t) HU=$(echo $JSON | jq .h) echo $(date "+%Y/%m/%d,%H:%M,")$TE,$HU 2021/12/06,10:00,29,31これを一定間隔で実行してファイルに追記すると温湿度ログが取れます。 お手軽ですね。 2021年12月6日
次は信号を送信してエアコンを操作してみます。
R3=識別子 TOKEN=トークン SIG="1-a-n-3-1-1-26" RET=$(curl -s https://uapi1.sremo.net/user_api/$R3/send_sig?sig=$SIG -H "Authorization: Bearer $TOKEN") echo $RET OK
sig=の後にコマンドを設定して送信します。
なお、送信に成功すると変数RETにOKが返ります。
先頭から
{画面番号}-a-{ON/OFF}-{モード}-{風量}-{風向}-{温度}
の順にパラメータを設定します。上記例では
画面番号1-a(固定)-on-暖房-風量自動-ルーバー停止-26℃
となっています。
3番目をfに変更すると停止です。
プリセットではなくアプリで学習した信号を送信することもできます。 その場合はsig=に単に学習したボタン番号をセットします。
SIG=1 RET=$(curl -s https://uapi1.sremo.net/user_api/$R3/send_sig?sig=$SIG -H "Authorization: Bearer $TOKEN") echo $RET OK
スマートリモコンのプリセットはたまに間違っていることがあるようです。 ところがそれを確認する方法はありません。 なのでよく使うパターンを学習しておいてそちらを使った方が確実です。
これでAPIによる自動制御の準備ができました。
<補足>
試してみたらうちの東芝のエアコンでは6番目の風向は無視されました。
APIの説明だと2が上下とあるんですが、機能しません。
試した感じでは物理リモコンでルーバー上下は「スイング」ボタンで
トグル動作になっており、単独で送信されるようです。
また、電源オン時は前回運転時の状態をキープするようです。
室温取得と信号送信ができるようになったので、 アプリと同様の制御をAPIでやってみます。 今どきだとIFTTTとNode-REDを組み合わせるのが王道みたいなんですが、 私は定年間近の筋金入りCUI派なのでbashとcurlでやります。
以下は完成品から見通しをよくするためにエラーハンドリングを削り込んだものです。 このスクリプトをcronで一定間隔で実行すれば、アプリと同様の制御が可能です。 うちだと5分間隔でちょうどいい感じです。
#!/bin/bash R3=識別子 TOKEN=トークン JSON=$(curl -s https://uapi1.sremo.net/user_api/$R3/get_thl -H "Authorization: Bearer $TOKEN") TENOW=$(echo $JSON | jq .t) if [ "$TENOW" -lt 30 ]; then SIG="1-a-n-3-1-1-26" else SIG="1-a-n-3-7-1-24" fi RET=$(curl -s https://uapi1.sremo.net/user_api/$R3/send_sig?sig=$SIG -H "Authorization: Bearer $TOKEN")APIから取得した温度が30より低い場合は通常モード、 30以上の場合は弱モードに設定しています。 ただしこのままだといくつか致命的な問題があります。 次回はその対策を。 2021年12月8日
前回のスクリプトでも一応最低限の動作はするのですが、 実際の運用にはざっと以下のような対策が必要です。
#!/bin/bash
R3_ROOT=$(cd $(dirname $0); pwd)
. $R3_ROOT/acc.def
[ ! -f $ACCSW ] && exit
CTGT=$(cat $ACCSW)
JSON=$(curl -s https://uapi1.sremo.net/user_api/$R3/get_thl -H "Authorization: Bearer $TOKEN")
[ ${JSON:0:1} != '{' ] && exit
TENOW=$(echo $JSON | jq .t)
if [ "$TENOW" -lt 30 ]; then
TGT=26
#SIG="1-a-n-3-1-1-$TGT"
SIG=2
else
TGT=24
#SIG="1-a-n-3-7-1-$TGT"
SIG=3
fi
if [ "$TGT" -ne "$CTGT" ]; then
sleep 5
RET=$(curl -s https://uapi1.sremo.net/user_api/$R3/send_sig?sig=$SIG -H "Authorization: Bearer $TOKEN")
[ ${RET:0:2} != "OK" ] && exit
echo $(date "+%H:%M ")$CTGT"->"$TGT >> $R3_ROOT/acc.log
echo $TGT > $ACCSW
fi
これから先スクリプトをたくさん作るので、
トークンなどはスクリプトと同じディレクトリに以下をacc.defとして置いて参照します。
ACCSW=$R3_ROOT/accsw R3=識別子 TOKEN=トークンなお、温度設定を変更したタイミングでacc.logに履歴を残しています。 だいたい1時間に2〜3回切り替わっているようです。 2021年12月9日
室温制御ができるようになったので、次は起動と停止の自動化です。
以下が起動スクリプトですが、本当は処理部分は
touch $ACCSWの1行であとは制御スクリプトが面倒見てくれます。
ですが冬の朝は夜間に壁や床が冷えているので ガンガンに温めた方が快適です。 なので設定を2度高めの28℃で起動しています。
ただ、正直にスイッチファイルにそれを書くと、 初回の室温制御のチェックにより勝手に26℃に再設定されてしまいます。 そこで実際のエアコン設定は28℃、ファイルの中身は26℃として 室温制御スクリプトを騙しています。 これで最初だけ目標温度25℃に達するまでは全開で運転されます。
送信に失敗した場合は一応2回リトライするようにして、 成功したら温度設定ファイルを作成してから 普段は止めてあるルーバーのスイング信号#5を送信しています。 スイング停止は業務開始時に物理リモコンかスマホアプリで手動でやってます。
#!/bin/bash
R3_ROOT=$(cd $(dirname $0); pwd)
. $R3_ROOT/acc.def
TGT=28
#SIG="1-a-n-3-1-1-$TGT"
SIG=1
echo $(date "+%Y/%m/%d %H:%M ")"fireup ac" >> $R3_ROOT/acc.log
for i in 0 1 2; do
RET=$(curl -s https://uapi1.sremo.net/user_api/$R3/send_sig?sig=$SIG -H "Authorization: Bearer $TOKEN")
echo $RET >> $R3_ROOT/acc.log
if [ ${RET:0:2} = "OK" ]; then
TGT=26
echo $TGT > $ACCSW
#swing
sleep 5
SIG=5
RET=$(curl -s https://uapi1.sremo.net/user_api/$R3/send_sig?sig=$SIG -H "Authorization: Bearer $TOKEN")
exit
fi
sleep 70
done
停止は以下です。起動とほぼ同じですね。
停止信号を送信した後、
スイッチファイルを削除して室温制御を無効化しているだけです。
#!/bin/bash
R3_ROOT=$(cd $(dirname $0); pwd)
. $R3_ROOT/acc.def
TGT=25
#SIG="1-a-f-3-1-1-$TGT"
SIG=4
echo $(date "+%H:%M ")"shutdown ac" >> $R3_ROOT/acc.log
for i in 0 1 2; do
RET=$(curl -s https://uapi1.sremo.net/user_api/$R3/send_sig?sig=$SIG -H "Authorization: Bearer $TOKEN")
echo $RET >> $R3_ROOT/acc.log
if [ ${RET:0:2} = "OK" ]; then
rm -f $ACCSW
exit
fi
sleep 70
done
crontabに以下3つの設定を追加すれば起動停止も併せて自動制御されます。
月〜金7:59に起動 始業1時間前
毎時1〜56分まで5分毎に室温制御
毎日17:30定時に停止 土日は無駄だけど気にしない
としています。なお、毎時0分は温湿度ログを取るので
API実行が被らないようにずらして避けています。
59 7 * * mon-fri /home/user/sremo/accup.sh 1-56/5 * * * * /home/user/sremo/accw.sh 30 17 * * * /home/user/sremo/accdown.sh2021年12月10日
前回まででやっとスマホアプリと同じことができるようになりました。 ここからはAPIの強みを生かして作り込みます。
アプリの制御で不満に思ったのが、祝日や休暇の際に切り替えるのが面倒なことです。 色々やっていると設定をたくさんon/offしないといけないし、 忘れると無駄にエアコンが動くのもなんとなく嫌です。 幸いAPIだとそのへんはいくらでも柔軟に対応可能です。 祝日の自動判定スクリプトはネットにたくさん例があるので それらを参考にしました。
まず祝日のリストをダウンロードしてスクリプトと同じ場所に置きます。
curl -s https://raw.githubusercontent.com/holiday-jp/holiday_jp-ruby/master/holidays.yml | awk '{print $1}' > holiday-jp.txt
以下を起動スクリプトの先頭に追加して、
祝日と年末年始は何もせずに抜けます。
TODAY=$(date "+%Y-%m-%d")
grep ${TODAY} $SCRIPT_DIR/holiday-jp.txt > /dev/null 2>&1 && exit
MMDD=$(date +%m%d)
[ $MMDD -ge 1229 ] && exit
[ $MMDD -le 0103 ] && exit
これで祝日は意識する必要がなくなりました。
次は休暇対応を実装します。
2021年12月12日
次は休暇対応です。 色々と方法は考えられますが、シンプルにスイッチファイルを作って対処します。 以下1行を起動スクリプトの先頭に追加すればOK。 起動スクリプトと同じ場所にaccoffというファイルがあれば 何もせずに抜けます。
[ -f $R3_ROOT/accoff ] && exit休暇前の終業時に
touch 起動スクリプトのディレクトリ/accoffとやっておけば消すまで起動しなくなります。 予め休暇の予定が決まっているときにはatコマンドで仕掛けてもいいでしょう。 例えば1/14〜1/17だったらこんな感じ。
at 07:00 011422 at> touch 起動スクリプトのディレクトリ/accoff at> ctrl+D at 07:00 011822 at> rm -f 起動スクリプトのディレクトリ/accoff at> ctrl+D
問題は休暇に出かけてから切り忘れに気が付いたときです。 今回の仕組みではLinuxに完全に制御を任せているので、 アプリリモコンでエアコンを停止しても 室温が下がれば再起動されてしまいます。
調べてみると、JuiceSSHというスマホ用のターミナルがあったので それで接続して対処することにしました。 操作性は最低限ですが、コマンドをいくつか叩くだけなので十分でしょう。 スイッチファイルを作成してから停止スクリプトを実行すればいいです。
touch 起動スクリプトのディレクトリ/accoff 起動スクリプトのディレクトリ/accdown.shこれで休暇への対応は取れました。 2021年12月13日
どうにもsRemoの温度センサーが返す値が安定しません。 横のエンペックスの温湿度計と比較するとだいたい+5なんですが、 たまに+4〜+6までフラフラしている感じで、 室温制御におかしな挙動が入ってしまうことがあります。 やっぱり熱設計かなと思って本体を眺めてみると確かに良くない点があります。
sRemoの筐体は縦が幅の倍くらいの長方形なんですが、 メッシュ状の開口部が筐体下半分両側にあります。 これ、筐体内上半分に基板で発生した熱が滞留します。 たぶんそのせいで室温がうまく取れていない気がします。
対処としては上に穴を開けて自然対流を起こすのがいいと思いますが、 そのうち売るかもしれないので手を加えるのは見送りました。 というわけで本体を90度横に向けてみます。それでも一応抜けるはず。
効果はてきめんでした。エンペックス+4でほぼぶれません。 意図しないエアコン制御もかなり減りました。 これならnature remo3に買い替えるまでもないかなと思います。
2021年12月14日
温度に関しては本体を横向きに設置することで解決しました。
問題は湿度で、単純なプラスマイナス補正では対応できない値が返ります。
冷房や除湿運転時には湿度での自動制御をしたいのである程度まともな値が欲しいです。
というわけでエンペックスとsRemoの値を比較してプロットしてみました。
横軸がsRemoの値、縦軸がエンペックスの値で青がデータ点です。
係数倍でいけるかと思いましたが、原点を通らないようなので
まずExcelで線形近似して、あとは上限と下限を重視して手動で追い込みました。
結果として得られたのが図中赤の以下係数で、概ねプラスマイナス3%くらいになります。
エンペックス = 2.4×sRemo-36
これで実用上問題ない湿度の値が得られました。以下はスクリプト内での補正例です。
TERAW=$(echo $JSON | jq .t) TENOW=$(($TERAW-4)) HURAW=$(echo $JSON | jq .h) HUNOW=$(echo "$HURAW*2.4-36" | bc -l)2021年12月15日
普通に「湿度」というと相対湿度のことを意味します。 確か中学校の理科でやると思うのですが、飽和水蒸気量に対する比率のことを指します。 ひとことで乱暴に説明すると、ある温度での結露する水分量に対する割合です。 ほとんどの教師はこれをわかりやすく説明できないので 生徒はテスト対策に丸覚えするしかなく、結果理科嫌いを大量生産している概念です。 私も当時さっぱり理解できませんでした。
さて。
湿度には相対湿度の他に絶対湿度と言う概念があって、 分母は飽和水蒸気量ではなく空気の量です。 これを使うと湿度の管理が非常にシンプルになります。
ややこしいことに、分母が質量[g/kg]と容積[g/m3]の2種類あります。 日本の空調の規格では質量、国際的には容積で混乱が見られます。 分母が容積だと、意味が部屋[m3]に存在する水分[g]と とてもイメージしやすい単位になるので概念的に優れていると思います。 よって当サイトでは分母が容積のVH[g/m3]を使います。
絶対湿度に関しては さとるパパの住宅論 がお勧めです。決定版と言っていい内容です。
相対湿度は温湿度の管理の指標としてとても使いずらいです。 多くの目安を見るとわかるように、温度により適正な範囲が異なるからです。 例えばあるシャープの除湿器は自動モードでは以下の条件で運転されます。
| 室温[℃] | 湿度[%] |
|---|---|
| 〜24 | 60 |
| 24〜28 | 55 |
| 28〜 | 45 |
実はこれ絶対湿度だとどれも概ね12〜13g/m3です。 ひょっとすると内部では絶対湿度で制御しているかもしれませんね。
ちなみにだいたい10〜11g/m3としておけば通年快適となるようです。 私がモニタリングしてみた感じでも12g/m3くらいからもやっとした感じがありますし、 朝起きた時に乾燥していると感じた時は8g/m3くらいでした。 要するに絶対湿度を見ておけば温度に関わらず統一的に判断できます。
ではなぜいまいちな相対湿度が一般的なのかというと 昔からあったアナログ湿度計が原理的にそういう仕様だから というのがたぶん一番大きな理由だと思います。 温湿度センサーICから返る値も原理的に相対湿度だと思います。
絶対湿度は温度と相対湿度から簡単な計算で求めることができます。 デジタルの場合はほぼコストゼロで変換できるので 対応してくれればいいのにと思うのですが、 需要が無いのかそういう製品はあまり見かけません。 幸いLinuxでAPIを利用していると自分で計算すればいいので 利用すれば制御が楽になるはずです。 計算例は以下です。
PE=$(echo "6.1078*e(7.5*$TENOW/($TENOW+237.3)*l(10))" | bc -l) VH=$(echo "(217.0*$PE/($TENOW+273.15))*($HUNOW/100.0)" | bc -l)
式は先程紹介したサイトからいただきました。 現在の温度に対する飽和水蒸気圧PEを求め、 それと温度と相対湿度から容積絶対湿度VHを求めています。
2021年12月16日絶対湿度が計算できたのでログに取ってみます。 以下がスクリプト完成品です。
#!/bin/bash
R3_ROOT=$(cd $(dirname $0); pwd)
. $R3_ROOT/acc.def
for i in 0 1 2 3 4; do
JSON=$(curl -s https://uapi1.sremo.net/user_api/$R3/get_thl -H "Authorization: Bearer $TOKEN")
[ ${JSON:0:1} = "{" ] && break
echo $(date "+%H:%M ")"thlog retry" >> $R3_ROOT/acc.log
sleep 298
done
TERAW=$(echo $JSON | jq .t)
TENOW=$(($TERAW+$OFFT))
HURAW=$(echo $JSON | jq .h)
HUNOW=$(echo "$HURAW*$SFH+$OFFH" | bc -l)
PE=$(echo "6.1078*e(7.5*$TENOW/($TENOW+237.3)*l(10))" | bc -l)
VH=$(echo "(217.0*$PE/($TENOW+273.15))*($HUNOW/100.0)" | bc -l)
HUNOW=$(printf "%.0f\n" $HUNOW)
VH=$(printf "%.1f\n" $VH)
echo $(date "+%Y/%m/%d,%H:%M,")$TENOW,$HUNOW,$VH,$TERAW,$HURAW >> $R3_ROOT/th.log
これをcronで毎時0分に実行します。 sRemoの温度取得APIはよく失敗するので5分間隔で4回リトライしています。 他のスクリプトでも補正することがあるので係数をacc.defで共通化しています。 あと、計測技術の基本中の基本ですが 補正値を見直した時のために補正前の温湿度を併せて保存しています。
以下はある日の仕事部屋のログをプロットしたものです。
相対湿度は左軸、温度と絶対湿度は右軸です。
朝エアコンが自動起動し温度が上がると相対湿度が下がります。
エアコン暖房時は水分量は変わらないので絶対湿度は一定です。
厳密には窓で結露して少し下がっているかもしれません。
日中は私がずっと部屋にいるので
呼気から供給された水分で絶対湿度もじわじわ上がります。
17:30にエアコンが停止して温度が下がると相対湿度は上がりますが、
私が居なくなったので絶対湿度は一定です。
19時。夕食の準備で換気扇が回った影響で外気が入り湿度が下がります。
22時。ローラー台を回したので発汗で跳ね上がりますが、
終わった後に換気したので元に戻っています。
0時。入浴の影響で温度と湿度が上がり、その後浴室換気扇で元に戻っています。
相対湿度が温度によって乱高下するのに対し、 絶対湿度は変動要因が無い限りぶれないことがよくわかります。
2021年12月17日絶対湿度について調べているときに、 お手軽な湿度計の精度測定方法の例を発見しました。 私には直リンクが取れなかったので「湿度計の誤差と簡易な校正方法の紹介」で検索してください。 JIS B 7920の飽和塩法によるもので簡便なわりに安定しているように思えます。 私も正としているエンペックスの湿度計でやってみました。
100円ショップででぎりぎり湿度計が入る透明な密閉容器を買ってきて 99%食塩20gを50ccの水に良く溶かしたものと一緒に入れます。 室温程度では相対湿度75%で平衡するはずが、 湿度計の値はぐんぐん上がり、90%を超え振り切りました。あれれ。
塩を良く溶かそうとお湯を使ったのが原因でした。 溶液と空間は熱的にも平衡でないといけないですね。 いったん開けて冷まし、再度挑戦。 が、80%になったり60%になってみたりで全然安定しません。 高い方はまだ冷めてないとして、低い方はいったいなんだと不思議に思いながら とりあえず仕事部屋に静置して寝ました。
朝起きて値を読むとなんと40%。あれれ。 部屋の湿度をsRemoで確認すると34%。 おかしいなーと思いながらまた容器のふたを開けているときに気が付きました。 ずいぶんと手応えが軽いような。これ、全然密閉してないやん!
エッジ部にストレッチフィルムをぐるぐる巻きにして再挑戦。
最初は60%でしたが、4時間後に74%に落ち着きました。合格です。
なお、後でJISを読み直してわかったことですが、 私は小さなコップに少し塩が溶け残るようにしましたが 皿に塩を広げ少量の水でペースト状にした方が良いようです。 緩衝効果が高く取り扱いも楽です。
他にも市販の99%食塩で実測したら 77%で平衡したというデータがありました。 にがり成分の影響だそうで、本気出すなら特級の塩化ナトリウムを使った方がいいみたいです。 あとは密閉容器内の湿度はあまり均一ではないようで、 ファンで攪拌した方がいいとか色々奥が深そうです。
アナログ湿度計は工場出荷時にはデジタルより高精度なのですが、 輸送中の振動や落下させた衝撃でずれてしまうことがよくあるようです。 あとセンサーの感湿材の経年劣化もあるので 気になるようなら測定してみるといいかもしれません。
2021年12月18日仕事部屋の温度環境は概ね落ち着きました。 となるとリビングと寝室のエアコンも気になります。 仕事部屋とは異なりそこそこ最近のモデルなので温度制御は任せていいのですが、 起動と停止を自動化したい需要があります。 あと、寝室は加湿制御もしたいです。 sRemoの温度センサーはいまひとつなこともわかったので、 仕事部屋用をnature remoに買い替えてsRemoを他に流用しましょう。
湿度センサーが欲しいのでminiは除外。 初代(remo-01)は完成度がいまいちなので除外。 現行(remo-1W3)は高いので買えない。 というわけで第2世代(remo-1W2)をメルカリで3500円で購入しました。 制御部分は完成しているので温湿度を校正してAPI部分をちょっと書き換えればいいはずです。
2021年12月19日sRemo同様にやればいいだけかと思いましたが、 やってみたら色々出たのでメモ。
まず温度から見てみます。横軸がAPIの値(補正なし)、縦軸はエンペックスの値です。
綺麗に0.6℃刻みです。0.1℃かと思ってたら違いました。
まあそれでもsRemoの約2倍の分解能ですが。
温度はだいたい+1.4でよさげです。
湿度は思ってもみない結果となりました。
横軸がAPIの値(補正なし)、縦軸青丸はエンペックスの値です。
最初湿度30%あたりから計測開始して、加湿器でガンガン65%まで上げました。
だいたい線形だなと納得して、加湿器を止めてエアコンで温度を上げ、相対湿度を下げました。
すると全然違うパスを戻ります。どうやらかなり応答が遅いようです。
温度を一定にして様子を見るとそのうち行きと帰りの中間あたりで落ち着きました。
赤丸は行きと帰りの中間あたりを通るように決めた係数での値です。
この係数でログを取ると急激な変動のないときはエンペックス±5くらいで収まりました。
APIで温湿度センサーの値を取ると、その値がいつのデータなのか一緒に返ります。 見ていると更新間隔が20分から1時間くらいの不定です。 たぶん家電の制御にはあまり値がふらつくと良くないので クラウド側でフィルターをかけているようです。
以前息子のremo3で自動制御したときにとても安定していたのに対し sRemoがふらつくのはここに原因があったようです。 だとしたらロジックでなんとかなるかもしれませんね。
2021年12月20日機械的に書き換えればOKかと思いましたが意外と仕様が違って手間だったのでメモ。 sRemoと違ってやっている人がたくさんいるので詳細は略。
nature remoはクラウドで機器のステータスがわかるので運転状況はそっちで管理するかなと思いましたが ローカルのスイッチファイルの方が確実そうなのでsRemo同様のままとしました。
温湿度センサー取得は以下です。 sRemoより多くの情報が返るのでjqで取り出すのがややこしいです。
JSON=$(curl -s "https://api.nature.global/1/devices" -H "Authorization: Bearer $TOKEN") TERAW=$(echo $JSON | jq .[].newest_events.te.val) HURAW=$(echo $JSON | jq .[].newest_events.hu.val)
温度が整数から実数になったので補正にbashの演算が使えません。 よって湿度同様にbcで演算しました。
TENOW=$(echo "$TERAW+$OFFT" | bc -l) HUNOW=$(echo "$HURAW*$SFH+$OFFH" | bc -l)温度の比較も同様。
if [ $(echo "$TENOW > 24.5" | bc) = 1 ]; then TGT=24 AV=3 else TGT=26 AV=auto fi
以下で登録してある家電のデバイスIDと送信可能な設定がわかります。
curl -s "https://api.nature.global/1/appliances" -H "Authorization: Bearer $TOKEN" | jq .
信号送信はこんな感じにコマンドを&で繋げます。以下例だと暖房&温度&風量です。 電源offの状態で温度などを送信すると電源onになるようです。
SIG="operation_mode=warm&temperature=$TGT&air_volume=$AV" curl -s -X POST "https://api.nature.global/1/appliances/$ACW/aircon_settings" -d "$SIG" -H "Authorization: Bearer $TOKEN"電源offは以下です。 単に電源onする場合は=の後がonではなくブランクなので注意。
SIG="button=power-off" curl -s -X POST "https://api.nature.global/1/appliances/$ACW/aircon_settings" -d "$SIG" -H "Authorization: Bearer $TOKEN"これでスクリプトを書き換えればsRemoからnature remoへの移行は完了です。 2021年12月21日
次にやりたいのが寝室の加湿制御です。 具体的には寝ている間湿度が極端に下がらないようにしたいです。 たまに起床時に喉の渇きを覚えてそのまま風邪ひくことがあるので。
加湿器は長年愛用しているKAZのV100です。 タンクに微量の塩を投入して沸騰させて加湿するシンプルなものです。 私は気化式はカビをばらまくようでどうも好きになれません。 この方式だと殺菌と加湿が同時に行われる点が優れています。
V100の制御は電源ごとon/offでいける(というかそもそもスイッチが無い) のでスマートプラグを購入しました。 とりあえず安いもので探すとTP-LinkのHS105は 非公式ながらAPIが使えるようなので選定。amazonで1280円でした。 スマホアプリのできもなかなかいいです。 スケジュールで決まった時間にon/offも可能なようです。 これとスマートリモコンの温湿度センサーを組み合わせて使います。
2021年12月22日まずお約束。これ非公式なので何が起きても私は知りません。
ほとんどネットで見た実例そのままですが、 一応メモ代わりにAPIの使用例を残しておきます。
トークン取得。UUIDはあらかじめ適当に生成しておきます。
curl -X POST -H "Content-Type: application/json" -d '{"method": "login", "params": {"appType": "Kasa_Android", "cloudUserName": "メールアドレス", "cloudPassword": "パスワード", "terminalUUID": "生成したUUID"}}' https://wap.tplinkcloud.com/
TOKEN=トークン
デバイスID取得
curl -X POST -H "Content-Type: application/json" -d '{"method": "getDeviceList"}' https://wap.tplinkcloud.com/?token=$TOKEN
HS105=デバイスID
ステータス取得
電源onで1、offで0です。
ちょっと気になるのがresponseDataに緯度と経度が出るんですよね。
数字見ると自宅の値です。こんなに簡単に取れていいんだろうか?
curl -s -X POST -H "Content-Type: application/json" -d "{"method":"passthrough", "params": {"deviceId": "$HS105", "requestData": '{\"system\":{\"get_sysinfo\":null},\"emeter\":{\"get_realtime\":null}}'}}" https://wap.tplinkcloud.com/?token=$TOKEN | jq -r .result.responseData | jq .system.get_sysinfo.relay_state
電源on送信
curl -s -X POST -H "Content-Type: application/json" -d "{"method":"passthrough", "params": {"deviceId": "$HS105" , "requestData": '{\"system\":{\"set_relay_state\":{\"state\":1}}}'}}" https://wap.tplinkcloud.com/?token=$TOKEN
電源off送信
curl -s -X POST -H "Content-Type: application/json" -d "{"method":"passthrough", "params": {"deviceId": "$HS105" , "requestData": '{\"system\":{\"set_relay_state\":{\"state\":0}}}'}}" https://wap.tplinkcloud.com/?token=$TOKEN
2021年12月23日
寝室の自動制御の需要は冬だけです。夏は寝ている間はずっと冷房onなので特に問題なし。 寝ている間にエアコンで暖房をかけるのが好きじゃないので たまに寒さで目が覚めるのをなんとかしたいのと、乾燥し過ぎを避けたいです。
仕事部屋のような細かい制御は不要なのでざっくりでいいと考えました。
23:00〜6:00まで1時間おきに以下条件で起動。
エアコン:23℃未満で暖房on
加湿器:絶対湿度8.0未満
23:30〜6:30まで1時間おきに両方電源off。
2晩ほどこれで試したらほぼ毎時両方起動してしまいました。 特に寒くて乾燥していた日だったこともあるかもしれません。 30分くらいではあまり下がらないと予想したのですが、 意外と温度も湿度もoffにするとすぐに下がってしまうようです。 エアコンはonになるたびに30分全開運転になって電気代もかかりそうです。 弱運転で長くするか、閾値を見直す必要があるようです。
2021年12月28日寝室に移設したsRemo R3が故障しました。 ログを見ると1/4になったあたりで温湿度ログが欠損しています。 1/1にファームウェアのアップデートが配信されたらしいので 自動更新に失敗してお亡くなりになったのかもしれません。 初期化しても再設定できずでゴミになってしまいました。 仕事部屋に置いてあるときからたまにLEDが点滅して再接続している様子だったので たまたまこのタイミングで重篤化した可能性もあります。 導入当初からしょっちゅうステータスが取れなくなったりしていたので まあこんなものかなと思います。
<追記>
1/1のアップデートに不具合があったようです。
1/7のアップデートで解消し復活しました。
なんともお粗末ですね。
これはリビングのタイマー制御に使うことにします。
年明けのamazonのセールで安くなっていたのでSwitchBotを購入してみました。 他との大きな違いは温湿度計が別体になっているところでしょうか。 温湿度計は電池式なので電池交換が面倒そうと思いましたが、 BLEなので1年以上は大丈夫なようです。
SwitchBotのエアコンのプリセットはかなり怪しいです。
家の複数のメーカーのエアコンで試してみましたが、
暖房にしたはずが冷房になってみたり、勝手にルーバーがスイングしてみたり。
手動学習でやったほうが無難だと思います。
<追記>
信号送信による自動認識は怪しいのですが、
手動で機種を細かく指定すると大丈夫なようです。
エアコンだと本体リモコン両方で登録できて、どちらもOKでした。
温湿度計はざっとempexと比較してみましたが、 最初派手にずれたものの数日使うと安定してきました。 単純なプラスマイナス補正で行けそうです。 他とは違い新品だったのもあるかもしれません。 なお、湿度計の応答遅れはほとんどありません。 息を吹きかけると数%上がり、30秒ほどで元の値に戻ります。
APIの実行例は豊富なので結果だけ羅列しておきます。
TOKEN=アプリで取得したトークン
curl -s https://api.switch-bot.com/v1.0/devices -H "Authorization: $TOKEN" | jq .
TH=温湿度計ID
AC=エアコンID
OT=その他で学習したID
JSON=$(curl -s https://api.switch-bot.com/v1.0/devices/$TH/status -H "Authorization: $TOKEN")
echo $JSON | jq .body.temperature
echo $JSON | jq .body.humidity
curl -X POST -H "Authorization: $TOKEN" https://api.switch-bot.com/v1.0/devices/$AC/commands -H "Content-Type: application/json" -d '{"command":"setAll","parameter":"26,5,1,on","commandType":"command"}'
curl -X POST -H "Authorization: $TOKEN" https://api.switch-bot.com/v1.0/devices/$OT/commands -H "Content-Type: application/json" -d '{"command":"コマンド名","parameter":"default","commandType":"customize"}'
curl -X POST -H "Authorization: $TOKEN" https://api.switch-bot.com/v1.0/devices/$AC/commands -H "Content-Type: application/json" -d '{"command":"turnOff","parameter":"default","commandType":"command"}'
温湿度計の設置に自由度がある利点を活かして寝室の制御はこれで行こうと思います。
2022年1月11日
寝室の自動制御の設定を見直したところいい感じに落ち着きました。
こんな感じです。
エアコン:23時と5時に23℃未満なら暖房on。2時と7時にoff。
加湿器:23時以降絶対湿度7.5未満で1時間加湿し1時間休止。7時にoff。
この制御で極端な寒さと乾燥は避けられています。 スクリプト実例は以下のような感じです。 255w1はSwitchBotに25.5℃暖房風量弱を学習させたコマンドです。 加湿器のスマートプラグは赤外線リモコンと違いステータスが読めるのでそれを使っています。
# aircon
HH=$(date +%H)
case $HH in
23 | 05 )
[ $(echo "$TENOW < 23.0" | bc) = 1 ] && SIG=255w1
;;
02 | 07 )
SIG=off
;;
esac
if [ -n "$SIG" ]; then
sleep 5
curl -s -X POST -H "Authorization: $TOKEN4" https://api.switch-bot.com/v1.0/devices/$AC/commands -H "Content-Type: application/json" -d "{\"command\":\"$SIG\",\"parameter\":\"default\",\"commandType\":\"customize\"}"
fi
# kaz
RET=$(curl -s -X POST -H "Content-Type: application/json" -d "{"method":"passthrough", "params": {"deviceId": "$HS105", "requestData": '{\"system\":{\"get_sysinfo\":null},\"emeter\":{\"get_realtime\":null}}'}}" https://wap.tplinkcloud.com/?token=$TOKEN3 | jq -r .result.responseData)
RSTAT=$(echo $RET | jq .system.get_sysinfo.relay_state)
sleep 5
if [ $RSTAT = 1 ]; then
curl -s -X POST -H "Content-Type: application/json" -d "{"method":"passthrough", "params": {"deviceId": "$HS105" , "requestData": '{\"system\":{\"set_relay_state\":{\"state\":0}}}'}}" https://wap.tplinkcloud.com/?token=$TOKEN3
else
[ $HH = 07 ] && exit
if [ $(echo "$VH < 7.5" | bc) = 1 ]; then
curl -s -X POST -H "Content-Type: application/json" -d "{"method":"passthrough", "params": {"deviceId": "$HS105" , "requestData": '{\"system\":{\"set_relay_state\":{\"state\":1}}}'}}" https://wap.tplinkcloud.com/?token=$TOKEN3
fi
fi
これをcronで以下のように夜間1時間おきに呼び出しています。温湿度ログを避けて2分ずらしています。
2 23,0-7 * * * /home/user/sremo/accb.shsRemoと違いAPIが安定しているのでエラーハンドリングは省略してよさそうです。 2022年1月12日
アップデートの不具合から復活したsRemoをリビングに移設しました。 ここはスマホアプリでの単純なタイマー制御でもいいのですが、 祝日対応と不在時の処理は他と統一したいのでAPIでやっています。
以下はcrontabの関連行です。
45 6 * * * /home/user/sremo/acl.sh on 45 8 * * * /home/user/sremo/acl.sh off 30 11 * * mon,wed-fri /home/user/sremo/acl.sh on 45 12 * * mon,wed-fri /home/user/sremo/acl.sh off 30 15 * * mon,wed-fri /home/user/sremo/acl.sh on 30 16 * * mon,wed-fri /home/user/sremo/acl.sh offスクリプトの引数でon/offを切り替えています。 一応温度を見て寒いときだけonにするようにしています。
朝は休日も含めて部屋を暖めます。 平日は私しかいなく昼食時に寒いのでちょっと前に暖めています。 16時に床暖房がタイマー起動するのですが、 立ち上がりだけエアコンでブーストしています。 火曜だけ嫁がパート休みで床暖房が手動onされているので除外。
これでうちのエアコン3台の設定ができました。
2022年1月13日これまで3メーカーのスマートリモコンを使ってみたわけですが、 温湿度計だけ見るとSwitchBotのできがかなり良好です。
まずsRemoは頻繁にAPIでの取得に失敗するので除外。 nature remoは安定していますが余計な処理による応答遅れが好みに合いません。
その点SwitchBotは応答が速く精度も良好です。 分解した方によると センシリオンという定評あるメーカーのSHTC3というチップが採用されているそうです。
またリモコンと別体になっているのも利点で、 リモコン基板の発熱の影響を受けないので安定するはずです。 さらに温湿度計だけ複数設置することも可能ですし 配線が無いので設置の自由度が高いです。 ちなみに監視だけならBTで直接通信できるのでハブは不要です。
スマートリモコンとしての出来はnatureが明らかにいいので 私みたいにAPIで全部やる場合は 温湿度センサーだけSwitchBotを参照するのがいいのではと思います。
2022年1月14日当サイトでは信号送信には専らcurlコマンドを使っていますが、 httpのステータスコードがわからなくなるので困っていました。 httpのPOSTに失敗してもcurlコマンド自体は常に成功するので $?は成功を示すゼロとなり使えません。
調べてみたらちゃんと方法があったので紹介します。 以下のようにcurlのオプションに追加すればOKです。
RET=$(curl -s -X POST "https://api.nature.global/1/appliances/$ACW/aircon_settings" -d "$SIG" -H "Authorization: Bearer $TOKEN" -o /dev/null -w '%{http_code}')
[ $RET != 200 ] && exit
-oでbodyをnullデバイスに捨てて、代わりに-wでhttpステータスを出力します。
どのリモコンのAPIも成功時には200を返すのでそこで送信成功を判定できます。
これまで結果を見て特定の文字列で判断していましたが、これですっきりしました。
2022年1月17日
寒い朝、業務開始時に部屋が十分に温まっていないことがあります。 一応90分前に暖房を起動しているのですが、 ヒートポンプエアコンは外気温が低いと能力が低下するので 時間切れが起こるようです。 なお、早朝の室温はだいたい20℃くらい一定で判定には使えません。 特に寒さを感じるほどではないので対策は不要なのですが、 外気温を参照してひと工夫する余地はあるのでちょっと考えてみます。
まずSwitchBotの温湿度計が電池式であることを利用して 室外に設置するという手が考えられます。 ただ、雨のことを考えると密閉容器に入れたいところですが 湿度が測れなくなるのはもったいないし 百葉箱のようなものを設置するのは大げさです。
まあいまどきはネットだろうということで 公開サーバを探してみたらOpenWeahterMapがお手軽なようです。 以下に練馬の現在気温取得の実例を示します。
TOKENW=事前に取得しておいたトークン JSON=$(curl -s "https://api.openweathermap.org/data/2.5/weather?q=Nerima&units=metric&lang=en&appid=$TOKENW") TOUT=$(echo $JSON | jq .main.temp)これで普段の1時間前にでも起動判定を追加すればよいでしょう。 湿度を参照して梅雨時の冷房と除湿の判定などにも応用できそうです。 他にもweatherをforecastに変更すると予報が取れたり色々活用方法はありそうです。 2022年1月18日
2022年現在、除湿器のスマート化は事実上できないみたいです。 もっとも必要性もそんなには無いかもしれませんが。
まず最初からスマート化されているまともな除湿器はたぶん無いようです。
次に赤外線リモコン対応となると、たぶんダイキンのカライエしかないと思います。 ただこれほとんどエアコン同様の工事や配管が必要で気軽に導入できません。 というか別荘などでの単体の制御で常時運転を前提としている製品だと思います。
となると可搬型の一般的な除湿器をスマート化したくなるのですが、 用途からして赤外線リモコンの付いたものがありません。 いわゆる指ボットでon/offするしかないのでしょうがあまりにスマートさに欠けます。
ではスマートプラグではどうかと言うと、これも問題ありです。 普通は除湿能力を考えるとコンプレッサー式になるのですが、 スマートプラグで電源offすると運転中に突然電源を引っこ抜くことに相当するので 頻繁にやるとたぶんコンプレッサーが壊れます。 ちなみにうちのシャープの除湿器は運転中にプラグを抜いて挿すとoffになるので無理です。 三菱電機だと全機種に「停電復帰機能」というのがあるので機能的にはOKですが、 やはりコンプレッサーにはかなりの負担となると思います。
現実的には除湿器の自動モードがそこそこ賢いので十分に対応可能だと思います。 それ以上にon/offの自動判定を適切にできる気がしません。 除湿器は毎年型番だけ変えたものが新機種として出て来る停滞した商品なので この先スマート化対応が追加される可能性は低いのではないでしょうか。
2022年1月19日今朝起きたら7時に切れているはずの加湿器がonのままでした。 そのうちどれかで起きるかなと思っていたAPIトークンの期限切れが 運悪くonの状態で起きたようです。
購入してすぐに作ったトークンを使い続けていたはずなので 購入時期から考えるとTP-Linkのトークンの期限は30日のようです。 幸いトークンはcurlで取れるので自動更新は可能です。 月に2回程度cronで更新しておけばTP-Linkの場合は大丈夫そうです。 以下にサンプルを示します。
#!/bin/bash
ACC_ROOT=$(cd $(dirname $0); pwd)
UUID=適当に生成したUUID
RET=$(curl -s -X POST -H "Content-Type: application/json" -d '{"method": "login", "params": {"appType": "Kasa_Android", "cloudUserName": "メールアドレス", "cloudPassword": "パスワード", "terminalUUID": "$UUID"}}' https://wap.tplinkcloud.com/ | jq -r .result.token)
perl -pi.bak -e "s/^TOKEN3=.*/TOKEN3=$RET/" $ACC_ROOT/acc.def
ただ、気分の問題ですがIDとパスワードをスクリプトに書くのは何となく抵抗があります。
あと他のもそのうち切れるかもしれないので期限を把握しておく必要がありそうです。
TP-Linkのスマートスイッチの場合にはクラウド経由ではなく LAN内で直接の制御もtplink-smarthome-apiというやつで可能なようなので その方が安定性と言う意味ではいいはずです。 ただ、Node.js上で動作するみたいなんで導入がちょっと面倒そうかな。
2022年1月20日ちょっと不思議なことが起きたのでメモ。
うちにはダイキンのエアコンが2台あります。 リビングは2013年製、寝室は2020年製です。 まずsRemo R3を寝室に設置し、プリセットで使っていました。 後にリビングに移設し、同じダイキンだからいけるかなーと思い そのまま再設定せずに試したら使えました。
確か1/19のことです。 仕事を終えてリビングに行くと止まっているはずのエアコンが稼働していました。 どうやら夕方の床暖房ブーストで起動は成功したものの停止に失敗したようです。 ただしログを見ると信号送信自体には成功しているようです。
そういうこともあるのかなと思ってアプリで停止してもエアコンが反応しません。 それどころかその後一切反応しなくなりました。 sRemo送信部のハード故障かと思いテレビや照明を操作すると大丈夫。 sRemoを寝室に戻してみると正常に動作します。 試しにリビングのエアコンのボタンを学習するとこれは反応します。 どうやら突然プリセットの送信信号が変わってしまったようです。
ちなみに寝室のエアコンのリモコンでリビングを操作しても反応なし。逆も同様です。 つまりもともと2つのエアコンの信号は同じでは無かったようです。 なぜかしばらくの間、対応してないはずの信号で リビングのエアコンが操作できていたということになります。
となると夕方の暖房起動の後にファームウェアにアップデートでもあったのでしょうか。 あるいはクラウドのプリセットのDBに更新があったか。 どうもsRemoは色々と挙動不審です。
2022年1月24日リビングのダイキンのエアコンのsRemoのプリセットが使えなくなったことが気になっています。 そこで信号解析をしてみることにしました。
Nature RemoのLOCAL APIでは、リモコンの信号を簡単に取得できます。 手順は以下です。
Remoに向けて信号発信すると青く光る curl -s http://IPアドレス/messages -H "X-Requested-With: local"するとこんなデータが出てきます。
{"format":"us","freq":35,"data":[378,493,378,488,381,490,382,488,377,489,389,25257,3420,1795,386,1352,387,484,378,488,381,489,381,1356,389,481,380,491,378,493...
ダイキンのリモコンはAEHAフォーマットらしいので、
この値を基準のT=425で割った値が8T4Tでフレームの先頭、
その後はデータ部分で1T1Tなら0、1T3Tなら1となるようです。
上記例だと3420が8T、1795が4Tでフレーム先頭、次の8T4Tまでがデータ部分です。
以下のスクリプトで1Tで割った信号列が出て来ます。
#!/bin/bash AA=$(cat $1 | jq .data[]) for f in $AA; do T=$(echo "$f / 425" | bc -l) T=$(printf "%.0f\n" $T) echo $T done改行を除くとこんな感じ。
1 1 1 1 1 1 1 1 1 1 1 59 8 4 1 3 1 1 1 1 1 1...データ部分の偶数番目の1/3がコマンドのビット0/1に対応するので、 後は成形してネットにたくさんある解析結果と比較すればOKです。 なお、スマートリモコンが一般的になる前は オシロスコープを使ったり読み取りデバイスを自作したりしていたようです。 私には無理ですね。 2022年1月27日
信号解析をしたところ、さらに謎が深まりました。
まず、リビングと寝室のリモコンはほぼ同じ信号を送りますが、 ヘッダーの一部がわずかに違います。 フレーム数は2つで、1フレーム目の後半に少しコマンドを含むものです。 この形式はたぶんちょっと旧いです。
次に現在のsRemoのプリセット。これは寝室のみ反応しますが、 なんと根本的にフォーマットが異なります。 フレーム数は3つで、1と2がほぼ同一の8バイト固定で、 3フレーム目にコマンドが集約されているタイプです。 この形式がたぶん最新です。
ヘッダーは具体的にはこんな感じです。 信号の並びに出力したので最下位ビットが左になっているので注意。 左から、リビング、寝室、sRemo(frame1)、sRemo(frame2)です。
1 10001000 10001000 10001000 10001000
2 01011011 01011011 01011011 01011011
3 11100100 11100100 11100100 11100100
4 00000000 00000000 00000000 00000000
5 10000000 01000000 10100011 01000010
6 00000000 00000000 00000000 00000000
7 00000000 00000000 00000000 00000000
8 00000000 00000000 11101011 00101010
9 00000000 00000000
10 00000000 00001000
11 00000000 00000000
12 00000000 00000000
13 00000000 00000100
14 00000000 00000000
15 00000000 00000000
16 00000000 00000000
17 00000000 00000000
18 00000000 00000000
19 00000000 00000000
20 11001000 00100010
先頭3バイトはダイキンのカスタマーコードで固定です。
5バイト目が違うのでここがお互いに認識しない原因かと。
ただ、sRemoのプリセットに寝室のエアコンが反応するのがよくわかりません。
あと、寝室の信号は10バイト目に暖房、13バイト目に風向のコマンドが入っています。
最終バイトはチェックサムなので違いは無視していいです。
コマンドのフレームはこんな感じ。 暖房27℃風量自動で、左からリビング、寝室、sRemo(frame3)です。
1 10001000 10001000 10001000
2 01011011 01011011 01011011
3 11100100 11100100 11100100
4 00000000 00000000 00000000
5 00000000 00000000 00000000
6 10010010 10010010 10010010
7 01101100 01101100 01101100
8 00000000 00000000 00000000
9 00000101 00000101 00000101
10 00000000 00000000 00000000
11 00000000 00000000 00000000
12 01100000 01100000 01100000
13 00000110 00000110 00000110
14 00000000 00000000 00000000
15 00000000 00000000 00000000
16 10000011 11000011 00000011
17 00000001 00000000 00000000
18 00000000 00000000 00000000
19 00011011 01011010 11101010
16バイト目と17バイト目が数ビット違うのですが、
発見した資料ではここの意味は不明でお手上げです。
Nature RemoのローカルAPIでは記録した信号を送信することもできます。 以前のsRemoのプリセットのように両方のエアコンが反応する信号を作れないかと 1フレーム目の5バイト目をいくつかビット反転して チェックサムも整合させましたがリビングのエアコンは反応せず。 私にはこのあたりが限界かなという気がします。
2022年1月31日加湿器に使っているスマートプラグHS105はトークンの有効期限が短く、 定期的に更新する必要があります。 一応月に2回自動更新するようにしてみましたが、 私の場合はLANでできれば事足りるのでローカルAPIに移行しました。
まず最初に試したのはtplink-smarthome-apiです。 Node.js上に構築されたものなので 動かすにはあれこれ追加が必要でかなり苦労しましたが、 試してみると高機能なものの返り値に余計なものがたくさん入っていて私には使いづらいものでした。 一応ログから設定手順を残しておきます。
sudo apt update
sudo apt install nodejs npm
sudo npm install -g n
sudo n latest
sudo npm update -g npm
sudo npm install -g tplink-smarthome-api
sudo vi /usr/local/lib/node_modules/tplink-smarthome-api/lib/cli.js
以下修正
const results = await device[command]({...commandParams});
npmが旧いとか言われて、芋づる式にnも入れました。
他にないかと探したら、 tplink-smartplug.pyというPythonのスクリプトを発見しました。 これ、シンプルで私好みです。 JSONだけ返すように書き換えて以下のように使っています。
RET=$($ACC_ROOT/tplink-smartplug.py -t IPアドレス -c info | jq .system.get_sysinfo.relay_state) RET=$($ACC_ROOT/tplink-smartplug.py -t IPアドレス -c on | jq .system.set_relay_state.err_code) RET=$($ACC_ROOT/tplink-smartplug.py -t IPアドレス -c off | jq .system.set_relay_state.err_code)これでトークンの更新が不要になりましたし、クラウドサービスが不調の際も影響を受けません。 2022年2月3日
スマートリモコンでの制御により仕事部屋の温度環境は快適になりましたが、 設定温度を頻繁に切り替えているので電気代はかなり上がっているはずです。 仕事部屋のエアコンは2005年製の東芝の6畳用です。 17年前のモデルなので制御がいまいちですし効率も良くないと思われます。 更新すればスマートリモコンでの制御が不要になり 下がった電気代で更新費用が回収できるかもしれません。
エアコンの性能指標は2006年からAPFという通年のエネルギー効率に変わったのですが、 仕事部屋のはその直前のモデルということになります。APFは4.8です。 2020年に導入した寝室のダイキン製エアコンのAPFは5.8と20%ほど改善されています。 同様のモデルに更新すれば単純計算で電気代が8割ほどになる見込みです。
仕事部屋のエアコンにはコンプレッサーの稼働状況を見るために電力量計が付けてあります。 記憶によれば除湿や冷房の時期は150〜300Wくらいで運転していることが多かったです。 なのでその時期はあまり改善が見込めません。 対して暖房時期は400Wくらいで、26℃に切り替えると750Wくらいまで上がることが多いので 電気代に対するインパクトは明らかに冬期の方が大きいです。
契約している東京ガスのサイトで昨年の日ごとの使用量を見ると3月中旬まで暖房を使っていたようです。 秋頃にリセットした電力量計は300kWhくらいを示しているので、 だいたいこの冬の使用量は400kWhくらいになりそうです。 今の電気代は再生エネルギーの上乗せ込みでだいたい30円/kWhなので 冬期の仕事部屋の電気代は概ね12000円です。 仮にAPFを信頼して20%減、制御が賢くなってさらに20%減と楽観的に見積もると ひと冬の節約額は5000円程度でしょうか。 6畳用の普及モデルは工事費込みで60000円程度なので、 単純に回収するのは冷房時若干改善したとして10年ほどかかる計算になります。
ただ、今のエアコンの寿命はいつ尽きてもおかしくないでしょうから まだ動いているうちに早めにリプレースするのが賢い消費者な気もします。 寝室のエアコンは夏の一番暑い時期に壊れたので工事待ちの数週間はかなりきつかったです。 更新費用は回収できなくてもさっさと更新するべきなのでしょうね。
2022年2月8日sRemo R3が不調です。温度は-5℃の補正でだいたい合ってたんですが、 数日前から補正値が突然-9℃くらいにずれてます。 中古で買ったものなので評価は保留としますが、 またずれるようだと意図したように制御できないので対応が必要です。
とりあえずこれまで試した中で良好だったSwitchBotの温湿度計をリビングに増設しようかと思いましたが、 試しに寝室の温湿度計をリビングに持って行ってみるとBLEが寝室のハブに届かないようで APIで温湿度の値を取得してもリアルタイムで更新されません。
幸い測定値は2秒間隔でブロードキャストしているようなので リビングに設置しているLinuxサーバから直接読むことができそうです。 ラズパイでの実例 があったので設定手順とスクリプトをまるっと頂きました。 最後の出力のみJSON形式で出るようにこんな感じで書き換えて使うことにします。
print(''.join(['{"t":', str(temperature),',"h":',str(humidity),'}']))
ちなみに寝室の温湿度計のパケットもリビングに届かないので、
そちらは逆にハブ経由でないと見えません。
なんともややこしいことになりそうです。
2022年2月9日
エアコンの電力使用ログを取ってみたいなと思いましたが、 仕事部屋のエアコンに付けているELPAのエコキーパーには 外部通信機能がありません。 スマートプラグの中には電力計内蔵のものもあるのですが、 中華製メインの商品だけに1000W近いエアコンに使うには度胸がいります。 まあ、エコキーパーも公式にはエアコン不可なわけですが。
そこで最近安く買えるwebcamで表示を撮影し、 画像認識で数値を読み取ってみることにしました。 まあ、実用上は1日1回撮影しておいて後で目視転記で全く問題ありませんが 単に最近流行りのことをやってみたかっただけです。
選定にあたっては、Linuxのコマンドラインで静止画が簡単に取れそうなものを探しました。 と、TP-LinkのTapo C100がRTSPという規格に仕様外で対応しているようなので購入してみました。 説明書通りに設定して、Linuxにffmpegをインストールしたら以下コマンドで一発でした。 なお、LANアクセスにはローカルアカウントの設定が必要です。
ffmpeg -y -i rtsp://アカウント:パスワード@IPアドレス/stream1 -frames:v 1 ファイル名あとはこれを画像認識にかければいいはず。
ところでこの製品、どうやっているのかわかりませんが ポート開放なしで外から見えてしまいます。 一応スマホアプリを起動していない状態では画像は送信されていないようですが Tapoのアカウント管理がいいかげんだと誰にでも見えてしまいます。 あんまり好きな仕様ではないですね。 まあクラックされても電力計の数字が見えているだけなので問題無いですが、 ペットの監視なんかで導入する場合はちょっと気になる仕様です。
2022年2月14日
画像認識にかけるにはまずはデータ取りだなということで、
以下のような感じにwebcamを設置して10分おきに撮影してみました。
スクリプトは以下です。例によってIDやパスワードなどは別ファイルに格納してあります。
FNAME=$(date +%Y%m%d%H%M).jpg ffmpeg -y -loglevel quiet -i rtsp://$IDC100:$PWC100@$IPC100/stream1 -frames:v 1 $ACC_ROOT/image/$FNAMEとりあえず部屋の照明が点いていてエアコンが稼働中だと以下のような感じです。 ちょっと表示画面に映り込みがあります。 このままだと画像認識にノイズが入りそうですが たぶんノングレアの保護シートを貼るとある程度は改善すると思います。
表示画面への映り込みを改善するために、
スマホ用のノングレアの保護シートを貼ってみました。
劇的に改善されました。これなら画像認識でも問題無さそうです。
ところが早朝の画像に問題が。
認識精度を上げようとついでにカメラを正面に移設したら
ナイトモードの赤外線LEDが乱反射を起こしています。
困ったなと思って試しに自動ナイトモードを日中モード固定に変更してみたら
朝の照明オフなら普通に読めるみたいです。
というわけで使えそうなテスト用のデータは用意できました。
テスト用のデータが溜まったので実際に画像認識にかけてみます。 最終的にはやったことのないOpenCVを使ってみたいのですが、 まずはお手軽にということで7セグメント表示に特化したSSOCRを試してみます。 バイナリ配布はよくわからなかったのでソースを取って来て 必要なライブラリを用意すればmake一発でした。 こんな感じです。
sudo apt install libimlib2-dev make cp ssocr ~/bin使い方は読み取り範囲を指定すればいいのですが、 あまり賢くないので色々と工夫が必要なようです。 とりあえず消費電力は以下で読めました。
ULX=左上X座標 ULY=左上Y座標 W=幅 H=高さ ssocr crop $ULX $ULY $W $H -d 3 -T ファイル名"-d 3"は桁数の指定です。これ指定しないと失敗しますが、 今度は3桁でないときに失敗します。 待機状態は1W、コンプレッサーが切れた時は10W程度なので このときはブランクとなってしまいます。 まあ実用上は問題ありません。
"-T"は閾値の自動設定です。"-at 数値"で手動設定できるのですが、 朝の画像で最適にすると昼間は読めなかったりです。 他にも"erosion 1"とすると認識率が上がることもあるのですが、 逆に読めないものが出てきたりで微妙です。
次に累積の消費電力量kWhを読んでみましたが、 こっちは小数点をどうにも認識してくれませんでした。 あと、位置的にカメラの前面が映り込むようで、 全桁まとめて処理すると失敗します。 これは1桁ごとに処理すると大丈夫でした。
読み取り範囲が完全に手動なので、 カメラがちょっとずれると左上座標を変更して再処理になります。 画像だけ溜めておいて気が向いたときに確認する程度なら実用性はありますが、 あんまり私の好みではないかなあという感じです。
<追記>
小数点を読みたい場合は文字が斜めになっていると数字の一部と認識されて失敗するようです。
SSOCRのあるあるみたいで検索するとたくさん出てきます。
その場合は"shear 数字"で傾きを調整するといいみたいです。
小数点が存在することを"-d -1"で明示的に指定できるようです。
なお、"-Dファイル名"でデバッグ用の画像が出力できます。
エアコンの一日の出力変動を見てみたいと思ったので 前回のコマンドを利用して以下スクリプトを走らせてみました。
for f in $*; do
W=$(ssocr crop $ULX $ULY $W $H erosion 1 -d 3 -c digits -T $f)
T=${f%.*}
echo ${T: -4}','$W >> w.log
done
するとちょくちょく失敗しています。
それでもだいたい傾向はわかるんで実用上問題ないんですが、
試しに以下スクリプトで桁ごとに認識させてみました。
for f in $*; do
DH=$(ssocr crop $ULX $ULY $W1 $H erosion 1 -d 1 -c digits -T $f)
DT=$(ssocr crop $ULX2 $ULY $W1 $H erosion 1 -d 1 -c digits -T $f)
DO=$(ssocr crop $ULX3 $ULY $W1 $H erosion 1 -d 1 -c digits -T $f)
W=0
[[ $DH =~ [0-9] ]] && W=$(($W+$DH*100))
[[ $DT =~ [0-9] ]] && W=$(($W+$DT*10))
[[ $DO =~ [0-9] ]] && W=$(($W+$DO))
T=${f%.*}
echo ${T: -8}','$W >> z.log
done
ちょっと長いんですが全部並べて表示してみます。
02180600 880 02180610 808 02180620 0 02180630 0 02180640 1 02180650 1 02180700 1 02180710 1 02180720 801 02180730 1 02180740 74_ 741 02180750 776 776 02180800 786 786 02180810 798 798 02180820 802 802 02180830 817 817 02180840 815 815 02180850 680 680 02180900 547 547 02180910 570 570 02180920 574 574 02180930 576 576 02180940 511 511 02180950 492 492 02181000 494 494 02181010 497 497 02181020 498 498 02181030 585 585 02181040 697 697 02181050 526 526 02181100 96 02181110 713 713 02181120 554 554 02181130 434 02181140 462 02181150 505 505 02181200 422 422 02181210 303 303 02181220 511 511 02181230 538 538 02181240 514 514 02181250 447 447 02181300 306 306 02181310 466 466 02181320 546 546 02181330 443 443 02181340 10 02181350 462 462 02181400 688 688 02181410 324 324 02181420 308 308 02181430 464 02181440 751 751 02181450 326 326 02181500 309 309 02181510 306 306 02181520 371 371 02181530 812 812 02181540 329 329 02181550 286 286 02181600 462 462 02181610 767 767 02181620 320 320 02181630 309 309 02181640 306 306 02181650 304 304 02181700 304 304 02181710 304 304 02181720 760 760 02181730 328 328 02181740 0 02181750 0 02181800 0 02181810 880 02181820 701 02181830 __1 80 02181840 ___ 508 02181850 87:30エアコン起動直前は1Wなのに3桁指定しているので失敗が改善。 7:40まだ薄暗くカメラの映り込みで下1桁が失敗が改善。 中間の欠損は100W未満かと思っていたら4が苦手なようです。 17:40は消灯して読み取れずです。
問題は暗い時間帯に派手に誤認識しています。 これは最大輝度で暗い画像を除外するなどの処理が必要ですかね。 例えば以下のようにImagemagickで調べればいいと思います。
convert 元画像 -crop $Wx$H+$ULX+$ULY w.jpg MAXL=$(identify -format %[max] w.jpg)毎日の出力変動を観察するつもりはないのでこれで満足しました。 ちなみにグラフにするとこんな感じです。
<追記>
なんかグラフの波形が不自然だなと思ったら横軸が時刻なので不等間隔になってました。
修正したらこんな感じです。
けっこう電気代がかかってそうですね。
やっぱりエアコン更新するかなあ。
ワット数は読めるようになったので積算値の電力量kWhも読んでみます。
表示部へのカメラの映り込みによりうまく読めていません。
以下は撮影画像からメーターを切り出したものです。
表示画面右下側にカメラ前面が映り込んで暗くなっています。
人間には明瞭に読めるのですが、SSOCRのデバッグ画像はこうなります。
前回同様に桁ごとにバラすと読めはするのですが、面倒になってきました。
そこでメータの設置角度を調整して映り込みを解消します。
こんな感じです。
斜め下から撮影しているので台形になっていますが、映り込みが消えました。
色々調整した結果、以下コマンドで90%くらいの認識率になります。
ssocr crop $ULX $ULY $W $H shear 4 closing 1 erosion 1 -c decimal -d -1 -T $fデバッグ画像はこうなります。
for D in 3 1 2; do
W=$(ssocr crop $ULX $ULY $W $H shear 4 closing 2 erosion 1 -d $D -c digits -T $f)
if expr "$W" : "[0-9]*$" ; then
break
fi
done
3桁,1桁,2桁の順に数字だけ読めるまでリトライしています。
2022年3月1日
だいぶ暖かくなってきたのでエアコン制御の必要性はあまりなくなってきました。 消費電力量も下がって来たしSSOCRの読み取り精度で十分なので 少しモチベーションが下がっていたのですが、 まだ寒いうちにためておいたデータでOpenCVに手を付けようと思います。
リモコン制御に使っているLinux PCはサブノートで、CPUはAtomです。 OpenCVを使うにはちょっと心許ないです。 というわけで重たい画像処理には普段仕事で使っているPCを投入します。
仕事用のPCにはCUDAの使えるGPUが載っています。 息子の卒研のテーマは深層学習なのですが、 帰省してきたときにちょっと試させてというので使わせてみたら 設定にどえらい苦労をしていました。 どうもWindowsネイティブで構築するとバージョン依存がきつくて かなり難しいようです。
調べた感じではWSL2という仕組みでWindows上でLinuxを走らせておいて、 最近GPUに対応したDockerを使って構築済みのコンテナを使うのが一番楽そうです。 しかもLinuxの方が最適化が進んでいるのでネイティブより速いようです。 以下に設定内容をメモ代わりに列挙しておきます。
wsl --installその後
notepad $env:USERPROFILE\.wslconfig 以下2行をペースト [wsl2] memory=4GBこれ書かないと無制限にメモリを使ってえらいことになります。 最大でもメインメモリ-4GB程度にしておくのが無難。
wsl -l -vでdocker-desktopとdocker-desktop-dataがRunngingであることを確認します。 Win用のDockerでは一番楽に使えますが、 商用利用は有償なのでその場合はWSL2上のUbuntuでDocker-CEを使うことになるようです。
docker run --gpus all -it -v c:\work:/work pytorch/pytorch:1.11.0-cuda11.3-cudnn8-runtime"--gpus all"でGPUの使用を宣言します。WSL2でこれが可能になりました。 nvidia-smiコマンドでGPUの情報が出てくればOKです。 "-v"オプションでWindows側のデータ置き場のフォルダが見えるようにしています。 なお、":"の後のタグを指定しないで起動するとlastestが使われますが、 知らないうちにバージョンアップされてしまうので明示的に指定した方がいいと思います。
Nature Remoには人感センサーが付いていますが、使ってませんでした。 そういえば最初に試した時に部屋に入ったら勝手に照明オンとかやってみたような。 照明は壁スイッチが好みなので現状でいいのですが、 エアコンの切り忘れ対応なんかには使えそうです。 ちょっとテストしてみました。 以下はAPI実行例です。
JSON=$(curl -s "https://api.nature.global/1/devices" -H "Authorization: Bearer $TOKEN") MZ=$(echo $JSON | jq -r .[].newest_events.mo.created_at) echo $MZ 2022-03-28T00:27:51Zなんか見慣れないフォーマットで表示されていて、いまひとつ使いづらいです。 調べてみるとこれはISO 8601フォーマットというそうです。 最後のZはUTCを意味するそうですが、ますます使いづらいです。 さらに調べてみるとdateコマンドで変換できるようです。 以下で日本時間になります。
/bin/date -d $MZ --iso-8601="seconds" 2022-03-28T09:27:51+09:00"-d"オプションで文字列を自動認識してくれて、 カレントのタイムゾーンに変換出力されます。 思い切り環境依存なので美しくないですがまあいいでしょう。
以下のように指定するとUNIX時間になるので経過時間の演算などに便利です。
/bin/date -d $MZ +%sただ、かなり敏感なようで、ログを取ってみたら Remoから少し見えている廊下を人が通っただけで反応してます。 廊下から見えない場所に移設したら大丈夫でした。 試してませんが、以下のように書けば 1時間以上動きが無い場合は不在と見なしてエアコンオフという感じになるはずです。
JSON=$(curl -s "https://api.nature.global/1/devices" -H "Authorization: Bearer $TOKEN") MZ=$(echo $JSON | jq -r .[].newest_events.mo.created_at) MU=$(/bin/date -d $MZ +%s) NU=$(/bin/date +%s) MD=$(($NU-$MU)) if [ $MD -gt 3600 ]; then エアコンオフ送信 fi例えば始業1時間後にこのチェックを入れれば 休暇の設定を入れ忘れた時に自動制御をキャンセルとかできそうです。 2022年3月28日
まず最初に書いておきますが、
この記事を読んでエコキーパーがあてにならないと思わないこと。
メーカーがダメだと明言しているのを私が自己責任で用途外の使い方をしていただけです。
そこを勘違いしないようにお願いします。
<補足>
エコキーパーは正確みたいでした。理由は後述。
電気料金の請求書を見ていてちょっとびっくりしました。 1/22〜2/21の使用量は605kWh。 仕事部屋の旧式エアコンでかなり無駄な制御をやっているのと、 リビングや寝室でガンガンタイマー制御をかけていたりで 普通の家より電気代がかかるのはいいんですが、 それにしても家族3人で一日20kWhとは凄いです。
契約している東京ガスのサイトで日ごとの使用量を見ると、
完全に不在にした日は3.5kWhでした。
おそらくこれが冷蔵庫+待機電力だと思います。
605-3.5x30 = 500
一ヶ月500kWhですか。
大きいのはエアコンと乾燥機、あと加湿器ですが
私の感覚ではそこまで使っていないように思います。
電力量の測定に使っているELPAのエコキーパーは エアコンには使えないと注意書きがあります。 勝手にまあだいたいは測れているんじゃないのと自己責任で使っていました。 ですがやっぱりだめだったのかもしれません。
そこでクランプメーターを購入してみました。 以前会社のサーバーをラックに搭載するときに 総務の人が電流を計測しているのがかっこよくて前から欲しかったのです。 Aliexpressで1389円と激安でした。
最初は電源ケーブルをそのままクランプして値がほぼゼロになって不良品かと慌てたりしましたが、
交流を両側クランプしたら相殺してゼロになるんでしたね。
というわけでダイソーで200円の延長コードを買ってきて
片側詰めてループさせてこんなものを作ってみました。
ショートすると火を噴いたりすると思うので真似しないように。
まずドライヤーで計測してみると値はほぼ一致しています。
激安のクランプメーターは一応大丈夫なようです。
次にエアコンで試してみるとエコキーパーは80%くらいの値となっています。
インバーター機器だと低めの値が出るということはありそうで、
どうやらこれまで使用量を過小評価していたようです。
ということはこれまでの値を1.25倍すると正しい値になるようです。
<補足>
クランプメーターの電流から電力を算出するには力率というものをかけないといけないらしいです。
エアコンの力率は、低出力時は0.7、全開時には0.9程度になるようです。
ということで、エコキーパーで計測したエアコンの消費電力は信頼していいみたいです。
2/8の検討で積算値からこの冬の使用量は400kWhと推測しましたが、
実は500kWhくらいが正しい予測値だったようです。
2/25のグラフも縦軸を1.25倍すると請求書と整合した感じの値になります。
ところで暖房全開でも表示が800Wくらいなので
仕事部屋のエアコンならエコキーパーで大丈夫と思っていたのですが
実際には1000Wを超えていたようです。
この冬でだいたいデータが取れたので来冬の計測はやめたほうが無難なようです。
WindowsのDockerでCUDAが使えるようになったので次はOpenCVの設定だなと思っていたのですが、 Xの表示でエラーが出てちょっと停滞しています。 どうもバージョン依存みたいなんですが、 そのへんはDockerを使えば解消すると思っていたのでちょっと期待外れです。
というわけで制御用のLinuxPCでOpenCVを使って試してみました。 遅いですが画像数枚程度ならば大丈夫です。 というかラズパイでリアルタイム処理やっている人もいるみたいなので ひょっとしたらCUDAいらないかもしれません。
基本方針はこうです。 SSOCRはそこそこの認識率まで持って来れたのですが、 ちょっとカメラがずれただけで調整が必要になるので面倒です。 色々調べたらパターンマッチングで認識するのが正解のようです。 ただしその前に電力計の表示画面の位置を認識して 切り出さないと数値として解釈するときに面倒なことになりそうです。 なのでまずは画面の矩形を認識します。
矩形認識の決定版は以下サイトです。
7セグメントディスプレイを機械学習を使わずにOCRするほとんどこれで正解なのですが、 私には高度過ぎて理解できない点がたくさんあったので 最低限必要な部分を抜き出して整理を試みます。
上記サイトは全体の流れが詳細に解説されているところが秀逸なのですが、 エッジ検出の前にcv2.edgePreservingFilterでの平滑化処理を入れるのが肝なようです。 試した感じではこれで一気に認識率が上がりました。
上記サイトでは二値化は自作のラプラシランフィルタを適用されているようですが、 私は普通のcv2.thresholdで代用しました。
二値化さえできればあとはcv2.findContoursで輪郭のリストを作って cv2.approxPolyDPで多角形近似したものを cv2.isContourConvexで判定して凸四角形ならばほぼ当たりです。
ただしそれだけではたまたま似たような面積の領域が紛れ込むことがありました。 エコキーパーの画面はほぼ正方形なので、 輪郭の周長の1/4の自乗が面積に近いという条件を追加すればほぼ追い込めました。 以下はpytyonのリストです。まずは輪郭の候補を作って元画像に追記するところまで。 面積比が全体の1%以下と90%以上は除外しています。
import sys import cv2 fname = sys.argv[1] img = cv2.imread(fname) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) gray = cv2.edgePreservingFilter(gray, None, sigma_s=60, sigma_r=.4) h, w = gray.shape hxw = h*w ret, thresh = cv2.threshold(gray, 115, 255, cv2.THRESH_BINARY) contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) contours = list(filter(lambda x: cv2.contourArea(x)/hxw > 0.01, contours)) contours = list(filter(lambda x: cv2.contourArea(x)/hxw < 0.9, contours)) output = cv2.drawContours(img, contours, -1, (200,200,200), 2)この後のループで細かい条件で必要なものだけ近似した四角形を表示します。 重心位置に面積比とアスペクト比(みたいなもの)を表示しています。
for i, cnt in enumerate(contours):
aa = a_contours[i]/hxw
ar = a_contours[i]/(l_contours[i]*0.25)**2
c4 = cv2.approxPolyDP(cnt, l_contours[i]*0.05, True)
cv2.drawContours(output, [c4], 0, (0,255,0), 3)
if len(c4) != 4: continue
if not cv2.isContourConvex(c4): continue
if ar < 0.8: continue
m = cv2.moments(c4)
cx = int(m["m10"]/m["m00"])
cy = int(m["m01"]/m["m00"])
cv2.putText(output, str('{:.1f}'.format(aa*100)),
org=(cx, cy),
fontFace=cv2.FONT_HERSHEY_PLAIN, fontScale=3,
color=(255,0,0), thickness=2, lineType=cv2.LINE_AA)
cy = cy+40
cv2.putText(output, str('{:.2f}'.format(ar)),
org=(cx, cy),
fontFace=cv2.FONT_HERSHEY_PLAIN, fontScale=3,
color=(0,0,255), thickness=2, lineType=cv2.LINE_AA)
cv2.imshow('outline', output)
cv2.waitKey(0)
cv2.destroyAllWindows()
一例としてこんな感じになります。天井やコードのカビは無視してください。
これでもかなり頑張って落としたんですが。
pythonをまともに使ったのは初めてだったのですが、 ブロックをインデントで表現するとは驚きました。 あと、なんでOpenCVの色コードはBGRなんですかね。 私はガチガチのFortranプログラマで仕事ではほとんど最近の言語を使ったことが無いので あまりそれっぽい記述になっておらず恥ずかしいのですが参考になれば幸いです。 細かい言語仕様も理解していないので変なことをしているかもしれませんが、一応動いています。 これで四隅の座標は得られたので台形補正をすれば各表示桁の位置は確定しました。
2022年4月26日
そこそこ矩形で認識率が出そうなので以前取っておいた画像全部にかけてみましたが、
やはり単純な閾値による二値化では対応できない場合があるようです。
特に3/1記事のサンプルのように広い範囲でグラデーションがかかったような場合に読み外します。
以下のような感じになってしまいます。
表示画面左上の明るい領域を外側と誤認識しているわけですね。
昨日紹介したサイトで採用されているラプラシアンフィルタとは、
隣り合うピクセルの輝度差を強調するものだそうで、グラデーションに強いはずです。
調べてみるとOpenCVにラプラシアンフィルタがあったので以下のように適用してみました。
gray = cv2.Laplacian(gray, -1, ksize=5)これはかなり強力で、手持ちの画像ではほぼ読み外しがなくなりました。 上記と同じ画像もきちんと認識しています。
ラプラシアンフィルタを適用したバージョンで手持ちの全画像を処理したところ、 薄暗い時間帯の誤認識が見られました。 正しく認識できた時の多角形近似面積比(前/後)はほぼ102%で固定だったので、 105%より上を除外することにより、 暗過ぎて人間でも認識困難なものを除き認識率100%に持ち込めました。 また、表示画面以外の誤認識もありません。
というわけで台形補正をやってみます。 頂点の座標を左上から正しい順にソートする必要があるのですが、 以下サイトがいちばんシンプルでわかりやすかったので頂きました。
opencvでスキャン後の余白カット
そんなに斜めになっていないことを前提にすると以下手順でOKとなります。
まずx+yでソート。原点からの距離に近い意味なので左上と右下は確定します。
次に中間の2点のX座標が大きい方を前に。
これで[左上、右上、左下、右下]の順にできました。
c4 = sorted(c4, key=lambda x: (x[0][0]+x[0][1]))
if c4[1][0][0] < c4[2][0][0]: c4[1], c4[2] = c4[2], c4[1]
sq_contours.append(c4)
ところでPythonでは変数のスワップはテンポラリ変数を介さずに ダイレクトにできるんですね。便利です。 変換後矩形の縦横サイズは参考サイトでは対辺の長い方を採用していましたが、 対辺の平均の方がパターンマッチングには有利ではないかと考えました。
for i, cnt in enumerate(sq_contours):
l_top = cnt[0][0]
r_top = cnt[1][0]
l_btm = cnt[2][0]
r_btm = cnt[3][0]
top_len = np.linalg.norm(r_top - l_top)
btm_len = np.linalg.norm(r_btm - l_btm)
lft_len = np.linalg.norm(l_top - l_btm)
rgt_len = np.linalg.norm(r_top - r_btm)
w2 = int((top_len + btm_len)*0.5)
h2 = int((lft_len + rgt_len)*0.5)
src = np.float32(cnt)
dst = np.float32([[0,0], [w2,0], [0,h2], [w2,h2]])
trn = cv2.getPerspectiveTransform(src, dst)
crop = cv2.warpPerspective(raw, trn, (w2,h2))
これで手持ちの全画像の画面表示部分を矩形でcropに抜き出せました。
ところでPythonの言語仕様でかなり驚いたのが以下です。
img_org = imgとかやってimgを加工して最後にimg_orgから切り出すと加工後の画像が出てきて仰天しました。 複製ではなく同じオブジェクトを指すだけのようです。
img_org = copy.deepcopy(img)とやらないといけないとは知りませんでした。嵌る人多そう。 いよいよ次はパターンマッチングです。 2022年4月28日
これまでTapo C100で撮りためた画像で色々テストしていたのですが、 これをスマホでテキトーに撮影した画像に適用するとどうなるかなと思いました。 やってみるとだいたい認識したのですが、一部読み外します。 まず、撮影距離が遠いので画面の面積が全体の1%だと範囲外になります。 これは閾値を0.5%に下げてクリア。
困ったのは以下例。
見た目は多角形近似前後でほぼ一致していますが、
輪郭の周長の1/4の自乗が面積に近いはずが読み外しています。
細かく見ると近似前の曲線がリアス式海岸のようにギザギザになっています。
そのため周長が見た目よりずっと長く認識されています。
C100はフルHDなのに対し、高精細なスマホ画像が仇となったようです。
いくつか対策は考えられるのですが、 cv2.approxPolyDPのepsilonを5%と1%の2段階試して一致すれば 近似四角形の周長で判定することにしました。 epsilonは参考にしたサイトから元の周長の5%としていましたが、 面積のルートを取った方がギザギザの影響を受けにくいかもしれません。
次に誤認識したのが以下例。
微妙な濃淡から条件にマッチしている領域を拾ったようです。
これは先の2段階の多角形近似の周長が近くないものを除外。
他にも円に近い領域が誤認識されていたので近似前後の面積比で除外。
以下は上記判定のサンプルコードです。
contours = list(filter(lambda x: cv2.contourArea(x)/hxw > 0.005, contours))
l_contours = [cv2.arcLength(contour, True) for contour in contours]
a_contours = [cv2.contourArea(x, False) for x in contours]
for i, cnt in enumerate(contours):
c4 = cv2.approxPolyDP(cnt, l_contours[i]*0.05, True)
c001 = cv2.approxPolyDP(cnt, l_contours[i]*0.01, True)
lc4 = cv2.arcLength(c4, True)
lc001 = cv2.arcLength(c001, True)
if len(c4) != 4: continue
if not cv2.isContourConvex(c4): continue
# omit rias
if lc001/lc4 > 1.05: continue
# omit not square
if a_contours[i]/(lc4*0.25)**2 < 0.8: continue
# omit round
if a_contours[i]/cv2.contourArea(c4) > 1.05: continue
例によってPythonらしくないですが動けばそれでいいことにします。
これでちょっと汎用性が改善されました。
2022年5月10日
ここまでの記事でパターンマッチングと書いていましたが、 意図していたのはその一手法であるテンプレートマッチングです。 あまり用語を正しく理解していませんでした。
テンプレートマッチングは用意しておいたテンプレート画像を
評価対象の全領域をスイープして類似度が高い位置を探す手法です。
以下サイトの解説がとてもわかりやすかったです。
OpenCVのTemplate Matchingサンプルを詳しく調べる
これまでにためておいた画像から前回のスクリプトで表示画面部を抜き出し、 表示が鮮明なものをピックアップして0〜9の数字を テンプレート画像として手でさらに抜き出しました。 二値化した方がいい気もしますが、とりあえずそのままとしました。
grayに抜き出した表示画面を、tmplにテンプレート画像を読み込み、 以下の処理でresultに類似度がピクセルごとに出てきます。 numpyのwhereで類似度が0.9より大きいものだけlocに抜き出せます。
result = cv2.matchTemplate(gray, tmpl, cv2.TM_CCOEFF_NORMED) loc = np.where(result > 0.9)以下処理でマッチしたテンプレート画像の中心位置に マーカーを打ちます。
h, w = tmpl.shape
w2 = int(w/2)
h2 = int(h/2)
for pos in zip(*loc[::-1]):
cv2.drawMarker(disp, (pos[0]+w2, pos[1]+h2), (0,0,255))
以下のように表示画面を上下2分割、左右5分割とすると
だいたい4桁表示と位置が合いました。
ho, wo = disp.shape[:2] dw = int(wo/5) dh = int(ho/2) disp[dh:ho:dh, :] = 0 disp[:, dw:wo:dw] = 0部屋の照明が点いている場合の認識率は100%でしたが、 早朝や夕方の照明が消えている時間帯はちょっと苦しいです。 SSOCRには余裕で勝てました。 以下は1を読んでみた例です。
前回記事のスクリプトで色々テストして分かったのですが、 薄暗いときなど不鮮明な画像を認識するには類似度の閾値を下げる必要があります。 ところがその場合は別の数字にマッチしてしまうので ちょっと工夫が必要です。
というわけで類似度の閾値を0.5とかなり甘めにして、 そこから各桁位置において全数字の中で最も類似度の高いものを採用することにしました。
まず手持ちの全画像の画面部分を固定サイズで抜き出し、 そこから各数字を手作業で抜き出しました。 テンプレートマッチングはサイズが異なるとうまく認識できないのですが、 このやり方だとサイズは一致するので高い認識率が期待できます。
表示画面全体のサイズからセルの幅と高さを決めます。 幅は見た目だと1/5でぴったりでしたが、 1が右隣の8の縦棒にマッチするケースが発生したので2ピクセル狭めました。
disp = cv2.imread(fnamed) gray = cv2.cvtColor(disp, cv2.COLOR_BGR2GRAY) ho, wo = gray.shape dw = wo//5 - 2 dh = ho//2次にテンプレート画像をリストに格納しておきます。
tmpls = []
for n in range(10):
fnamet = '7s'+str(n)+'.jpg'
tmpl = cv2.imread(fnamet, cv2.IMREAD_GRAYSCALE)
tmpls.append(tmpl)
以下が処理の本体です。 0〜9の各数字に対してセルごとの類似度の最大値を求めます。 digit1に各数字の2Dリストをいったん作成し、 digitsに追加して3Dリストを完成させます。 類似度が0.5以下の場合はゼロのままです。
numw = 4
numh = 2
digits = []
for n in range(10):
print('loop:', n)
h, w = tmpls[n].shape
w2 = w//2
h2 = h//2
result = cv2.matchTemplate(gray, tmpls[n], cv2.TM_CCOEFF_NORMED)
print('rmax:', np.max(result))
loc = np.where(result > th)
loc = np.array(loc)
digit1 = np.zeros((numh, numw))
for pos in zip(*loc[::-1]):
xc = pos[0] + w2
yc = pos[1] + h2
i = min(xc//dw, numw-1)
j = min(yc//dh, numh-1)
digit1[j,i] = max(digit1[j,i], result[pos[1]][pos[0]])
digits.append(digit1)
あとはnumpyのargmaxでaxis=0を指定し返ったインデックスを並べれば完成です。 私が馴染んでいる旧来のプログラミング言語では このあたりけっこう面倒なのですが、 Pythonにはnumpyがあるので1命令で終わりです。ちょっと感動しました。
ds = np.argmax(digits, axis=0) d = ds[0] watt = d[0]*1000 + d[1]*100 + d[2]*10 + d[3] print(watt, "[W]") d = ds[1] kwh = d[0]*1000 + d[1]*100 + d[2]*10 + d[3] print(kwh, "[kWh]")
手持ちの画像のうち人間でも読み取りが難しいものもほぼ全て読み取れました。
特に以下が読めたのはなかなかのものだと思います。
私にも確信が持てず、前後画像からやっと正解がわかったものです。
唯一の失敗例が以下です。
右の縦棒のみ濃いので、たぶん1と9の切り替えの瞬間と思われます。
さすがにこれは読めなくてもいいでしょう。
これで上段のワット数は整数なのでOK。 あとは下段の小数点位置を読めば完成です。
2022年5月14日
小数点を精度良く認識するのはけっこうやっかいそうです。
以下は適当な表示画面画像から切り出した小数点のテンプレート画像です。
黒い丸の周囲が白い、という特徴があります。
鮮明な画像の場合は概ね大丈夫そうですが、
そうでない場合閾値を下げるとそこらじゅうでマッチしそうです。
実際やってみたらそうなりました。
対策が必要です。
エコキーパーの場合は小数点が存在するのは下段kWhのみで、 リセット後には小数点以下2桁、100kWhを超えると1桁で表示されます。 というわけで位置の可能性は2箇所しかないのでその仕様を利用してみます。
result = cv2.matchTemplate(gray, tmpl, cv2.TM_CCOEFF_NORMED) msk1 = int(ho*0.87) msk2 = int(ho*0.97) msk3 = int(dw*1.5) msk4 = int(dw*3.5) result[:msk1-h2, :] = 0 result[msk2-h2:, :] = 0 result[:, :msk3-w2] = 0 result[:, msk4-w2:] = 0
数字同様にいったん類似度を求めておいて、
該当する範囲の外側をゼロクリアしています。
以下は認識結果にマーカーを打ってみた例です。
黄色が最大類似度の位置で、小数点位置を正しく読めているようです
ところがエコキーパーの説明書を読んでみると
1000kWh以上は整数表示となるようです。もうひと工夫必要なようです。
小数点の認識はパターンマッチングでは泣き所のようで、
やりたいと思いつつしばらく着手しなかったのも
解決法に見通しが立っていなかったからです。
ところが世の中には頭のいい人がいるもので、
小数点付きの数字をテンプレートにするというアイデアが以下サイトに紹介されていました。
WINDOWS上で7セグLED数字を判定
表示位置が固定されている場合、これならかなりの精度が期待できそうで、
これ発見しなかったらまだ着手していなかったと思います。
以下では小数点入りのテンプレート画像を読み込んだ後に、 二値化してから右下の小数点をマスクしています。
doth = 9
dotw = 10
tmpls = []
tmplp = []
for n in range(10):
fnamet = '7s'+str(n)+'p.jpg'
tmpl = cv2.imread(fnamet, cv2.IMREAD_GRAYSCALE)
_, tmpl = cv2.threshold(tmpl, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
h, w = tmpl.shape
tmplp.append(tmpl)
ts = copy.deepcopy(tmpl)
ts[h-doth:h, w-dotw:w] = 255
tmpls.append(ts)
いったん小数点無しで全桁読みます。
そのとき、最大類似度を求めるところでその点の座標を覚えておきます。
for pos in zip(*loc[::-1]):
..................................
#digit1[j,i] = max(digit1[j,i], result[pos[1]][pos[0]])
if result[pos[1]][pos[0]] > digit1[j,i]:
digit1[j,i] = result[pos[1]][pos[0]]
d1p[j,i] = pos
digits.append(digit1)
posn.append(d1p)
下段0,1,2,3カラムのうち、可能性のある1,2カラムで、
覚えておいた位置での小数点付きテンプレートでの類似度と比較します。
row2 = 1
for col in range(1, 3):
n = ds[row2][col]
if digits[n][row2][col] == 0: continue
nh = posn[n][row2][col][0]
nw = posn[n][row2][col][1]
if col == 1:
gain1 = resps[n][nw][nh] / digits[n][row2][col]
else:
gain2 = resps[n][nw][nh] / digits[n][row2][col]
if max(gain1, gain2) < 1.003:
sf = 1
elif gain1 < gain2:
sf = 10
else:
sf = 100
if sf > 1: kwh = kwh / sf
どちらもあまり改善しなかった場合、小数点無しと判断。
それ以外は改善率が大きい方に小数点が存在すると判断。
全体的にもっとすっきりかけるはずなんですが、 残念ながら私には難しかったので昔風の記述になっています。
以上の修正で、綺麗に撮影できているものは100%の認識率に持ち込めました。 ただし斜めに光が入っているようなものは読み外します。
2022年5月19日ログを見ると、最後に仕事部屋のエアコンが自動起動されたのは4/8のようです。 寝室はもうちょっと遅く、5/5まで起動されていました。 そこから後は1回もトリガーがかかっていません。 さて、スマートリモコンを導入したのが11月下旬だったので、 まだ暖房しか制御していません。 そろそろ梅雨がやってくるのでどう制御したものか考えてみます。
基本的には暖房時同様に閾値を上下したら設定温度を変更することでいいはずです。 なので変更点は運転モードと閾値を変更すれば制御部はそのままでいけそうです。 ただ、昨年の梅雨時の自分の挙動を振り返るとちょっとややこしい制御が必要かもしれません。
これを仕事しながら延々繰り返していました。 たまにエコキーパーの表示を見て、 10Wくらいだとコンプレッサーが止まっていることがわかるので 湿度が上がる前に停止したりもしてました。 ちなみに一部のメーカーの機種にはコンプレッサーが停止したときに ファンを停止する機能があります。例えば富士通の「省エネファン」がそうです。 これ、有効だと思うんですがあまり採用例が多くないようです。 フィンが濡れたままファンを止めるとカビの繁殖が懸念されるからでしょうか。
除湿を含む冷房運転時は、コンプレッサーが動いていないと 湿気の戻りにより一気に不快になります。 十分に暑い日は常にパワーがかかるので工夫いらずですが、 あまり暑くないけど湿度は高い梅雨時の制御は 最低限のパワーでできるだけコンプレッサーが動いている時間を長くすることが 快適性の向上につながります。
幸いこの冬に除湿器を導入したのでわりとシンプルに解決できそうです。 たぶんこんな感じ。
5/19のスクリプトでは斜めに影が入ったグループの誤認識が顕著だったのですが、 良く調べてみると画面表示の抜き出しの際に出力サイズを間違っていました。 テンプレートマッチングでは画像を原寸そのままで比較するので 僅かな寸法差でも大幅に読み外すようです。 正しいサイズで抜き出しをやり直すとかなり改善されました。
テンプレートマッチングの解説を読むと このあたりを問題視して実用性が無いと結論付けている例があるのですが、 想像していた以上にサイズの依存性は大きいようです。 特に今回の場合は小数点の位置がテンプレート画像の右下で 基準点から一番遠いので僅かなサイズ違いの影響を強く受けたようです。
今回の場合は画面の右の方に[W]と[kWh]が常に表示されているので この2点間の距離で正規化すると改善できる可能性があると思います。
2022年5月24日
5/19バージョンで失敗した例を見ると以下のような感じを
なぜか左から2カラム目と判断した誤りが多いです。
人間の目だと一見良好に見えますが、これを単純な閾値による二値変換するとこうなります。
左から2カラム目の右下あたりの影に運悪く小数点がマッチしてしまっているようです。
そこで適応的閾値処理というものを導入してみました。 全体一律ではなく、ある程度小さい領域ごとに閾値を決める手法で、 影やムラのある画像に有効らしいです。 サンプルコードと適用例は以下。
bs = 51 c = 15 gray = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, bs, c)
綺麗に二値化できています。 これであまり撮影状況の良くないものも含め 手持ちのほぼ全ての画像で小数点を正しく読めるようになりました。 もっとも下段を読むのはせいぜい一日一回なのであまり意味はありませんが。 あと、実用上はこれにSSOCRをかけるのが最強ではないかと思われます。
2022年5月25日今週に入ってからうちのあたりは最高気温が27℃を上回る日が出てきました。 除湿器を自動運転にしていると少し暑さを感じるので、 手動でエアコンの除湿運転の条件を試してみると、 設定25℃だと寒いけど26℃だと暑いという微妙な感じです。 冬に使っていた暖房制御に少し修正を加えて、 26℃を超えたら設定25℃除湿、下回ったらoffで試すと以下のように発振しました。
07:46 off->26 07:51 26->off 08:11 off->26 08:16 26->off 08:36 off->26 08:41 26->off 08:56 off->26
除湿運転中の消費電力は200W程度で、ちょっとパワー過剰ぎみなようです。 体感でも室温の上下が大きくあまり快適ではありません。
幸いうちの東芝のエアコンには「まろやか運転」というボタンがあって、 設定25℃冷房まろやかだと120W程度まで絞るようです。 この設定は除湿器の自動運転との併用と相性が良いようで、 室温はじわじわ下がるものの、寒さを感じるまで1時間以上かかります。 26℃を超えたらまろやか冷房、25.5℃を下回ったらoff で試すととても快適です。
あと、暖房の場合は早朝寒くなければ日中も大丈夫なので 起動判定は早朝の1回でOKですが、 冷房は途中で暑くなるので早朝に電源off状態で自動制御を起動しています。
なお、うちの東芝のエアコンは冷房を10分以上運転した後に停止すると、 「クリーン運転」といって微送風で数時間フィンを乾燥するモードに入ります。 カビを防止するとてもありがたい機能なのですが、 自動制御時には湿気の戻りが発生するので不要です。 というわけで自動制御時に一時停止する場合にはoff-on-offと3回信号を送信して クリーン運転をキャンセルしています。
これだと夕方の自動停止時に運が悪いとフィンが濡れたままになってしまいます。 そこでいったん11分運転してから停止して強制的にクリーン運転にしています。
ほとんど暖房と同じでいけるだろうと思っていたのですが、 意外なことにかなり違った制御が必要になりました。
2022年5月26日コロナ禍の今、多くの施設の入り口で顔と体温の自動検知が良く見られます。 ああいうことがやってみたいけど難しそうだなと思っていたのですが、 OpenCVだと死ぬほど簡単でした。びっくりです。 Tapo C100での最低限の基本形は以下です。なんとこれだけ。
uid = "ユーザ名"
passwd = "パスワード"
ipadr = "IPアドレス"
url = 'rtsp://'+uid+':'+passwd+'@'+ipadr+'/stream1'
capture = cv2.VideoCapture(url)
while(True):
_, frame = capture.read()
frameを認識処理し加工
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'): break
capture.release()
cv2.destroyAllWindows()
cv2.VideoCaptureでインスタンスを生成しておいて、 無限ループの先頭でreadし、なんらかの処理をして、cv2.imshowで表示。 waitKeyで'q'を押されたら終了処理。
これまでに作ったスクリプトをdefでいくつかの関数にして、 実行してみたところいくつか問題が出たため少し工夫が必要でした。
まずそのままだと全フレーム処理するのですが、 うちのサブノートだと全然追いつきません。 get(cv2.CAP_PROP_FPS)でフレーム数を調べてfor iループで読み飛ばします。 なお、set(cv2.CAP_PROP_FPS,フレームレート)で フレームレートを設定できるようなんですが、 C100ではうまくいきませんでした。15FPS固定仕様みたいです。 あとそもそもRTSPではsetできないかもしれません。
表示画面の抜き出しはcropDisplay関数を作ったのですが、 cv2.putTextで使うためにc4pで四隅の座標を返しています。 なお、nsqは認識した矩形の数で、エラー処理用です。 正常なら1が返りますが暗いときなどは0や稀に2以上が返ります。
認識部はread7segですが、末尾の0の扱いを楽にするために intやfloatではなくstrで返す仕様にしました。
テンプレート画像はもとのスクリプトでは数字ごとにファイルから読み込む仕様だったのですが、 無駄なので最初に1回だけ読んで参照するようにreadTmplとして別にしました。
完成形は以下です。可読性を上げるために細かいエラー処理は除いてあります。
if __name__ == '__main__':
dfps = 1
tmpls, tmplp = readTmpl()
uid = "ユーザ名"
passwd = "パスワード"
ipadr = "IPアドレス"
url = 'rtsp://'+uid+':'+passwd+'@'+ipadr+'/stream1'
capture = cv2.VideoCapture(url)
cfps = capture.get(cv2.CAP_PROP_FPS)
numf = int(cfps*dfps)
while(True):
for i in range(numf):
_, frame = capture.read()
nsq, disp, c4p = cropDisplay(frame)
if nsq != 1: break
watt, kwh = read7seg(disp)
cv2.putText(frame, watt, org=(c4p[0][0][0]+50, c4p[0][0][1]-50),
fontFace=cv2.FONT_HERSHEY_PLAIN, fontScale=3,
color=(0,0,255), thickness=2, lineType=cv2.LINE_AA)
cv2.putText(frame, kwh, org=(c4p[2][0][0]+50, c4p[2][0][1]+50),
fontFace=cv2.FONT_HERSHEY_PLAIN, fontScale=3,
color=(0,0,255), thickness=2, lineType=cv2.LINE_AA)
half = cv2.resize(frame, dsize=None, fx=0.5, fy=0.5)
cv2.imshow('half',half)
if cv2.waitKey(1) & 0xFF == ord('q'): break
capture.release()
cv2.destroyAllWindows()
私のような初心者でもこんなことがすぐにできるとは
有り難い時代になったものです。ちょっと感動しました。
2022年5月27日
昼食休憩でリビングに移動すると暑さを感じるようになってきました。 あとログを見ると深夜に少し寝苦しい気温や湿度になっているようです。 暖房の制御を少し修正して実装してみると、 リビングには追加条件が必要なことがわかりました。
仕事部屋は夏も常に窓が締まっているのですが、 リビングは夏でもそこそこの頻度で網戸になっていることが多いです。 その状態で冷房をかけるのはさすがにどうかと思います。 というわけでドアの開閉センサーが必要なようです。
ドアセンサーくらいならAliExpressでもいいなと思ったのですが、 zigbeeかWiFiの製品しかみつかりませんでした。 zigbeeだとハブが無いので導入する必要がありますし、 WiFiはすでに機器が20台くらい接続されているので増やしたくありません。
幸いSwitchBotに2000円ちょっとであるようです。 思ったより高いのは照度センサーもついているからでしょうか。 BLE対応で、APIは温湿度センサーと共通みたいです。 次のamazonのセールで買おうと思います。
2022年6月1日快適となるエアコンの設定温度が外気温の影響を受けることは 誰もが体感していることだと思います。 先の冬の暖房制御時もたまに目標設定温度をちょっとずつ手動で調整していました。 部屋の温湿度を一定に保てば外気温は関係ないと思うのですが 実際には設定温度は可変とする必要があります。
なぜ外気温の影響を受けるかなのですが、 室外機の熱交換機の効率が変わるからかなと思っていましたが、 調べてみたら特許になってました。 特開平6-147586「空調システムにおける室温制御方法」です。 (ただ、1994年公開なのでたぶん期限が切れてます。) 外気温により壁の温度が上下して 輻射熱により体感気温が変わるからだそうです。なるほど。 しかしこんな普遍的な原理を特許にされたらエアコンメーカーは たまらんだろうなと思いますが実際はどうだったんでしょうかね。 防衛のために抑えておいたのかな?
この特許情報を参考に、
目標温度-3℃より外気温が高い場合は目標温度を0.5℃下げる
とすることによりかなり快適になりました。
サンプルコードは以下。
色々とスクリプトを量産した結果ごちゃごちゃしてきたので
thv.shというスクリプトで各部屋の現在温湿度をjsonで返すように整理しました。
以下例でwは仕事部屋、oはOpenWeahterMapでの外気温です。
JSON=$($ACC_ROOT/thv.sh w) TENOW=$(echo $JSON | jq .te) JSON=$($ACC_ROOT/thv.sh o) TONOW=$(echo $JSON | jq .te) [ $(echo "$TONOW > $TMAXW-3" | bc) = 1 ] && TMAXW=$(echo "$TMAXW-0.5" | bc)今の季節は外気温の乱高下があるので手動での調整は 限界を感じていたので助かりました。 2022年6月3日
梅雨時の温湿度制御を検討しているときに再熱除湿についてわかったことをメモ。
エアコンの除湿は基本的には弱冷房運転です。 室内機の熱交換器で室内の水蒸気を結露させ、ドレンホースから室外へ排出します。 冷媒の熱は室外機で放出されるので室温は下がります。 蒸し暑い日は適温適湿になるので問題無いですが、 そんなに暑くないのに湿度が高い場合は寒くなってしまいます。
一方、一般的なコンプレッサー式除湿器は熱交換器が2層になっていて、 1層目でエアコン同様に空気を冷やして結露させ、 2層目で空気を温めて冷媒を液化して戻します。 1層目で結露した水はタンクにたまります。 エアコンの室外機と除湿器の2層目は熱サイクル的に等価です。 室外との熱の出入りが無いので消費電力ぶん室温が上がります。 なのでエアコンの除湿で寒くなるような条件だとちょうどいいのですが、 蒸し暑い日は室温が上がるのでエアコンの冷房との併用が必要です。 暖房と冷房を同時にかけるので無駄なようですが、 寒くなることは無いのでいちばん快適な方法だと思います。
昔の再熱除湿は専用の電熱ヒーターで暖めて室温が下がらないようにしていたようです。 ただしヒートポンプではないので電気代が跳ね上がり市場から消えました。 そこで最近の再熱除湿では少し工夫してあるようです。
普通の冷房運転時、室外機で液化した冷媒は膨張弁により低圧となり、 室内機の熱交換器で蒸発して室内の空気を冷やします。 室内機の熱交換器は横から見た断面では逆Lや逆U字型ですが、 最近の再熱除湿では途中で2分割され間の2段目の膨張弁に切り替えられ、 1段目では弱暖房、2段目では弱冷房としています。 室内機からは温風と冷風がミックスされて出てきます。 暖房は電熱ヒーターではないので効率は良いです。 ただし室外機でも冷媒の熱を外に放出することになるので 弱冷房程ではないものの室温は少し下がります。 なので商品説明には「寒くなり過ぎない」などの微妙な表現が使われています。
再熱除湿は快適なものの、「電気代が高くなる」というイメージが固定化されたので ダイキンは「新・ハイブリッド方式」と称して 再熱除湿という単語を前面に出すのを避けているようです。 日立は最初に再熱除湿を始めたメーカーらしいのですが、 堂々と「再熱除湿」と明記しています。潔いですね。
2022年6月8日実家の母が高齢の一人暮らしということで 人感センサーで日々の活動状況がわかるといいなと思い AliExpressでPIRセンサーを買ってみました。 まずは相談前に仕様確認です。
実家にはスマートリモコンを設置する需要はないので
単体で動作してほしいということで、
TuyaのWifiタイプにしてみました。
1000円ほどでした。
なお、広義にはTuyaというのはメーカー名ではなくて
デファクトスタンダードとなった通信規格を指すようです。
つまりいっぱい売っている製品はTuya製品ではなくTuya対応という意味になるようです。
ところがこれ、実際に使ってみると色々と気の利かないものでした。 スマホのアプリは妙な日本語化がされていて、 英語設定がみつかりません。無い? 動きを感知するとセンサーが赤く光りますが、オフにする設定が見つかりません。無い? 露骨に監視されているみたいでこれどうなんだろ。
この時点でかなり使う気が失せたのですが、一応LAN経由でAPIを叩いてみました。
かなり面倒なんですが、以下サイトを参考にさせてもらいました。
スマートテーブルタップを Python から制御する
TuyaのpythonのAPIはtinytuyaというものが公開されています。
すると返事が無い。
Wifi版の人感センサーでは電池を節約するために普段はWifiはoffの状態で、
動きを感知したらクラウドにステータスを飛ばし、すぐにWifiを切るようです。
なのでセンサーを反応させてAPI叩くと返事があります。
確かに仕様としては正しいです。 常時接続するとあっという間に電池が切れるでしょうから。 しかしこの仕様ではクラウドが前提となってしまいます。 ところがTuyaはAPIでクラウドを使う場合個人使用は想定されておらず、 1か月のトライアルしかありません。 また実際にクラウドを叩いてみると"t"というキーがunix時間[ms]で返るのですが、 最後にセンサーが反応した時間かと思いきや単に現在時刻でした。 スマホのアプリでは過去の履歴がわかるのですが、 APIから履歴を得る方法は不明でした。
まる一日反応が無かった場合にアラートメールを飛ばしたり、 活動状況のサマリーを出してみたりというような運用を考えていたのですが、 残念ながらAPIで使いたい私の場合は用途に合わない感じです。
IOTの黎明期に象印がインターネット対応の電気ポットを世に送り出しました。 ポットを使った時間が定期的にメールで配信されるというもので、 お互いに監視している、されている感が低いので定着したようです。 秀逸なサービスだと思うのですが、月額3000円程度とそこそこします。 なんとか安価にそういう感じのことがやりたいのですがTuyaではちょっと難しいようです。
2022年6月13日うちの嫁は天気が悪くなると頭痛で寝込むことがあります。 最近では、僅かな気圧の振動を内耳が感知し 交感神経を刺激するのが原因ではないかという説が出ているようです。 こないだ見たテレビ番組では僅か0.5hPaの振動が影響するという ちょっと信じがたい説明がなされていました。
例えば海面高度あたりでは100m上昇するとだいたい10hPa下がるはずなんですが、 うちは4階なのでだいたい10mで1hPa変動するはず。 0.5hPaで調子崩すならばそこらじゅうに寝込む人が出そうですが。 気になったので調べてみましたが、 気圧の変動と体調不良の相関が確認された例は存在しないようです。
とはいうものの、実際にこれを判断基準として
症状が改善された例もたくさんあるのも事実です。
例え理論が怪しくても改善すれば正義です。
冒頭のメカニズムが原因ならば、内耳での気圧変動を緩やかにするために
航空機用の耳栓を使うと緩和することがあるそうで、
ダイソーで買ってきて嫁さんが寝込んだ時に
詳細を説明せずにちょっと付けてもらいました。
すると30分くらいして
「何これ!目の奥がずっと痛かったのが消えた!」
と凄い勢いで起きてきてそのまま通常モードに。
やっぱり信じがたいですがとりあえずなんかありそうです。
エアコンの制御に使う外気温は、これまでOpenWeatherMapから取得していました。 ついでに外の絶対湿度を計算しながらログを取っていたのですが、 気圧変動も追加してみるかと思い立ちました。 ところがOpenWeatherMapが返す気圧は整数で、今回の用途にはちょっと使えません。 調べてみると気象庁のサイトならば0.1hPa単位で配信されているようです。 トークンさえ取れば後はcurl一発なOpenWeatherMapと比較するとちょっと面倒でした。 次回はその具体的な手順を。
2022年6月16日
気象庁の実況データの取得方法は以下が詳しいです。
気象庁ホームページ防災気象情報のURL構造
気象庁の配信方法は豪快です。 一般的なAPIではなくjsonファイルそのものが平置きしてあるようです。 ファイル名は"yyyymmddhhmmss.json"です。 たぶん10分間隔で更新されていると思います。 まず現在時刻より少し前のデータを眺めてみます。
curl -s 'https://www.jma.go.jp/bosai/amedas/data/map/20220617080000.json' | jq . | lessうちの最寄りの練馬のデータを見たいですが、 計測点は5桁のコードしか情報がありません。 というわけで以下一覧でNerimaのコードを調べます。44071でした。
curl -s 'https://www.jma.go.jp/bosai/amedas/const/amedastable.json' | jq . | less
再度配信データを眺めてみると、最寄りの練馬には気圧データがありません。 どうやら気圧を計測している計測点は多くないようです。 おそらく先の一覧で"type"が"A"のところでしょうか。 GUIのサイトで調べてみると東京(44132)の測候所が最寄りでした。
圧力は2つ提供されています。 "pressure"と"normalPressure"で、前者は生データ、後者は海面気圧に補正したものです。 各項目は要素が2つの配列になっていて、[0]が計測値、[1]が信頼度で0以外の時は 信頼性が低いとみなすようです。 というわけで海面気圧を以下のように抜き出します。
JSON=$(curl -s 'https://www.jma.go.jp/bosai/amedas/data/map/20220617080000.json') NP=$(echo $JSON | jq '."44132".normalPressure[0]')ログを取る時は最新データが欲しいのですが、時刻からファイル名を以下のように生成します。
LT=$(curl -s 'https://www.jma.go.jp/bosai/amedas/data/latest_time.txt') LT=$(date -d $LT "+%Y%m%d%H%M%S")ついでに温湿度のデータも気象庁に切り替えようかと思います。 計測点は最寄りの練馬だとこうなります。
JSON=$(curl -s "https://www.jma.go.jp/bosai/amedas/data/map/$LT.json") NP=$(echo $JSON | jq '."44132".normalPressure[0]') TENOW=$(echo $JSON | jq '."44071".temp[0]') HUNOW=$(echo $JSON | jq '."44071".humidity[0]')
すると湿度がエラーになりました。練馬では湿度は計測していないようです。 調べてみると湿度を計測している最寄りはさいたま(43241)でした。 過去の経験から、自宅はさいたまより練馬の予報がマッチするので 温度だけでも練馬を使いたいところなのですが、 絶対湿度は温度と相対湿度をセットで考えるべきですかね。
これで0.1hPa単位で気圧のログが取れるようになりました。 気象庁のサイトでも参照できるのですが、 絶対湿度と比較できるところが利点です。
2022年6月17日以前OpenCV用のDocker環境がうまくいかないと書きましたが、 その後の試行錯誤で落ち着いたのでメモ代わりに公開します。
FROM ubuntu:20.04 ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Asia/Tokyo ENV DISPLAY host.docker.internal:0.0 ENV NO_AT_BRIDGE=1 RUN apt update RUN apt install -y --no-install-recommends vim RUN apt install -y --no-install-recommends less rsync RUN apt install -y --no-install-recommends libgl1-mesa-dev libgtk2.0-dev RUN apt install -y --no-install-recommends x11-xserver-utils RUN apt install -y --no-install-recommends eog dbus-x11 gnome-icon-theme RUN apt install -y --no-install-recommends python3-pip RUN pip3 install opencv-python RUN apt install -y --no-install-recommends openssh-server RUN mkdir /var/run/sshd RUN echo 'root:screencast' | chpasswd RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config RUN sed -i 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' /etc/pam.d/sshd RUN sed -i 's/#Port 22/Port 20022/' /etc/ssh/sshd_config EXPOSE 20022 CMD ["/usr/sbin/sshd", "-D"] # docker build -t cv2:1.3 . # docker run -d -p 20021:20022 -v c:\work:/work --name cv213 cv2:1.3 # putty -P 20021 root@localhost # docker stop cv213 # docker start cv213
できるだけバージョンは固定した方が将来困らないと思うんですが、 そのあたり残念ながらよくわかりません。
最初のENVのあたりはインストール中に言語の選択を求められるのを回避しています。
DISPLAYは毎回指定するのが面倒なのでこうやると大丈夫みたい。
vim,less,rsyncは私が良く使うだけなので不要なら外してOK。
X Windowで表示するところでエラーになっていたんですが、
libgl1-mesa-dev,libgtk-dev,x11-server-utilsの3つを入れれば
足りないものがなくなるようです。
eogはよく使うので入れてますがこの行も不要です。
RUN〜CMDのところは外からsshで入るために定義してますが不要です。
最後のコメントのところはビルドと起動停止の手順です。
毎回docker runするのではなくdocker stop/startで前回の状態から再開して使っています。
暑くなってきて各部屋のエアコンにAPI制御が入るようになりました。 そこで気が付いたのがカビ防止機能のメーカーによる挙動の相違です。 いまどきのエアコンには必ずついている、冷房あるいは除湿運転後に自動的に弱送風モードで 室内機のフィンを乾燥させるあれです。
うちのエアコンは仕事部屋は東芝、リビングと寝室はダイキンなのですが、 ダイキンはスマートリモコンのプリセット信号で停止すると この機能(ダイキンでは内部クリーンと呼んでいます)が働きません。 どうやらダイキンはこの機能のon/offは 予め停止時にリモコンの操作でモードを切り替えておくと、 送られるリモコン信号にモードon/offが含まれる仕様のようです。
一方、東芝はon/offは本体側で記憶されておりリモコン信号では制御されていません。
本体設定がonの状態で意図的にoffにするには
私が仕事部屋のエアコンでやっているようにoff-on-offという操作が必要です。
<追記>
東芝の説明書によるとoff-on-offという手順なんですが、
これはうちの機種のリモコンの電源ボタンがトグル動作になっているからです。
スマートリモコンだとoffを連続で送れるので試してみたらそれでいけました。
ちょっとリビングのエアコンで信号を学習して試してみましたが、 物理リモコンで内部クリーンonで冷房運転すると本体の内部クリーンランプが点灯します。 これで5分以上運転してから停止すると内部クリーンが始まるはずなのですが、 スマートリモコンで内部クリーンoffの停止信号を送ると 内部クリーン運転されません。本体ランプも消灯されます。
逆にスマートリモコンの内部クリーンoffの信号で冷房運転を開始すると 本体の内部クリーンランプは点灯しません。 ここで5分以上運転してから物理リモコンで停止すると、 今度は内部クリーン運転され本体ランプも点灯します。 つまり停止信号に内部クリーンonのコマンドが含まれているかどうかで挙動が決まるようです。
なのでダイキンのエアコンをスマートリモコンのプリセットで停止すると、 フィンが濡れたままになってカビの発生が懸念されます。 学習機能でクリーン運転を有効にした停止信号を記憶させるか、 停止前に手動でしばらく送風モードで運転する必要があります。 長期の不在時に出かけた後にスマホから冷房を停止したときなどは カビが大繁殖する危険性があるので注意が必要だと思います。 ちなみにダイキンのトラップ仕様として、 タイマーで停止した場合は内部クリーンは働きません。 お出かけ前に消し忘れ防止で停止タイマーとかやるとカビ祭りです。
2022年6月27日これまで仕事部屋の制御は温度を見て 冷房25℃まろやか/停止 でやっていたのですが、 外気温が30℃を上回るようになってパワー不足が発生しました。 そこで外気温>目標温度+3の場合は冷房24℃とするように追加したところ、 ほぼ手動での修正が不要な理想的な制御になりました。
TMAXW=27.0
[ $(echo "$TONOW > $TMAXW-3" | bc) = 1 ] && TMAXW=$(echo "$TMAXW-0.5" | bc)
if [ $(echo "$TENOW > $TMAXW" | bc) = 1 ]; then
SIG=$C25M
if [ $(echo "$TONOW > $TMAXW+3" | bc) = 1 ]; then
SIG=$C24A
fi
SIG送信処理
elif [ $(echo "$TENOW < $TMAXW-0.5" | bc) = 1 ]; then
停止処理(off-on-off)
fi
まあ最近のエアコンに更新すればこんな制御は不要かとは思いますが。 コロナ起因の半導体不足で私が欲しい富士通の普及モデルは品切れが続いているようです。 今のが故障したらどうしようとかなり不安な毎日です。 こんなことなら在庫が豊富だった春に更新しておけばよかったです。
2022年6月30日寝室は夏場は自動制御の需要はほとんどありません。 だいたい毎日暑いので寝る前にエアコンを起動して朝起きたら消すだけで特に不満はありません。 ただ、深夜温度が上がった時に寝苦しさを感じて途中で起きてつけることがあるので そこだけ何とかしてみました。
まずcrontabで寝ている時間帯の毎時2分に起動チェックをかけます。
2 23,0-7 * * * /home/user/sremo/acb.sh on
色々試したところ、絶対湿度16.5を閾値とするといい感じでした。 乾燥した暑い日に対応するために28℃も追加。 閾値を下回った場合にoffにするのも試してみましたが、 次の判定で間違いなくonになったのでやめました。 寝室では外気温での判定は不要でした。日照の影響が無いからでしょうか。
JSON=$($ACC_ROOT/thv.sh b)
TENOW=$(echo $JSON | jq .te)
VHNOW=$(echo $JSON | jq .vh)
if [ ! -f $ACC_ROOT/acbsw ]; then
PW=off
echo $PW > $ACC_ROOT/acbsw
fi
CPW=$(cat $ACC_ROOT/acbsw)
if [ $(echo "$VHNOW > 16.5" | bc) = 1 ]; then
PW=on
SIG=275c1
elif [ $(echo "$TENOW > 28.0" | bc) = 1 ]; then
PW=on
SIG=275c1
else
PW=$CPW
fi
if [ $1 = off ]; then
PW=off
SIG=offc
fi
if [ $PW != $CPW ] || [ $1 = "off" ]; then
SIG送信
fi
if [ $1 = "off" ]; then
rm -f $ACC_ROOT/acbsw
else
echo $PW > $ACC_ROOT/acbsw
fi
エアコンの設定は冷房27.5℃で制御不要。 SwitchBotはプリセットでは0.5℃の送信ができないので学習信号を送信します。 後は8:45に停止しておしまいです。 なお、offはプリセットではなく内部クリーンを学習した信号を送信しています。
45 8 * * * /home/user/sremo/acb.sh offこの程度ならほとんどスマホアプリでもいけそうですね。 2022年7月6日
仕事部屋のエアコン制御に気象庁サイトから取得した外気温による補正を導入して以来、 ほとんど手動操作の必要が無い快適な毎日が過ごせています。 特に昼頃に外気温が上がってくると先読みする感じで設定が下がるのがとても快適です。 ところがこれはネットからの取得でないと実現できないようです。
製品のエアコンで外気温を計測するには室外機の吸気側しかないのですが、 ここの温度はかなり外乱の影響を受けるので普通まともな値は取れません。 例えばうちの仕事部屋の室外機はもろに直射日光を受けますし、 リビングのはベランダのコの字型に奥まった場所なので排熱が滞留しています。 いずれもそのまま制御に使うにはかなり無理があります。
実際の室外機センサーの適用例を探しても 機器異常を感知するために使われているものばかりで、 6/3に紹介した特許のように設定温度の補正に使われている例は見当たりませんでした。 そこで見つかったのがシャープのCOCORO AIRというクラウドサービスで、 これは予報で先取りして制御したりまでするかなり高度なものです。 私のはそれの原始的なやつを自前でやってみたということになりますね。
2022年7月21日夏のセールで安くなっていたので仕事部屋のエアコンを発注しました。 色々考えて選定したのでメモ。
条件は以下。 仕事部屋は狭いので6畳用の2.2kWで、フィルターの自動清掃は邪魔なので無し。 この条件でほぼ普及クラスで確定します。 このクラスだと高効率のハイエンドモデルでは 価格差を回収するのに10年以上かかる見込みなのでそれで十分です。 好みから、ダイキン、三菱電機、富士通が候補に残りました。
ダイキンのEシリーズは寝室で使っていて非常にできがいいことはわかっていますが、 同じものは面白くないので見送り。
富士通は除湿時にコンプレッサーが停止するとファンを止める機能が 湿気戻り対策として魅力的です。 普及機はCシリーズですが、+1万円程度で買えるVシリーズが 6畳用普及機だとAPF5.8くらいが普通なのに6.6と高性能です。 年間の使用電力が100kWhくらい下がる見込みで、数年で元が取れそうです。 ただ、リモコンの風向や風量ボタンがカバー内という信じられない仕様です。 あと、制御がおおざっぱという評判が気になり見送り。
三菱電機は普及機も国産というのが好印象です。
霧ヶ峰は分解清掃もしやすくDIY派には定評があります。
決め手はGEシリーズには簡易版ながら赤外線床温度センサーが付いています。
なお、ほぼ同価格のGVシリーズは色々省略されているので注意。
<補足>
工事前に説明書読んでたら霧ヶ峰も富士通同様に
風向や風量ボタンがカバー内でした。
自動モードに自信があるということでいいのでしょうか。
工事と回収費用、ポイント還元を併せて7万円ちょっとでした。 暑さの盛りは過ぎたようですがちょっと楽しみです。
2022年8月17日まあたいしたもんだな、というのが率直な感想です。
冷房に関しては基本的には一度それなりの温度設定にすればほぼ設定要らずで 快適な室温を完璧に保ちます。 スマートリモコンの自動制御で一応外気温で設定温度を微調整してみましたが、 基本的にはタイマーでon/offだけでもいけそうです。 床温度センサーもとりあえず有効にしてありますが役に立っているようです。
感心したのが気温が下がっても寒さを感じることがありません。 気流の設計が優秀なのでしょうか。 ただ、除湿能力は低いようで、旧エアコンだと絶対湿度13g/m3くらいだったのに これだと15g/m3とかなり高いです。 冷房ではなく除湿にしても温度だけ下がって湿度が下がりません。 湿度が高いので体感温度が高めになっているのかもしれませんね。
ドレンの水量を見てもほとんど出ていないので除湿能力の低さは確実なようです。 まあ湿度を下げたい場合は除湿器併用でいいかなと思っています。 最近のエアコンは効率を追求してか室内機の熱交換器がどんどん大型化しているのですが たぶんその影響でフィンがあまり冷たくならないのが原因じゃないかと思います。 湿度の高さを感じることは無いので湿度計を見なければ問題無いです。
室外機を見てびっくり。非常にコンパクトでかつ中がスカスカです。 熱交換器は薄いものが1段だけ。 こんなんで大丈夫かと思いましたが設定を下げるとガンガンに効きます。
電力計を見ていると絞っても250W程度で、かつ頻繁にコンプレッサーが止まります。 旧エアコンで「まろやか」を使わないときの挙動に似ています。 ただ、旧エアコンではコンプレッサーが止まったところで もわっとした不快なぬるい気流が出ていたのがこいつには全くありません。 かなり芸の細かい制御をやっているようです。 間欠運転で使用電力量は大丈夫かと思ったら 同じような外気温の日での比較では旧エアコンとほぼ同等でした。 「まろやか」で130Wくらいまで絞れる東芝の旧エアコンは 省エネ性能に関してはかなり優秀だったようです。
内部クリーンの仕様はダイキンと概ね同じで、 off信号のフラグで起動される仕様です。 注意が必要な点としては送風運転の後に弱暖房が必ず入るようなので 人がいるのにちょっと止めた場合でも温風が吹き出す困った仕様です。 モード切替は結構面倒なので、ちょっと止める場合は スマートリモコンのプリセットで操作するのがいいと思います
気になった点を色々列挙しましたが、 基本的にはボタン一発で温度環境が快適に保たれるので非常に優秀です。 満足度の高い買い物でした。
2022年8月25日しばらく仕事部屋の冷暖房は不要でしたが、 だんだん寒くなって来たので暖房をつけてみました。 結果、霧ヶ峰の制御で十分でした。 床温度センサーを有効にして23℃暖房の設定で快適です。 電力量計のログを見るとたまに運転してはすぐ止まっている感じです。 ただ、昼に外気温が上がってくるとちょっと暑さを感じることがあります。
というわけで
私はほぼ100%在宅勤務で、嫁も近所の職場なので起床は遅いです。 一方娘は在宅ではできない仕事なので通勤のために起床は07:00前です。 そこでリビングのエアコンは毎朝06:30に起動しています。 ところが遊びまわっていて帰って来ないこともしばしば。 そういう時は無駄に早く起動することになるので気になっていました。 スマホアプリだとGPS情報と組み合わせたりするみたいですが、 もっとお手軽な方法は無いかなと考えてみました。
会社LANの死活監視はarpwatchを使ってましたが、 常時接続が前提のサーバ系とは違い、 スマホはスリープ時にWi-Fi切ったりしそうであてにならない気がします。 結局は定期的にpingで叩くのがいちばんだろう、ということで試してみました。
まず娘のスマホのMACアドレスを調べておいて、 自宅ルータのDHCPサーバ設定でIPアドレスを固定しておきます。 あとは一定間隔でpingで叩いてステータスをログに取るだけ。 ただし全部取ると長くなるので、前回とステータスが異なる場合だけログに残すことにしました。 完成品は以下。
#!/bin/bash
ACC_ROOT=$(cd $(dirname $0); pwd)
. $ACC_ROOT/acc.def
FNAME=$ACC_ROOT/musume.log
PING=$(ping -c 1 $IPM)
ISM=$?
PS=$(tail -1 $FNAME | awk 'BEGIN{FS=","}{print $2}')
NJ=$(/bin/date --iso-8601="minutes")
[ $PS -ne $ISM ] && echo $NJ","$ISM >> $FNAME
最後にステータスに変化があった時刻と、 居る場合には0、居ない場合は1がログに記録されます。 最後に在宅を確認できたのがステータスが0の最終行の時刻ですから、 以下スクリプトで前日21:00以降に在宅したかどうかがわかります。
#!/bin/bash
ACC_ROOT=$(cd $(dirname $0); pwd)
. $ACC_ROOT/acc.def
FNAME=$ACC_ROOT/musume.log
PS=$(tail -1 $FNAME | awk 'BEGIN{FS=","}{print $2}')
[ $PS -eq 0 ] && exit 0
LJ=$(grep '0$' $FNAME | tail -1 | awk 'BEGIN{FS=","}{print $1}' | /bin/date -f - +%s)
Y21=$(/bin/date -d '1 days ago 2100' +%s)
[ $LJ -ge $Y21 ] && exit 0
exit 1
後はこれで06:30の起動時にチェックして、居なければキャンセルすればOKです。 起動スクリプトは私が起きるちょっと前の07:30にも仕掛けておけば 60分ほどエアコンの運転時間を短縮できます。
<補足>
android9以降はWi-Fiはスリープ時も常に有効みたいで、
帰宅から翌日まで常にping応答がある状態でした。
初期バージョンだと21:00前に帰宅した場合不在判定になるので
最新のステータスが0なら在宅の処理を追加。
というかそれならログ取らなくても都度pingだけでもいいかも。
結論から行くと、ほとんどのマンションでは かなり広い部屋でもエアコンは6畳用でいいみたいです。 例外は建物の端や最上階の場合は能力不足の可能性がありますが、 それもだいたい2000年以前の断熱材が入って無かった時代の物件のみ問題となるようです。
現在リビングのエアコンは12畳用のを使ってます。 冷房能力は3.6kW、低温時暖房能力は4.0kW。2013年モデルです。 廉価グレードなのでAPFは4.9と低効率です。 前回故障での更新時リビング10畳+隣の6畳をカバーできるという観点でテキトーに選定しました。 電力会社の1時間ごとの使用量を確認した感じだと リビングのエアコンがついている時間帯が目立って消費量が多いようだったので 最近の高効率なものに更新すると削減できないかと考えました。
普段使っている感じだと暑さ寒さを感じて運転を開始すると 30分くらいで風量が落ち着くのでかなり余裕があるように感じます。 エアコンは無駄に大きいものを選ぶと効率が落ちるそうなので もう少し小さいものが適切なようです。 というわけで調べてみると、驚くことにマンションのリビングは 6畳用で全然問題なかったという人がたくさんいます。 これは一般的な推奨目安が1964年(!)の 断熱性能皆無の住宅が前提となっているからだそうです。
マンションの断熱性能は住宅性能表示の法律が施行された 2000年あたりを境に大きく向上したようです。 自宅マンションの竣工は2000年8月で、残念ながらぎりぎり間に合わなかったようです。 例えば窓は見事にアルミサッシ+単板ガラスで断熱性能は皆無です。 ただ、メンテナンスホールから見た感じだと外壁空間には しっかりウレタン吹付がなされていてそこそこ外壁の断熱は期待していいようです。 マンションの場合は両隣と上下は同一温度で熱境界ではないという考え方なんだそうですが、 うちは建物の端なのでリビングは片側が外壁に面していてここが無断熱だと さすがにダメですが幸い大丈夫でした。
住宅の断熱性能にQ値という指標があります。 単位は[W/m2K]で、これに床面積と室内外温度差をかけると必要なエアコンの能力が出てきます。 床面積じゃなくて境界の表面積じゃないのと思ったら 後にUA値という外皮面積を使う指標に取って代わられています。やっぱり。 ただ歴史が長いだけあって情報も豊富なので今回はQ値を使って検討します。
エアコンの要求能力を計算するためにはうちのQ値が必要です。
本来は壁や窓の面積に係数をかけてから平均化するらしいんですが、
よくわからないので既往の検討例から推測します。
色々探して発見したのが以下サイトです。
マンション住戸位置による温熱環境の違い
この例の場合、無断熱壁+単板ガラスの場合、
Q値は中層階で角部屋の場合5.60、中間では3.20という値となっています。
うちの場合は角部屋の断熱壁+単板ガラスなのでQ値は
3.20よりは上、5.60よりは下、のはずです。まあざっくり4でいいでしょう。
うちはこの計算例よりガラスの占める割合が大きいのでもうちょっと高いかもしれませんが。
ちなみに断熱壁+ペアガラスの場合は角部屋で1.63、中間で1.32と非常に良好です。
Q値を4として試算してみます。 リビング+隣の部屋で16畳≒29m2で、 最大室内外温度差は夏(40-26)=14K、冬(25-0)=25Kを想定すると 必要能力は冷房1.6kW、暖房2.9kWとなります。 先日更新した仕事部屋のエアコンは冷房能力2.2kW、低温時暖房能力2.8kWなのですが、 仮に同じ機種で更新した場合、夏は余裕、冬はほぼぴったりです。 あくまで最悪の条件なのでやっぱり普段は6畳用で余裕がありそうですし、 現状床暖房を併用しているので問題ないです。 不安があるとすると立ち上がりでしょうか。 計算上はぎりぎりなので6畳用では全開でも速やかに温度が上がらないことが懸念されます。 本当は全開運転時の消費電力を直接計測できるといいんですが、 エコキーパーでは容量不足でリビングのは計測できません。 ちなみに無断熱壁のQ値5.6を使うと必要な暖房能力4.1kWとなるので 現状のエアコンでほぼぴったりとなるようです。
他の観点でも見てみましょう。 この冬のログを見ると、明け方に室温18℃くらいまで下がることもありますが、 日が出るとそこから上がり始めます。 帰省して数日間不在にした後の年始でも最低室温15℃でした。 この事実からするとちょっと暖めればすぐに適温になるのは自明です。
メーカーの推奨目安が大昔のままなのは価格の高い大きい機種を売りたいからでしょうし、 量販店の販売員も売り上げを考えると6畳用で大丈夫とは言わないでしょう。 それにダメで返品交換再工事となった時の責任を考えると 余裕を見た目安とするのも仕方ない気もします。 が、世の中全体で省エネルギーを掲げている現状、 もうちょっと良心的な目安を示してもいいんじゃないかなと思います。
2023年1月11日前回の検討ではそれらしいQ値を拾ってきて、 それに床面積と温度差をかけてエアコンの必要性能を推定しました。 今回は面積から直接熱損失量を手作業で試算してみます。 今回は似たような物理量が山のように出てきますが、ポイントは単位です。 欲しい単位になるように逆数を取ったり割ったりして求めれば間違いません。
まずスケールでリビングの外皮面積とガラス(+アルミサッシ)面積を測定します。 外皮面積は約29m2、ガラス面積は約14m2でした。 よって断熱壁の面積は15m2ということになります。 ずいぶんと外皮面積に対してガラス面積が大きいですが、 自宅マンションが竣工していた2000年頃は逆梁工法というものが流行しており、 ベランダ側の床から天井までほぼ全面ガラスだからです。 とても開放感があって気に入っているのですが、断熱性能という観点では不利です。
次に壁とガラスの熱貫流率を調べます。 熱貫流率の単位は[W/m2K]で、 材料の熱伝導率と厚さおよび表裏表面の熱伝達率をまとめて 設計に使いやすくしたものです。 Q値と単位が同じですが、建物全体を壁やガラスなど部材ごとに分解したと思えばいいかと。
ガラスは単板ガラスの値で6.51というのがあったのでそのまま使えばいいのですが、 うちの場合は断熱壁の値が問題でした。 メンテナンスホール内のウレタンにキリを突き刺すと厚さは30mmでした。 ネットの情報だと最薄で40mmまでしか無かったので自分で算出します。
発泡ウレタンの熱伝導率として0.026[W/mK]というのがあったので、 厚さをそれで割ってウレタン層の熱抵抗1.15[m2K/W]が求まります。 空気との表面熱抵抗は一律0.11[m2K/W]でいいみたいなので 全部足すと0.11+1.15+0.11 = 1.37[m2K/W]。 これが断熱壁全体の熱抵抗で、 逆数を取ると断熱壁の熱貫流率0.73[W/m2K]と出てきます。 ガラスの値に比較して非常に小さいです。
<補足>
室内側の石膏ボードが抜けてました。
厚さ15mmで計算すると熱貫流率0.70と僅かに下がるみたいです。
実際にはウレタンは壁全面に入っているわけではなく 木枠が等間隔に入っていてそこは直接熱が伝わるので その部分(熱橋部と呼ばれるそうです)の断熱性能は悪化するようですが、 面積比率で数%程度なので無視することにします。 いずれにしてもガラスの値に比較してかなり小さいのでテキトーでいいはず。 今回は表面の熱伝達率を無視して算出した 熱貫流率0.87[W/m2K]を使うことにします。
それぞれの係数に面積をかけて足すと以下の数字が出てきます。
ガラス+断熱壁 = 90.2+13.5 = 104[W/K]
これはQ値に床面積をかけたものに相当しますが、
意味は1Kの温度差での外皮全体の熱貫流量で、総合熱貫流率と呼ばれるそうです。
30mmと乏しい断熱壁でも効果は絶大で9割近くがガラス面から出入りすることがわかります。
なお、Q値には実は1時間に1回の換気の損失0.39[W/m2K]が含まれているようですが、 うちはほとんど換気をしないので無視していいことにしました。 キッチンの換気扇を強めにするとベランダドアが開かなくなるくらいなので気密性も高いはず。
さて、前回は暖房能力がギリギリではないかということで問題となりました。 冬の想定温度差25をかけると2.6kW。6畳用2.8kWでも少し余裕がある試算結果となりました。 やっぱり大丈夫そうです。
2023年1月12日結論から行きますと、単板ガラスの場合 カーテンの断熱効果はそれなりに期待していいようです。 以前からカーテン閉めると暖房の効きが少し良くなる気がしてたのですが 実際にカーテンとガラスの間の温度を計測してみました。
なお、ちょっと出典が確認できなかったのですが、 最新の住宅性能基準ではカーテンは断熱効果に考慮できないみたいです。 ただしうちの場合は単板ガラスで実際に効いているようなので検討してみました。
カーテン布単体の断熱性能は単板ガラスと概ね同等みたいです。 つまり理想的にカーテンと窓の間が密閉されている場合、 熱貫流率は半分に、空間内の温度は外気温と室温の中間値になるはず。 ただしコールドドラフトという現象で実際にはかなり性能低下するようです。 コールドドラフトとは窓で冷やされた冷気により下向きの気流が発生するやっかいな現象です。 カーテンの場合は上の隙間から入り、下の隙間から冷やされた空気が出てきます。
以下はリビングの室温およびカーテン裏の上下位置の温度ログです。
温度計は上側はだいたい2m高さ、下はガラスの下端床付近に設置しました。
外気温の参考としてJMAのさいたまの数字を併せてプロットしています。
この日は前日22時頃に床暖房を切って、
3つの温度計の差はほぼ一定で推移しており、
朝6時頃にほぼ平衡状態になっています。
そのときの温度は、室内19.5、上側16.3、床付近14.1、外気温2.5でした。
最後に少し上がっているのは日の出の影響だと思います。
朝7時に天井と床の温度を非接触温度計で測ったら天井21℃床20℃だったので
カーテン室内側に高さ方向の温度勾配はほぼ無いようでした。
なので温度差はコールドドラフトの影響と考えられます。
カーテンで発生するコールドドラフトの理解に一番参考になったのは以下サイトです。
窓の断熱の工夫による効果計算
計算過程も含めて詳細に解説されているのが秀逸で、
条件を変更して傾向を確認できるのも素晴らしいです。
ちなみにうちのカーテンの隙間を計測すると上1cm、下2cmでした。
小さい方の1cm、近い値として外気温0℃を入力すると間隙の温度は13.6℃と
ほぼ床付近の実測値と同じ値となりました。
このときのカーテンの断熱性能への寄与率は0.32。
およそ全体の1/3で、カーテン無しと比較すると断熱性能はおよそ1.5倍となります。
カーテンを閉めればエアコンの暖房能力は6畳用で完全にOKと判断できます。
ここで隙間を2cmとすると寄与率が0.205と一気に悪化します。 カーテンの断熱には上下の隙間を小さくすることが非常に大事だということがわかります。 ちなみに普通のカーテンは左右がガバガバなので、 上側の隙間を小さくする方が効果が高いと思います。 逆の場合、上側の全幅から入った気流は下端の両側から左右に抜けてしまいます。 一方、上をふさぐと両側から入った気流はすぐに下を向くので 中央付近の上半分くらいは滞留してくれるはず。 市販のコールドドラフト対策グッズは下側をふさぐものが多いのですが、 カーテンのフックを調節して上の隙間をギリギリまで詰めた方がゼロ円かつ効果的だと思います。
実はこれまでリビングのカーテンはソファーに干渉するので 幅1/3くらい開けたままでレースのカーテンのみでした。 今回カーテン裏の温度計を設置するときに、配置を見直してぴったり閉めたら 体感はっきりわかるくらい改善されてびびりました。 今まで一体どれだけのエネルギーを無駄に消費していたのかと反省することしきりです。
2023年1月16日リビングのエアコンは100V20Aなのでエコキーパーでは測れません。 最大消費電力1500Wと容量上限なので危険ですし、 そもそも20Aはプラグ形状が違って接続不能です。 でもエアコンを更新するなら熱計算による推定ではなく直接計測して確認したいと思っていました。
ところが先日自宅の電気設備点検に立ち会った時に見物していて気がつきました。 分電盤のカバーを外すとエアコンの安全ブレーカーの配線にクランプメーターが入りそうです。 だったら直接測れるな、ということでやってみました。
今日の昼休みにセットしてまずエアコンを普段通り設定26℃風量自動で起動します。 カーテンはぴったり閉めておきました。 運転前の室温は23℃、外気温は10℃でした。 起動後数分で最大11A程度まで上がり、さらに数分後8Aに下がり、 30分ほどして室温が25℃に達したあたりで6.5A程度で定常状態になりました。 消費電力は電圧×電流×力率で、エアコンの力率は低出力時に0.7程度、全開時に0.9程度らしいです。 定常時でも室外機はけっこうがんばっている感じなので0.8とすると、 消費電力は
起動時:100×11×0.9 ≒ 1000[W]
定常時:100×6.5×0.8 ≒ 520[W]
となります。 ただしこれは外気温10℃の条件です。 本当は深夜や早朝などのもっと外気温が低い条件で再計測したいところですが、 そんな時間に分電盤開けて作業していると家族に迷惑なので推定します。
消費電力は室内外の温度差に比例します。 早朝の外気温0℃、起動前20℃、定常時25℃とすると、
早朝起動時:1000×(20-0)/(23-10) ≒ 1540[W]
早朝定常時:520×(25-0)/(25-10) ≒ 870[W]
最近更新した仕事部屋の6畳用は低温時消費電力1160Wなので、 仮に暖房COPが同等と仮定すると定常時にはかなり余裕がありそうです。 一方、起動時の立ち上がりには今よりだいぶ時間がかかりそうです。
2023年1月18日
クランプメーターでの計測では推定力率で消費電力を算出しましたが、
わりとギリギリの値だったので気になりました。
というわけで調べてみたら200V20A対応の電力計が
安価に入手可能なことがわかったので購入してみました。
「DIYをめぐる冒険」
というYouTubeチャンネルで紹介されていたものです。
200V20A対応の電力計は何種類かあるみたいなんですが、
この機種は力率が表示されるのでそこが決め手となりました。
Amazonでも買えるようですが、AliExpressだと1000円ちょっと、
あとはコネクタとコードも合わせると合計2000円ちょっとでした。
200V20A対応の電力計に配線がなされた安価な完成品は無いようです。 今回のも自分で配線が必要です。 色々と危ないので完成写真や加工の詳細は伏せておきます。 昼休みに配線加工して測定してみると10.6A時の力率は0.85でした。 これで早朝のフルパワー時の正確な消費電力を確認してみようと思います。
2023年1月24日というわけで最も厳しい条件の早朝に電力計で直接計測してみました。 負荷によって力率がけっこう変動するので やはりクランプメーターでは限界があったようです。
1/25に計測してみたら10年に一度と報道された寒波の影響で 起動後10分で1400Wのほぼ全開運転になってしまい、 60分経過しても全開のままだったのでテストになりませんでした。 一応室温は18℃から23℃に上がったので、 厳寒時能力にかなり余裕があることははっきりしましたが。
というわけで1/26に再チャレンジ。結局前日と大差ない条件だったようですが以下時系列で示します。
開始時のJMAさいたまの気温が強烈ですが、 ベランダ床の実測値が3℃だったので意外とガラス外側はそうでもなかったようです。 室温23℃で消費電力850Wくらいで熱収支が均衡するようです。 内外気温差20℃ということになるでしょうか。
リビングのエアコンの低温時性能は室内機ステッカーによると、 消費電力1500W 暖房能力4000Wだそうです。なのでCOP値は4000/1500≒2.67[-]です。 つまり850x2.67≒2270Wが均衡する暖房能力。これより低いと室温を23℃まで上げることができません。
室温変化を見ると概ね5分で0.5℃、つまり0.1[℃/min]上昇していて消費電力は1300Wくらい。 そのときの暖房能力は1300x2.67≒3470Wです。 3470-2270=1200Wの上乗せで速やかな温度上昇が達成されていることがわかります。 なお、6:05〜6:10の消費電力は1400W近いですが、短時間なので無視していいです。
仮に仕事部屋の6畳用エアコンをリビングに設置した場合を考えます。 カタログによると低温時暖房能力は2800W。 2800-2270=530W。全開時の上乗せがざっと半分。 私の体感だと22℃くらいでかなり快適になるのでそこを目標とすると、 現状35分が1時間以上かかるようになりそうです。
それでも十分という判断もあるかと思いますが、 家族から苦情が出そうな立ち上がり性能差です。 同じシリーズの10畳用だと低温時暖房能力は3400Wでほぼぴったり。 これで現状12畳用と同程度の立ち上がり性能を確保して効率アップ というあたりがうちの場合は正解ではないかと思います。
2023年1月26日AliExpressではたまに粗悪品に遭遇することがあります。 今回はかなりその可能性が高いものに手を出して敗北しました。 まあ楽しめたので良しとし、記録に残しておきます。
自宅はそこそこ気密性が高いのですが、私はあまり換気をする習慣がありません。 在宅勤務の際にCO2濃度が上昇し仕事の効率が落ちているのではないかと気になっていました。 CO2モニターはコロナ禍で飲食店などで需要が急増したようですが、 便乗してそれっぽい表示を偽装した偽物が蔓延っているようです。 まあ届いたものが偽物だったら笑えばいいかと思ってAliExpressで1505円のを注文しました。 YouTubeの分解動画でNDIRセンサーが入った本物があったので、 一応外観の特徴をよく見て同じものを注文しました。
春節の影響でほぼ1ヶ月後到着。開封すると形状が写真と違います。あれれ。
呼気を吹きかけても反応なし。アルコールには激しく反応で偽物確定です。
分解するとVOCセンサーが出てきました。残念。
じゃあ日本の通販で確実にNDIRセンサーを使っているものを買うかなと思いましたが やっぱりちょっと高い3500円程度します。 何とか格安で買えないかと思ってメルカリを見たら欲しかったのと同じ外観のが1500円で出ていました。 これなら違うものが届くこともないだろうと購入。翌日到着しました。
製品外観はYouTubeの分解動画と同じですし、外箱も同じものです。
呼気を吹きかけるとちゃんと反応します。よし。
ところがアルコールにも反応します。あれれ。
分解すると基板が動画と別物で、しっかりVOCセンサーでした。
こっちの方が偽装ロジックが凝っているようです。
最初からNDIRセンサーを明記しているものを買えば本物が買えたのですが、失敗でした。 後でわかったことですが、秋月でNDIRセンサー単体で2500円くらいしています。 いくらなんでも1500円で販売するのは不可能なようです。 今回は失敗を認め潔く撤退しようかと思います。
2023年2月13日SwitchBotのAPIの新バージョンv1.1がリリースされたようです。 スマートロックへの対応に伴いセキュリティが強化されています。 当面は従前のv1.0も併用できるようですが、更新は無いそうです。
v1.0だと誤ってトークンを流出させてしまうと 世界中から操作し放題になるのでスマートロックへは使えない仕様にしていたものと思われます。 対して、v1.1のサンプルコードを眺めてみると、秘密鍵での署名とタイムスタンプを組み合わせてあります。 確かに多少はましになりそうですが、トークンをうっかり流出させてしまうような人なら セットで秘密鍵も流出させてしまう気がします。 面倒になっただけであんまり対策になっていないような。
bashのサンプルコードは無かったので自力での対応を試みましたが、 私の知識ではどうにもうまくいきませんでした。 sha256sumとbase64を組み合わせればいけると思うのですが、 bashが苦手とするバイナリの扱いが解決できません。
とりあえずpythonのサンプルコードを小変更して、 トークンと秘密鍵を渡せばsignとタイムスタンプをセットで返す単体のスクリプトにして 従前のようにbash+curlで試したところ動作はすることを確認しました。 これで一応v1.0が廃止されても大丈夫です。
SwitchBotはちょっと前にAWSの障害の影響でAPIが数時間死ぬという失態を犯しています。 冗長化が甘いのと、失敗しているのにステータスに成功を返すという素人っぷりでした。 高精度な温湿度計と豊富なオプションという魅力はあるものの どうにもお粗末ですね。
2023年6月21日ふと思い立ってSwitchBotの温湿度計の電池残量を確認してみました。 現在うちの温湿度計は全4部屋SwitchBotに置き換わっています。 確認してみると以下のようでした。使用電池は製品付属のままです。
2022/1購入 42% 2022/3購入 67% 2022/4購入 93% 2022/7購入 100%
最後のが100%というのがちょっと不思議ですが、 ネットで見ると 2年持った人 もいるので目安にはなるかなと思います。 本体表示の目盛りがゼロになってからもしばらく使えたそうですが、 安いものですし半分切ったら交換くらいでよいのではと思います。 誤作動したりデータ欠損起こすよりいいかな。
なお、API v1.0で確認したらバッテリー残量は対応せず、BLEだとちゃんと出てきました。 ではAPI v1.1はというと対応してます。 セキュリティ強化以外にも細かいところで改善されているようではあります。
2023年6月22日v1.1で新たに必要となったsignの生成がbashではできなかったのでpythonで誤魔化していましたが、 色々試しているうちに何とかなりました。 bashの場合は以下でOKです。
TOKEN=トークン
SECR=秘密鍵
NONCE=任意文字列
TS=$(date +%s000)
SIGNV11=$(echo -n ${TOKEN}${TS}${NONCE} | openssl dgst -sha256 -hmac $SECR -binary | base64)
タイムスタンプは単位msの13桁なので末尾に000を追加して1000倍してます。 NONCEは都度uuidgenで生成してもいいですが、別に固定でいい気がします。
sha256sumだと署名ができないという点が抜けていたのでopensslに変更。 あとはこれまで段階的に環境変数に格納しながら試していましたが、 全部パイプで一気にやればOKだということに気が付きました。 電子署名は概念がわかりづらく苦手です。
2023年6月23日夏のボーナスが無事出たということで、何か無駄遣いがしたくなりました。 というわけで以前AliExpressで敗北したCO2センサーのちゃんとしたやつをamazonで購入しました。 ここで製造販売されているものです。 構成としてはNDIRセンサーのMH-Z19Cに USB変換基盤を組み合わせてケースに収めたものだと思います。 自分でも作れるのでしょうが、 2023年7月現在5000円程度とほぼ部品代と大差ない価格なので工作が苦手な私にはありがたいです。
amazonの販売ページにもリンクがあるんですが、 ここ でMH-Z19用のサンプルコードが公開されています。 今回はとりあえず販売ページにあった最低限CO2濃度が読めるpythonのスクリプトを使いました。
やりたいことは仕事部屋のCO2濃度の把握です。 スマートリモコンの制御用PCはリビングに設置しているので まずは仕事部屋にPCの設置が必要です。 以前使っていた余ったノートPCがあったので 軽いと評判でちょっと興味があったラズパイDesktopを入れて使うことにしました。 セットアップは全部デフォルトで特に問題なし。 以下設定でroot権限無しにUSBが読めるようにしておきました。
% sudo usermod -aG dialout ユーザ名
USBデバイス番号はCO2センサーしか接続していないので/dev/ttyUSB0固定でOKでした。 あとは液晶を閉じた時に止まらないように/etc/systemd/logind.confでHandleLidSwitch=ignoreとしておきました。
サンプルコードを5分毎に実行してログを取ってみましたが、 換気扇を全開にして様子を見ると500ppmを切るあたりで安定したので そこそこちゃんと測れているようです。よかった。 今後は閾値を上回ったらアラートを出すような運用を考えています。
2023年7月3日早速使い始めてみたわけなんですが、 とりあえず買ったらこれだけは最初にやっておいた方がいいことと、 絶対に実行してはいけないことを。
まず一点目。 オートキャリブレーション(ABC)機能を切ることです。 この機能、過去24時間の最小値を外気の濃度として自動補正します。 推測ですが、たぶんオフセット補正ではないかと思います。 最近の住宅でCO2濃度が外気と等しくなることはまず無いと思われるので 完全にいらないおせっかい機能です。 おそらく工場出荷時にはちゃんとした環境下で補正されていると思うので その設定値をとりあえず保持しておいた方がいいです。 工場出荷時には有効になっているので、 速やかにコマンド(x79x00)を送信して機能を無効にしておきましょう。
絶対に実行してはいけないのが、スパン点キャリブレーション(x88)です。 こっちはたぶんスケール補正だと思います。 この機能は高濃度側の補正なんですが、 信頼できる既知の高濃度環境がないと復旧できません。 興味本位でうっかり実行してしまうとかなり厳しい状況になります。
あと手動でのゼロ点キャリブレーション(x87)もとりあえず実行は保留にしておいた方がいいです。 私の場合は全力で換気しても500ppm弱までしか下がらなかったので 初期値がおかしかったのではと覚悟を決めて実施しましたが、 そこそこ使えそうな値が出ていたらそのまま使用した方がいいと思います。
普通はこの手のものを買うとひと通りのコマンドを試してみるものですが、 うっかりやってしまうとたぶん出荷時の状態に戻すことができません。 取り返しがつかないので要注意です。
2023年7月4日とりあえずログを取るようにしておいて、簡単に確認できるようにコマンドを整備しました。 まず基本となる濃度表示。先日の公開サンプルを同じ仕様でシンプルに書き換えました。実行例は以下。
% python3 co2.py
{"co2":410}
これを実行してログファイルに追記するスクリプトが以下。
#!/bin/bash ACC_ROOT=$(cd $(dirname $0); pwd) CO2=$(python3 $ACC_ROOT/co2.py | jq .co2) echo $(date "+%Y/%m/%d,%H:%M,")$CO2 >> $ACC_ROOT/co2.logcronで5分に1回実行してログファイルに追記。
# m h dom mon dow command 0-55/5 * * * * /home/user/CO2/co2log.shラズパイPCにいちいち入るのは面倒なので、 普段ログインしている制御用PCからは以下のように実行。
% ssh IPアドレス python3 CO2/co2.py | jq .co2 % ssh IPアドレス tail -25 CO2/co2.log普通IOT機器の場合はMQTTというやつで構築するのが本当らしいんですが、 面倒そうだし別にこれで困らないのでいいことにします。 2023年7月5日
あまり実用性は考えずに購入したCO2センサーですが、かなり大切なことがわかったようです。 どうやら今まで全然換気が足りていなかったようです。
在宅勤務の際はずっと6畳の仕事部屋に一人で籠りきりです。 窓はほぼ通年閉めたままで、廊下に面したドアだけ常時開です。 この状態ではCO2濃度はどんどん上がり続けて換気後でも数時間で1000ppmを超えます。
どうやらいくつかの調査によると1000ppmあたりから 思考力の低下が認められる結果となっています。 そういえばたまになんかぼーっとするなあと思っていましたが。
試したことを列挙します。
以下は昨日の24時間のCO2濃度ログです。
少し前にゼロ点キャリブレーションを実施するために全開で換気していたので 500ppmくらいの低い値でスタートしています。 吸気口は開けた状態で就寝。
3:00くらいまで低い値でキープされてそこから上昇してますが、 これは浴室の換気扇がタイマーでオフになったからだと思います。 隣の部屋で2人寝ているところからの流入だけで朝までに900ppmまで上がっています。 これって寝室の値はどうなっているんでしょうか。心配なレベルです。
テストのために9:00に吸気口を閉めてみました。
ここで嫁さんが出勤したので家には私ひとりです。
一時的に1100ppmまで跳ね上がってますが、なぜかその後1000ppmくらいで落ち着いています。
理由はよくわかりません。全部屋の窓は閉まっているので上がり続けるはずなんですが。
12:00〜13:00に少し下がっているのは昼休みで退室した影響です。
<補足>
後でわかったことですが、嫁さんが出勤したことで家の中全体での
排出量が半分になったので下がったようです。
14:00に吸気口を開けてトイレの換気扇をオンにしてみました。 すると夕方までどんどん下がり続けて700ppmを切っています。
20:00頃に跳ね上がっているのはガスレンジで炒め物を作った影響です。 途中何度か上がっているのは誰かがトイレに入った後にスイッチを切ったためで、 入れ直すと最終的には500ppmあたりまで下がっています。
とりあえずトイレの換気扇を常時回せば問題無いようです。 換気扇の手動スイッチを追加するかとも思いましたが、 止める理由も無さそうなので常時通電に配線を変更してしまいました。 ちなみに私は電工2種持ちなので合法です。
2023年7月6日トイレの換気扇を常時稼働にしてみたところ、 私ひとりが在宅勤務している限りは外気に近い環境をキープできるようです。 ところが3人以上が在宅している場合1000ppmを超える場合が出ていて、 換気量が追いついていないようです。 特に先週久しぶりに息子が帰省してきて4人になった晩は凄い勢いで上昇しました。
CO2濃度を基準値に抑えようとすると30[m3/h/人]というのが
一般的な必要換気量の目安だそうで、
おおまかな計算式は、以下となるようです。
必要換気量[m3/h]=呼気中の排出量[m3/h]÷(許容濃度[%]-外気濃度[%])
呼気中の排出量はおよそ20L/hらしいので、例えば許容濃度を1000ppm、外気を400ppmとすると
1000ppm=0.1%なので
20[L/h]÷(1000ppm-400ppm) = 0.02[m3/h]÷(0.1%-0.04%) ≒ 33[m3/h]
確かにそのくらいになります。
トイレの換気扇の送風能力は単体では125m3/hなので 一見3人でも余裕があるようにも思えますが、 実際には排気ダクトが5mくらいあるのと、自然吸気口でも損失があるのだと思います。
在宅勤務時には高々2人くらいなので問題ないとして、 就寝時は3人になることが多いので 良質な睡眠を追求するなら何らかの対策が必要になるようです。
2023年7月11日厳寒期の暖房時の消費電力は昨冬に把握できました。 今度は酷暑時の冷房時の消費電力を計測してみます。
気温32℃とかだと起動時800Wくらいでそのうち200〜400Wくらいに落ち着きますが、 ここ数日は最高温度36℃と暑さのピークに近いので さすがにそこまで暑いと1000Wくらいになっている時間がけっこう長いようです。 うちは東向きなので朝だけ室外機に直射日光が当たって そのときは少しの間1200W近くなりますが、これは考慮しなくていいかと思います。
熱損失量からの試算では冷房時は6畳用2.2kWで40℃でも完全に余裕だと出ていたのですが、 例えば仕事部屋の機種だと冷房時最大消費電力940Wなので同一効率だと少し足りません。 ただ、小型の方が効率は良いので 同じ消費電力でも今より冷房能力は高いとするとぎりぎりというところでしょうか。
暖房の場合はピーク能力不足でも温まるのに時間がかかるだけですし 特別に寒い日は他の暖房を併用したり、最悪着込めばどうにでもなるのですが、 冷房能力不足だけはどうしようもないです。 ここ数年のさいたまの最高気温は38℃台だったのでもう少し余裕が必要そうです。 やはり暖房時の立ち上がりを考えても10畳用がよさそうです。
<追記>
ダイキンにはパワーセーブモードがあることを思い出して試してみました。
ブレーカー落ちの暫定対策で出力を85%にリミッターかける機能です。
外気温37℃室温30℃で、リビング10畳+6畳を開放して冷房27℃設定で起動しました。
普段より少しパワー不足気味な感じでしたが60分で28℃まで下がって落ち着きました。
最大消費電力は850W程度。
最近の効率の良い6畳用の上位機種ならこれと同等の性能は出ると思います。
狭い場所に室外機を設置した場合、ショートサーキットという現象で効率が低下するそうです。 例えば冷房時の場合は室外機から排出された熱い空気が壁などで回り込み、 背面から循環して吸気されることで発生します。 うちのリビングのエアコンが思い切り該当するので気になっていました。 散らかっているうえに汚いので恐縮ですが、以下はうちの室外機周りです。
室外機から見て背面と側面が壁になっていて、 さらに前面側も少し離れて壁と劣悪な環境です。 購入設置当初は写真奥の壁を背にしてあったのですが、 マンションの大規模修繕のときに一時的に移設された後なぜかこの向きになっていました。 さらに移動すると配管がやられそうな気がするのでそのままになっています。
あと、1年ほど前にプランターの配置換えの時に 仮置きのつもりで収納ボックスを積んだのが そのままになっていて気流を阻害している気がします。
ネットでプラ段などでルーバーを自作して排気向きを変えることで ショートサーキットの改善をしている例をよく見かけます。 私もやってみようかと思っていたのですが、 とりあえず現状を把握してみました。 写真右下の室外機吸気側に温湿度計を設置してログを確認。
すると運転開始前が34.4℃で、1時間ほどで38.8℃で安定しました。 +4.4℃なのでショートサーキットが発生しているとみなしてよいようです。 ただ、アメダスを見るとこの時間帯に外気温も同じくらい上昇していたようなので いまひとつよくわかりません。 実験室ではないのでこのへんが限界かという気がします。 ただ、うちの環境だとダクトでも使って直接排気しないと改善は難しい気がします。
面白いと思ったのは収納ボックスで、撤去すると吸気温度が上昇し悪化し、 再設置すると下がりました。 邪魔かと思ったら逆で、どうやら排気を直接ベランダ外へ導くように働いていたようです。
次のエアコン更新時には今より上に壁吊りにしようと思っているので そしたら排気向きをベランダ外に向けて直接排気にできそうです。
2023年7月14日CO2濃度が閾値を超えたら音を鳴らすというのをやってみました。 まずはUSBセンサーを接続しているノートPC本体のビープ音を鳴らしてみます。
beep; sleep 0.3 ; beep
警告音ぽくてそれらしいのですが、 ふと仕事部屋に設置してあるAmazon Echoが目に入りました。 これ、なんとかしてしゃべらせることはできないでしょうか。 調べてみたらalexa_remote_control.shというスクリプトが公開されていました。 使用例は豊富にありますが、いくつか注意点があります。
まず公開後にAPIのアクセスパスが変更になっているようです。 500行目ちょっと後あたりのcurlのアクセスパスを以下のように変更しないと認証エラーになります。
-L https://alexa.${AMAZON}/spa/index.html
あと、最近は初回はAmazonの二段階認証が必須となっているようです。 一度通ると後はその端末からは秘密鍵は不要となるみたいですが、 ファイルに書かれたパスワードが流出すると大惨事になるので 有効にしておいた方が無難な気がします。
以下のようにして勤務時間中は60分毎にチェックを入れるようにしてみました。
#!/bin/bash
ACC_ROOT=$(cd $(dirname $0); pwd)
CO2=$(python3 $ACC_ROOT/co2.py | jq .co2)
if [ $CO2 -gt 1000 ]; then
$ACC_ROOT/alexa_remote_control.sh -d "仕事部屋" -e "speak: co2濃度が${CO2}ppmです<break/>換気が必要です"
elif [ $CO2 -gt 800 ]; then
beep; sleep 0.3 ; beep
fi
800ppmを超えると短いbeep音が鳴り、1000ppmでEchoがしゃべります。 文の区切りはSSMLとかいう書式を挟んでみました。
2023年7月18日先日ひとりで在宅勤務中に仕事部屋のCO2濃度が上がり続ける傾向になりました。 稼働していた換気扇はトイレのひとつのみでしたが、 私1人分の換気能力は十分に確保されているはずです。 どうにも不可解だったので考えてみると、 どうやら普段閉めていた仕事部屋と対角位置の吸気口を少し前に開けてみたことが原因で、 そこを閉めると下がる傾向になるようでした。
以下はうちの間取りの概念図です。
赤い丸がCO2排出源で、各寝室には夜間だけ人がいます。 青矢印が外気、白矢印が部屋境界での流れ方向、 オレンジ矢印が換気扇による排気です。
矢印の向きだけ見ると四隅から中央換気扇に向かう流れしかないように見えますが、 在宅勤務時には右下の仕事部屋だけが高い濃度となり、 他の部屋に徐々に拡散して拡がっていくようです。 このときトイレの換気扇で家の中全体がわずかに負圧となり、 差圧により各部屋の吸気口から外気が入り希釈されるはずで、 仕事部屋の濃度はそこそこ外気と近いところで均衡します。
ところが各吸気口の流入量は開口面積比率で決まるようで、 反対側の寝室Bを開けると仕事部屋の流入量は相対的に減るみたいです。 これが不可解な濃度上昇の原因だったと思われます。
まあ、最終的には家全体の換気量(=トイレの換気扇の能力)と 何人が家にいるかである平均濃度に均衡するわけなんですが、 特定の部屋の数時間程度の短期の増減には 吸気口の開度のバランスは大きく影響するようです。
寝室Bの冷暖房はリビングのエアコンに頼っているので 吸気口を開けると効きがあまりに悪いこともあり、 最終的にはここだけ常時閉とする運用で落ち着きそうです。
2023年7月19日ここのところリビングのエアコンに電力計を付けたままにして 消費電力を観察しているのですが、かなり乱高下するみたいです。 暖房の場合は室内外の温度差とかなり相関が高いですし、 手計算ともそこそこ一致します。 ところが冷房時には200Wくらいで落ち着いたかなと思ったら しばらくしてみると1000Wくらいでギンギンに回っていることがあったりさっぱり安定しません。 均すと外気温30℃ちょっとの最近では700Wくらいになっていることが多い気はします。
なんとなくの推定ですが、どうも日照の影響をかなり強く受けるようです。 ただ、日没後もけっこう上下するので正直よくわかりません。 調べてみると住宅設計の専門家でも 「冷房の必要能力の正確な試算は不可能」とまで言っている人がいます。 というわけで暖房能力の算出は室内外温度差と熱損失でいけそうですが、 冷房能力は実測値のピークから推定するしかないのかなという気がします。
メーカーカタログによると、うちのエアコンの最大冷房能力は3.7kW、最大消費電力は1300Wです。
3700×1000/1300≒2850
これが推定される必要最大冷房能力です。やっぱり10畳用でぴったりみたいです。
まずお約束。スマートプラグHS105を販売しているTP-Linkによると扇風機への使用は非推奨です。 換気扇も扇風機の一種ではないかと思うので真似しないように。
うちに設置されている換気扇3つのうち、もっとも強力なのがキッチンのレンジフードです。 これにスマートプラグを挟んでCO2センサーの値で制御すれば宅内のCO2濃度を閾値以下にキープできそうです。 レンジフードの上の化粧板(幕板と称するそうです)を外すと アース付きの3極ソケット接続でした。よって電気工事は不要で簡単に試せます。 この空間は空気の出入りが無いようで、トラッキングの危険性も無さそうです。
ただ、うちのHS105には3極プラグは入らないので変換プラグを使用します。 このままだとアースが接続されていないので危険ですが、 今回はテストだし消費電力も最大100W程度なのでいいことにします。 換気扇のスイッチは濡れた手で触ることが多いので本来はアース接続は必須です。 逆アダプターってあるのかなと探したらありました。パナソニックだとWH2881Pがそれです。
あとはちょちょいとスクリプトを書いておしまい。完成品イメージは以下です。
#!/bin/bash HSADR=IPアドレス CO2=$(python3 co2.py | jq .co2) JSON=$(python3 tplink-smartplug.py -t $HSADR -c info) RSTAT=$(echo $JSON | jq .system.get_sysinfo.relay_state) ONTIM=$(echo $JSON | jq .system.get_sysinfo.on_time) sleep 1 [ $CO2 -gt 800 ] && [ $RSTAT -eq 0 ] && JSON=$(python3 tplink-smartplug.py -t $HSADR -c on) [ $CO2 -lt 600 ] && [ $ONTIM -gt 720 ] && JSON=$(python3 tplink-smartplug.py -t $HSADR -c off)
換気扇のスイッチは中にしたままとしています。 閾値の800ppmを上回ったら運転開始で、600ppmを下回ったら停止。 ガスレンジを使うときはEchoと連携させて「アレクサ、ファンつけて」で運転。 そのままだと運転直後に自動停止判定されることがあるので 最低12分間は運転するようにしています。 HS105は通電時間がわかるのですっきり書けました。
トイレの換気扇では3人在宅時に能力不足なようで、 根本的な解決には浴室の換気扇を24時間対応に更新する必要があるみたいです。 DIYでも4万円くらいしそうだし、施工もけっこう大変そうなので これでお手軽に済ますのもいいかもしれません。
2023年7月20日短期テストとは言え気になったので逆アダプタを購入しアースを接続しました。 さて、嫁さんから「回してもすぐ止まる」と苦情が出たのでスクリプト改良です。 煮込み料理なんかだと12分で止まっては面倒で仕方がないそうです。それはそうか。 改良版イメージは以下です。
HSADR=IPアドレス
CO2=$(python3 co2.py | jq .co2)
JSON=$(python3 tplink-smartplug.py -t $HSADR -c info)
ONTIM=$(echo $JSON | jq .system.get_sysinfo.on_time)
OTMOD=$((($ONTIM+1) % 600))
sleep 1
if [ $ONTIM -eq 0 ]; then
[ $CO2 -gt 800 ] &&
JSON=$(python3 tplink-smartplug.py -t $HSADR -c on)
else
[ $CO2 -lt 600 ] && [[ $OTMOD -le 1 || $ONTIM -gt 3600 ]] &&
JSON=$(python3 tplink-smartplug.py -t $HSADR -c off)
fi
リレーのステータスはon_timeだけ見ればいいことに気がついたので統一。 cronでの10分間隔で自動起動された場合上記タイミングでは on_timeは下2桁が99か00になるみたいなので、 +1して600秒で割った余りが0か1なら自動起動と見なし、 そうでない場合は手動で起動されたとして1時間で停止としました。 手動起動が運悪くcronのタイミングと重なるとすぐ止まりますが、 確率2/600とほとんど起こらないので例外処理は不要としました。
<追記>
最近Echoが賢くなって、「アレクサ、60分ファンつけて」とか
タイマー付きで指示できるようになってます。
なので1時間で停止の判定は抜いても良いですね。
ところでレンジフードもかなり旧いので更新が必要かなとカタログを眺めましたが、 最近の機種はほとんど電子スイッチになっています。 スマートスイッチでの制御ができそうなのはノーリツのS20くらいしかないみたいです。 色々便利にはなってますが、私はこういう機器は原始的な方が好みです。
2023年7月27日CO2センサーのゼロ校正では、外気が400ppm付近であることを前提としています。 ところが調べてみると意外とそうでもないみたいです。
CO2濃度をネットで公開している観測所はほとんど無いみたいです。 たぶん信頼できるお手軽な測定方法が無いからだと思います。 幸い埼玉県では加須市の騎西にある環境科学国際センターでの値が 速報として公開されています。 ただしネットの速報値は当日と前日のみで、 過去の観測値はきちんと校正されてからサマリーのみ公開されるようです。 ちなみに今年の6月末の落雷の影響で施設が被害を受けたようで、しばらく値が更新されていませんでした。
年次レポートを読むと、 以前は観測所が浦和にあったらしいことがわかります。 移転の際に平成13年度だけ並行期間があって、 年間平均だと浦和は騎西より約9ppm高い傾向があるようです。 なので騎西の値に+9すればうちからそこそこ近い浦和の値がおおざっぱに推定できるはず。
例えばここ数日の値を見ると、未明に500ppm程度まで上がり、昼過ぎに400ppmちょっとまで下がるという傾向になっています。 どうも東京湾にたくさんある火力発電所の影響を受けているそうです。 未明に換気してゼロ校正すると100ppmくらい低い値を返すことになります。 なのでゼロ校正を手動で実施する場合は、 速報値を眺めて400ppmに低いことを確認してから実施するのが良さそうです。
もっともMH-Z19シリーズは安いわりにはそこそこの精度があるので人気ですが、 実際のところは100ppmくらいの測定誤差は見ておいた方がいいみたいです。 そんなに気にしなくてもいいかもしれません。
2023年7月31日霧ヶ峰の制御は優秀で、いったん温度を設定すればその日の操作はほぼ不要です。 一応外気温に応じて設定温度を変更する制御は入れておいたのですが、 9月に入って少し冷え過ぎになることが出てきました。 そう言えば昨年夏の末に設定した目標温度を今年の初夏に少し低めに変更した記憶があります。
原因を考えてみるとどうやら建物の壁などの蓄熱によるものではないかという気がします。 何か自動判定の判断基準はないかと外気温のログを見ると、 早朝の気温と冷え過ぎと感じた日に相関があるようです。 というわけで以下制御を追加したらいい感じになりました。
外気温ログはこういうフォーマットです。
2023/09/15,03:00,25.9,93,22.5,1011.7 2023/09/15,04:00,25.8,94,22.7,1012.0 2023/09/15,05:00,25.8,95,22.9,1012.4 2023/09/15,06:00,25.5,98,23.2,1012.9 2023/09/15,07:00,26.9,93,23.8,1013.4 2023/09/15,08:00,29.0,83,23.9,1013.6 2023/09/15,09:00,30.9,69,22.0,1013.8その日の朝6時の気温を抜き出して、26℃より低い場合には 設定温度を+0.5℃としました。 これで季節の変わり目も自動でOKです。
TGT=23.5
TO06=$(grep '06:' 外気温ログファイル名 | tail -1 | cut -f 3 -d ,)
if [ $(echo "$TO06 < 26.0" | bc) = 1 ]; then
TGT=$(echo "$TGT+0.5" | bc)
fi
TGT="${TGT%.0}"
2023年9月15日
テストと言いつつ結局定常運用に入ってしまいました。 以前感じていた在宅勤務時の効率低下が改善された気がします。 ただし冬が近づいて外気が乾燥してきたので 換気開始の閾値が800ppmでは乾燥し過ぎるようで、 絶対湿度が7.0を切ることもしばしば。
というわけで閾値を1000ppmに上げたところ、乾燥し過ぎはましになりました。 ただし朝の目覚めがややすっきりしない感じになったので 寝室だけでも夜間加湿して閾値を下げる対応が必要かもしれません。 冬場にCO2濃度と湿度を両立させるのはなかなか難しそうです。
2023年11月29日私は喉が弱いので冬場は加湿器が欠かせません。 以前にもちょっと書きましたが、長年愛用しているのはKAZのV100です。 構造は極めてシンプルで、タンクにひとつまみの塩を投入し電極の間の水を直接過熱気化します。 そう聞くと空焚きによる火災を心配されるかもしれませんが、 水が無くなると電気が流れないので物理的に非常に安全です。
一方、世の中の加湿器はほとんどが送風気化式だと思います。 ちょっと高いやつだとハイブリッド気化式でしょうか。 これらは静かで省電力なのがメリットですが、 あっという間にカビだらけになる(特にオフシーズンの保管時)ので私は好みじゃないです。
KAZを含む加熱式の弱点は消費電力が大きいことです。 これを使い始めると一日の使用電力量がはっきり上がります。 快適性第一なので特に気にはしていませんが、実際のところどんなものかなと思ったので 電力計を接続して計測してみました。
普段は寝室だけで使用しているのですが、 まず朝にタンクが減った状態で計測してみました。 スイッチを入れると200Wくらいで、徐々に上がって300W弱で安定。 理由がわからず不思議に思いましたが、 水の温度が上がるとイオン活性が上がって導電率が上がるそうです。 電圧は一定なので電流が上がり消費電力も上がるということか。
次に就寝時を想定して満水にして起動すると今度は400Wくらいで安定しました。 塩分濃度は下がっているはずなんですが、 水位が上がると電極がより長く水に沈むからだと思います。 徐々に水位が下がると消費電力も下がっていくはず。 なお、導電性を上げるために投入する塩の量も大きく関係するので この数値はあくまで一例です。 試しに水を半分に希釈したら投入時120W、定常240Wに下がりました。 これだとちょっと加湿能力が不足気味です。
以前はこれを使うとパワフル過ぎて寝室の窓が強烈に結露していましたが、 今は温湿度計の値で最低限の加湿に自動制御しているので問題ありません。 それでも一晩の電気代は100円くらいですが健康には必要な投資だと思っています。
V100は生産が終了しているので一応私の寿命まで使う分のストックは確保してあるのですが、 何か代替品が無いかと調べてみたら象印が加熱式を出しているようです。 しかも温湿度センサー内蔵で単体で自動制御するようです。素晴らしい。
2024年1月11日どうも月曜日だけ仕事部屋がちょっと寒い感じで、手動での補正が必要なことが多いです。 夕方頃には落ち着くみたいなので、週末に壁が冷えてしまって体感温度が下がっているようです。 壁にぴったり設置してあるエンペックスの温湿度計の値は 仕事中には24℃くらいを指しているのですが、寒い時期の月曜だけ23℃くらいなんですよね。 というわけで月曜日は暖房の設定温度を+0.5しておく制御を追加しました。 あと、祝日の翌日も同様のことが起きるはずなので同様に。 記述例は以下です。
CU=$(date +%u) # mon if [ $CU -eq 1 ]; then TGT=$(echo "$TGT+0.5" | bc) # tue-fri else YD=$(date -I -d '-1 day') $ACC_ROOT/holiday_check.sh $YD && TGT=$(echo "$TGT+0.5" | bc) fidateコマンドの%uは月から順に1,2,3...が返ります。 仕事部屋の制御スクリプトは平日だけ呼ばれるので上記でOK。 holiday_check.shは以前紹介したスクリプトで、 元は当日が休みかどうか判定する仕様でしたが 引数が存在すれば指定した年月日を判定するように修正しました。
なお、仕事部屋のエアコンは霧ヶ峰普及グレードのCEシリーズで床温度センサーしかありません。 壁温度センサーのある上位機種ならエアコン任せで良さそうです。
2024年1月29日今年のふるさと納税は何を貰おうかなと探していたら、 象印のスチーム式加湿器がどういうわけか藤井寺市の返礼品に。 額も丁度良かったので寄付してみました。 ほどなく届いたので早速使ってみましたが、本当に出来がいいです。
湿度センサー内蔵で、「ひかえめ」/「標準」/「しっかり」の3段階の設定ができます。 試した感じでは温度は見ていないようで、相対湿度を一定値にキープする制御だと思います。 「ひかえめ」だと50%前後で安定します。普通はこれでいいと思います。 「しっかり」に変更すると60%を超えて窓が派手に結露しました。 普段は使わないかなと思います。風邪ひいたときなんかいいかも。 さらに「標準」に変更すると55%あたりで安定しました。 結露は収まりましたがここまで加湿しなくてもいいかな。 タンク容量は3Lで、「ひかえめ」ならばリビング全部加湿しても一晩余裕で持ちました。
いまどきの家電なので電子スイッチで、電源プラグを抜くと再起動しない仕様なので スマートプラグでの制御はできません。 ただ、原理的に空焚きが起きないKAZと違って安全装置が故障すると発火の恐れがあるはずで、 不在時の運転はご法度なのでこれでいいと思います。 私の場合は寝る前に手動でスイッチを入れればそれでよさげです。 朝は手動で止めるか、水の量を調節して自動停止に任せるという感じでしょうか。
KAZの対極に位置する製品ですが、素晴らしい進化だと思います。
2024年2月9日特に自動制御はやってないのですが、消費電力の記事はよく書くのでここにメモしておきます。 寒くなって来てトイレで座ると「冷たっ!」となる時期が来ました。 自宅でもちょっと前から暖房便座のスイッチが入ってます。
最新機種だと人感センサーで急速に暖める機能があったり、 学習して夜間は自動的にオフになったりするようですが、 うちのは常時オンの低機能なので消費電力がどうなっているか気になりました。 以前エコキーパーを買ったときに色々な機器の消費電力を計測しましたが、 ほとんど考えなくていいという結論になったことは記憶しています。
あと、蓋を閉めておかないと熱が逃げて消費電力が増えるというのも耳にしますが、 実際のところどうなのか気になったので計測してみました。 以下は定期的に手で記録した約12日間の積算消費電力量の推移です。 リセットせずに計測したので縦軸は増分のみ意味を持ちます。
基本的には蓋は閉めてありましたが、たまに誰かが閉め忘れたり 意図的に数時間開けたままにしてみたりもしたのですが、 傾きが一定なので消費電力はほぼ変化がありません。 観察してみると、ほとんどの時間はだいたい1.5Wくらいで、 たまに冷えると25Wか55Wくらいに上がって、10秒くらいで切れる、 という挙動になってました。 うちがマンションで気温が20℃を下回ることはまず無いからでしょうか。 戸建てで寒かったりするとこのあたりの挙動は全然違ってくると思います。
結局うちの場合の消費電力量は0.2kWh/dayでほぼ一定、 便座の蓋は特に閉める必要もないかなという結論となりました。
2024年11月8日どうもSwitchBotの旧API v1.0が廃止されたっぽいです。 12/17朝起きたら、止まっているはずの寝室のエアコンがついてます。 温度ログを見ると12/16の夕方から値が取れてません。 どうもAPIが死んでるっぽいです。 噂ではDNS更新時のトラブルでAPIがv1.1も含めアクセス不能になっているようで、 海外フォーラムでアクセス先を"api.switch-bot.com"から"api.switchbot.net"に変更する ワークアラウンドが発見されていました。 試してみるとv1.1はそれでいけましたが、私が使い続けていたv1.0はやっぱりダメ。
仕方がないので以前用意してあったv1.1用の処理に書き換えて復旧。 そのうちアクセスサイトは復活したものの、v1.0は依然として死んでます。 その間公式サイトはだんまり。 相変わらずここの運営はお粗末ですねえ。素人丸出しです。
<補足>
12/19夜にv1.0が復旧したようです。特に戻す理由も無いのでそのままv1.1利用とします。
この春に大学で家を離れていた息子が帰って来ました。 息子もIT関係ということで在宅勤務が2人になってしまいました。 どちらもオンラインの打ち合わせが多いので狭い我が家では物理的に無理だなということで 家の近くにリモートワーク用にワンルームのアパートを確保しました。 たぶん数年後には独立するだろうということで揃えた家財道具などを一時的に仮置きする意味もあります。
ここでもスマートリモコンは欲しいなということで導入しました。 試行錯誤はありましたが、最終的に以下のように落ち着きました。
またまた自動制御とは関係無いですが、エアコン関連の記事ということで。
リモートワーク部屋はロフト付きなのでワンルームにしては室内容積が大きく、エアコンの効きが少し良くないです。 暑い日にロフトの梯子を上ると天井近くの高さで頭だけかなりの暑さを感じます。 寝るわけではない完全に物置の空間なのでここは仕切る方が効率が良いです。 そこでエアコンの清掃用に使っているマスカーテープで仮に仕切ってみました。 ペラペラなので断熱効果は期待できませんが、気流は止められるはず。
するとはっきり体感できるくらい良く冷えます。逆にロフト内は温室みたいです。 ロフト上部は直接屋根が照らされているのでかなり熱が入っているようです。 ちなみに開口部の上端あたりの高さではそんなに暑くないのでここは塞がなくてもいいみたいです。
別にそのままでもいいのですが、プラダンと100均の壁掛けフックで簡易間仕切りを施工してみました。 4mmの方が強度があっていい気もしますが意外と高かったので軽量安価な2.5mmとしました。 微妙に室内側に傾けてあり、天井のフックに立てかけている構造です。
単にカットしただけだとたわんで外れたので、両側を折り返してステープラで止めて曲げ強度を出しています。 見た目重視なら「かぶせ」を使うといいかもしれません。 ちなみに費用は2.5mmのプラダン195×3+壁掛けフック110x5=1135円でした。
施工前にマスカーを撤去して開放したらエアコンの効きがいきなり悪くなって、終わると復活しました。 やはり効果は抜群のようです。 プラダンには断熱性が期待できるはずで、心なしかさらに効きが良くよくなった気がしますがプラセボかな。 寝ないロフトがある部屋にはお勧めです。
2025年7月7日