cwadayi commited on
Commit
69f80eb
·
verified ·
1 Parent(s): 118b8c9

Update cwa_service.py

Browse files
Files changed (1) hide show
  1. cwa_service.py +53 -12
cwa_service.py CHANGED
@@ -33,21 +33,64 @@ def fetch_cwa_alarm_list(limit: int = 5) -> str:
33
 
34
  # --- 顯著有感地震 (E-A0015-001) (此區塊不變) ---
35
  def _parse_significant_earthquakes(obj: dict) -> pd.DataFrame:
36
- # ... (此函式內容不變) ...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  return df
38
 
39
  def fetch_significant_earthquakes(days: int = 7, limit: int = 5) -> str:
40
  # ... (此函式內容不變) ...
41
- return "\n\n".join(lines)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
- # --- [新功能] 最新一筆顯著地震 ---
 
44
  def fetch_latest_significant_earthquake() -> dict | None:
45
  """從 CWA 獲取最新一筆顯著有感地震的詳細資料,包含報告圖。"""
46
  if not CWA_API_KEY:
47
- # 在這種情況下拋出錯誤,讓呼叫者處理
48
  raise ValueError("錯誤:尚未設定 CWA_API_KEY Secret。")
49
 
50
- # 查詢過去24小時內最新的一筆資料
51
  now = datetime.now(timezone.utc)
52
  time_from = (now - timedelta(days=1)).strftime("%Y-%m-%dT%H:%M:%S")
53
 
@@ -55,8 +98,9 @@ def fetch_latest_significant_earthquake() -> dict | None:
55
  "Authorization": CWA_API_KEY,
56
  "format": "JSON",
57
  "timeFrom": time_from,
58
- "limit": 1, # 只取最新一筆
59
- "sort": "OriginTime desc" # 依時間倒序
 
60
  }
61
 
62
  r = requests.get(CWA_SIGNIFICANT_API, params=params, timeout=15)
@@ -69,26 +113,23 @@ def fetch_latest_significant_earthquake() -> dict | None:
69
 
70
  q = quakes[0]
71
  ei = q.get("EarthquakeInfo", {})
72
- epic = ei.get("Epicenter", {})
73
  mag_info = ei.get("Magnitude", {})
74
 
75
  depth_raw = ei.get("FocalDepth") or ei.get("Depth")
76
  mag_raw = mag_info.get("MagnitudeValue") or mag_info.get("value") or mag_info.get("Magnitude")
77
 
78
- # 將解析出的資料存入字典
79
  result = {
80
  "Time": ei.get("OriginTime"),
81
  "Location": epic.get("Location"),
82
  "Magnitude": _to_float(mag_raw),
83
  "Depth": _to_float(depth_raw),
84
  "URL": q.get("Web"),
85
- "ImageURL": q.get("ReportImageURI") # 獲取報告圖網址
86
  }
87
 
88
- # 將時間轉換為台北時區
89
  if result["Time"]:
90
  dt = pd.to_datetime(result["Time"]).tz_localize("UTC").tz_convert(TAIPEI_TZ)
91
  result["TimeStr"] = dt.strftime('%Y-%m-%d %H:%M')
92
 
93
  return result
94
-
 
33
 
34
  # --- 顯著有感地震 (E-A0015-001) (此區塊不變) ---
35
  def _parse_significant_earthquakes(obj: dict) -> pd.DataFrame:
36
+ records = obj.get("records") or obj.get("Records") or {}
37
+ quakes = records.get("earthquake") or records.get("Earthquake") or []
38
+ rows = []
39
+ for q in quakes:
40
+ ei = q.get("EarthquakeInfo") or q.get("earthquakeInfo") or {}
41
+ epic = ei.get("Epicenter") or ei.get("epicenter") or {}
42
+ mag_info = ei.get("Magnitude") or ei.get("magnitude") or ei.get("EarthquakeMagnitude") or {}
43
+ depth_raw = ei.get("FocalDepth") or ei.get("depth") or ei.get("Depth")
44
+ mag_raw = mag_info.get("MagnitudeValue") or mag_info.get("magnitudeValue") or mag_info.get("Value") or mag_info.get("value")
45
+ rows.append({
46
+ "ID": q.get("EarthquakeNo"), "Time": ei.get("OriginTime"),
47
+ "Lat": _to_float(epic.get("EpicenterLatitude") or epic.get("epicenterLatitude")),
48
+ "Lon": _to_float(epic.get("EpicenterLongitude") or epic.get("epicenterLongitude")),
49
+ "Depth": _to_float(depth_raw), "Magnitude": _to_float(mag_raw),
50
+ "Location": epic.get("Location") or epic.get("location"),
51
+ "URL": q.get("Web") or q.get("ReportURL"),
52
+ })
53
+ df = pd.DataFrame(rows)
54
+ if not df.empty and "Time" in df.columns:
55
+ time_series = pd.to_datetime(df["Time"], errors="coerce")
56
+ if pd.api.types.is_datetime64_any_dtype(time_series):
57
+ df["Time"] = time_series.dt.tz_localize("UTC").dt.tz_convert(TAIPEI_TZ)
58
  return df
59
 
60
  def fetch_significant_earthquakes(days: int = 7, limit: int = 5) -> str:
61
  # ... (此函式內容不變) ...
62
+ if not CWA_API_KEY: return "❌ 顯著地震查詢失敗:管理者尚未設定 CWA_API_KEY。"
63
+ now = datetime.now(timezone.utc)
64
+ time_from = (now - timedelta(days=days)).strftime("%Y-%m-%d")
65
+ params = {"Authorization": CWA_API_KEY, "format": "JSON", "timeFrom": time_from}
66
+ try:
67
+ r = requests.get(CWA_SIGNIFICANT_API, params=params, timeout=15)
68
+ r.raise_for_status()
69
+ data = r.json()
70
+ df = _parse_significant_earthquakes(data)
71
+ if df.empty: return f"✅ 過去 {days} 天內沒有顯著有感地震報告。"
72
+ df = df.sort_values(by="Time", ascending=False).head(limit)
73
+ lines = [f"🚨 CWA 最新顯著有感地震 (近{days}天內):", "-" * 20]
74
+ for _, row in df.iterrows():
75
+ mag_str = f"{row['Magnitude']:.1f}" if pd.notna(row['Magnitude']) else "—"
76
+ depth_str = f"{row['Depth']:.0f}" if pd.notna(row['Depth']) else "—"
77
+ lines.append(
78
+ f"時間: {row['Time'].strftime('%Y-%m-%d %H:%M') if pd.notna(row['Time']) else '—'}\n"
79
+ f"地點: {row['Location'] or '—'}\n"
80
+ f"規模: M{mag_str} | 深度: {depth_str} km\n"
81
+ f"報告: {row['URL'] or '無'}"
82
+ )
83
+ return "\n\n".join(lines)
84
+ except Exception as e:
85
+ return f"❌ 顯著地震查詢失敗:{e}"
86
 
87
+
88
+ # --- 最新一筆顯著地震 ---
89
  def fetch_latest_significant_earthquake() -> dict | None:
90
  """從 CWA 獲取最新一筆顯著有感地震的詳細資料,包含報告圖。"""
91
  if not CWA_API_KEY:
 
92
  raise ValueError("錯誤:尚未設定 CWA_API_KEY Secret。")
93
 
 
94
  now = datetime.now(timezone.utc)
95
  time_from = (now - timedelta(days=1)).strftime("%Y-%m-%dT%H:%M:%S")
96
 
 
98
  "Authorization": CWA_API_KEY,
99
  "format": "JSON",
100
  "timeFrom": time_from,
101
+ "limit": 1,
102
+ # [修正] 移除不支援的 sort 參數,API 預設即為時間倒序
103
+ # "sort": "OriginTime desc"
104
  }
105
 
106
  r = requests.get(CWA_SIGNIFICANT_API, params=params, timeout=15)
 
113
 
114
  q = quakes[0]
115
  ei = q.get("EarthquakeInfo", {})
116
+ epic = q.get("Epicenter", {})
117
  mag_info = ei.get("Magnitude", {})
118
 
119
  depth_raw = ei.get("FocalDepth") or ei.get("Depth")
120
  mag_raw = mag_info.get("MagnitudeValue") or mag_info.get("value") or mag_info.get("Magnitude")
121
 
 
122
  result = {
123
  "Time": ei.get("OriginTime"),
124
  "Location": epic.get("Location"),
125
  "Magnitude": _to_float(mag_raw),
126
  "Depth": _to_float(depth_raw),
127
  "URL": q.get("Web"),
128
+ "ImageURL": q.get("ReportImageURI")
129
  }
130
 
 
131
  if result["Time"]:
132
  dt = pd.to_datetime(result["Time"]).tz_localize("UTC").tz_convert(TAIPEI_TZ)
133
  result["TimeStr"] = dt.strftime('%Y-%m-%d %H:%M')
134
 
135
  return result