# Retrieve and print Sea-Tac weather observations from weather.gov
# CircuitPython code for ESP32-S3 Feather

import os
import time
import ssl
import microcontroller
import supervisor
import adafruit_connection_manager
import wifi
import adafruit_requests
from cedargrove_temperaturetools.unit_converters import celsius_to_fahrenheit

try:
    # Connect to WiFi access point
    print(f"Connecting to {os.getenv("CIRCUITPY_WIFI_SSID")}")
    wifi.radio.connect(os.getenv("CIRCUITPY_WIFI_SSID"), os.getenv("CIRCUITPY_WIFI_PASSWORD"))
    print("SUCCESS: connected to WiFi access point")
except Exception as wifi_access_error:
    print(f"FAILED to connect to WiFi. Error: {wifi_access_error}")
    print("MCU will soft reset in 60 seconds.")
    time.sleep(60)
    supervisor.reload()  # soft reset: keeps the terminal session alive

# Initialize a requests session
pool = adafruit_connection_manager.get_radio_socketpool(wifi.radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())

# Get weather observations from the Sea-Tac station
DATA_SOURCE = f"https://api.weather.gov/stations/KSEA/observations/latest"

while True:
    # Fetch and update the weather conditions from weather.gov
    print(f"Fetching Weather Observations from {DATA_SOURCE}")
    try:
        with requests.get(DATA_SOURCE):
            response = requests.get(DATA_SOURCE)

        # print(f"response.json(): {response.json()}")
        print("SUCCESS: Fetch Observations")

        # Extract temperature and weather condition data from API response
        if response is not None:
            _w_desc = response.json()["properties"]["textDescription"]
            if _w_desc is None or _w_desc == "":
                _w_desc = "---"

            _w_temp_c = response.json()["properties"]["temperature"]["value"]
            if _w_temp_c is None:
                _w_temp_f = None
            else:
                # Convert Celsius to Fahrenheit
                _w_temp_f = round(celsius_to_fahrenheit(_w_temp_c), 1)

            _w_humid = response.json()["properties"]["relativeHumidity"]["value"]
            if _w_humid is not None:
                _w_humid = round(_w_humid, 1)

            _w_wind_speed = response.json()["properties"]["windSpeed"]["value"]
            if _w_wind_speed is None:
                _w_wind_speed = 0
            else:
                # Convert kph to mph
                _w_wind_speed = round(_w_wind_speed * 0.6214, 0)

            _w_wind_dir = response.json()["properties"]["windDirection"]["value"]
            if _w_wind_dir is None:
                _w_wind_dir = -999
            else:
                _w_wind_dir = round(_w_wind_dir, 0)

            _w_wind_gusts = response.json()["properties"]["windGust"]["value"]
            if _w_wind_gusts is None:
                _w_wind_gusts = 0
            else:
                # Convert kph to mph
                _w_wind_gusts = round(_w_wind_gusts * 0.6214, 0)
            
            _w_timestamp = response.json()["properties"]["timestamp"]
            if _w_timestamp is None:
                _w_timestamp = "---"

            print("=" * 25)
            print(_w_timestamp)
            print(f"Weather Temp: {_w_temp_f}˚F")
            print(f"Weather Humidity: {_w_humid} %")
            print(f"Weather Wind Speed: {_w_wind_speed}mph")
            print(f"Weather Wind Gusts: {_w_wind_gusts}mph")
            print(f"Weather Wind Direction: {_w_wind_dir}˚")
            print(f"Weather Description: {_w_desc}\n")
            
            # Throttle query rate to 1 per min
            time.sleep(60)

    except Exception as update_weather_error:
        print("FAILED: Fetch Observations")
        print(str(update_weather_error))
        print("MCU will hard reset in 60 seconds.")
        time.sleep(60)
        microcontroller.reset()  # hard reset