[Python Code Example] National Weather Service(NWS) API, 스케쥴러을 사용하여 시간별 날씨 예측, 실측 데이터를 확보하는 Python 예제 코드

Posted by

이번 포스트에서는 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 라이브러리는 매우 유용한 도구가 될 수 있으니 활용해 보자.

Leave a Reply

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다