在宅チェックAPIを開発した話
こんにちは!
先日、自分が家に在宅しているかどうかをチェックするAPIを作ったので、今回はそれについて書いていきたいと思います。
開発のモチベーション
冒頭に書いたとおり、今回作成したのは自分が家にいるかどうかをチェックするためのAPIです。自分が家にいるかどうかなんか自分が一番わかってるだろと突っ込まれそうですがw、自分自身が知るためというよりはプログラムにそれを認識させるためのものですね。具体的には、前回書いた湿度通知システムの件です。
前回の記事も書いた課題として、自分が家にいないときにもガンガンSlackに通知が送られてくるというものがありました。外出中に部屋が乾燥しているとか言われてもどうでもいいですしw、そんなことを言われても対処のしようもありません。
コロナ以降自宅にいる時間が増えているとはいえ、外出中にこういう通知が来るのは非常に煩わしいので、自分が家にいないときは通知を切るようなアルゴリズムが必要だったわけですね。そういうわけで、在宅状況をチェックするAPIを作り、通知の際にそのAPIを叩いてその状況によって分岐させるような実装をしたわけです。
また、在宅状況をチェックする仕組みができると、なにかと応用はしやすいかなと思っています。家にいるときのみプログラムになにか作業・処理をさせたり、逆に外出しているときだけ動作するなにかを作ったりとか、色々とできることは広がるかなと。そんなこともあって、在宅チェックについては湿度通知システムにコーディングするのではなく、単独のAPIとして開発することにしました。
システム構成
今回作成したシステムの全体システムはこんな感じです。
ざっくりいうと、
① 携帯とのBruetooth接続を常設のAndroid Tabletで検出。接続したら「帰宅」、切断したら「外出」信号を送る
② 外出・帰宅をラズパイで稼働するPythonプログラムで受領
③ 在宅状況をGoogle Driveにファイルとして保存
④ 任意のプログラムからPythonプログラムにアクセスして在宅状況を返す
といったところです。これも、前回の湿度通知システムと同様にこれまでに作ったものの組み合わせで作れた感じですね。①はTaskerの自動通知システムで作った「ゆっくりしていってね!!!」システムにhttpリクエストのタスクを追加しただけですし、②と④は前回使ったPythonのFlaskを使って実装できますし、③はPythonでGoogle DriveのAPIを叩くコードを流用したかんじです。やはり、色々と手をつけているとできることが増えて夢が広がりまくリングですw
動作環境
動作環境は前回同様にラズパイにDockerを載せて動作環境を作ります。Dockerfileのリポジトリはこちら。
内容としては特に解説することはないですね。前回の湿度通知のときとほどんど変わりません。
ちなみにこちらのサーバーは外部には公開しておらず、自宅ネットワーク内部からのみアクセスできるような形としています。IPアドレス等を公開しなければ問題ないとは思いますが、やはり在宅状況は防犯上機密性の高い情報なので、一応気をつけているって感じですね。
今のところはローカルのみからのアクセスで特に困っていないのでそうしている感じですが、今後必要になったらまた考えます。在宅状況の保存先をGoogle Driveとしているのはそのあたりも見越してのことだったりします(単純にローカルで動かすだけなら、チェック用のファイルも手元にローカルにおいておけばいい話なので^^;)
メインプログラム
今回作成したAPIのソースコードはこちら。
プログラムの内容としては、HTTPリクエストを受け付けるメインプログラムが「in」「out」「check」の三種類のURLパラメータを受け取り、
- 「in」を受領したらDriveに「output.txt」という空のファイルを作成
- 「out」を受領したらDriveの「output.txt」を削除
- 「get」を受領したらDriveの「output.txt」の存在を確認し、1か0を返す
というシンプルなもの。実際のコードはこんな感じです。
from flask import abort, Flask, jsonify, request
from Drive import DriveUpload
import requests
import json
import os
app = Flask(__name__)
@app.route("/")
def go_test():
return "hello"
@app.route("/out")
def go_out():
drive = DriveUpload("out.txt")
drive.FileUpload()
return "hello"
@app.route("/in")
def go_in():
drive = DriveUpload("out.txt")
drive.FileDelete()
return "hello"
@app.route("/get")
def get_status():
drive = DriveUpload("out.txt")
status = drive.CheckOut()
return str(status)
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True, port=5555)
このコードに書かれているDriveUploadクラスはDrive.pyで実装しているので、中身が気になる方はリポジトリを確認いただければと思います。
こういうコード構造にしておくと、他のプログラムからのアクセスが非常にシンプルになり、単純にHTTPリクエストでIPアドレスにルートパラメーター(/get)をつけてアクセスすれば、自宅にいるかどうかの回答が得られるという寸法です。
湿度通知への実装
そして、実際に前回作った湿度通知に在宅チェック機能をつけたのがこちら。
from flask import abort, Flask, jsonify, request
import requests
import json
import os
app = Flask(__name__)
@app.route("/")
def PostHumid():
ACCESS_URL = ""
SLACK_URL = ""
temp = ""
humid = ""
abs_humid = ""
message = ""
with open('url.json','r') as f:
json_load = json.load(f)
ACCESS_URL = json_load["ACCESS_URL"]
SLACK_URL = json_load["SLACK_URL"]
temp = request.args.get('temp')
humid = request.args.get('humid')
abs_humid = request.args.get('abs_humid')
if temp == "" or humid == "" or abs_humid == "":
message = "センサーエラーです"
elif float(abs_humid) > 15:
message = "部屋の湿度が高いです\n絶対湿度は" + abs_humid + "です"
elif float(abs_humid) < 5:
message = "部屋が乾燥しています\n絶対湿度は" + abs_humid + "です"
flug = requests.get(ACCESS_URL+"get")
if flug.text == "0" and message != "":
requests.post(SLACK_URL,data=json.dumps({
"text" : message
}))
return "hello"
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True, port=5000)
前回からの変更点は最後の方の
flug = requests.get(ACCESS_URL+"get")
if flug.text == "0" and message != "":
requests.post(SLACK_URL,data=json.dumps({
"text" : message
}))
の部分ですね。今回作った在宅チェックAPIにgetというルートパラメータをのせてチェックを行い、それをフラグとしてSlackに通知を出すかどうかを判定させている感じです。こんなかんじで、使う側の実装も非常にシンプルな形で実現できるので、今後もうまく使っていきたいところです。
まとめ
ということで、今回は開発した在宅チェックAPIについて書きました。APIという形で実装すると、いろんなプログラムから汎用的につかえるので、色々と応用がききそうだなというのが率直な印象です。
自宅IoT化を進める上で、自分が家にいるかどうかで動作を変更したいというニーズはでてくると思うので、このAPIを使って面白いことができればなと思っています。
それでは、また!
この記事が気に入ったらサポートをしてみませんか?