본문 바로가기
AI 도구

오픈 API로 날씨 미세먼지 정보 자동업데이트 디스플레이 만들기

by James AI Explorer 2024. 1. 29.

목차

    728x90

    안녕하세요! 오늘은 집에서 잘 안쓰는 구형 노트북에 띄우기 위해 주기적으로 자동 업데이트되는 날씨와 미세먼지 정보를 디스플레이하는 프로그램을 만들어 보았습니다. 날씨정보는 OpenWeatherMap API를 사용하여 현재 온도와 날씨 설명을 가져오고, 미세먼지 정보는 한국 공공데이터 포털 API를 사용하여 PM2.5 및 PM10 입자의 농도 값과 등급정보를 가져오도록 합니다. 이 블로그에서는 날씨와 대기질 정보를 가져오는 API의 사용방법과, 추출한 데이터의 활용방법, 그리고 미세먼지 등급 구분 및 디스플레이 업데이트 방법에 대해 확인하실 수 있습니다. 

    날씨 미세먼지 정보 자동업데이트 디스플레이 만들기

    "이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."

    프로그램 및 API 개요

    오늘 만들어볼 프로그램은 특정지역의 현재 날씨와 미세먼지 정보를 수집하여 웹 브라우저를 통해 시각적으로 표시하는 프로그램으로, OpenWeatherMap공공 데이터 포털 API를 활용하여 실시간 날씨와 미세먼지 데이터를 획득하며, 이를 기반으로 화면 배경색을 설정하여 사용자에게 직관적인 정보를 제공합니다. 프로그램은 초기 실행 후 설정시간마다 자동으로 업데이트되며, HTML을 생성하여 시각적 표현을 웹 브라우저를 통해 실시간으로 제공합니다. 이 코드에서 사용되는 OpenWeatherMap API와 한국환경공단의 미세먼지 정보 API에 대한 구체적인 설명은 다음과 같습니다.

    1. OpenWeatherMap API

    OpenWeatherMap (OWM)은 날씨 정보를 제공하는 온라인 기상 서비스 및 API 제공 업체입니다. OWM은 전 세계의 다양한 위치에 대한 현재 날씨, 예보, 기상 데이터를 제공하며, 다양한 응용 프로그램 및 웹 사이트에서 사용되고 있습니다.

    주요 특징과 정보는 다음과 같습니다.

    • 날씨 데이터 제공: OWM은 현재 날씨, 일일 및 주간 예보, 기상 지도 등 다양한 날씨 관련 데이터를 제공합니다.
    • 다양한 위치 지원: OWM은 전 세계 수백만 개의 위치에 대한 날씨 정보를 제공하며, 도시 및 지역별로 쉽게 조회할 수 있습니다.
    • API 제공: OWM은 개발자들이 날씨 데이터를 활용할 수 있도록 API를 제공합니다. 이를 통해 사용자는 자신의 애플리케이션에서 실시간 날씨 정보를 통합할 수 있습니다.
    • 다양한 날씨 정보 포함: OWM API는 기온, 습도, 풍속, 강수량, 구름 양, 일출 및 일몰 시간 등 다양한 날씨 정보를 제공합니다.
    • 무료 및 유료 플랜: OWM은 무료 플랜과 유료 플랜을 제공하며, 무료 플랜은 제한된 호출 횟수와 일부 기능만을 제공하며, 유료 플랜은 더 많은 기능과 호출 횟수를 제공합니다. API를 사용하려면 OWM 웹 사이트에서 계정을 생성하고 API 키를 발급받아야 합니다. 이 키를 사용하여 API에 접근하여 원하는 날씨 데이터를 가져올 수 있습니다.

    2. 한국환경공단 미세먼지 정보 API

    한국환경공단 미세먼지 정보 API는 대한민국의 다양한 지역에서 측정된 대기 오염 정보를 제공하는 API 서비스입니다. 이 API를 활용하면 특정 지역의 미세먼지(PM10, PM2.5), 오존, 이산화질소 등의 대기질 정보를 실시간으로 조회할 수 있습니다. 주요 특징과 정보는 다음과 같습니다.

    • 대상 데이터: 주로 대기 오염 관련 데이터를 포함하며, 주요 관측 항목으로는 미세먼지(PM10, PM2.5), 오존, 이산화질소 등이 있습니다.
    • 서비스 키: API를 사용하기 위해서는 한국환경공단에서 발급하는 서비스 키가 필요합니다. 서비스 키를 사용하여 API에 접근하고 데이터를 요청합니다.
    • 측정소 정보: 측정소별로 측정된 대기질 정보를 조회할 수 있습니다. 각 측정소는 특정 지역을 대표하며, 측정소의 이름을 이용하여 데이터를 얻을 수 있습니다.
    • 데이터 형식: 주로 XML 형식으로 응답이 제공되며, XML 데이터를 파싱 하여 필요한 정보를 추출합니다.
    • 실시간 및 통계 정보: API를 통해 실시간 측정값 뿐만 아니라 특정 기간 동안의 통계 정보도 조회할 수 있습니다.
    • 무료 제공 및 활용 제한: API는 기본적으로 무료로 제공되지만, 호출 횟수에는 제한이 있습니다. 더 높은 호출 횟수나 기능을 원하는 경우 유료 플랜을 검토해야 할 수 있습니다. API 사용을 위해서는 한국환경공단 홈페이지에서 계정을 생성하고 API 키를 발급받아야 합니다. 발급받은 키를 사용하여 API에 요청을 보내고 응답으로 받은 데이터를 활용할 수 있습니다.
    반응형

    API 설정 및 종속성 설치

    코드에서 사용된 API Key (OpenWeatherMap)와 서비스 키 (한국환경공단)는 코드를 실행할 때 인증을 위해 필요한 키이며, 실제로 코드를 실행하기 전에 아래 링크에서 개발자 등록과 데이터 활용요청을 통해 받아야 합니다.

    OpenWeatherMap API Key

    미세먼지 정보를 가져오기위한 API는 공공데이터포털에 가입한 후, 한국환경공단 에어코리아 대기오염정보에 대한 데이터활용요청을 해서 승인을 받아야 하는데요, 간단한 과정만으로 신청즉시 승인 받을수 있습니다. 

    공공데이터 포털 한국환경공단 에어코리아 대기오염정보

     

    다음은 종속성 설치 단계입니다. 이 프로그램에서 사용되는 종속성 설치는 가상환경이 활성화된 상서 "pip install requests==2.31.0" 명령어로 설치합니다.  requests를 제외한 라이브러리는 파이썬 표준라이브러리를 사용합니다. `requests`는 파이썬에서 HTTP 요청을 보내기 위한 라이브러리입니다. HTTP 프로토콜을 통해 서버와 통신할 때 사용되며, 웹 서비스와의 상호작용, 데이터 수집, 웹 스크래핑, API 요청 등 다양한 웹 기반 작업에 활용됩니다. 주요 특징과 기능은 다음과 같습니다.

    • 간편한 HTTP 요청 전송: `requests`를 사용하면 GET, POST, PUT, DELETE 등 다양한 HTTP 메서드를 사용하여 간편하게 요청을 보낼 수 있습니다.
    • 세션 관리: 세션을 통해 상태를 유지하고 여러 요청 간에 쿠키 및 인증 정보를 공유할 수 있습니다.
    • 파라미터 및 헤더 관리: URL에 파라미터를 첨부하거나, 요청 헤더를 설정하여 요청을 커스터마이징 할 수 있습니다.
    • 응답 처리: HTTP 응답을 쉽게 처리하고, JSON 또는 XML 형식으로 응답을 파싱할 수 있습니다.
    • 인증 및 보안: HTTP 기본 인증, 세션 쿠키, 토큰을 활용하여 보안 요구사항을 충족시킬 수 있습니다.
    • 업로드 및 다운로드: 파일 업로드, 다운로드 등과 관련된 작업을 지원합니다. 

     

    파이썬 코드 실행 

    이 코드의 출처는 창작이며, 소스 코드의 활용과 배포시에는 "출처 URL"을 "https://fornewchallenge.tistory.com/"와 같이 표시해주시기 바랍니다. 이 코드의 동작에 대한 설명은 다음과 같습니다.

    • 1. 라이브러리 임포트: `requests`: HTTP 요청, `xml.etree.ElementTree as ET`: XML 데이터 파싱,  `webbrowser`: 사용자에게 웹 기반 문서를 표시, `json`: JSON 데이터를 처리하는 데 사용됩니다.
    • 2. 상수: `MAX_RETRIES`: 공기 오염 데이터를 가져오는 데 최대 재시도 횟수입니다.
    • 3. 날씨 정보 가져오기: `get_weather_info` 함수는 OpenWeatherMap API를 사용하여 서울의 현재 날씨 정보를 가져옵니다. API 응답에서 온도 및 날씨 설명(예: 맑음, 흐림)과 같은 관련 정보를 추출합니다. 받아온 JSON 응답에서 온도를 섭씨로 변환하고, 현재 날씨와 시간을 추출합니다. 시간, 온도 및 날씨 정보를 담은 딕셔너리를 반환합니다.
    • 4. 대기 질(미세먼지) 정보 가져오기: `get_dust_info` 함수는 한국 공공데이터 포털 API를 사용하여 서울의 특정 측정소에서 대기 오염 (미세먼지) 정보를 가져옵니다. 데이터를 가져오기 위해 여러 번 시도하며(`MAX_RETRIES` 횟수까지), 네트워크 문제를 처리합니다. 검색된 데이터에는 다른 타임스탬프에서의 PM10 및 PM2.5 입자의 농도가 포함됩니다.
    • 5. 대기 질 등급 계산: 스크립트는 PM2.5 및 PM10 입자의 농도 값을 기반으로 대기 질 등급("좋음", "보통", "나쁨", "매우 나쁨")을 계산하기 위한 함수를 정의합니다. 이러한 함수는 입자 농도 값을 사전 정의된 범위와 비교하여 등급을 결정합니다.
    • 6. HTML 파일 생성: `update_info` 함수는 날씨 및 대기 질 정보를 결합하여 HTML 파일(`weather_info_final.html`)을 생성합니다. HTML 페이지의 배경색은 PM2.5 등급에 따라 설정됩니다. 생성된 HTML 파일에는 현재 온도, 날씨 설명, PM2.5 등급, PM10 등급 및 업데이트 타임스탬프가 포함됩니다. 생성된 HTML 파일은 웹 브라우저에서 열립니다.
    • 7. 지속적인 업데이트: 스크립트는 처음에 `update_info` 함수를 한 번 실행하여 HTML 파일을 생성하고 엽니다. 그런 다음 무한 루프에 들어가며 `update_info`를 30분 간격으로 반복적으로 호출합니다 (`time.sleep(1800)`). 이를 통해 HTML 파일에 표시되는 정보가 정기적으로 업데이트됩니다.

    참고로 이 코드는 XML 응답에서 데이터를 추출하기 위해 웹 스크래핑을 사용하며, API 구조의 변경에 민감할 수 있습니다. 또한 API 사용 정책을 준수하고 오류를 적절히 처리하는 것이 중요합니다.

    import requests
    import xml.etree.ElementTree as ET
    import datetime
    import time
    import webbrowser
    import json
    
    MAX_RETRIES = 5
    
    def get_weather_info():
        # Retrieve current weather information
        weather_url = "https://api.openweathermap.org/data/2.5/weather?q=Seoul&appid=본인 API Key&lang=kr"
        weather_response = requests.get(weather_url)
        weather_data = json.loads(weather_response.text)
    
        # Extract relevant information from the response data
        weather = weather_data["weather"][0]["description"]
        temperature = round(weather_data["main"]["temp"] - 273.15, 1)  # Convert temperature from Kelvin to Celsius (with one decimal place)
    
        # Return the current weather information
        return {
            "time": datetime.datetime.now().strftime("%Y년 %m월 %d일 %H:%M"),
            "temperature": temperature,
            "weather": weather  # Include the 'weather' key in the dictionary
    
        }
    
    def get_dust_info():
        retries = 0
        dust_info = None
    
        while retries < MAX_RETRIES:
            # Get air pollution (dust) information
            dust_url = 'http://apis.data.go.kr/B552584/ArpltnInforInqireSvc/getMsrstnAcctoRltmMesureDnsty'
    
            # Define query parameters as a dictionary
            dust_params = {
                'serviceKey': '...본인이 발급받은 Service Key...',
                'returnType': 'xml',
                'numOfRows': 100,
                'pageNo': 1,
                'stationName': '동작구',
                'dataTerm': 'DAILY',
                'ver': 1.0
            }
    
            # Send GET request with query parameters
            dust_response = requests.get(dust_url, params=dust_params)
    
            try:
                # Parse XML response data
                dust_root = ET.fromstring(dust_response.content)
                dust_items = dust_root.findall('.//item')
    
                # Extract dust information
                dust_info = {}
                for dust_item in dust_items:
                    dust_time = dust_item.find('dataTime').text
                    dust_pm10 = dust_item.find('pm10Value').text
                    dust_pm25 = dust_item.find('pm25Value').text
                    dust_pm10_grade = dust_item.find('pm10Grade').text
                    dust_pm25_grade = dust_item.find('pm25Grade').text
    
                    dust_info[dust_time] = {
                        'pm10': dust_pm10,
                        'pm25': dust_pm25,
                        'pm10_grade': dust_pm10_grade,
                        'pm25_grade': dust_pm25_grade
                    }
    
                # Break the loop if dust information is successfully obtained
                if dust_info:
                    break
    
            except ET.ParseError as e:
                # Print any parse errors
                print(f"Parse Error: {e}")
    
            # Increment retries and wait before the next attempt
            retries += 1
            time.sleep(1)
    
        return dust_info
    
    def get_pm25_grade(pm25_value):
        # Convert pm25 value to an integer
        pm25_value = int(pm25_value)
    
        # Define the pm25 grade ranges
        grade_ranges = {
            '좋음': range(0, 16),
            '보통': range(16, 36),
            '나쁨': range(36, 76),
            '매우나쁨': range(76, 10000)  # Use a large integer as the upper bound
        }
    
        # Find the corresponding grade for the pm25 value
        for grade, value_range in grade_ranges.items():
            if pm25_value in value_range:
                return grade
    
        # Default to '등급 정보 없음' if the value doesn't match any range
        return '등급 정보 없음'
    
    def get_pm25_grade_from_dust_info():
        # Get PM25 grade
        dust_info = get_dust_info()
    
        # Find the highest PM25 grade among all timestamps
        if dust_info:
            pm25_values = [get_pm25_grade(info['pm25']) for info in dust_info.values() if info['pm25'].isdigit()]
            pm25_grade = max(pm25_values, default='등급 정보 없음')
            return pm25_grade
    
        return '등급 정보 없음'
    
    def get_pm10_grade(pm10_value):
        # Convert pm10 value to an integer
        pm10_value = int(pm10_value)
    
        # Define the pm10 grade ranges
        grade_ranges = {
            '좋음': range(0, 31),
            '보통': range(31, 81),
            '나쁨': range(81, 151),
            '매우나쁨': range(151, 10000)  # Use a large integer as the upper bound
        }
    
        # Find the corresponding grade for the pm10 value
        for grade, value_range in grade_ranges.items():
            if pm10_value in value_range:
                return grade
    
        # Default to '등급 정보 없음' if the value doesn't match any range
        return '등급 정보 없음'
    
    def get_pm10_grade_from_dust_info():
        # Get PM10 grade
        dust_info = get_dust_info()
    
        # Find the highest PM10 grade among all timestamps
        if dust_info:
            pm10_values = [get_pm10_grade(info['pm10']) for info in dust_info.values() if info['pm10'].isdigit()]
            pm10_grade = max(pm10_values, default='등급 정보 없음')
            return pm10_grade
    
        return '등급 정보 없음'
    
    def update_info():
        # Get current weather information
        current_weather_info = get_weather_info()
    
        # Get dust information
        dust_info = get_dust_info()
    
        # Find the most recent PM2.5 value and its grade
        latest_pm25_info = None
        latest_pm25_time = None
    
        for timestamp, info in dust_info.items():
            if 'pm25' in info and info['pm25'].isdigit():
                if latest_pm25_time is None or timestamp > latest_pm25_time:
                    latest_pm25_time = timestamp
                    latest_pm25_info = info
    
        if latest_pm25_info:
            pm25_value = latest_pm25_info['pm25']
            pm25_grade = get_pm25_grade(pm25_value)
    
            # Find the most recent PM10 value and its grade
            latest_pm10_info = None
            latest_pm10_time = None
    
            for timestamp, info in dust_info.items():
                if 'pm10' in info and info['pm10'].isdigit():
                    if latest_pm10_time is None or timestamp > latest_pm10_time:
                        latest_pm10_time = timestamp
                        latest_pm10_info = info
    
            if latest_pm10_info:
                pm10_value = latest_pm10_info['pm10']
                pm10_grade = get_pm10_grade(pm10_value)
    
                # Determine background color based on PM2.5 grade
                if pm25_grade == '좋음':
                    background_color = 'blue'
                elif pm25_grade == '보통':
                    background_color = 'green'
                elif pm25_grade == '나쁨':
                    background_color = 'yellow'
                elif pm25_grade == '매우나쁨':
                    background_color = 'red'
                else:
                    background_color = 'white'
    
                # Open the HTML file and write the content
                with open("weather_info_final.html", "w", encoding='utf-8') as file:
                    file.write("<div style='display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; background-color: {};'>".format(background_color))
                    file.write("<h1 style='font-size: 180px; text-align: center;'>{} °C {}</h1>".format(current_weather_info['temperature'], current_weather_info['weather']))
                    file.write("<p style='font-size: 70px; text-align: center;'>초미세먼지: {}</p>".format(pm25_grade))
                    file.write("<p style='font-size: 70px; text-align: center;'>미세먼지: {}</p>".format(pm10_grade))
                    file.write("<p style='font-size: 50px; text-align: center;'>업데이트: {}</p>".format(current_weather_info['time']))
                    file.write("</div>")
    
                # Open the HTML file in the browser
                webbrowser.open("weather_info_final.html")
    
        # Wait for 5 minutes before running again
        time.sleep(300)
    
    if __name__ == "__main__":
        # Run once initially
        update_info()
    
        # Continuously update by running an infinite loop
        while True:
            update_info()
    import requests
    import xml.etree.ElementTree as ET
    import datetime
    import time
    import webbrowser
    import json
    
    MAX_RETRIES = 5
    
    def get_weather_info():
        # Retrieve current weather information
        weather_url = "https://api.openweathermap.org/data/2.5/weather?q=Seoul&appid=본인 API Key&lang=kr"
        weather_response = requests.get(weather_url)
        weather_data = json.loads(weather_response.text)
    
        # Extract relevant information from the response data
        weather = weather_data["weather"][0]["description"]
        temperature = round(weather_data["main"]["temp"] - 273.15, 1)  # Convert temperature from Kelvin to Celsius (with one decimal place)
    
        # Return the current weather information
        return {
            "time": datetime.datetime.now().strftime("%Y년 %m월 %d일 %H:%M"),
            "temperature": temperature,
            "weather": weather  # Include the 'weather' key in the dictionary
    
        }
    
    def get_dust_info():
        retries = 0
        dust_info = None
    
        while retries < MAX_RETRIES:
            # Get air pollution (dust) information
            dust_url = 'http://apis.data.go.kr/B552584/ArpltnInforInqireSvc/getMsrstnAcctoRltmMesureDnsty'
    
            # Define query parameters as a dictionary
            dust_params = {
                'serviceKey': '...본인이 발급받은 Service Key...',
                'returnType': 'xml',
                'numOfRows': 100,
                'pageNo': 1,
                'stationName': '원하는 지역 설정',
                'dataTerm': 'DAILY',
                'ver': 1.0
            }
    
            # Send GET request with query parameters
            dust_response = requests.get(dust_url, params=dust_params)
    
            try:
                # Parse XML response data
                dust_root = ET.fromstring(dust_response.content)
                dust_items = dust_root.findall('.//item')
    
                # Extract dust information
                dust_info = {}
                for dust_item in dust_items:
                    dust_time = dust_item.find('dataTime').text
                    dust_pm10 = dust_item.find('pm10Value').text
                    dust_pm25 = dust_item.find('pm25Value').text
                    dust_pm10_grade = dust_item.find('pm10Grade').text
                    dust_pm25_grade = dust_item.find('pm25Grade').text
    
                    dust_info[dust_time] = {
                        'pm10': dust_pm10,
                        'pm25': dust_pm25,
                        'pm10_grade': dust_pm10_grade,
                        'pm25_grade': dust_pm25_grade
                    }
    
                # Break the loop if dust information is successfully obtained
                if dust_info:
                    break
    
            except ET.ParseError as e:
                # Print any parse errors
                print(f"Parse Error: {e}")
    
            # Increment retries and wait before the next attempt
            retries += 1
            time.sleep(1)
    
        return dust_info
    
    def get_pm25_grade(pm25_value):
        # Convert pm25 value to an integer
        pm25_value = int(pm25_value)
    
        # Define the pm25 grade ranges
        grade_ranges = {
            '좋음': range(0, 16),
            '보통': range(16, 36),
            '나쁨': range(36, 76),
            '매우나쁨': range(76, 10000)  # Use a large integer as the upper bound
        }
    
        # Find the corresponding grade for the pm25 value
        for grade, value_range in grade_ranges.items():
            if pm25_value in value_range:
                return grade
    
        # Default to '등급 정보 없음' if the value doesn't match any range
        return '등급 정보 없음'
    
    def get_pm25_grade_from_dust_info():
        # Get PM25 grade
        dust_info = get_dust_info()
    
        # Find the highest PM25 grade among all timestamps
        if dust_info:
            pm25_values = [get_pm25_grade(info['pm25']) for info in dust_info.values() if info['pm25'].isdigit()]
            pm25_grade = max(pm25_values, default='등급 정보 없음')
            return pm25_grade
    
        return '등급 정보 없음'
    
    def get_pm10_grade(pm10_value):
        # Convert pm10 value to an integer
        pm10_value = int(pm10_value)
    
        # Define the pm10 grade ranges
        grade_ranges = {
            '좋음': range(0, 31),
            '보통': range(31, 81),
            '나쁨': range(81, 151),
            '매우나쁨': range(151, 10000)  # Use a large integer as the upper bound
        }
    
        # Find the corresponding grade for the pm10 value
        for grade, value_range in grade_ranges.items():
            if pm10_value in value_range:
                return grade
    
        # Default to '등급 정보 없음' if the value doesn't match any range
        return '등급 정보 없음'
    
    def get_pm10_grade_from_dust_info():
        # Get PM10 grade
        dust_info = get_dust_info()
    
        # Find the highest PM10 grade among all timestamps
        if dust_info:
            pm10_values = [get_pm10_grade(info['pm10']) for info in dust_info.values() if info['pm10'].isdigit()]
            pm10_grade = max(pm10_values, default='등급 정보 없음')
            return pm10_grade
    
        return '등급 정보 없음'
    
    def update_info():
        # Get current weather information
        current_weather_info = get_weather_info()
    
        # Get dust information
        dust_info = get_dust_info()
    
        # Find the most recent PM2.5 value and its grade
        latest_pm25_info = None
        latest_pm25_time = None
    
        for timestamp, info in dust_info.items():
            if 'pm25' in info and info['pm25'].isdigit():
                if latest_pm25_time is None or timestamp > latest_pm25_time:
                    latest_pm25_time = timestamp
                    latest_pm25_info = info
    
        if latest_pm25_info:
            pm25_value = latest_pm25_info['pm25']
            pm25_grade = get_pm25_grade(pm25_value)
    
            # Find the most recent PM10 value and its grade
            latest_pm10_info = None
            latest_pm10_time = None
    
            for timestamp, info in dust_info.items():
                if 'pm10' in info and info['pm10'].isdigit():
                    if latest_pm10_time is None or timestamp > latest_pm10_time:
                        latest_pm10_time = timestamp
                        latest_pm10_info = info
    
            if latest_pm10_info:
                pm10_value = latest_pm10_info['pm10']
                pm10_grade = get_pm10_grade(pm10_value)
    
                # Determine background color based on PM2.5 grade
                if pm25_grade == '좋음':
                    background_color = 'blue'
                elif pm25_grade == '보통':
                    background_color = 'green'
                elif pm25_grade == '나쁨':
                    background_color = 'yellow'
                elif pm25_grade == '매우나쁨':
                    background_color = 'red'
                else:
                    background_color = 'white'
    
                # Open the HTML file and write the content
                with open("weather_info_final.html", "w", encoding='utf-8') as file:
                    file.write("<div style='display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; background-color: {};'>".format(background_color))
                    file.write("<h1 style='font-size: 180px; text-align: center;'>{} °C {}</h1>".format(current_weather_info['temperature'], current_weather_info['weather']))
                    file.write("<p style='font-size: 70px; text-align: center;'>초미세먼지: {}</p>".format(pm25_grade))
                    file.write("<p style='font-size: 70px; text-align: center;'>미세먼지: {}</p>".format(pm10_grade))
                    file.write("<p style='font-size: 50px; text-align: center;'>업데이트: {}</p>".format(current_weather_info['time']))
                    file.write("</div>")
    
                # Open the HTML file in the browser
                webbrowser.open("weather_info_final.html")
    
        # Wait for 30 minutes before running again
        time.sleep(1800)
    
    if __name__ == "__main__":
        # Run once initially
        update_info()
    
        # Continuously update by running an infinite loop
        while True:
            update_info()

     

    코드를 실행하면 상단에 현재온도와 날씨정보가 표시되고, 중앙에는 초미세먼지와 미세먼지의 등급이 표시됩니다. 미세먼지의 등급은 아래에 표시된 한국환경공단의 분류기준을 적용하였습니다. 화면 하단에는 날씨와 미세먼지 정보가 업데이트된 시간을 표시하여 참고하도록 하였습니다. 업데이트 주기는 현재 1,800초(30분)로 되어있으며 소스 코드 내에서 "time.sleep(1,800)"부분을 수정할 수 있습니다. 

    한국환경공단 미세먼지 등급 분류기준
    파이썬 코드 실행 결과 화면
    https://fornewchallenge.tistory.com/

    "이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."

    마치며

    이번 블로그 글에서는 OpenWeatherMap API한국환경공단의 미세먼지 정보 API를 이용하여 날씨와 미세먼지 정보를 수집하고 시각적으로 표시하는 프로그램을 만들어 보았습니다. 프로그램은 OpenWeatherMap API와 한국환경공단의 API를 사용하여 실시간으로 날씨와 미세먼지 정보를 가져오고, 이를 기반으로 웹 브라우저를 통해 업데이트되는 화면을 구성했습니다. 또한, 대기 질 등급을 계산하여 화면 배경색을 변경함으로써 한눈에 알아보기 쉽게 만들었습니다.

     

    더 나아가서는 이 프로젝트를 확장하여 사용자 정의 위치를 입력받아 해당 지역의 날씨와 미세먼지 정보를 가져오도록 기능을 추가하거나, 그래픽 인터페이스(GUI)를 통해 사용자 친화적인 환경을 제공하는 방향으로 발전시킬 수 있을 것 같습니다. 이번 프로젝트 오픈 API를 사용하여 실제로 유용하고 흥미로운 애플리케이션을 만들 수 있는 기초를 다지고, 미세먼지 등급 분류, 날씨 정보 추출, HTML 파일 생성 등의 다양한 기술들을 다루면서 프로그래밍 스킬도 향상시킬 수 있는 기회가 되셨기를 바라면서 저는 다음에 더 유익한 프로젝트로 찾아뵙겠습니다. 감사합니다. 🚀👩‍💻👨‍💻

     

     

    2024.01.28 - [AI 도구] - Ollama Python 라이브러리와 RAG으로 웹 사이트 요약하기

     

    Ollama Python 라이브러리와 RAG으로 웹 사이트 요약하기

    안녕하세요! 오늘은 최근 공개된 대규모 언어 모델 활용도구 Ollama의 Python 라이브러리를 활용한 RAG(Retrieval-Augmented Generation, 검색 강화 생성) 프로그램에 대해 알아보겠습니다. RAG는 외부 지식소

    fornewchallenge.tistory.com

     

    반응형