最近、仕事やら出張やら旅行やら遊びやらで一体どれくらい自宅が稼働しているのかを把握するために、Raspberry Piで在宅/外出をモニタするシステムを作ろうと思います。
使用しているIPhoneがLANに接続されているかどうかで在宅・外出を判断するシステムとします。
今回は前回セットアップしたSQLサーバーにIPhoneがLAN内に接続されているかどうか(在宅中か外出中か)の状態をアップロードするコードをPythonで書きます。
まず、SQLサーバーのセットアップはこちらの記事を参照。
RaspberryPiでSQLサーバー構築 - あきらぼ
また前準備として、今回はLAN内にIPhoneがいるかどうか確認するのにarp-scanコマンドを使用するのでインストールする必要があります。(下記記事参照)
Raspberry Pi でLAN内のIPアドレス一覧表示 - あきらぼ
次に今回Pythonからデータベースへの書き込みをするのでPythonのMySQLdbのパッケージをインストールする必要があります。(下記記事参照)
Raspberry Pi でPythonのMySQLClientをインストール - あきらぼ
そして今回のコードになります。
# -*- coding: utf-8 -*- import MySQLdb import time from enum import Enum import subprocess class State(Enum): Home = 0 Away = 1 if __name__ == "__main__": # Get LAN State to check existence of IPhone arp_result = subprocess.getoutput('sudo arp-scan -I eth0 -l') # Show arp-scan result print(arp_result) # Check if IPhone MAX adress is in LAN MacMatch = arp_result.find('xx:xx:xx:xx:xx:xx') if MacMatch == -1: CurrentState = State.Away else: CurrentState = State.Home # Connect to MySQL server connector = MySQLdb.connect(host="localhost", db="homeaway", user="user_homeaway", passwd="pass_homeaway", charset="utf8") cursor = connector.cursor() sql = u"insert into homeaway_table(`id`,`date`,`state`) values(0,now(),'%s')" % CurrentState.name cursor.execute(sql) connector.commit() cursor.close() connector.close() #Show Current State print(CurrentState.name)
基本的にはarp-scanの結果から該当するMACアドレスがあるかを参照してそれに応じてHome(在宅)、Away(外出)をデータベースに送るようにしています。
今回はSQLサーバーもPython実行もRaspberry Pi になるので、localhostとなっています。
コードはGitHubにも置いてあります。
GitHub - Aki-R/HomeAwayMonitor: Monitor existence of certain device in LAN and send the status to SQL.
実際にSSH経由で実行してみます。
python homeaway.py
実行は問題ありません。
実際にデーターベースの書き込んだTableを見てみます。
MariaDB [homeaway]> SELECT * FROM homeaway_table; +----+---------------------+-------+ | id | date | state | +----+---------------------+-------+ | 1 | 2022-01-02 12:10:19 | Away | | 2 | 2022-01-02 12:50:37 | Home | +----+---------------------+-------+ 2 rows in set (0.003 sec)
問題なく書き込まれていますね。
今回はこれで終了です。
次はこのコードを一定期間(30分毎)に実行するのとデータベース上の情報をHTTPサーバー上で可視化しようと思います。
2021/01/06 追記
こちらIPhoneはスリープ(画面オフ)の状態になってしまうとWiFiをスタンバイ状態にしてしまい、ARPにも応じないようです。
スタンバイ状態でもBonjour用のポート(5353)が開いておりそこにUDPでパケット送るとWiFiが復帰するという記事を見つけたのですが、毎回復帰してくれるわけではないようです。
参考までにやり方ですが、hping3のパッケージを使用します。
デフォルトではインストールされていないので、まずこれをインストールします。
sudo apt intall hping3
次にUDPで5353ポートに3パケットを送ります。
sudo hping3 -2 -c 3 -p 5353 -i u1 (iPhoneのIPアドレス)