pythonweather

weather.gov api script ChatAI not getting right values for temperature


Currently the current temp, high and low are all the same value. I've hit a roadblock with Chatai and Bard. The code for the three are all the same and I'm not sure what the proper values are for weather_info. No the long/lat aren't mine.

current_temp = weather_info["temperature"]
high_temp = weather_info["temperature"]
low_temp = weather_info["temperature"]

import requests
from datetime import datetime
import http.client
import urllib
from astral import LocationInfo
from astral.sun import sun
import math

# Feels like code come from this Github gist: https://gist.github.com/jfcarr/e68593c92c878257550d#file-feels_like-py
# Weather.gov code came from Chatai
# Pushover code is a mixture of Chatai, and example code from pushover.net
# Sunrise sunset code from examples and Chatai

#
# User editable variables
#

# Replace with your Pushover API token and user key
api_token = "supersecretapitoken"
user_key = "supersekretuserkey"

# Example GPS coordinates (replace with actual coordinates)
latitude = 34.41089
longitude = -92.22582
#
# end user editable variables
#


# Function to calculate "feels like" temperature
def calculate_feels_like_temperature(temperature, wind_speed, relative_humidity):
    if temperature <= 50 and wind_speed >= 3:
        feels_like = 35.74 + (0.6215 * temperature) - 35.75 * (wind_speed ** 0.16) + \
                     ((0.4275 * temperature) * (wind_speed ** 0.16))
    else:
        feels_like = temperature

    if feels_like == temperature and temperature >= 80:
        feels_like = 0.5 * (temperature + 61.0 + ((temperature - 68.0) * 1.2) + (relative_humidity * 0.094))

        if feels_like >= 80:
            feels_like = -42.379 + 2.04901523 * temperature + 10.14333127 * relative_humidity - \
                          0.22475541 * temperature * relative_humidity - 0.00683783 * temperature ** 2 - \
                          0.05481717 * relative_humidity ** 2 + 0.00122874 * temperature ** 2 * relative_humidity + \
                          0.00085282 * temperature * relative_humidity ** 2 - 0.00000199 * temperature ** 2 * \
                          relative_humidity ** 2
            if relative_humidity < 13 and temperature >= 80 and temperature <= 112:
                feels_like -= ((13 - relative_humidity) / 4) * math.sqrt((17 - math.fabs(temperature - 95.)) / 17)
                if relative_humidity > 85 and temperature >= 80 and temperature <= 87:
                    feels_like += ((relative_humidity - 85) / 10) * ((87 - temperature) / 5)

    return math.ceil(feels_like)

# Function to get weather information
def get_weather_info(latitude, longitude):
    base_url = f"https://api.weather.gov/points/{latitude},{longitude}"

    response = requests.get(base_url)
    if response.status_code == 200:
        data = response.json()
        forecast_url = data["properties"]["forecast"]
        
        forecast_response = requests.get(forecast_url)
        if forecast_response.status_code == 200:
            forecast_data = forecast_response.json()
            return forecast_data["properties"]["periods"][0]
        else:
            return None
    else:
        return None

# Create a LocationInfo instance for Hot Springs, AR
city = LocationInfo('Little Rock', 'AR', 'America/Chicago', latitude, longitude)

# Get the sunset and sunrise times for today
s = sun(city.observer, date=datetime.today(), tzinfo=city.timezone)
sunset = s['sunset'].strftime("%m/%d/%Y %I:%M %p")
sunrise = s['sunrise'].strftime("%m/%d/%Y %I:%M %p")

# Get the current date
today = datetime.today().date()

# Format the sunrise time for the title
sunrise_title = sunrise.split()[1] + " " + sunrise.split()[2]

# Construct the title
title = f"Today's sunrise - {today.strftime('%B')} {today.day} {today.year} at {sunrise_title}"

# Get weather information
weather_info = get_weather_info(latitude, longitude)

if weather_info:
    current_conditions = weather_info["shortForecast"]
    current_temp = weather_info["temperature"]
    humidity_value = weather_info["relativeHumidity"]["value"]
    wind_speed = weather_info["windSpeed"]
    high_temp = weather_info["temperature"]
    low_temp = weather_info["temperature"]

    # Calculate "feels like" temperature
    feels_like_temp = calculate_feels_like_temperature(current_temp, wind_speed, humidity_value)

    # Construct the message with correct high and low temperatures
    message = f"Current Conditions: {current_conditions}\n" \
              f"Current Temp: {current_temp}\n" \
              f"Feels Like: {feels_like_temp}\n" \
              f"High: {high_temp}\n" \
              f"Low: {low_temp}\n" \
              f"Wind: {wind_speed}\n" \
              f"Wind Direction: {weather_info['windDirection']}\n" \
              f"Humidity: {humidity_value}{'%' if weather_info['relativeHumidity']['unitCode'] == 'wmoUnit:percent' else ''}\n" \
              f"Sunrise: {today.strftime('%B')} {today.day}, {today.year} at {sunrise.split()[1]} {sunrise.split()[2]}\n" \
              f"Sunset: {today.strftime('%B')} {today.day}, {today.year} at {sunset.split()[1]} {sunset.split()[2]}"

    # Pushover API endpoint
    pushover_url = "/1/messages.json"

    # Establish HTTPS connection to Pushover
    conn = http.client.HTTPSConnection("api.pushover.net", 443)

    # Send the message to Pushover
    conn.request("POST", pushover_url,
                 urllib.parse.urlencode({
                     "token": api_token,
                     "user": user_key,
                     "title": title,
                     "message": message
                 }), {"Content-type": "application/x-www-form-urlencoded"})
    conn.getresponse()

    print("Message successfully sent to Pushover.")
else:
    print("Failed to fetch weather information.")

To get the correct temperatures for low and high for the date.

MORE info 1: I'm trying to recreate the pushover notification I get fron IFTTT.

Today's sunrise - October 11 2023 at 07:14 AM 
Current Conditions: Mostly Sunny
Current Temp: 80
Feels Like: 87
High: 80
Low: 42
Wind: 5 to 10 mph
Wind Direction: S
Humidity: 93%
Sunrise: October 11, 2023 at 07:14 AM
Sunset: October 11, 2023 at 06:42 PM

I didn't write any of this code so I don't know how to make changes even with examples.


Solution

  • I'm not sure if I understand your problem but there is not high and low temperature for current period (["periods"][0]).

    You can only get all periods (["periods"] instead of ["periods"][0])

    all_periods = forecast_data["properties"]["periods"]
    

    and use for-loop to get all temperatures from all periods

    all_temperatures = [x["temperature"] for x in all_periods]
    

    and use min() and max() to get high and low value in all temperatures.


    Full working example:

    import requests
    
    latitude = 34.41089
    longitude = -92.22582
    
    base_url = f"https://api.weather.gov/points/{latitude},{longitude}"
    
    response = requests.get(base_url)
    if response.status_code == 200:
        data = response.json()
        forecast_url = data["properties"]["forecast"]
        
        forecast_response = requests.get(forecast_url)
        if forecast_response.status_code == 200:
            forecast_data = forecast_response.json()
    
            all_periods = forecast_data["properties"]["periods"]
    
            all_temperatures = [x["temperature"] for x in all_periods]
    
            print('current:', all_temperatures[0])
            print('    min:', min(all_temperatures))
            print('    max:', max(all_temperatures))
    

    Result:

    current: 81
        min: 42
        max: 83
    

    EDIT:

    If you need more information about period with high and low temperature (ie. you need startTime and endTime) then you could use all_periods directly with min(... key=...) max(... key=...)

    min_period = min(all_periods, key=lambda x:x["temperature"])
    max_period = max(all_periods, key=lambda x:x["temperature"])
    

    and later you can display more information

    print('    min:', min_period["temperature"], '| start:', min_period["startTime"], '| end:', min_period["endTime"])
    print('    max:', max_period["temperature"], '| start:', max_period["startTime"], '| end:', max_period["endTime"])
    

    Full working code:

    import requests
    
    latitude = 34.41089
    longitude = -92.22582
    
    base_url = f"https://api.weather.gov/points/{latitude},{longitude}"
    
    response = requests.get(base_url)
    if response.status_code == 200:
        data = response.json()
        forecast_url = data["properties"]["forecast"]
        
        forecast_response = requests.get(forecast_url)
        if forecast_response.status_code == 200:
            forecast_data = forecast_response.json()
    
            all_periods = forecast_data["properties"]["periods"]
    
            cur_period = all_periods[0]
            min_period = min(all_periods, key=lambda x:x["temperature"])
            max_period = max(all_periods, key=lambda x:x["temperature"])
            
            print('current:', cur_period["temperature"], '| start:', cur_period["startTime"], '| end:', cur_period["endTime"])
            print('    min:', min_period["temperature"], '| start:', min_period["startTime"], '| end:', min_period["endTime"])
            print('    max:', max_period["temperature"], '| start:', max_period["startTime"], '| end:', max_period["endTime"])
    

    Result:

    current: 81 | start: 2023-10-10T16:00:00-05:00 | end: 2023-10-10T18:00:00-05:00
        min: 42 | start: 2023-10-16T18:00:00-05:00 | end: 2023-10-17T06:00:00-05:00
        max: 83 | start: 2023-10-13T06:00:00-05:00 | end: 2023-10-13T18:00:00-05:00