[{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eThe weather API of\u0026nbsp;\u003ccode\u003eopenweathermap.org\u003c/code\u003e has been a trusted source of local weather, reliably feeding my projects for quite a few years. Their API design is very complete and easy to understand, not to mention that it interfaces nicely with \u003cem\u003e\u003cstrong\u003eCircuitPython\u003c/strong\u003e\u003c/em\u003e.\u003c/p\u003e\n\u003cp\u003eThey recently changed the API service model for \u003ccode\u003eopenweathermap.org\u003c/code\u003e. Although there is a \"free\" service tier, a credit card is required just in case the usage exceeds the free use threshold. My projects only need a single query response every 20 minutes, clearly falling in to the lower portion of the lowest tier, but I didn't like having to share a credit card number when no money would need to change hands. Call me old-fashioned, I guess. I started looking for better alternatives.\u003c/p\u003e\n\u003ch1\u003eThe National Weather Service API\u003c/h1\u003e\n\u003cp\u003eAfter reviewing many of the free-ish weather API offerings, I stumbled on the mythological metrological holy grail, the\u0026nbsp;\u003ca href=\"https://www.weather.gov/documentation/services-web-api\" target=\"_blank\"\u003eNOAA National Weather Service (NWS) API Web Service\u003c/a\u003e. The NWS API provides free access to alerts, observations, and forecasts without the need for a user account or API key. I was pretty excited to find that NOAA's NWS data was available to the general public since I assumed that other weather APIs use NOAA NWS as an essential data source for their services.\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/000/937/original/Screenshot_2024-06-30_at_3.25.31%E2%80%AFPM.png?1719786354","metadata":{"caption":"The NOAA NWS API Service Documentation Site"}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eThe NWS API incorporates the entire national network of NWS offices and stations. A large range of services are available through the API including alerts, forecasts, aviation weather advisories, and summary report products. For my projects, I'm primarily interested in obtaining current local weather observations such as temperature, humidity, and wind speed/direction. We'll focus on that limited data scope for this Playground Note.\u003c/p\u003e\n\u003cp\u003eQueries are requested with a simple URL call to\u0026nbsp;\u003ca href=\"https://api.weather.gov\" target=\"_blank\"\u003ehttps://api.weather.gov\u003c/a\u003e, such as\u003c/p\u003e\n\u003cp style=\"padding-left: 40px;\"\u003e\u0026nbsp;\u003ca href=\"https://api.weather.gov/stations/KSMP/observations/latest\" target=\"_blank\"\u003ehttps://api.weather.gov/stations/KSEA/observations/latest\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eto see the latest weather values for the Seattle-Tacoma airport in Washington state. You can test the query by pasting the URL into your browser.\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/000/946/original/Screenshot_2024-07-02_at_11.28.25%E2%80%AFAM.png?1719944984","metadata":{"caption":"Query Result Extract: SEA Current Weather Observations"}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch4\u003eAPI Specification\u003c/h4\u003e\n\u003cp\u003eThe API Specification page is a good place to spend some time to learn about the service since it lists all the available queries and includes the ability to test an API query. The testing feature is very useful for finding an observation station in your area and to see how to formulate a query URL.\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/000/938/original/Screenshot_2024-06-30_at_3.29.04%E2%80%AFPM.png?1719786574","metadata":{"caption":"The API Specification and Testing Page"}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n        \u003ch4\u003eJSON Data Structure\u003c/h4\u003e\n\u003cp\u003eBehind the API is a hierarchical data structure that primarily focuses on Forecast Offices (a.k.a. Zones) and Observation Stations. For most projects, the station layer will meet the need for current and historical weather observations.\u003c/p\u003e\n      \n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/000/962/original/Screenshot_2024-07-02_at_6.44.19%E2%80%AFPM.png?1719971102","metadata":{"caption":"NWS API Data Structure Example for Sea-Tac"}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch1\u003eFinding Your Local Observation Station\u003c/h1\u003e\n\u003cp\u003eLocating and identifying the observation station for your area isn't as straightforward as you'd think it would be; it's not as easy as just entering your city or zip code. It's a multi-step process to achieve our objective of finding the name (identifier) of the observation station that produces the data we need.\u003c/p\u003e\n\u003ch2\u003eThe (More Difficult but Precise) Points Method to Locate a Station\u003c/h2\u003e\n\u003ch4\u003eStep 1: Find Your Coordinate Points\u003c/h4\u003e\n\u003cp\u003eFirst, you will need to know the latitude and longitude coordinates (the \"points\") of your locale. Most map applications can help with that. For example, dropping a pin onto an Apple Map will show the coordinates.\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/000/942/original/Screenshot_2024-07-01_at_6.46.38%E2%80%AFPM.png?1719885508","metadata":{"caption":"Seattle-Tacoma International Airport Coordinates"}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eThe map details show the airport located at \u003ccode\u003e47.45˚N\u003c/code\u003e latitude and \u003ccode\u003e122.31˚W\u003c/code\u003e longitude, which is 47.45˚ above the equator and 122.31˚ to the west of the Greenwich meridian. The NWS API requires that values above the equator and East of the Greenwich meridian be positive values. Southern hemisphere latitude values and longitude values West of the meridian are expressed as negative values. For the Sea-Tac airport, the NWS API point pair would be modified slightly and becomes \u003ccode\u003e47.45,-122.31\u003c/code\u003e\u0026nbsp;with just a comma between the values (no spaces).\u003c/p\u003e\n\u003cp\u003eYou can also use the points that correlate to your home or business -- or tent if you're camping in the woods. The next step will locate the forecast office responsible for the zone that surrounds you.\u003c/p\u003e\n\u003ch4\u003eStep 2: Locate the Nearest Forecast Office\u003c/h4\u003e\n\u003cp\u003eThe next step in the process to find the observation station's designation, we'll use the lat/long (points) to find the closest NWS forecast office. Here's the API query URL that'll provide the information:\u003c/p\u003e\n\u003cp style=\"padding-left: 40px;\"\u003e\u003ca href=\"https://api.weather.gov/zones?point=47.45,-122.31\"\u003ehttps://api.weather.gov/zones?point=47.45,-122.31\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/000/943/original/Screenshot_2024-07-01_at_8.17.34%E2%80%AFPM.png?1719890284","metadata":{"caption":"Query Result: Using Points to Find the Forecast Office"}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eSo apparently \u003cstrong\u003eSEW\u003c/strong\u003e is the NWS forecast office that covers that zone. Also, it looks like there are at least nine observation stations in the hierarchy associated with the \u003cstrong\u003eSEW\u003c/strong\u003e office. I'll bet one of those is Sea-Tac. Let's check.\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch4\u003eStep 3: Find an Observation Station\u003c/h4\u003e\n\u003cp\u003eWe'll construct a query URL to examine the properties of the listed observation stations:\u003c/p\u003e\n\u003cp style=\"padding-left: 40px;\"\u003e\u003ca href=\"https://api.weather.gov/stations/?id=KBFI,KPAE,KPLU,KPWT,KRNT,KSEA,KTCM,KTIW,WPOW1\"\u003ehttps://api.weather.gov/stations/?id=KBFI,KPAE,KPLU,KPWT,KRNT,KSEA,KTCM,KTIW,WPOW1\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eThis query will produce the properties of each station in the list. And here's the one we need:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/000/944/original/Screenshot_2024-07-01_at_8.50.53%E2%80%AFPM.png?1719892350","metadata":{"caption":"Query Result Extract: Observation Station Properties"}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eIt's \u003cstrong\u003eKSEA\u003c/strong\u003e with a name property of \u003ccode\u003eSeattle, Seattle-Tacoma International Airport\u003c/code\u003e. The station coordinates are spot-on. The elevation is about 130 meters (427 feet). The other properties of the station include boundary coordinates of its forecast, county, and fire weather zones, handy for creating polygons to superimpose on a map.\u003c/p\u003e\n\u003cp\u003eTo view the properties of a single station, just use:\u003c/p\u003e\n\u003cp style=\"padding-left: 40px;\"\u003e\u003ca href=\"https://api.weather.gov/stations/KSEA\" target=\"_blank\"\u003ehttps://api.weather.gov/stations/KSEA\u003c/a\u003e\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch4\u003eStep 4: Verify -- Check the Latest Observations\u003c/h4\u003e\n\u003cp\u003eWe now have an observation station that should work for the project. Let's check the current weather data to be certain we've made the correct choice. The query URL is:\u003c/p\u003e\n\u003cp style=\"padding-left: 40px;\"\u003e\u003ca href=\"https://api.weather.gov/stations/KSMP/observations/latest\" target=\"_blank\"\u003ehttps://api.weather.gov/stations/KSEA/observations/latest\u003c/a\u003e\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/000/947/original/Screenshot_2024-07-02_at_11.40.57%E2%80%AFAM.png?1719945694","metadata":{"caption":"Query Result Extract: KSEA Latest Observations"}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eAnd there you have it. As of 17:56 GMT, it's 13.9˚C (57˚F) at the airport. We'll use this query URL in our project's CircuitPython code to extract the weather description, temperature, humidity, wind speed, and wind direction from the JSON results. The dew point value may also be handy for monitoring the potential for metal corrosion in the workshop.\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch2\u003eThe Slightly Simpler Method to Locate a Station: Where Airplanes Live\u003c/h2\u003e\n\u003cp\u003eYou may have noticed that the observation station identifier \u003cstrong\u003eKSEA\u003c/strong\u003e is very similar to what you may see on your airplane luggage tag, the three-letter\u003cstrong\u003e \u003c/strong\u003e\u003ca href=\"https://en.wikipedia.org/wiki/IATA_airport_code\" target=\"_blank\"\u003eIATA airport code\u003c/a\u003e \u003cstrong\u003eSEA\u003c/strong\u003e. That is no coincidence; almost all airport-based NWS observation stations have an identifier that follows the International Civil Aviation Organization's (ICAO) four-letter airport \u003ca href=\"https://en.wikipedia.org/wiki/ICAO_airport_code\" target=\"_blank\"\u003ecode scheme\u003c/a\u003e. The \"K\" prefix is a country code that represents the contiguous (kontiguous?) United States. So if the weather data of a nearby airport will work for you, it's likely that the ICAO code will suffice for identifying the NWS observation station. By the way, many small community airports have observation stations, but be aware that quality may not be as reliable as the observations of larger airport stations.\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n        \u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003ch1\u003eUsing the API with CircuitPython\u003c/h1\u003e\n\u003cp\u003eUp to this point, we've been using a browser to tour weather.gov and to find our local observation station. Now let's incorporate the API query URL into a CircuitPython project.\u003c/p\u003e\n\u003cp\u003eThe following code example connects to your Wi-Fi access point as specified in the \u003ccode\u003esettings.toml\u003c/code\u003e file in the root directory of the microcontroller (MCU) board, an ESP32-S3 Feather in this case. After connecting, a socket pool and requests session are created. If the connection process encounters a Wi-Fi access error, the MCU will be reset in a minute to try again.\u003c/p\u003e\n\u003cp\u003eIn the main \u003ccode\u003ewhile True\u003c/code\u003e loop, an attempt is made to retrieve the latest observations from weather.gov for the SeaTac airport. If retrieving the response json result is successful, the results are extracted and converted from metric to imperial values as needed. If not successful, the MCU is rebooted in order to try again.\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eNote:\u0026nbsp;\u003ccode\u003ecedargrove_temperaturetools.unit_converters\u003c/code\u003e can be found in the CircuitPython Community Bundle. It is available using the \u003cem\u003ecircup\u003c/em\u003e command-line library installation utility.\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n      ","metadata":{}},{"element_type":"code","content":"# Retrieve and print Sea-Tac weather observations from weather.gov\n# CircuitPython code for ESP32-S3 Feather\n\nimport os\nimport time\nimport ssl\nimport microcontroller\nimport supervisor\nimport adafruit_connection_manager\nimport wifi\nimport adafruit_requests\nfrom cedargrove_temperaturetools.unit_converters import celsius_to_fahrenheit\n\ntry:\n    # Connect to WiFi access point\n    print(f\"Connecting to {os.getenv(\"CIRCUITPY_WIFI_SSID\")}\")\n    wifi.radio.connect(os.getenv(\"CIRCUITPY_WIFI_SSID\"), os.getenv(\"CIRCUITPY_WIFI_PASSWORD\"))\n    print(\"SUCCESS: connected to WiFi access point\")\nexcept Exception as wifi_access_error:\n    print(f\"FAILED to connect to WiFi. Error: {wifi_access_error}\")\n    print(\"MCU will soft reset in 60 seconds.\")\n    time.sleep(60)\n    supervisor.reload()  # soft reset: keeps the terminal session alive\n\n# Initialize a requests session\npool = adafruit_connection_manager.get_radio_socketpool(wifi.radio)\nrequests = adafruit_requests.Session(pool, ssl.create_default_context())\n\n# Get weather observations from the Sea-Tac station\nDATA_SOURCE = f\"https://api.weather.gov/stations/KSEA/observations/latest\"\n\nwhile True:\n    # Fetch and update the weather conditions from weather.gov\n    print(f\"Fetching Weather Observations from {DATA_SOURCE}\")\n    try:\n        with requests.get(DATA_SOURCE):\n            response = requests.get(DATA_SOURCE)\n\n        # print(f\"response.json(): {response.json()}\")\n        print(\"SUCCESS: Fetch Observations\")\n\n        # Extract temperature and weather condition data from API response\n        if response is not None:\n            _w_desc = response.json()[\"properties\"][\"textDescription\"]\n            if _w_desc is None or _w_desc == \"\":\n                _w_desc = \"---\"\n\n            _w_temp_c = response.json()[\"properties\"][\"temperature\"][\"value\"]\n            if _w_temp_c is None:\n                _w_temp_f = None\n            else:\n                # Convert Celsius to Fahrenheit\n                _w_temp_f = round(celsius_to_fahrenheit(_w_temp_c), 1)\n\n            _w_humid = response.json()[\"properties\"][\"relativeHumidity\"][\"value\"]\n            if _w_humid is not None:\n                _w_humid = round(_w_humid, 1)\n\n            _w_wind_speed = response.json()[\"properties\"][\"windSpeed\"][\"value\"]\n            if _w_wind_speed is None:\n                _w_wind_speed = 0\n            else:\n                # Convert kph to mph\n                _w_wind_speed = round(_w_wind_speed * 0.6214, 0)\n\n            _w_wind_dir = response.json()[\"properties\"][\"windDirection\"][\"value\"]\n            if _w_wind_dir is None:\n                _w_wind_dir = -999\n            else:\n                _w_wind_dir = round(_w_wind_dir, 0)\n\n            _w_wind_gusts = response.json()[\"properties\"][\"windGust\"][\"value\"]\n            if _w_wind_gusts is None:\n                _w_wind_gusts = 0\n            else:\n                # Convert kph to mph\n                _w_wind_gusts = round(_w_wind_gusts * 0.6214, 0)\n            \n            _w_timestamp = response.json()[\"properties\"][\"timestamp\"]\n            if _w_timestamp is None:\n                _w_timestamp = \"---\"\n\n            print(\"=\" * 25)\n            print(_w_timestamp)\n            print(f\"Weather Temp: {_w_temp_f}˚F\")\n            print(f\"Weather Humidity: {_w_humid} %\")\n            print(f\"Weather Wind Speed: {_w_wind_speed}mph\")\n            print(f\"Weather Wind Gusts: {_w_wind_gusts}mph\")\n            print(f\"Weather Wind Direction: {_w_wind_dir}˚\")\n            print(f\"Weather Description: {_w_desc}\\n\")\n            \n            # Throttle query rate to 1 per min\n            time.sleep(60)\n\n    except Exception as update_weather_error:\n        print(\"FAILED: Fetch Observations\")\n        print(str(update_weather_error))\n        print(\"MCU will hard reset in 60 seconds.\")\n        time.sleep(60)\n        microcontroller.reset()  # hard reset","metadata":{"language":"python","linenums":false}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/000/963/original/Screenshot_2024-07-03_at_7.07.47%E2%80%AFAM.png?1720015692","metadata":{"caption":"Code Example REPL Output"}},{"element_type":"text","content":"\n  \n  \n        \u003ch1\u003e\u0026nbsp;\u003c/h1\u003e\n\u003ch1\u003eResources\u003c/h1\u003e\n\u003cp\u003e\u003ca href=\"https://adafruit-playground.com/u/DJDevon3\" target=\"_blank\"\u003eDJDevon3\u003c/a\u003e's \u003ca href=\"https://adafruit-playground.com/u/DJDevon3/pages/web-api-s-you\" target=\"_blank\"\u003eWeb APIs and You\u003c/a\u003e is an exceptional guide to understanding how to use application program interfaces with CircuitPython. It's a must-read if you are developing projects that need APIs.\u003c/p\u003e\n\u003ch1\u003eSummary\u003c/h1\u003e\n\u003cp\u003eThe NWS Web API Service appears to be fairly mature as of this writing, although it is a living schema that is expected to evolve. From my experience, there have been a few occasions when observations froze and didn't resume for hours. Also, some properties such as wind gust values reverted to a None value (no observation) after an outage and has yet to be corrected. However, for my projects that only require a limited set of current observations, the service is acceptable.\u003c/p\u003e\n\u003cp\u003eThe service also has 34 linkable color graphic icons that show the weather for either day or night. The small size is 56 by 56 pixels; large is 134 by 134 pixels.\u003c/p\u003e\n\u003cp\u003eIn the near future, after converting a few weather monitoring projects to the new API, I'm planning to more deeply explore the API to figure out forecasts and report products. I will also spend some time to contribute to service and operational improvements, if possible.\u003c/p\u003e\n\u003ch1\u003eWish List (in progress)\u003c/h1\u003e\n\u003cul\u003e\n\u003cli\u003eAdafruit IO\n\u003cul\u003e\n\u003cli\u003eCollection of selectable server-side feeds for a client's AIO account with the latest weather observations for a particular latitude/longitude or NWS station, perhaps built on the existing AIO+ weather integration\u003c/li\u003e\n\u003cli\u003eUse the throttling feature in the \u003ccode\u003eadafruit_io\u003c/code\u003e CircuitPython library to manage to AIO service levels (free = 30 feeds/min, AIO+ = 60 feeds/min). Would be particularly useful for managing feed rates from multiple AIO projects.\u003c/li\u003e\n\u003cli\u003eProvide a CircuitPython library for displaying weather icons.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eNWS Web API\n\u003cul\u003e\n\u003cli\u003eObservation station identifier query using a zip code or geographic name (city/state, national park, etc.)\u003c/li\u003e\n\u003cli\u003eBackground aggregation scheme that provides estimated observation values during station outages\u003c/li\u003e\n\u003cli\u003eDocumented service level specifications including request rate limits\u003c/li\u003e\n\u003cli\u003eFeature and service request process\u003c/li\u003e\n\u003cli\u003eComprehensive set of code or process examples for each product and service\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n      \n\n","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/5483","metadata":{}}]