Mac でロケーションごとの気温を表示する
前に GeekTool でデスクトップに現在の気温を表示するスクリプトを公開した。
🔗 【Mac】現在の気温をデスクトップに | 林檎コンピュータ
これを書き直したいとずっと思ってたんだけど、あまりいいきっかけを見出せずにいた。
というところに、天気予報 – ウェザーニュースという素晴しいサイトを見つけた。
こちらのサイトさんは、URL に現在地の座標を噛ませることで、今いる場所の天気と気温を教えてくれるのである。
iPhone のコンパスを開くと、緯度、経度、高度を表示してくれる。
同じように Mac でも緯度と経度を取得できるはず。
取得できれば、ウェザーニュースさんで現在地の天気と気温を取得できることになり、すなわち MacBook Air をどこへ持っていっても、その場所の気温を表示できることになる。
Mac でジオロケーションを取得する
Mac で緯度と経度の座標を得る簡単な方法は、マップ.app を使うことだろう。どこかの地点をクリックし、ポップアップを表示する。右肩あたりの「 … 」メニューに、「座標をコピー」という項目がある。
たとえば新宿歌舞伎町の「ゴジラヘッド」は、「35.695012, 139.701867」という位置にあるらしい。
これはこれでわかりやすいが、最終的に GeekTool で表示したいので、シェルスクリプトの形になるものがいい。ターミナルで現在の座標を出せないか調べたら、そういうプログラムがちゃんと作られていた。
引数なしで、「whereami」というコマンドを打ちこむと、緯度、経度、精度、タイムスタンプの 4 行を返してくれる。
これを使って、30 分とか一時間ごとに座標を調べ、天候のデータを取得するのがいいかもしれない。
と、思ったが、筆者の環境だと今ひとつ動作が安定しない。Apple シリコンの Mac だからかもしれない。
lua スクリプト
他になにかないか、と捜したら、身近なところにあった。
筆者がやたら推す Hammerspoon にも、緯度と経度を出力してくれる関数があったのである。
さらに、Hammerspoon は wifi の切り替わりも検知してくれる。
家の wifi から外の wifi に切り替わった時に緯度と経度を出力する、というやり方がスマートではなかろうか。Mac は位置情報を wifi の情報から求めているらしいし。
なお、下記のスクリプトを動かす場合、Hammerspoon に位置情報サービスの許可を与える必要がある(システム環境設定>セキュリティとプライバシー>プライバシー>位置情報サービス、に Hammerspoon を追加する)。
また、今回は「書類」フォルダに「weather」というフォルダを設け、作業場とすることにした。
📝 init.lua
wifiWatcher = nil
function ssidChanged()
local loc = hs.location.get()
if loc then
local ido = loc['latitude']
local keido = loc['longitude']
local f = io.open(os.getenv("HOME").."/Documents/weather/loc.txt", "w")
f:write(ido..'/'..keido)
f:close()
end
end
wifiWatcher = hs.wifi.watcher.new(ssidChanged)
wifiWatcher:start()
Hammerspoon の Getting Started というページに wifi event を扱った一節があり、わかりやすい。
英語だけど、Google Chrome の翻訳や DeepL翻訳を使えば素直に読める。
どうであれ、これで wifi が切り替わった時、座標をテキストにして weather フォルダに出力してくれるはず。
そのテキストに基づいて気象データを取得すればいい。
シェルスクリプトは下記のようなものを考えてみた。
せっかく weather フォルダという作業場を作ったので、そこに現在地も出力する。
シェルスクリプト
📝 weather.sh
#!/bin/zsh
loc=$(cat $HOME'/Documents/weather/loc.txt')
html=$(curl -Ss 'https://weathernews.jp/onebox/'"$loc"'/&temp=c&lang=ja')
weather=$(echo "$html" | grep -A 2 'weather-now__ul' | sed -e 's/天気//' -e 's/気温//' -e 's/<[^>]*>//g' -e 's/ //g' -e '/^$/d')
address=$(echo "$html" | grep '<title>' | sed -e 's/<title>【一番当たる】//' -e 's/の最新天気(1時間・今日明日・週間) - ウェザーニュース<\/title>//' -e 's/ //g')
tenki=$(echo $weather | sed -n 1p)
kion=$(echo $weather | sed -n 2p)
echo $address > $HOME/Documents/weather/address.txt
echo $tenki $kion
GeekTool の command は、
sh /Users/ユーザ名/パス/weather.sh
ということになる。更新のインターバルは 3600 とした。
現在地の表示は、
cat $HOME/Documents/weather/address.txt
とした。
これでいいはず、なんだけど、なんかピンとこない。
というのも、筆者は自分の住んでいる町からほとんど出ないからだ。
MacBook Air を閉じたまま仕事場へいくと、なんかぬるっと wifi が切り替わっていて、Hammerspoon が切り替えの瞬間をうまく検知できたのかわからない。
いちおう、print('wifi 切り替わったよ')
などと加えてみると、Hammerspoon のコンソールには表示されるのである。
というか、田舎すぎて wifi が少なく、なかなか確認が出来ない。
隣村まで車でいって確かめようとしたら、wifi どころか携帯の電波さえなかなか捕まらねー有様。でもたぶん、これでいけると思うんだよな。
あるいは 30 分や一時間ごとに座標を吐き出し続けるほうがいいかもしれない。
その場合は init.lua をこう書き直す。
hs.timer.doEvery(1800, function()
local loc = hs.location.get()
if loc then
local ido = loc['latitude']
local keido = loc['longitude']
local f = io.open(os.getenv("HOME").."/Documents/weather/loc.txt", "w")
f:write(ido..'/'..keido)
f:close()
end
end)
hs.timer.doEvery(秒数 fn()
なので、この場合 1800 秒、30 分ごとに更新することになる。けっこう粗いというか、細やかな表示は期待できない。かといって一分おきに更新するようなもんでもないだろうし。
まぁでも、そこまでして正確な気温知りたいか、という話もあるからな。
きょう寒いけど何度くらい? みたいな、ちょっとした好奇心を満たせればそれでいいんである。大都会で頑張るヤングのライフスタイルは知らんけど、こちとらはイカ臭いおじさんしかいない群馬の山奥なんであって、そもそも MacBook Air なんか持ち歩かねーわ、という話だ。
だいたい、通知センターに天気ってあるからね。
気温も表示されっからね。
ということで、今回はここであきらめます。すみません。