diff --git a/README.md b/README.md index 2a5559e..cd58edb 100644 --- a/README.md +++ b/README.md @@ -236,6 +236,9 @@ If you run into any issues, consult the logs or reach out on the repository's [I --- # Changelog +- v0.75051 - updated `config.ini` for configuring NWS weather forecasts & alerts + - suggested method would be to supplement via NWS the things you need + - I highly recommend leaving U.S. NWS's alerts on in `config.ini`, even if you have other fetching methods enabled (i.e. OpenWeatherMap), rather be safe than sorry - v0.7505 - U.S. NWS (National Weather Service, [weather.gov](https://weather.gov)) added as a weather data source - for additional information; **especially weather alerts** - all data will be combined from OpenWeatherMap and U.S. NWS sources by default diff --git a/config/config.ini b/config/config.ini index 04d9265..272736e 100644 --- a/config/config.ini +++ b/config/config.ini @@ -168,3 +168,18 @@ Timeout = 30 # Chunk size for translation ChunkSize = 500 + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# U.S. National Weather Service (NWS) +# (weather.gov) +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +[NWS] +# Fetch NWS foreacsts and/or alerts? (true/false) +# Note that the service can be slow and unreliable at times. +# I recommand getting the alerts to supplement i.e. OpenWeatherMap. +# The alerts usually work, but sadly their open API forecasts are often broken. +FetchNWSForecast = false +FetchNWSAlerts = true +NWSUserAgent = ChatKekeWeather/1.0 (flyingfathead@protonmail.com) +NWSRetries = 3 +NWSRetryDelay = 2 diff --git a/src/api_get_nws_weather.py b/src/api_get_nws_weather.py index 4fb962d..38910c8 100644 --- a/src/api_get_nws_weather.py +++ b/src/api_get_nws_weather.py @@ -9,17 +9,12 @@ import asyncio import httpx import logging +from config_paths import NWS_USER_AGENT, NWS_RETRIES, NWS_RETRY_DELAY, FETCH_NWS_FORECAST, FETCH_NWS_ALERTS # Base URL for NWS API NWS_BASE_URL = 'https://api.weather.gov' -# Custom User-Agent as per NWS API requirements -USER_AGENT = 'ChatKekeWeather/1.0 (flyingfathead@protonmail.com)' - -# Default number of retries if not specified -RETRIES = 0 - -async def get_nws_forecast(lat, lon, retries=RETRIES, delay=2): +async def get_nws_forecast(lat, lon, retries=NWS_RETRIES, delay=NWS_RETRY_DELAY): """ Fetches the forecast from the NWS API for the given latitude and longitude. @@ -32,6 +27,11 @@ async def get_nws_forecast(lat, lon, retries=RETRIES, delay=2): Returns: dict: Combined forecast data or None if fetching fails. """ + + if not FETCH_NWS_FORECAST: + logging.info("Fetching NWS forecast is disabled in the config.") + return None + # Round coordinates to 4 decimal places lat = round(lat, 4) lon = round(lon, 4) @@ -41,7 +41,7 @@ async def get_nws_forecast(lat, lon, retries=RETRIES, delay=2): for attempt in range(retries + 1): # Ensure at least one attempt is made try: # Step 1: Retrieve metadata for the location - response = await client.get(points_url, headers={'User-Agent': USER_AGENT}) + response = await client.get(points_url, headers={'User-Agent': NWS_USER_AGENT}) response.raise_for_status() points_data = response.json() @@ -50,7 +50,7 @@ async def get_nws_forecast(lat, lon, retries=RETRIES, delay=2): forecast_hourly_url = points_data['properties'].get('forecastHourly') # Step 2: Retrieve forecast data - forecast_response = await client.get(forecast_url, headers={'User-Agent': USER_AGENT}) + forecast_response = await client.get(forecast_url, headers={'User-Agent': NWS_USER_AGENT}) forecast_response.raise_for_status() forecast_data = forecast_response.json() @@ -58,7 +58,7 @@ async def get_nws_forecast(lat, lon, retries=RETRIES, delay=2): forecast_hourly_data = None if forecast_hourly_url: try: - forecast_hourly_response = await client.get(forecast_hourly_url, headers={'User-Agent': USER_AGENT}) + forecast_hourly_response = await client.get(forecast_hourly_url, headers={'User-Agent': NWS_USER_AGENT}) forecast_hourly_response.raise_for_status() forecast_hourly_data = forecast_hourly_response.json() except httpx.HTTPStatusError as e: @@ -93,11 +93,16 @@ async def get_nws_alerts(lat, lon): Returns: list: A list of active alerts or an empty list if none are found. """ + + if not FETCH_NWS_ALERTS: + logging.info("Fetching NWS alerts is disabled in the config.") + return [] + alerts_url = f"{NWS_BASE_URL}/alerts/active?point={lat},{lon}" async with httpx.AsyncClient() as client: try: - response = await client.get(alerts_url, headers={'User-Agent': USER_AGENT}) + response = await client.get(alerts_url, headers={'User-Agent': NWS_USER_AGENT}) response.raise_for_status() alerts_data = response.json() diff --git a/src/config_paths.py b/src/config_paths.py index 2aa87bd..fc555b5 100644 --- a/src/config_paths.py +++ b/src/config_paths.py @@ -29,6 +29,11 @@ ELASTICSEARCH_USERNAME = '' ELASTICSEARCH_PASSWORD = '' +# Default NWS settings +NWS_USER_AGENT = 'ChatKekeWeather/1.0 (flyingfathead@protonmail.com)' +NWS_RETRIES = 0 +NWS_RETRY_DELAY = 2 + # Attempt to read the configuration file if CONFIG_PATH.exists(): try: @@ -71,6 +76,18 @@ ELASTICSEARCH_USERNAME = '' ELASTICSEARCH_PASSWORD = '' logger.warning("Elasticsearch section missing in config.ini. Using default Elasticsearch settings.") + + # NWS Configuration + if 'NWS' in config: + NWS_USER_AGENT = config['NWS'].get('NWSUserAgent', fallback='ChatKekeWeather/1.0 (flyingfathead@protonmail.com)') + NWS_RETRIES = config['NWS'].getint('NWSRetries', fallback=0) + NWS_RETRY_DELAY = config['NWS'].getint('NWSRetryDelay', fallback=2) + FETCH_NWS_FORECAST = config['NWS'].getboolean('FetchNWSForecast', fallback=True) + FETCH_NWS_ALERTS = config['NWS'].getboolean('FetchNWSAlerts', fallback=True) + logger.info(f"NWS Config: User-Agent={NWS_USER_AGENT}, Retries={NWS_RETRIES}, Retry Delay={NWS_RETRY_DELAY}, Fetch Forecast={FETCH_NWS_FORECAST}, Fetch Alerts={FETCH_NWS_ALERTS}") + else: + logger.warning("NWS section not found in config.ini. Using default NWS settings.") + except Exception as e: # Handle exceptions during config parsing logger.error(f"Error reading configuration file: {e}") diff --git a/src/main.py b/src/main.py index f8950fc..206530b 100755 --- a/src/main.py +++ b/src/main.py @@ -5,7 +5,7 @@ # https://github.com/FlyingFathead/TelegramBot-OpenAI-API # # version of this program -version_number = "0.7505" +version_number = "0.75051" # Add the project root directory to Python's path import sys