特定のWi-Fiに接続している場合に行いたい処理とかあるかもしれない。
例えば、操作しているMacbookが自宅のWi-Fiに接続されている状態であるならば、自宅のNASの音楽ライブラリと自動的に同期させたい……とか。
サンプル
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.14.1
BuildVersion: 18B75
$ python --version
Python 3.7.0
上記の通り、動作させるのがMacだとわかっているのであればこんな感じ。
import subprocess import re class WiFiUtil: """Wi-Fi関連ユーティリティ """ @staticmethod def getUsingSSID(): """接続中のWi-FiのSSIDを取得する Returns: str -- SSID """ cmd = ['/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport', '-I'] cmd_res = subprocess.run(cmd, stdout=subprocess.PIPE) output = cmd_res.stdout.decode('utf-8') matchs = re.findall(r' +SSID: .+', output) res = "" if len(matchs) > 0: res = matchs[0] res = re.sub(r'^ +SSID: ', '', res) res = res.rstrip() return res if __name__ == '__main__': res = WiFiUtil.getUsingSSID() print(res) #SSIDが出力される
サンプル解説
MacではWi-Fiの状態を確認、制御するコマンドが用意されている。
絶対パスで/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport
。
オプションに-I
をつけることで現在接続中のWi-Fiの状態を調べることができる。
出力結果はこんな感じ。
agrCtlRSSI: xxx agrExtRSSI: xxx agrCtlNoise: xxx agrExtNoise: xxx state: xxx op mode: xxx lastTxRate: xxx maxRate: xxx lastAssocStatus: xxx 802.11 auth: xxx link auth: xxx BSSID: xxx SSID: xxx MCS: xxx channel: xxx
Pythonからシェルコマンドを実行して、この標準出力結果を取得。
欲しいSSID: XXX
に該当する箇所を正規表現とかを使って引き抜いている。
なお、subprocess.run()
で取得している標準出力結果はbyte配列で変換されるので、Macのターミナルでデフォルトの文字コードとしてUTF-8でデコードしてから正規表現等で結果を引き抜いている。
いじょー。
余談
2018/11/21追記
結果的にOSのコマンドを利用する泥臭い感じになった。
「よっしゃ、OSのCLI動かして標準出力結果抜いたろ!」ってPythonでやる場合、ネックなのはクロスプラットフォームで動かす時なんかだろうか。
今回はSSIDを抜き取るためにmacOSのairport
というコマンドを使ったが、当然これがWindowsやLinuxなら同様な機能を持つ別コマンドにしなければならない。
Pythonのos
とかplatform
あたりのモジュールを使って、実行環境のOSを調べて実行するコマンドを変えることもそうだが、個人的に厄介だと思うのはsubprocess
に実装されている標準出力を得る方法で返却されるのがバイト配列だという点だろうか。
mac OSでは特にターミナルの設定をいじっていなければUTF-8
で(たぶん)デコードできるだろうが、Windowsのcmd.exeはOSに設定してあるロケールで文字コードが変化するし、LinuxもSSHで接続した時に文字化けとかする場合を考えると設定によりけりなんじゃないかな?。知らんけど。
最近はメインで使っているのがMacbookだからそんなに気はのらないけど、せっかくVMがガンガン動かせるようになってきたので暇ならクロスプラットフォームなPythonスクリプトの構築に向けていろいろ調べておこうかな。