こんにちは。 ソフトウェアエンジニアのスネ夫です。
弊社では緊急事態宣言後、在宅での勤務が基本となっており、私もほぼ自宅で仕事をしています。
私は太陽光が好きなので、窓の近くにデスクを置き部屋の照明はつけず、朝から太陽光を浴びて仕事をしています!
気持ちいいですね。
夕方ごろになると当然暗くなってくるのですが、気がつくと部屋が真っ暗なまま仕事をしていたりします。
暗くなったら勝手に照明がつけばいいのに・・・。
と考えていたら、目の前にはRespberryPiとNatureRemoが!
この2つを使って、「暗くなったら照明をつける」を実現してみたいと思います。
システム構成
ざっくりとこんな感じになります
- RaspberryPi
ボード型のスモールコンピューターで、大きさは名刺サイズ!
簡単なサーバ用途として使ったり、電子工作をしてラジコンを作ったりなど楽しいおもちゃです。
今回はRaspberryPi Model4とカメラモジュールを使い、部屋が暗くなったことを感知して、NatureRemoのAPIから部屋の照明をつけます。
- Nature Remo
家の中の家電をスマート家電化するためのスマートリモコンです。
赤外線リモコンで動く家電ならば、スマホやスマートスピーカーから操作することが可能になります!
また、NatureRemoはREST型のAPIも公開しているため、プログラミングによって操作することが可能です。
NatureRemoのAPIで照明をON/OFFする
まず、RaspberryPiからNatrueRemoを通して照明をつけるところから始めます。
つけたい照明の情報をアプリから確認しておく
NatureRemoを使っている方はわかると思いますが、家の中の機器にはそれぞれ名前をつけているはずなので、アプリからつけたい照明の名前を確認しておきましょう。
私の場合は「リビングの電気」になります。
API仕様の確認
APIの仕様がきっちりまとまっており、非常に簡単です。
ざっと眺めておきましょう。
https://developer.nature.global/
アクセストークンの取得
ここにブラウザでアクセスしてログインすると以下のページが表示され
「Generate Access Token」から、操作するためのアクセストークンが取得できます。
APIを使う時に必要なので、コピーしましょう。
機器情報(signal_idの確認)
「リビングの電気」をつけるためNatureRemo側で認識されている機器情報を確認します。
先ほどのアクセストークンと合わせて、以下のようなcurlコマンドをたたきます。
curl -X GET "https://api.nature.global/1/appliances" -H "accept: application/json" -k --header "Authorization: Bearer xxxAccessTokenxxx"
※xxxAccessTokenxxxの部分を、先ほど取得したアクセストークンに置き換えて実行します。
すると、以下のような情報が返ってきます。
[ -- 省略 -- { "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "device": { "name": "Remo", "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "created_at": "20xx-xx-xxTxx:xx:xxZ", "updated_at": "20xx-xx-xxTxx:xx:xxZ", "mac_address": "xx:xx:xx:xx:xx:xx", "serial_number": "xxxxxxxxxxxxxxxx", "firmware_version": "Remo/x.x.xx-g808448c", "temperature_offset": 0, "humidity_offset": 0 }, "model": null, "type": "IR", "nickname": "リビングの電気", "image": "ico_light", "settings": null, "aircon": null, "signals": [ { "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "name": "オン", "image": "ico_on" }, { "id": "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy", "name": "オフ", "image": "ico_off" } ] } ]
先ほどアプリから確認した、「リビングの電気」の情報のうち、ONとOFFのidをコピーしておきます。
上記のサンプルでいうと、
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" "id": "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy"
この部分になります。
ONにしてみる
先ほど取得したオンのシグナルIDを使って、「リビングの電気」をONにしてみます。
curl -H 'Authorization: Bearer xxxAccessTokenxxx' -H 'accept: application/json' -X POST "https://api.nature.global/1/signals/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/send" -H "accept: application/json" -H "Content-Type: application/x-www-form-urlencoded"
※AccessTokenの部分とsingalの部分は取得した情報に置き換えてください。
するとどうでしょう・・・。
照明がつきますヽ(´∀`)ノ
コマンドラインから照明がつく・・・。リモコン押せば照明はつきますが、コマンドラインから照明がつくって感動しますよね!
シェルから実行できるように以下のようにshファイルを作っておきます。
今回、OFFは使いませんが同様にOFFにもできます!
#!/bin/sh curl -H 'Authorization: Bearer xxxAccessTokenxxx' -H 'accept: application/json' -X POST "https://api.nature.global/1/signals/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/send" -H "accept: application/json" -H "Content-Type: application/x-www-form-urlencoded"
RaspberryPiのカメラから暗くなったことを検知してNatureRemoにONを送信する
RaspberryPiのセットアップ
基本的なセットアップの方法はたくさん記事があると思いますので、そちらを参照してください。
今回は、GUIのデスクトップ版で確認を行なっています。
カメラモジュールの設定
今回は、オフィシャルなカメラモジュールである
raspberry pi camera module v2.1
こちら使用しています。
RaspberryPi に接続して、設定からカメラを使える状態にしておきましょう!
Pythonやモジュールの設定
画像やデータの解析などでOpenCV、matplotlib、numpy、pnadsを使うためインストールしておきます。
pyenv環境を整えてpipからインストールする方法もありますが、バージョンによってはすんなりいかないようなので、自分の場合はaptとpip3からインストールしました。
sudo apt-get install libhdf5-dev libhdf5-serial-dev libhdf5-103 sudo apt-get install libatlas-base-dev sudo apt-get install libjasper-dev sudo apt-get install python3-matplotlib python3-numpy python3-pandas
sudo pip3 install opencv-python
画像の解析
カメラから部屋の画像を撮影して、その画像情報から明るさの情報を抽出します。
この辺り画像解析の知識はほとんどないので、かなり自己流?な方法かもしれません笑
まず、1分ごとに部屋の特定の場所を撮影してRGBとHSVの値を取得します。
それをCSVに出力して、傾向を見ることにしました。
import csv import pprint import datetime import cv2 import numpy as np import os # raspistillコマンドを使ってカメラで撮影して画像に保存する os.system('raspistill -o /home/pi/nature/image.jpg') # 画像をOpenCVで読み込んで、RGB情報とHSV情報をそれぞれ取得 img=cv2.imread(str('/home/pi/nature/image.jpg')) hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) h, s, v = cv2.split(hsv) b, g, r = cv2.split(img) dt_now = datetime.datetime.now() dt_str = dt_now.strftime('%Y/%m/%d %H:%M:%S') # csvファイルに書き込む with open('/home/pi/nature/data.csv', 'a') as f: writer = csv.writer(f) writer.writerow([dt_str, str(h.mean()), str(s.mean()), str(v.mean()), str(r.mean()), str(g.mean()), str(b.mean())])
上記の結果、HSV情報のうちV(明度)が使えそうなことがわかりました! 下のグラフが明度の平均値をプロットしたものですが、 18:30頃は120だったものが、暗くなってきた18:50には20になっています!
明度を判別して、基準値を下回っていたら照明をONにする
上記のグラフから、照明をつける必要がある明度の値を70として以下のようにプログラムを書き換えます。
直近の明度を3つ取得して、全てが70以下ならば照明をつけます。
(1回だけだと、猫とかが写り込んでしまうかもしれないので)
import csv import pprint import datetime import cv2 import numpy as np import os import pandas as pd # 明度の境界値 V_VALUE = 70 os.system('raspistill -o /home/pi/nature/image.jpg') # raspistillコマンドを使ってカメラで撮影して画像に保存する img=cv2.imread(str('/home/pi/nature/image.jpg')) # 画像をOpenCVで読み込んで、RGB情報とHSV情報をそれぞれ取得 hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) h, s, v = cv2.split(hsv) b, g, r = cv2.split(img) dt_now = datetime.datetime.now() dt_str = dt_now.strftime('%Y/%m/%d %H:%M:%S') file_name = '/home/pi/nature/' + dt_now.strftime('%Y%m%d') + ".csv" # csvファイルに書き込む with open(file_name, 'a') as f: writer = csv.writer(f) writer.writerow([dt_str, str(h.mean()), str(s.mean()), str(v.mean()), str(r.mean()), str(g.mean()), str(b.mean())]) # csvファイルをpandasで読む csv_input = pd.read_csv(filepath_or_buffer=file_name, encoding="ms932", sep=",") # 直近の明度を3件取得して、全て基準値以下ならon.sh呼び出してリビングの電気をつける is_dark = True; for v in csv_input.tail(3).iloc[:, 3]: if float(v) > V_VALUE: is_dark = False break if is_dark: os.system('/home/pi/nature/on.sh')
上記をコマンドラインから実行して、動作することを確認してみると・・・。
つきました!感動ですね!
コマンドラインから照明がつくなんt(略
cronに設定する
crontabで毎分、上記のpythonを動作させるようにします
*/1 8-21 * * * /usr/bin/python3 /home/pi/nature/on.py >> /tmp/on.log 2>&1
これで1分ごとにプログラムが実行されて、暗くなったら自動で照明がつきますヽ(´ω`)ノ
まとめ
実はNatureRemo、照度センサーがついているのでアプリだけでも
「暗くなったら照明をつける」
は実現できます!!
ただ、センサーの更新が1時間に1回なのでちょっと実用的ではないのです。
なので今回は、わざわざRaspberryPiとカメラを使って実現してみました。
NatureRemoのようなスマートホーム家電がいろいろと出てきていますが、RaspberryPiなどと組み合わせて使うと、いろんな可能性が広がって楽しいですね。
\\『真のユーザーファーストでマーケットを創造する』仲間を募集中です!! //