127 lines
4.5 KiB
Python
127 lines
4.5 KiB
Python
import requests
|
|
import json
|
|
import re
|
|
import sqlite3
|
|
import os
|
|
import time
|
|
from datetime import datetime
|
|
from config import serviceKey, TODAY
|
|
|
|
def parse_precip(value):
|
|
if value == '강수없음':
|
|
return 0.0
|
|
elif '1mm 미만' in value:
|
|
return 0.5
|
|
else:
|
|
match = re.search(r"[\d.]+", value)
|
|
if match:
|
|
return float(match.group())
|
|
else:
|
|
return 0.0
|
|
|
|
def get_precipitation_summary(retry=True):
|
|
url = "http://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getVilageFcst"
|
|
|
|
params = {
|
|
'serviceKey': serviceKey,
|
|
'numOfRows': '1000',
|
|
'pageNo': '1',
|
|
'dataType': 'JSON',
|
|
'base_date': TODAY,
|
|
'base_time': '0800',
|
|
'nx': '57',
|
|
'ny': '130'
|
|
}
|
|
|
|
response = requests.get(url, params=params)
|
|
|
|
try:
|
|
data = response.json()
|
|
total_rainfall = 0.0
|
|
time_precip_list = []
|
|
|
|
lines = [
|
|
'<div class="weatherinfo" style="max-width: 100%; overflow-x: auto; padding: 10px; box-sizing: border-box;">',
|
|
'<h3 style="font-size: 1.8em; text-align: center; margin: 20px 0;">[시간대별 예상 강수량]</h3>',
|
|
'<table style="border-collapse: collapse; width: 100%; max-width: 400px; margin: 0 auto; font-size: 1em;">',
|
|
'<thead>',
|
|
'<tr>',
|
|
'<th style="border: 1px solid #333; padding: 2px;background-color: #f0f0f0;">시간</th>',
|
|
'<th style="border: 1px solid #333; padding: 2px;background-color: #f0f0f0;">강수량</th>',
|
|
'</tr>',
|
|
'</thead>',
|
|
'<tbody>'
|
|
]
|
|
|
|
for item in data['response']['body']['items']['item']:
|
|
if item['category'] == 'PCP' and item['fcstDate'] == TODAY:
|
|
time = item['fcstTime']
|
|
if 900 < int(time) < 2300:
|
|
mm = parse_precip(item['fcstValue'])
|
|
time_str = f"{time[:2]}:{time[2:]}"
|
|
lines.append(f'<tr><td style="border: 1px solid #333; padding: 2px;text-align: center;">{time_str}</td><td style="border: 1px solid #333; padding: 2px;text-align: center;">{mm}mm</td></tr>')
|
|
total_rainfall += mm
|
|
time_precip_list.append((time_str, mm))
|
|
|
|
lines.append(f'<tr><td colspan="2" style="border: 1px solid #333; padding: 2px;text-align: center; font-weight: bold;">영업시간 중 총 예상 강수량: {total_rainfall:.1f}mm</td></tr>')
|
|
lines.append('</tbody></table><p style="text-align:right; font-size: 0.8em;">08:00 파주 조리읍 기상청 단기예보 기준</div>')
|
|
|
|
html_summary = ''.join(lines)
|
|
|
|
# SQLite 저장 함수 호출
|
|
save_weather_to_sqlite(date=TODAY, time_precip_list=time_precip_list, total_rainfall=total_rainfall)
|
|
|
|
return html_summary
|
|
|
|
except json.decoder.JSONDecodeError:
|
|
if retry:
|
|
print("JSON 디코드 오류 발생, 재시도 중...")
|
|
time.sleep(3) # 3초 대기
|
|
return get_precipitation_summary(retry=False)
|
|
else:
|
|
print("응답이 JSON 형식이 아닙니다.")
|
|
return ''
|
|
|
|
def save_weather_to_sqlite(date, time_precip_list, total_rainfall):
|
|
db_path = '/data/weather.sqlite'
|
|
os.makedirs(os.path.dirname(db_path), exist_ok=True)
|
|
|
|
conn = sqlite3.connect(db_path)
|
|
curs = conn.cursor()
|
|
|
|
# 테이블 생성 (없으면)
|
|
curs.execute('''
|
|
CREATE TABLE IF NOT EXISTS precipitation (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
date TEXT NOT NULL,
|
|
time TEXT NOT NULL,
|
|
rainfall REAL NOT NULL
|
|
)
|
|
''')
|
|
|
|
curs.execute('''
|
|
CREATE TABLE IF NOT EXISTS precipitation_summary (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
date TEXT NOT NULL UNIQUE,
|
|
total_rainfall REAL NOT NULL
|
|
)
|
|
''')
|
|
|
|
# 기존 데이터 삭제 (동일 날짜)
|
|
curs.execute('DELETE FROM precipitation WHERE date = ?', (date,))
|
|
curs.execute('DELETE FROM precipitation_summary WHERE date = ?', (date,))
|
|
|
|
# 데이터 삽입
|
|
curs.executemany('INSERT INTO precipitation (date, time, rainfall) VALUES (?, ?, ?)',
|
|
[(date, t, r) for t, r in time_precip_list])
|
|
|
|
curs.execute('INSERT INTO precipitation_summary (date, total_rainfall) VALUES (?, ?)', (date, total_rainfall))
|
|
|
|
conn.commit()
|
|
conn.close()
|
|
print(f"[DB 저장 완료] {date} 강수량 데이터 저장됨")
|
|
|
|
# 테스트용
|
|
if __name__ == "__main__":
|
|
print(get_precipitation_summary())
|