Triliumに記録しました。
ドキュメント整備が全て完了しました。今回のセッションで行った作業のまとめ: 実装した機能 Windmill フロー f/weather/weather_sync(毎朝6時 Asia/Tokyo)の作成・本番稼働 /weather フロントエンドページ(年別集計 / 期間指定の2モード) Recharts 3.7.0 による月別・日次グラフ(気温折れ線、降水量棒+日照折れ線 2軸) 整備したドキュメント ドキュメント 内容 CLAUDE.md weather 画面追加・Windmill フロー・マスタードキュメントリンク document/12_マスタードキュメント_気象データ編.md 気象機能の完全リファレンス(新規作成) MEMORY.md Windmill API パターン・Recharts TypeScript パターン Trilium マスタードキュメント フロントエンド2モード・Recharts・document/12_ 参照追加
This commit is contained in:
16
CLAUDE.md
16
CLAUDE.md
@@ -93,6 +93,7 @@ keinasystem_t02/
|
||||
│ ├── feedback/[token]/ # フィードバックページ(認証不要)
|
||||
│ ├── history/ # メール処理履歴
|
||||
│ └── rules/ # 送信者ルール管理
|
||||
├── weather/ # 気象データ画面(年別集計・期間指定・グラフ)
|
||||
└── settings/
|
||||
└── password/ # パスワード変更
|
||||
```
|
||||
@@ -280,10 +281,12 @@ WeatherRecord (日次気象記録)
|
||||
- `GET /api/weather/gdd/?start_date=&base_temp=&end_date=` 有効積算温度(GDD)
|
||||
- `GET /api/weather/similarity/?year=` 類似年分析(月別パターン比較)
|
||||
- 管理コマンド: `python manage.py fetch_weather [--full] [--start-date] [--end-date]`
|
||||
- Windmill フロー: `u/admin/weather_sync.flow`(ローカル作成済み、本番デプロイ要)
|
||||
- Windmill フロー: `f/weather/weather_sync`(本番稼働中、毎朝6時 Asia/Tokyo)
|
||||
- `Crop.base_temp`(GDD計算の基準温度、default=0.0℃)をCropモデルに追加
|
||||
- **初回データ投入**: `docker compose exec backend python manage.py fetch_weather --full`
|
||||
- フロントエンド `/weather` 画面(年別集計・期間指定 モード、グラフは Recharts)
|
||||
- **将来計画**: 開花・収穫予測(品種ごとの目標GDD設定 → 到達日予測)
|
||||
- マスタードキュメント: `document/12_マスタードキュメント_気象データ編.md`
|
||||
|
||||
### 🚧 既知の課題・技術的負債
|
||||
|
||||
@@ -340,9 +343,11 @@ Phase 2 のタスクに進む段階。
|
||||
|
||||
```bash
|
||||
# ⚠️ --env-file .env.production を必ず付けること(省略するとSECRET_KEYが空でbackendが起動しない)
|
||||
ssh keinafarm-claude 'cd /home/akira/keinasystem_t02 && \
|
||||
docker compose -f docker-compose.prod.yml --env-file .env.production build && \
|
||||
docker compose -f docker-compose.prod.yml --env-file .env.production up -d'
|
||||
# ⚠️ 本番ファイルは keinasystem ユーザー所有。git pull は sudo -u keinasystem で実行
|
||||
ssh keinafarm-claude 'sudo -u keinasystem git -C /home/keinasystem/keinasystem_t02 pull origin main && \
|
||||
cd /home/keinasystem/keinasystem_t02 && \
|
||||
sudo -u keinasystem docker compose -f docker-compose.prod.yml --env-file .env.production build && \
|
||||
sudo -u keinasystem docker compose -f docker-compose.prod.yml --env-file .env.production up -d'
|
||||
```
|
||||
|
||||
### マイグレーションエラー
|
||||
@@ -381,6 +386,7 @@ docker-compose exec backend python manage.py migrate
|
||||
|
||||
- **圃場管理機能**: `document/10_マスタードキュメント_圃場管理編.md`
|
||||
- **メール通知機能**: `document/11_マスタードキュメント_メール通知関連編.md`
|
||||
- **気象データ機能**: `document/12_マスタードキュメント_気象データ編.md`
|
||||
|
||||
### 設計ドキュメント(プロジェクト横断)
|
||||
|
||||
@@ -405,7 +411,7 @@ docker-compose exec backend python manage.py migrate
|
||||
|
||||
## 📝 更新履歴
|
||||
|
||||
- 2026-02-28: 気象データ基盤を実装。`apps/weather` Django app(WeatherRecord, GDD API, 類似年分析API)、Windmill フロー `u/admin/weather_sync.flow`、管理コマンド `fetch_weather`。`Crop.base_temp` 追加(GDD基準温度)。初回データ投入は `fetch_weather --full`
|
||||
- 2026-02-28: 気象データ機能を実装・本番稼働。`apps/weather`(WeatherRecord, 5 API)、Windmill `f/weather/weather_sync`(毎朝6時)、フロントエンド `/weather`(年別集計・期間指定・Rechartsグラフ)。`Crop.base_temp` 追加。デプロイコマンドの本番パス修正(/home/keinasystem/)。マスタードキュメント `document/12_マスタードキュメント_気象データ編.md` 追加
|
||||
- 2026-02-25: CLAUDE.md更新。パスワード変更機能追記。メールフィルタリング機能を本番稼働済みに更新。マスタードキュメント `document/11_マスタードキュメント_メール通知関連編.md` リンク追加。デプロイコマンド(`--env-file .env.production` 必須)をトラブルシューティングに追加
|
||||
- 2026-02-22: メールフィルタリング機能を実装。`apps/mail` Django app、Windmill向けAPI(APIキー認証)、フィードバックページ、ルール管理ページを追加。仕様書: `document/メールフィルタ/mail_filter_spec.md`
|
||||
- 2026-02-21: マスタードキュメント体系を導入。`document/10_マスタードキュメント_圃場管理編.md` を追加。セッション推奨フローにマスタードキュメント参照を追加
|
||||
|
||||
241
document/12_マスタードキュメント_気象データ編.md
Normal file
241
document/12_マスタードキュメント_気象データ編.md
Normal file
@@ -0,0 +1,241 @@
|
||||
# 気象データ機能 マスタードキュメント
|
||||
|
||||
> **最終更新**: 2026-02-28
|
||||
> **状態**: 本番稼働中
|
||||
|
||||
---
|
||||
|
||||
## 概要
|
||||
|
||||
Open-Meteo archive API から窪川の気象データを日次取得し、PostgreSQL に蓄積する。
|
||||
農業における積算温度計算・類似年分析・作期の気象振り返りを目的とする。
|
||||
|
||||
- **観測地点**: 窪川 (lat=33.213, lon=133.133)
|
||||
- **データソース**: [Open-Meteo Archive API](https://archive-api.open-meteo.com/v1/archive)(無料)
|
||||
- **蓄積期間**: 2016-01-01 〜 前日(毎朝自動更新)
|
||||
- **Django アプリ**: `backend/apps/weather/`
|
||||
|
||||
---
|
||||
|
||||
## データモデル
|
||||
|
||||
### WeatherRecord (`apps/weather/models.py`)
|
||||
|
||||
| フィールド | 型 | 説明 |
|
||||
|---|---|---|
|
||||
| date | DateField (unique) | 日付 |
|
||||
| temp_mean | FloatField nullable | 平均気温 (℃) |
|
||||
| temp_max | FloatField nullable | 最高気温 (℃) |
|
||||
| temp_min | FloatField nullable | 最低気温 (℃) |
|
||||
| sunshine_h | FloatField nullable | 日照時間 (h) |
|
||||
| precip_mm | FloatField nullable | 降水量 (mm) |
|
||||
| wind_max | FloatField nullable | 最大風速 (m/s) |
|
||||
| pressure_min | FloatField nullable | 最低気圧 (hPa) |
|
||||
|
||||
**Crop.base_temp** (`apps/plans/models.py` に追加):
|
||||
- FloatField, default=0.0
|
||||
- GDD(有効積算温度)計算の基準温度
|
||||
|
||||
---
|
||||
|
||||
## API エンドポイント (`/api/weather/`)
|
||||
|
||||
### POST `/api/weather/sync/`
|
||||
- **認証**: X-API-Key(MAIL_API_KEY 設定値、Windmill と共用)
|
||||
- **用途**: Windmill から日次データを受け取り upsert
|
||||
- **リクエスト**: 単一オブジェクトまたはリスト
|
||||
- **レスポンス**: `{"saved": N}` or `{"saved": N, "errors": [...]}`
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"date": "2026-02-27",
|
||||
"temp_mean": 8.5, "temp_max": 14.2, "temp_min": 3.1,
|
||||
"sunshine_h": 6.3, "precip_mm": 0.0,
|
||||
"wind_max": 4.2, "pressure_min": 1008.0
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### GET `/api/weather/records/`
|
||||
- **認証**: JWT
|
||||
- **クエリパラメータ**:
|
||||
- `?year=2025` — 年指定
|
||||
- `?start=2025-05-01&end=2025-09-30` — 日付範囲指定
|
||||
- **レスポンス**: WeatherRecord の配列(date 昇順)
|
||||
|
||||
---
|
||||
|
||||
### GET `/api/weather/summary/?year=2025`
|
||||
- **認証**: JWT
|
||||
- **レスポンス**:
|
||||
|
||||
```json
|
||||
{
|
||||
"year": 2025,
|
||||
"monthly": [
|
||||
{
|
||||
"month": 1,
|
||||
"temp_mean_avg": 5.2, "temp_max_avg": 10.1, "temp_min_avg": 0.8,
|
||||
"precip_total": 45.0, "sunshine_total": 98.3, "wind_max": 9.5,
|
||||
"hot_days": 0, "cold_days": 8, "rainy_days": 12
|
||||
},
|
||||
...
|
||||
],
|
||||
"annual": {
|
||||
"temp_mean_avg": 16.1, "precip_total": 2310.0, "sunshine_total": 1850.5,
|
||||
"hot_days": 12, "cold_days": 25
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- **hot_days**: 最高気温 ≥ 35℃ の日数
|
||||
- **cold_days**: 最低気温 < 0℃ の日数
|
||||
- **rainy_days**: 降水量 ≥ 1.0mm の日数
|
||||
|
||||
---
|
||||
|
||||
### GET `/api/weather/gdd/`
|
||||
- **認証**: JWT
|
||||
- **用途**: 播種日〜現在の有効積算温度(Growing Degree Days)を計算
|
||||
- **クエリパラメータ**:
|
||||
- `?start_date=2025-05-15` (必須) — 起算日
|
||||
- `?base_temp=10` (省略時=0) — 基準温度 ℃
|
||||
- `?end_date=2025-09-30` (省略時=昨日)
|
||||
- **レスポンス**:
|
||||
|
||||
```json
|
||||
{
|
||||
"start_date": "2025-05-15",
|
||||
"end_date": "2025-09-30",
|
||||
"base_temp": 10.0,
|
||||
"total_gdd": 1342.5,
|
||||
"records": [
|
||||
{"date": "2025-05-15", "temp_mean": 18.2, "daily_gdd": 8.2, "cumulative_gdd": 8.2},
|
||||
...
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- **日積算温度** = max(0, 平均気温 - 基準温度)
|
||||
|
||||
---
|
||||
|
||||
### GET `/api/weather/similarity/?year=2026`
|
||||
- **認証**: JWT
|
||||
- **用途**: 今年 1/1〜昨日 の気象パターンと過去年を比較し、類似年 Top3 を返す
|
||||
- **アルゴリズム**: (平均気温, 総降水量, 総日照時間) の正規化ユークリッド距離
|
||||
- **レスポンス**:
|
||||
|
||||
```json
|
||||
{
|
||||
"target_year": 2026,
|
||||
"comparison_period": "1/1〜2/27",
|
||||
"target_features": {"mean_temp": 7.3, "total_precip": 185.0, "total_sunshine": 240.5},
|
||||
"similar_years": [
|
||||
{
|
||||
"year": 2020, "distance": 0.312,
|
||||
"features": {...},
|
||||
"monthly": [...]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 管理コマンド
|
||||
|
||||
```bash
|
||||
# 全期間取得(初回のみ)
|
||||
docker compose exec backend python manage.py fetch_weather --full
|
||||
|
||||
# 差分取得(最終レコード翌日〜昨日)
|
||||
docker compose exec backend python manage.py fetch_weather
|
||||
|
||||
# 任意期間
|
||||
docker compose exec backend python manage.py fetch_weather --start-date 2025-01-01 --end-date 2025-12-31
|
||||
```
|
||||
|
||||
**仕様**:
|
||||
- 年単位で Open-Meteo API を呼び出し(API 制限回避のため分割)
|
||||
- upsert: 既存データを上書き更新
|
||||
- `--full`: 2016-01-01 から昨日まで(初回投入用)
|
||||
|
||||
---
|
||||
|
||||
## Windmill フロー
|
||||
|
||||
| 項目 | 値 |
|
||||
|---|---|
|
||||
| パス | `f/weather/weather_sync` |
|
||||
| スケジュール | `0 0 6 * * *`(毎朝 6:00 Asia/Tokyo) |
|
||||
| スクリプト | `windmill/u/admin/weather_sync.flow/a.inline_script.py` |
|
||||
| 状態 | ✅ 本番稼働中(windmill.keinafarm.net) |
|
||||
|
||||
**使用 Windmill Variables**:
|
||||
|
||||
| 変数名 | 内容 |
|
||||
|---|---|
|
||||
| `u/admin/KEINASYSTEM_API_KEY` | API キー(メール機能と共用) |
|
||||
| `u/admin/KEINASYSTEM_API_URL` | `https://keinafarm.net` |
|
||||
|
||||
---
|
||||
|
||||
## フロントエンド画面 (`/weather`)
|
||||
|
||||
### 年別集計モード(デフォルト)
|
||||
|
||||
- 年セレクタ (2016〜現在)
|
||||
- **年間サマリーカード**: 平均気温 / 年間降水量 / 年間日照時間 / 猛暑日数・冬日数
|
||||
- **グラフタブ**: 月別気温折れ線(最高・平均・最低)、月別降水量棒 + 日照時間折れ線(2軸)
|
||||
- **月別サマリータブ**: 12ヶ月のテーブル
|
||||
- **直近14日タブ**: 日次データテーブル(Windmill 同期確認用)
|
||||
|
||||
### 期間指定モード
|
||||
|
||||
- 開始日・終了日の date input + 「表示」ボタン
|
||||
- **期間集計カード**: 期間の平均気温 / 総降水量 / 総日照時間 / 猛暑日・冬日
|
||||
- **グラフタブ**: 日次気温折れ線 + 日次降水量棒+日照折れ線
|
||||
- X軸ラベル自動間引き(30日以内→3日おき、3ヶ月→週1、半年→2週、1年超→月1)
|
||||
- 60日以内はドット表示あり
|
||||
- **一覧タブ**: 日次データテーブル(スクロール対応)
|
||||
|
||||
**使用ライブラリ**: Recharts 3.7.x(`frontend/package.json` に登録済み)
|
||||
|
||||
---
|
||||
|
||||
## ファイル索引
|
||||
|
||||
| ファイル | 役割 |
|
||||
|---|---|
|
||||
| `backend/apps/weather/models.py` | WeatherRecord モデル |
|
||||
| `backend/apps/weather/views.py` | 5つのAPIビュー |
|
||||
| `backend/apps/weather/urls.py` | URL設定 |
|
||||
| `backend/apps/weather/serializers.py` | Serializer |
|
||||
| `backend/apps/weather/admin.py` | 管理画面登録 |
|
||||
| `backend/apps/weather/migrations/0001_initial.py` | 初回マイグレーション |
|
||||
| `backend/apps/weather/management/commands/fetch_weather.py` | 管理コマンド |
|
||||
| `backend/apps/plans/migrations/0004_crop_base_temp.py` | Crop.base_temp 追加 |
|
||||
| `frontend/src/app/weather/page.tsx` | 気象画面(400行) |
|
||||
| `windmill/u/admin/weather_sync.flow/a.inline_script.py` | Windmill Python スクリプト |
|
||||
| `windmill/u/admin/weather_sync.flow/flow.yaml` | Windmill フロー定義 |
|
||||
|
||||
---
|
||||
|
||||
## 将来計画(Phase 2 以降)
|
||||
|
||||
1. **GDD 到達日予測**: `Crop.base_temp` を使い、播種日から目標GDDに達する日を予測
|
||||
2. **類似年ベースの収穫予測**: 類似年の収穫時期を参考に今年の予測を表示
|
||||
3. **作付け計画との連携**: 作期ごとの気象サマリーを圃場詳細に表示
|
||||
4. **気象アラート**: 猛暑・長雨・強風などの異常気象を検知して通知
|
||||
|
||||
---
|
||||
|
||||
## 注意事項
|
||||
|
||||
- Open-Meteo archive API は**前日まで**のデータしか取得できない(リアルタイム不可)
|
||||
- `pressure_min` は `surface_pressure_min`(地表気圧)。海面更正気圧とは異なる
|
||||
- Open-Meteo の `sunshine_duration` は秒単位 → `sunshine_h` = 秒 ÷ 3600 で変換
|
||||
Reference in New Issue
Block a user