旭川の前日気温をSQLiteへ自動収集する
地域の活動記録や体調・作業環境の振り返りでは、「その日が暑かったのか、寒かったのか」を後から見られるだけで文脈が増える。今回はHermes Agentの定期実行で使う小さなデータ収集機能として、旭川市内2地点の前日最低・最高気温を取得し、SQLiteへ保存するスクリプトを実装した。
実際に行ったことと確認結果
手元の実装では、`asahikawa_temperature.py`という単独CLIを追加した。引数なしではAsia/Tokyo基準で完了済みの直近7日を再取得し、地点IDと日付をキーにSQLiteへUPSERTする。これにより、同じ期間を再実行しても重複せず、前回の通信失敗で欠けた日付も次回の成功時に補完できる。
取得対象は、旭川市の代表点と、もう1つの地域点の2地点にした。データはOpen-MeteoのJMA APIから取得する格子推定値であり、観測所の実測値ではない。保存時にはAPI応答のタイムゾーン、単位、日付範囲、最低気温が最高気温を超えていないこと、極端に非現実的な値でないことを検証する。
確認として、`python3 -m unittest discover -s tests -p 'test_asahikawa_temperature.py' -v`を実行し、9件すべて成功した。さらに一時SQLiteを使って2日分の実取得を行い、2地点×2日で4行が保存され、`status`で最終実行と地点別の欠損日が読めることを確認した。
仕組みの流れ
処理は次の順番で進む。
1. Asia/Tokyoの今日を基準に、前日までの収集窓を決める。
2. 各地点の緯度・経度を固定設定から選ぶ。
3. Open-Meteo JMA APIへ、日別の最高・最低気温をJSONで要求する。
4. 応答の単位、タイムゾーン、日付、数値範囲を検証する。
5. SQLiteへ地点ID・日付単位でUPSERTする。
6. 実行履歴と地点別の成功・失敗を保存する。
7. cron向けには、前日の2地点の気温と直近7日の欠損状況を日本語で出力する。
多重起動でDBが壊れないよう、同じDBに対する収集中はファイルロックで二重実行を拒否する。通信障害はバックオフつきで再試行し、片方の地点だけ成功した場合も成功分は保存し、結果は一部失敗として扱う。
再現手順
公開例では実際のユーザー名、通知先ID、保存場所は置き換える。まずプロジェクトへスクリプトを置き、依存を同期する。
“`bash
cd /path/to/project
uv sync
python3 -m unittest discover -s tests -p 'test_asahikawa_temperature.py' -v
“`
手動で状態確認やCSV出力を行う場合は、DBの場所を明示しておくと検証しやすい。
“`bash
python3 asahikawa_temperature.py –db /path/to/weather.sqlite3 collect –days 2 –json
python3 asahikawa_temperature.py –db /path/to/weather.sqlite3 status
python3 asahikawa_temperature.py –db /path/to/weather.sqlite3 export-csv \
–start-date 2026-08-01 –end-date 2026-08-14 \
–output weather.csv
“`
Hermes cronへ登録する場合は、LLMを介さないスクリプトジョブにする。例では通知先をプレースホルダーにしている。
“`bash
hermes cron create '17 5 * * *' \
–name '地域気温をSQLiteへ保存' \
–script asahikawa_temperature.py \
–no-agent \
–deliver discord:YOUR_TARGET \
–workdir /path/to/project
“`
失敗しやすい点と安全策
一番の注意点は、API値を観測所の実測値として扱わないことだ。確認日現在、Open-MeteoのJMA APIは日本向けにJMAのGSM/MSMモデルを使うと説明しており、MSMは約5km格子のモデル値である。記事やレポートに出す場合は「推定値」「確認日現在のAPI取得値」と明記する。
また、気象APIは一時的に欠損や通信失敗が起きる。直近7日を毎回再取得する設計にしておくと、翌日の成功で自然に穴埋めしやすい。通知は便利だが、医療・安全・法務判断の根拠にはせず、人が必要な一次情報を確認する前提にする。
再現チェックリスト
- [ ] 収集対象の日付がAsia/Tokyo基準の完了済み日だけになっている。
- [ ] 地点IDと日付をキーにUPSERTし、再実行で重複しない。
- [ ] API応答の単位、タイムゾーン、日付範囲を検証している。
- [ ] 片地点の失敗でも成功分を保存し、結果は一部失敗として通知する。
- [ ] `status`で直近7日の欠損が分かる。
- [ ] cron登録時に秘密値や実パスを記事・ログへ出していない。
- [ ] 気温値を観測所実測ではなく格子推定値として扱う。
公式一次情報
- [Open-Meteo JMA API](https://open-meteo.com/en/docs/jma-api)
- [Hermes Agent Scheduled Tasks](https://hermes-agent.nousresearch.com/docs/user-guide/features/cron)
- [Obsidian CLI](https://obsidian.md/cli)
- [Python sqlite3](https://docs.python.org/3/library/sqlite3.html)
