about summary refs log tree commit diff
path: root/weather.py
diff options
context:
space:
mode:
authorStarfall <us@starfall.systems>2022-12-01 11:37:03 -0600
committerStarfall <us@starfall.systems>2022-12-01 11:37:03 -0600
commitd39f6c9ec558fe2d6d5761e88a13ef9dd4152054 (patch)
tree3c1a0576cc99a9105baf80db50ba159431102a4f /weather.py
parent061ecde51d51ebdb5ab8a4d26c944b95c68d88cb (diff)
rename to meteor
Diffstat (limited to 'weather.py')
-rwxr-xr-xweather.py102
1 files changed, 0 insertions, 102 deletions
diff --git a/weather.py b/weather.py
deleted file mode 100755
index a30a4e7..0000000
--- a/weather.py
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/usr/bin/env python3
-from argparse import ArgumentParser
-import requests
-
-# doco is at https://www.weather.gov/documentation/services-web-api
-# openAPI spec is at https://api.weather.gov/openapi.json
-
-base_url = 'https://api.weather.gov'
-headers = {
-    'user-agent': 'Starweather/0.1 (us@starfall.systems)',
-    'accept': 'application/ld+json'
-}
-
-# SGR decorations / ANSI escape colors
-class term:
-    RESET = '\033[0m'
-    BOLD = '\033[1m'
-
-def handle_args():
-    parser = ArgumentParser()
-    parser.add_argument('lat', help='latitude')
-    parser.add_argument('lon', help='longitude')
-    return parser.parse_args()
-
-def print_alerts(county, zone): 
-    # in some areas, alerts are not published for the zone but only for the county
-    # you can request both like this rather than making two requests
-    alerts = requests.get(base_url + f'/alerts/active?zone={county},{zone}',
-                          headers=headers).json()
-
-    # this title was cooler when we requested only one zone
-    # e.g. it would end with "for Holmes County (MSC051) MS"
-    # but now it's just "current watches, warnings, and advisories"
-    print(f'{term.BOLD}{alerts.get("title")}')
-    print(f'===================={term.RESET}')
-    for alert in alerts.get('@graph'):
-        print(f'{alert.get("headline")}')
-        print(f'  {alert.get("severity")} - {alert.get("certainty")} - {alert.get("urgency")}')
-        print(f'  Until: {alert.get("expires")}')
-        print(f'{alert.get("description")}')
-        # TODO description can be quite long
-        # short desc appears to be available as parameters.NWSheadline[0]
-        # and follow up with instruction when it exists
-        print('--------------------')
-
-        # many more cool fields available.
-        # verious datetimes: sent, effective, onset, expires, ends
-        # severity: Minor, Moderate, Severe, Extreme, Unknown
-        # certainty: Possible, Likely, Observed, Unknown
-        # urgency: Future, Expected, Immediate, Unknown
-        # messageType: Alert, Update
-                
-        # can construct the headline ourseves as f'{event} issued {sent} [until {end}] by {senderName}'
-    print()
-
-def print_forecast(forecast_url):
-    # TODO pick up gridId AFC (AER/ALU), AFG, AJK, BOX< CAE, DLH, FSD, HGX, HNX, LIX, LWX, MAF, MFR, MLB, MRX, MTR, PIH and reduce gridX and gridY by 1 - known issue
-
-    forecast = requests.get(forecast_url, headers=headers).json()
-    # TODO retry on 500 - known issue
-    # TODO query param units=si
-    # TODO cache for like four hours per location, forecast doesn't change that frequently
-
-    # TODO replace the whole thing with /gridpoints/{point.gridId}/{gridX},{gridY} and create our own forecast
-    # there is lots more information there that would be useful
-    # probabilityOfPrecipitation is the neatest one that's not in .../forecast or .../forecast/hourly
-    # but there's also relativeHumidity, apparentTemperature (and, separately, windChill), skyCover, windGust
-    # downside, it appears to always convert the F/mph measurements into C/kph for no reason. e.g. all temps are measured in 9ths of C
-
-    print(f'{term.BOLD}forecast')
-    print(f'===================={term.RESET}')
-    for period in forecast.get('periods'):
-        # TODO parse isDaytime true/false to squish a day together
-        print(f'{term.BOLD}{period.get("name")}{term.RESET}:')
-        print(f'  {period.get("temperature")}°{period.get("temperatureUnit")}, wind {period.get("windSpeed")} {period.get("windDirection")}')
-        print(f'  {period.get("detailedForecast")}')
-
-def main():
-    args = handle_args()
-
-    point = requests.get(base_url + f'/points/{args.lat},{args.lon}',
-                         headers=headers).json()
-
-    county = point.get('county').split('/')[-1]
-    zone = point.get('forecastZone').split('/')[-1]
-    print_alerts(county, zone)
-
-    # TODO pick out location name from somewhere.
-    # city and state hide in point.relativeLocation.properties.city (and state)
-    # getting the county or zone's `name (id) state` is good too
-
-    # TODO can hazardous weather outlook be gotten programatically?
-
-
-    forecast_url = point.get('forecast')
-    print_forecast(forecast_url)
-
-    # hourly_forecast_url = point.get('forecastHourly')
-
-if __name__ == '__main__':
-    import sys
-    sys.exit(main())