X-Git-Url: https://wannabe.guru.org/gitweb/?a=blobdiff_plain;f=weather_renderer.py;h=8da01ab73bae05e880c3e3e9e3ac32191608e899;hb=ea1ee5f817c01c3736a64d73d496cf35cbd383e5;hp=46d891cf3c6497fcbd5cfdee37d0bb89c0dca7db;hpb=144f769da44d2a8411e320e2e66ad1dbc48ed091;p=kiosk.git diff --git a/weather_renderer.py b/weather_renderer.py index 46d891c..8da01ab 100644 --- a/weather_renderer.py +++ b/weather_renderer.py @@ -1,84 +1,30 @@ #!/usr/bin/env python3 -from datetime import datetime +import logging import json -import re +import urllib.request +import urllib.error +import urllib.parse +from datetime import datetime +from collections import defaultdict from typing import Dict, List -import urllib.request, urllib.error, urllib.parse import file_writer import renderer -import secrets -import random +import kiosk_secrets as secrets + +logger = logging.getLogger(__name__) -class weather_renderer(renderer.debuggable_abstaining_renderer): +class weather_renderer(renderer.abstaining_renderer): """A renderer to fetch forecast from wunderground.""" def __init__(self, name_to_timeout_dict: Dict[str, int], file_prefix: str) -> None: - super(weather_renderer, self).__init__(name_to_timeout_dict, False) + super().__init__(name_to_timeout_dict) self.file_prefix = file_prefix - def debug_prefix(self) -> str: - return f"weather({self.file_prefix})" - - def periodic_render(self, key: str) -> bool: - return self.fetch_weather() - - def describe_time(self, index: int) -> str: - if index <= 1: - return "overnight" - elif index <= 3: - return "morning" - elif index <= 5: - return "afternoon" - else: - return "evening" - - def describe_wind(self, mph: float) -> str: - if mph <= 0.3: - return "calm" - elif mph <= 5.0: - return "light" - elif mph < 15.0: - return "breezy" - elif mph <= 25.0: - return "gusty" - else: - return "heavy" - - def describe_magnitude(self, mm: float) -> str: - if mm < 2.0: - return "light" - elif mm < 10.0: - return "moderate" - else: - return "heavy" - - def describe_precip(self, rain: float, snow: float) -> str: - if rain == 0.0 and snow == 0.0: - return "no precipitation" - magnitude = rain + snow - if rain > 0 and snow > 0: - return f"a {self.describe_magnitude(magnitude)} mix of rain and snow" - elif rain > 0: - return f"{self.describe_magnitude(magnitude)} rain" - elif snow > 0: - return f"{self.describe_magnitude(magnitude)} snow" - return "rain" - - def fix_caps(self, s: str) -> str: - r = "" - s = s.lower() - for x in s.split("."): - x = x.strip() - r += x.capitalize() + ". " - r = r.replace(". .", ".") - return r - - def pick_icon( - self, conditions: List[str], rain: List[float], snow: List[float] - ) -> str: + @staticmethod + def pick_icon(conditions: List[str], rain: List[float], snow: List[float]) -> str: # rain snow clouds sun # fog.gif # hazy.gif @@ -134,107 +80,30 @@ class weather_renderer(renderer.debuggable_abstaining_renderer): return "partlysunny.gif" return "clear.gif" - def describe_weather( - self, - high: float, - low: float, - wind: List[float], - conditions: List[str], - rain: List[float], - snow: List[float], - ) -> str: - # High temp: 65 - # Low temp: 44 - # -onight------ -morning----- -afternoon-- -evening---- - # 12a-3a 3a-6a 6a-9a 9a-12p 12p-3p 3p-6p 6p-9p 9p-12p - # Wind: [12.1 3.06 3.47 4.12 3.69 3.31 2.73 2.1] - # Conditions: [Clouds Clouds Clouds Clouds Clouds Clouds Clear Clear] - # Rain: [0.4 0.2 0 0 0 0 0 0] - # Snow: [0 0 0 0 0 0 0 0] - high = int(high) - low = int(low) - count = min(len(wind), len(conditions), len(rain), len(snow)) - descr = "" - - lcondition = "" - lwind = "" - lprecip = "" - ltime = "" - for x in range(0, count): - time = self.describe_time(x) - current = "" - chunks = 0 - - txt = conditions[x] - if txt == "Clouds": - txt = "cloudy" - elif txt == "Rain": - txt = "rainy" - - if txt != lcondition: - if txt != "Snow" and txt != "Rain": - current += txt - chunks += 1 - lcondition = txt - - txt = self.describe_wind(wind[x]) - if txt != lwind: - if len(current) > 0: - current += " with " - current += txt + " winds" - lwind = txt - chunks += 1 - - txt = self.describe_precip(rain[x], snow[x]) - if txt != lprecip: - if len(current) > 0: - if chunks > 1: - current += " and " - else: - current += " with " - chunks += 1 - current += txt - lprecip = txt - - if len(current): - if ltime != time: - if random.randint(0, 3) == 0: - if time != "overnight": - descr += current + " in the " + time + ". " - descr += current + " overnight. " - else: - if time != "overnight": - descr += "In the " - descr += time + ", " + current + ". " - else: - current = current.replace("cloudy", "clouds") - descr += current + " developing. " - ltime = time - if ltime == "overnight" or ltime == "morning": - descr += "Conditions continuing the rest of the day. " - descr = descr.replace("with breezy winds", "and breezy") - descr = descr.replace("Clear developing", "Skies clearing") - descr = self.fix_caps(descr) - return descr + def periodic_render(self, key: str) -> bool: + return self.fetch_weather() def fetch_weather(self) -> bool: if self.file_prefix == "stevens": text_location = "Stevens Pass, WA" - param = "lat=47.74&lon=-121.08" + param = "lat=47.7322&lon=-121.1025" elif self.file_prefix == "telma": text_location = "Telma, WA" param = "lat=47.84&lon=-120.81" else: text_location = "Bellevue, WA" param = "id=5786882" - - www = urllib.request.urlopen( - "http://api.openweathermap.org/data/2.5/forecast?%s&APPID=%s&units=imperial" - % (param, secrets.openweather_key) - ) + secret = secrets.openweather_key + url = f"http://api.openweathermap.org/data/2.5/forecast?{param}&APPID={secret}&units=imperial" + logger.info(f"GETting {url}") + www = urllib.request.urlopen(url) response = www.read() www.close() + if www.getcode() != 200: + logger.error("Bad response: {response}") + raise Exception(response) parsed_json = json.loads(response) + logger.info("URL read ok") # https://openweathermap.org/forecast5 # {"cod":"200", @@ -253,52 +122,93 @@ class weather_renderer(renderer.debuggable_abstaining_renderer): # "dt_txt":"2017-01-30 18:00:00" # }, # {"dt":1485810000,.... - with file_writer.file_writer("weather-%s_3_10800.html" % self.file_prefix) as f: + + with file_writer.file_writer(f"weather-{self.file_prefix}_3_10800.html") as f: f.write( f""" -
%s | ' % text)
- # f.write('