cwadayi commited on
Commit
0bea8cb
·
verified ·
1 Parent(s): 8041dc5

Update weather_service.py

Browse files
Files changed (1) hide show
  1. weather_service.py +73 -5
weather_service.py CHANGED
@@ -1,21 +1,89 @@
1
  # weather_service.py
2
  import requests
3
- from config import CWA_API_KEY # [修改] 更新變數名稱
4
  from datetime import datetime
5
 
6
- # ... (檔案其餘部分不變) ...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
  def fetch_forecast_by_location(location_name: str) -> str:
9
  """根據地點名稱查詢未來 36 小時天氣預報。"""
10
- if not CWA_API_KEY: # [修改] 更新變數名稱
11
  return "❌ 天氣預報查詢失敗:管理者尚未設定 CWA_API_KEY。"
12
 
13
  normalized_loc = _normalize_location_name(location_name)
14
 
15
  params = {
16
- "Authorization": CWA_API_KEY, # [修改] 更新變數名稱
17
  "format": "JSON",
18
  "locationName": normalized_loc,
19
  "elementName": ["Wx", "PoP", "MinT", "MaxT"],
20
  }
21
- # ... (try...except 區塊不變) ...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  # weather_service.py
2
  import requests
3
+ from config import CWA_API_KEY
4
  from datetime import datetime
5
 
6
+ CWA_FORECAST_API = "https://opendata.cwa.gov.tw/api/v1/rest/datastore/F-C0032-001"
7
+
8
+ def _normalize_location_name(loc_name: str) -> str:
9
+ """自動校正縣市名稱,以符合 API 要求 (例如 台北 -> 臺北市)"""
10
+ loc_name = loc_name.replace("台", "臺")
11
+ if loc_name.endswith("市") or loc_name.endswith("縣"):
12
+ return loc_name
13
+
14
+ major_cities = "臺北,桃園,新竹,臺中,嘉義,臺南,高雄,基隆".split(',')
15
+ if any(city in loc_name for city in major_cities):
16
+ return f"{loc_name}市"
17
+
18
+ return f"{loc_name}縣"
19
+
20
+ def _format_time_period(start_str: str, end_str: str) -> str:
21
+ """將時間格式化為易讀的時段名稱"""
22
+ start_dt = datetime.fromisoformat(start_str)
23
+ start_hour = start_dt.hour
24
+
25
+ if start_hour >= 18 or start_hour < 6:
26
+ return f"{start_dt.strftime('%m/%d')} 晚上至隔日清晨"
27
+ elif start_hour >= 6 and start_hour < 18:
28
+ return f"{start_dt.strftime('%m/%d')} 白天"
29
+ return f"{start_dt.strftime('%m/%d %H:%M')}"
30
+
31
 
32
  def fetch_forecast_by_location(location_name: str) -> str:
33
  """根據地點名稱查詢未來 36 小時天氣預報。"""
34
+ if not CWA_API_KEY:
35
  return "❌ 天氣預報查詢失敗:管理者尚未設定 CWA_API_KEY。"
36
 
37
  normalized_loc = _normalize_location_name(location_name)
38
 
39
  params = {
40
+ "Authorization": CWA_API_KEY,
41
  "format": "JSON",
42
  "locationName": normalized_loc,
43
  "elementName": ["Wx", "PoP", "MinT", "MaxT"],
44
  }
45
+
46
+ try:
47
+ r = requests.get(CWA_FORECAST_API, params=params, timeout=10)
48
+ r.raise_for_status()
49
+ data = r.json()
50
+
51
+ if not data.get("records") or not data["records"]["location"]:
52
+ return f"找不到「{location_name}」的預報資訊。\n請確認是否為台灣的縣市名稱 (例如: 臺北市, 花蓮縣)。"
53
+
54
+ loc_data = data["records"]["location"][0]
55
+ elements = {elem["elementName"]: elem["time"] for elem in loc_data["weatherElement"]}
56
+
57
+ forecasts = []
58
+ for i in range(3):
59
+ try:
60
+ start_time = elements["Wx"][i]["startTime"]
61
+ end_time = elements["Wx"][i]["endTime"]
62
+ wx = elements["Wx"][i]["parameter"]["parameterName"]
63
+ pop = elements["PoP"][i]["parameter"]["parameterName"]
64
+ min_t = elements["MinT"][i]["parameter"]["parameterName"]
65
+ max_t = elements["MaxT"][i]["parameter"]["parameterName"]
66
+
67
+ period_name = _format_time_period(start_time, end_time)
68
+
69
+ forecast_str = (
70
+ f"➢ {period_name}:\n"
71
+ f" 天氣:{wx}\n"
72
+ f" 氣溫:{min_t}°C - {max_t}°C\n"
73
+ f" 降雨機率:{pop}%"
74
+ )
75
+ forecasts.append(forecast_str)
76
+ except (IndexError, KeyError):
77
+ continue
78
+
79
+ if not forecasts:
80
+ return f"無法解析「{location_name}」的預報資料。"
81
+
82
+ return f"📍 {loc_data['locationName']} 未來 36 小時天氣預報:\n\n" + "\n\n".join(forecasts)
83
+
84
+ except requests.exceptions.HTTPError as e:
85
+ if e.response.status_code == 401:
86
+ return "❌ 預報查詢失敗:CWA 授權金鑰 (API Key) 無效。"
87
+ return f"❌ 預報查詢失敗:{e}"
88
+ except Exception as e:
89
+ return f"❌ 預報查詢失敗:{e}"