이번 포스트에서는 National Weather Service(NWS) API를 사용하여 미래의 시간별로 예측 되는 예보 데이터를 받아오는 방법과 스케쥴링을 통해 실제 날씨 측정 데이터를 1시간마다 자동으로 업데이트하는 방법에 대해 알아보고자 한다.
특히 이 포스트는 LQ님께서 특별히 문의 주신 내용으로 많은 도움이 되셨으면 좋겠습니다.
NWS API를 사용하여 시간별 미래의 날씨 예측, 예보 데이터 받기
NWS에서는 forecastHourly라는 항목으로 미래에 대한 날씨 예측 데이터를 제공하고 있다.
이번에 NWS API를 사용하여 특정 위치에 대한 시간별 예보 데이터를 가져오는 코드를 작성해보도록 하자.
필요한 라이브러리 설치
pip install requests
예제 코드
import requests import json # 댈러스의 위도와 경도 latitude = 32.7767 longitude = -96.7970 # NWS API 엔드포인트 points_url = f"https://api.weather.gov/points/{latitude},{longitude}" # 위치 정보 가져오기 response = requests.get(points_url) data = response.json() # 시간별 예보 URL 추출 forecast_hourly_url = data['properties']['forecastHourly'] # 시간별 예보 데이터 가져오기 forecast_hourly_response = requests.get(forecast_hourly_url) forecast_hourly_data = forecast_hourly_response.json() # 화씨를 섭씨로 변환하는 함수 def fahrenheit_to_celsius(f): return (f - 32) * 5.0/9.0 # 시간별 예보 정보 출력 hourly_periods = forecast_hourly_data['properties']['periods'] for period in hourly_periods[:24]: # 앞으로 24시간의 데이터만 출력 temp_celsius = fahrenheit_to_celsius(period['temperature']) print(f"Time: {period['startTime']}") print(f"Temperature: {temp_celsius:.2f} °C") print(f"Forecast: {period['shortForecast']}") print("-" * 40)
위 코드는 미국 댈러스의 시간별 날씨 예측 데이터를 받아와서 앞으로의 24시간 동안의 예보를 출력하는 코드이다.
결과 출력
Time: 2024-06-29T11:00:00-05:00 Temperature: 32.22 °C Forecast: Mostly Sunny ---------------------------------------- Time: 2024-06-29T12:00:00-05:00 Temperature: 33.89 °C Forecast: Mostly Sunny ---------------------------------------- Time: 2024-06-29T13:00:00-05:00 Temperature: 35.00 °C Forecast: Mostly Sunny ---------------------------------------- Time: 2024-06-29T14:00:00-05:00 Temperature: 36.11 °C Forecast: Mostly Sunny ---------------------------------------- Time: 2024-06-29T15:00:00-05:00 Temperature: 36.67 °C Forecast: Mostly Sunny ---------------------------------------- Time: 2024-06-29T16:00:00-05:00 Temperature: 36.67 °C Forecast: Mostly Sunny ---------------------------------------- Time: 2024-06-29T17:00:00-05:00 Temperature: 36.67 °C Forecast: Mostly Sunny ---------------------------------------- Time: 2024-06-29T18:00:00-05:00 Temperature: 37.22 °C Forecast: Mostly Clear ---------------------------------------- Time: 2024-06-29T19:00:00-05:00 Temperature: 36.11 °C Forecast: Mostly Clear ---------------------------------------- Time: 2024-06-29T20:00:00-05:00 Temperature: 36.11 °C Forecast: Mostly Clear ---------------------------------------- Time: 2024-06-29T21:00:00-05:00 Temperature: 33.89 °C Forecast: Mostly Clear ---------------------------------------- Time: 2024-06-29T22:00:00-05:00 Temperature: 32.78 °C Forecast: Mostly Clear ---------------------------------------- Time: 2024-06-29T23:00:00-05:00 Temperature: 31.67 °C Forecast: Mostly Clear ---------------------------------------- Time: 2024-06-30T00:00:00-05:00 Temperature: 31.67 °C Forecast: Mostly Clear ---------------------------------------- Time: 2024-06-30T01:00:00-05:00 Temperature: 30.56 °C Forecast: Mostly Clear ---------------------------------------- Time: 2024-06-30T02:00:00-05:00 Temperature: 30.00 °C Forecast: Mostly Clear ---------------------------------------- Time: 2024-06-30T03:00:00-05:00 Temperature: 29.44 °C Forecast: Mostly Clear ---------------------------------------- Time: 2024-06-30T04:00:00-05:00 Temperature: 28.33 °C Forecast: Mostly Clear ---------------------------------------- Time: 2024-06-30T05:00:00-05:00 Temperature: 28.33 °C Forecast: Mostly Clear ---------------------------------------- Time: 2024-06-30T06:00:00-05:00 Temperature: 27.78 °C Forecast: Sunny ---------------------------------------- Time: 2024-06-30T07:00:00-05:00 Temperature: 27.22 °C Forecast: Sunny ---------------------------------------- Time: 2024-06-30T08:00:00-05:00 Temperature: 28.33 °C Forecast: Sunny ---------------------------------------- Time: 2024-06-30T09:00:00-05:00 Temperature: 29.44 °C Forecast: Sunny ---------------------------------------- Time: 2024-06-30T10:00:00-05:00 Temperature: 31.11 °C Forecast: Sunny ----------------------------------------
1시간마다 실측 데이터를 자동으로 업데이트하기
이번에는 NWS 실측 데이터를 1시간마다 자동으로 업데이트하는 기능을 만들어 보고자 한다.
일정 시간마다 동작 하도록 하려면 schedule
라이브러리를 사용할 수 있다. schedule
라이브러리는 일정 시간마다 특정 작업을 수행하도록 설정할 수 있다.
필요한 라이브러리 설치
pip install requests schedule
예제 코드
import requests import schedule import time from datetime import datetime, timedelta # NWS API로부터 실측 데이터를 가져오는 함수 def get_current_weather(): # 댈러스의 위도와 경도 latitude = 32.7767 longitude = -96.7970 # NWS API 엔드포인트 points_url = f"https://api.weather.gov/points/{latitude},{longitude}" # 위치 정보 가져오기 response = requests.get(points_url) data = response.json() # 관측소 URL 추출 observation_stations_url = data['properties']['observationStations'] # 관측소 데이터 가져오기 stations_response = requests.get(observation_stations_url) stations_data = stations_response.json() stations = stations_data['observationStations'] # 첫 번째 관측소 데이터 가져오기 station_url = stations[0] # 현재 날씨 데이터 가져오기 current_weather_url = f"{station_url}/observations/latest" current_weather_response = requests.get(current_weather_url) current_weather_data = current_weather_response.json() # 관측소 위치 정보 가져오기 station_info_response = requests.get(station_url) station_info_data = station_info_response.json() station_name = station_info_data['properties']['name'] station_location = station_info_data['geometry']['coordinates'] # 화씨를 섭씨로 변환하는 함수 def fahrenheit_to_celsius(f): return (f - 32) * 5.0 / 9.0 # 현재 날씨 정보 출력 current_observation = current_weather_data['properties'] temperature_value = current_observation['temperature']['value'] temperature_unit = current_observation['temperature']['unitCode'] if temperature_unit == 'wmoUnit:degF': temperature_celsius = fahrenheit_to_celsius(temperature_value) temperature_display = f"{temperature_celsius:.2f} °C" else: temperature_display = f"{temperature_value} °C" print(f"Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") print(f"Station: {station_name}") print(f"Location: {station_location}") print(f"Temperature: {temperature_display}") print(f"Humidity: {current_observation['relativeHumidity']['value']:.2f}%") print(f"Wind Speed: {current_observation['windSpeed']['value']} m/s") print(f"Wind Direction: {current_observation['windDirection']['value']}°") print(f"Weather: {current_observation['textDescription']}") print("-" * 40) # 스케줄 설정 함수 def set_schedule(interval, unit, start_now=True, on_the_hour=False): if unit == "hours": if start_now: schedule.every(interval).hours.do(get_current_weather) get_current_weather() elif on_the_hour: now = datetime.now() next_hour = (now + timedelta(hours=1)).replace(minute=0, second=0, microsecond=0) delay = (next_hour - now).seconds print(f"Starting at the next hour: {next_hour.strftime('%Y-%m-%d %H:%M:%S')}") time.sleep(delay) schedule.every(interval).hours.at(":00").do(get_current_weather) get_current_weather() else: schedule.every(interval).hours.do(get_current_weather) get_current_weather() elif unit == "minutes": if start_now: schedule.every(interval).minutes.do(get_current_weather) get_current_weather() else: now = datetime.now() next_minute = (now + timedelta(minutes=1)).replace(second=0, microsecond=0) delay = (next_minute - now).seconds print(f"Starting at the next minute: {next_minute.strftime('%Y-%m-%d %H:%M:%S')}") time.sleep(delay) schedule.every(interval).minutes.at(":00").do(get_current_weather) get_current_weather() # 1시간마다 데이터 업데이트 설정 (지금부터 시작) # set_schedule(interval=1, unit="hours", start_now=True) # 1시간마다 데이터 업데이트 설정 (정각에 시작) # set_schedule(interval=1, unit="hours", on_the_hour=True) # 10분마다 데이터 업데이트 설정 (지금부터 시작) set_schedule(interval=10, unit="minutes", start_now=True) # 10분마다 데이터 업데이트 설정 (다음 분 0초에 시작) # set_schedule(interval=10, unit="minutes", start_now=False) # 스케줄러 실행 while True: schedule.run_pending() time.sleep(1)
위 코드는 다음과 같이 사용할 수 있다
set_schedule(interval=1, unit="hours", start_now=True)
: 1시간마다 데이터를 지금부터 시작하여 업데이트.set_schedule(interval=1, unit="hours", on_the_hour=True)
: 1시간마다 데이터를 다음 정각부터 시작하여 업데이트.set_schedule(interval=10, unit="minutes", start_now=True)
: 10분마다 데이터를 지금부터 시작하여 업데이트.set_schedule(interval=10, unit="minutes", start_now=False)
: 10분마다 데이터를 다음 분 0초부터 시작하여 업데이트.
결과 출력
Time: 2024-06-29 15:36:52 Station: Dallas Love Field Location: [-96.85506, 32.85416] Temperature: 36.1 °C Humidity: 46.41% Wind Speed: 18.36 m/s Wind Direction: 150° Weather: Mostly Cloudy ---------------------------------------- Time: 2024-06-29 15:46:52 Station: Dallas Love Field Location: [-96.85506, 32.85416] Temperature: 36.1 °C Humidity: 46.41% Wind Speed: 18.36 m/s Wind Direction: 150° Weather: Mostly Cloudy ----------------------------------------
결론
위 코드 예제는 National Weather Service(NWS) API를 사용하여 특정 위치의 관측소 데이터를 주기적으로 수집하고 로그 파일로 저장하는 방법을 보여준다. 이 과정에서 schedule
라이브러리를 사용하여 주기적인 데이터 수집 작업을 설정하고, 실행 시간을 제어할 수 있다. schedule
라이브러리는 Python에서 주기적인 작업을 간단하게 설정할 수 있는 유용한 도구로, 주로 다음과 같은 방법으로 사용할 수 있다
import schedule import time def job(): print("Doing scheduled job...") # 매 1분마다 job() 함수 실행 schedule.every(1).minutes.do(job) while True: schedule.run_pending() time.sleep(1)
every(interval).units.do(job)
: 특정 간격(interval
)과 단위(units
, 예: 분, 시간)로 작업(job
)을 실행한다.run_pending()
: 모든 예약된 작업을 실행한다. 주기적으로 호출하여 예약된 작업을 처리할 수 있다.
위 예제는 매 1분마다 job()
함수를 실행하는 간단한 스케줄러를 설정하는 코드이며, 이러한 방법으로 주기적인 작업을 손쉽게 설정하고 관리할 수 있다. Python을 사용한 스케줄링 작업에서 schedule
라이브러리는 매우 유용한 도구가 될 수 있으니 활용해 보자.