Auto-update: Thu Nov 14 14:13:58 PST 2024

This commit is contained in:
sanj 2024-11-14 14:13:58 -08:00
parent 940cba17e4
commit a7c52fec65

View file

@ -583,37 +583,38 @@ async def update_dn_weather(date_time: dt_datetime, force_refresh: bool = False,
try: try:
if lat and lon: if lat and lon:
place = await GEO.code((lat, lon)) place = await GEO.code((lat, lon))
else: else:
l.debug(f"Updating weather for {date_time}") l.debug(f"Updating weather for {date_time}")
places = await gis.fetch_locations(date_time) places = await gis.fetch_locations(date_time)
place = places[0] place = places[0]
lat = place.latitude lat = place.latitude
lon = place.longitude lon = place.longitude
l.debug(f"lat: {lat}, lon: {lon}, place: {place}") # Get local timezone for the coordinates
local_tz = await GEO.timezone(lat, lon)
if not local_tz:
raise ValueError("Could not determine timezone for coordinates")
l.debug(f"lat: {lat}, lon: {lon}, place: {place}, timezone: {local_tz}")
city = GEO.find_override_location(lat, lon) city = GEO.find_override_location(lat, lon)
if city: if city:
l.info(f"Using override location: {city}") l.info(f"Using override location: {city}")
else: else:
if place.city and place.city != "": if place.city and place.city != "":
city = place.city city = place.city
l.info(f"City in data: {city}") l.info(f"City in data: {city}")
else: else:
location = await GEO.code((lat, lon)) location = await GEO.code((lat, lon))
l.debug(f"location: {location}") l.debug(f"location: {location}")
city = location.name city = location.name
city = city if city else location.city city = city if city else location.city
city = city if city else location.house_number + ' ' + location.road city = city if city else location.house_number + ' ' + location.road
l.debug(f"City geocoded: {city}") l.debug(f"City geocoded: {city}")
# Assemble journal path absolute_path, relative_path = assemble_journal_path(date_time, filename="Weather", extension=".md", no_timestamp=True)
absolute_path, relative_path = assemble_journal_path(date_time, filename="Weather", extension=".md", no_timestamp = True)
l.debug(f"Journal path: absolute_path={absolute_path}, relative_path={relative_path}") l.debug(f"Journal path: absolute_path={absolute_path}, relative_path={relative_path}")
try: try:
l.debug(f"passing date_time {date_time.strftime('%Y-%m-%d %H:%M:%S')}, {lat}/{lon} into get_weather") l.debug(f"passing date_time {date_time.strftime('%Y-%m-%d %H:%M:%S')}, {lat}/{lon} into get_weather")
day = await weather.get_weather(date_time, lat, lon, force_refresh) day = await weather.get_weather(date_time, lat, lon, force_refresh)
@ -622,44 +623,44 @@ async def update_dn_weather(date_time: dt_datetime, force_refresh: bool = False,
DailyWeather = day.get('DailyWeather') DailyWeather = day.get('DailyWeather')
HourlyWeather = day.get('HourlyWeather') HourlyWeather = day.get('HourlyWeather')
if DailyWeather: if DailyWeather:
# l.debug(f"Day: {DailyWeather}")
icon = DailyWeather.get('icon') icon = DailyWeather.get('icon')
l.debug(f"Icon: {icon}") l.debug(f"Icon: {icon}")
weather_icon, admonition = get_icon_and_admonition(icon) if icon else (":LiSunMoon:", "ad-weather") weather_icon, admonition = get_icon_and_admonition(icon) if icon else (":LiSunMoon:", "ad-weather")
temp = DailyWeather.get('feelslike') temp = DailyWeather.get('feelslike')
if DailyWeather.get('tempmax', 0) > 85: if DailyWeather.get('tempmax', 0) > 85:
tempicon = ":RiTempHotLine:" tempicon = ":RiTempHotLine:"
elif DailyWeather.get('tempmin', 65) < 32: elif DailyWeather.get('tempmin', 65) < 32:
tempicon = ":LiThermometerSnowflake:" tempicon = ":LiThermometerSnowflake:"
else: else:
tempicon = ":LiThermometerSun:" tempicon = ":LiThermometerSun:"
wind_direction = convert_degrees_to_cardinal(DailyWeather.get("winddir")) wind_direction = convert_degrees_to_cardinal(DailyWeather.get("winddir"))
wind_str = f":LiWind: {DailyWeather.get('windspeed')}mph {wind_direction}" wind_str = f":LiWind: {DailyWeather.get('windspeed')}mph {wind_direction}"
gust = DailyWeather.get('windgust', 0) gust = DailyWeather.get('windgust', 0)
if gust and gust > DailyWeather.get('windspeed') * 1.2: if gust and gust > DailyWeather.get('windspeed') * 1.2:
wind_str += f", gusts to {DailyWeather.get('windgust')}mph" wind_str += f", gusts to {DailyWeather.get('windgust')}mph"
uvindex = DailyWeather.get('uvindex', 0) uvindex = DailyWeather.get('uvindex', 0)
uvwarn = f" - :LiRadiation: Caution! UVI today is {uvindex}! :LiRadiation:\n" if (uvindex and uvindex > 8) else "" uvwarn = f" - :LiRadiation: Caution! UVI today is {uvindex}! :LiRadiation:\n" if (uvindex and uvindex > 8) else ""
sunrise = DailyWeather.get('sunrise') # Convert sunrise/sunset times to local timezone
sunset = DailyWeather.get('sunset') sunrise = DailyWeather.get('sunrise').astimezone(local_tz)
srise_str = sunrise.time().strftime("%H:%M") sunset = DailyWeather.get('sunset').astimezone(local_tz)
sset_str = sunset.time().strftime("%H:%M") srise_str = sunrise.strftime("%H:%M")
sset_str = sunset.strftime("%H:%M")
date_str = date_time.strftime("%Y-%m-%d") date_str = date_time.astimezone(local_tz).strftime("%Y-%m-%d")
now = dt_datetime.now().strftime("%Y-%m-%d %H:%M:%S") now = dt_datetime.now(local_tz).strftime("%Y-%m-%d %H:%M:%S")
detailed_forecast = ( detailed_forecast = (
f"---\n" f"---\n"
f"date: {date_str}\n" f"date: {date_str}\n"
f"latitude: {lat}\n" f"latitude: {lat}\n"
f"longitude: {lon}\n" f"longitude: {lon}\n"
f"timezone: {local_tz}\n"
f"tags:\n" f"tags:\n"
f" - weather\n" f" - weather\n"
f"updated: {now}\n" f"updated: {now}\n"
@ -675,69 +676,67 @@ async def update_dn_weather(date_time: dt_datetime, force_refresh: bool = False,
f"title: {DailyWeather.get('description')} \n" f"title: {DailyWeather.get('description')} \n"
) )
narrative = f"{city} on {date_str}: high of {DailyWeather.get('tempmax')}, low of {DailyWeather.get('tempmin')}. {DailyWeather.get('description')}" narrative = f"{city} on {date_str}: high of {DailyWeather.get('tempmax')}, low of {DailyWeather.get('tempmin')}. {DailyWeather.get('description')}"
if HourlyWeather: if HourlyWeather:
times, condition_symbols, temps, winds = [], [], [], [] times, condition_symbols, temps, winds = [], [], [], []
for hour in HourlyWeather: for hour in HourlyWeather:
if hour.get('datetime').strftime("%H:%M:%S") in HOURLY_COLUMNS_MAPPING.values(): # Convert hourly datetime to local timezone before checking/formatting
local_hour = hour.get('datetime').astimezone(local_tz)
times.append(format_hourly_time(hour)) if local_hour.strftime("%H:%M:%S") in HOURLY_COLUMNS_MAPPING.values():
# Pass localized datetime to formatting functions
times.append(format_hourly_time(local_hour))
condition_symbols.append(format_hourly_icon(hour, sunrise, sunset)) condition_symbols.append(format_hourly_icon(hour, sunrise, sunset))
temps.append(format_hourly_temperature(hour)) temps.append(format_hourly_temperature(hour))
winds.append(format_hourly_wind(hour)) winds.append(format_hourly_wind(hour))
detailed_forecast += assemble_hourly_data_table(times, condition_symbols, temps, winds) detailed_forecast += assemble_hourly_data_table(times, condition_symbols, temps, winds)
detailed_forecast += f"```\n\n" detailed_forecast += f"```\n\n"
l.debug(f"Detailed forecast: {detailed_forecast}.") l.debug(f"Detailed forecast: {detailed_forecast}.")
with open(absolute_path, 'w', encoding='utf-8') as note_file: with open(absolute_path, 'w', encoding='utf-8') as note_file:
note_file.write(detailed_forecast) note_file.write(detailed_forecast)
l.debug(f"Operation complete.") l.debug(f"Operation complete.")
return narrative return narrative
else: else:
l.error(f"Failed to get DailyWeather from day: {day}") l.error(f"Failed to get DailyWeather from day: {day}")
else: else:
l.error(f"Failed to get day") l.error(f"Failed to get day")
raise HTTPException(status_code=500, detail="Failed to retrieve weather data") raise HTTPException(status_code=500, detail="Failed to retrieve weather data")
except HTTPException as e: except HTTPException as e:
l.error(f"HTTP error: {e}") l.error(f"HTTP error: {e}")
l.error(traceback.format_exc()) l.error(traceback.format_exc())
raise e raise e
except Exception as e: except Exception as e:
l.error(f"Error: {e}") l.error(f"Error: {e}")
l.error(traceback.format_exc()) l.error(traceback.format_exc())
raise HTTPException(status_code=999, detail=f"Error: {e}") raise HTTPException(status_code=999, detail=f"Error: {e}")
except ValueError as ve: except ValueError as ve:
l.error(f"Value error in update_dn_weather: {str(ve)}") l.error(f"Value error in update_dn_weather: {str(ve)}")
l.error(traceback.format_exc()) l.error(traceback.format_exc())
raise HTTPException(status_code=400, detail=f"Value error: {str(ve)}") raise HTTPException(status_code=400, detail=f"Value error: {str(ve)}")
except Exception as e: except Exception as e:
l.error(f"Error in update_dn_weather: {str(e)}") l.error(f"Error in update_dn_weather: {str(e)}")
l.error(traceback.format_exc()) l.error(traceback.format_exc())
raise HTTPException(status_code=500, detail=f"Error in update_dn_weather: {str(e)}") raise HTTPException(status_code=500, detail=f"Error in update_dn_weather: {str(e)}")
def format_hourly_time(hour): def format_hourly_time(hour_datetime):
try: try:
hour_12 = convert_to_12_hour_format(hour.get("datetime")) # Assumes hour_datetime is already in local timezone from the calling function
hour_12 = convert_to_12_hour_format(hour_datetime)
return hour_12 return hour_12
except Exception as e: except Exception as e:
l.error(f"Error in format_hourly_time: {str(e)}") l.error(f"Error in format_hourly_time: {str(e)}")
l.error(traceback.format_exc()) l.error(traceback.format_exc())
return "" return ""
def format_hourly_icon(hour, sunrise, sunset): def format_hourly_icon(hour, sunrise, sunset):
try: try:
icon_str = hour.get('icon', '') icon_str = hour.get('icon', '')
@ -753,9 +752,13 @@ def format_hourly_icon(hour, sunrise, sunset):
precip_type = hour.get('preciptype', ['']) precip_type = hour.get('preciptype', [''])
sp_str = f"{str(precip)}mm" sp_str = f"{str(precip)}mm"
if abs(hour.get('datetime') - sunrise) < timedelta(minutes=60): # Use the already-converted datetime from the calling function
hour_datetime = hour.get('datetime') # This should already be in local timezone
# Sunrise and sunset should already be in local timezone from calling function
if abs(hour_datetime - sunrise) < timedelta(minutes=60):
icon = ":LiSunrise:" icon = ":LiSunrise:"
elif abs(hour.get('datetime') - sunset) < timedelta(minutes=60): elif abs(hour_datetime - sunset) < timedelta(minutes=60):
icon = ":LiSunset:" icon = ":LiSunset:"
elif "thunder" in hour.get('icon'): elif "thunder" in hour.get('icon'):
icon += ":LiZap:" icon += ":LiZap:"