X-Git-Url: https://wannabe.guru.org/gitweb/?a=blobdiff_plain;f=weather_renderer.py;h=f10f1ceb7d132f0e92965e8368b60d404f63409b;hb=0113d4ae8b11e01b695cd15cdb2c317d887e0935;hp=e11703bd5cdc3980530ada67d0658226d43daa66;hpb=5e241dc47e497c547463cecc07946ea6882835a7;p=kiosk.git
diff --git a/weather_renderer.py b/weather_renderer.py
index e11703b..f10f1ce 100644
--- a/weather_renderer.py
+++ b/weather_renderer.py
@@ -1,27 +1,32 @@
+#!/usr/bin/env python3
+
from datetime import datetime
+import json
+from typing import Dict, List
+import urllib.request
+import urllib.error
+import urllib.parse
+
import file_writer
import renderer
-import json
-import re
-import secrets
-import urllib.request, urllib.error, urllib.parse
+import kiosk_secrets as secrets
import random
-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, file_prefix):
- super(weather_renderer, self).__init__(name_to_timeout_dict, False)
+ def __init__(self, name_to_timeout_dict: Dict[str, int], file_prefix: str) -> None:
+ super().__init__(name_to_timeout_dict)
self.file_prefix = file_prefix
- def debug_prefix(self):
- return "weather(%s)" % (self.file_prefix)
+ def debug_prefix(self) -> str:
+ return f"weather({self.file_prefix})"
- def periodic_render(self, key):
+ def periodic_render(self, key: str) -> bool:
return self.fetch_weather()
- def describe_time(self, index):
+ def describe_time(self, index: int) -> str:
if index <= 1:
return "overnight"
elif index <= 3:
@@ -31,7 +36,7 @@ class weather_renderer(renderer.debuggable_abstaining_renderer):
else:
return "evening"
- def describe_wind(self, mph):
+ def describe_wind(self, mph: float) -> str:
if mph <= 0.3:
return "calm"
elif mph <= 5.0:
@@ -43,26 +48,27 @@ class weather_renderer(renderer.debuggable_abstaining_renderer):
else:
return "heavy"
- def describe_magnitude(self, mm):
- if mm < 2:
+ def describe_magnitude(self, mm: float) -> str:
+ if mm < 2.0:
return "light"
- elif mm < 10:
+ elif mm < 10.0:
return "moderate"
else:
return "heavy"
- def describe_precip(self, rain, snow):
- if rain == 0 and snow == 0:
+ 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 "a %s mix of rain and snow" % self.describe_magnitude(magnitude)
+ return f"a {self.describe_magnitude(magnitude)} mix of rain and snow"
elif rain > 0:
- return "%s rain" % self.describe_magnitude(magnitude)
+ return f"{self.describe_magnitude(magnitude)} rain"
elif snow > 0:
- return "%s snow" % self.describe_magnitude(magnitude)
+ return f"{self.describe_magnitude(magnitude)} snow"
+ return "rain"
- def fix_caps(self, s):
+ def fix_caps(self, s: str) -> str:
r = ""
s = s.lower()
for x in s.split("."):
@@ -71,7 +77,9 @@ class weather_renderer(renderer.debuggable_abstaining_renderer):
r = r.replace(". .", ".")
return r
- def pick_icon(self, conditions, rain, snow):
+ def pick_icon(
+ self, conditions: List[str], rain: List[float], snow: List[float]
+ ) -> str:
# rain snow clouds sun
# fog.gif
# hazy.gif
@@ -91,7 +99,7 @@ class weather_renderer(renderer.debuggable_abstaining_renderer):
seen_snow = False
cloud_count = 0
clear_count = 0
- total_snow = 0
+ total_snow = 0.0
count = min(len(conditions), len(rain), len(snow))
for x in range(0, count):
seen_rain = rain[x] > 0
@@ -127,7 +135,15 @@ class weather_renderer(renderer.debuggable_abstaining_renderer):
return "partlysunny.gif"
return "clear.gif"
- def describe_weather(self, high, low, wind, conditions, rain, snow):
+ 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----
@@ -202,7 +218,7 @@ class weather_renderer(renderer.debuggable_abstaining_renderer):
descr = self.fix_caps(descr)
return descr
- def fetch_weather(self):
+ def fetch_weather(self) -> bool:
if self.file_prefix == "stevens":
text_location = "Stevens Pass, WA"
param = "lat=47.74&lon=-121.08"
@@ -238,178 +254,178 @@ class weather_renderer(renderer.debuggable_abstaining_renderer):
# "dt_txt":"2017-01-30 18:00:00"
# },
# {"dt":1485810000,....
- f = file_writer.file_writer("weather-%s_3_10800.html" % self.file_prefix)
- f.write(
- """
-
Weather at %s:
+ with file_writer.file_writer("weather-%s_3_10800.html" % self.file_prefix) as f:
+ f.write(
+ f"""
+Weather at {text_location}:
-
- """
- % text_location
- )
- count = parsed_json["cnt"]
-
- ts = {}
- highs = {}
- lows = {}
- wind = {}
- conditions = {}
- rain = {}
- snow = {}
- for x in range(0, count):
- data = parsed_json["list"][x]
- dt = data["dt_txt"] # 2019-10-07 18:00:00
- date = dt.split(" ")[0]
- time = dt.split(" ")[1]
- wind[date] = []
- conditions[date] = []
- highs[date] = -99999
- lows[date] = +99999
- rain[date] = []
- snow[date] = []
- ts[date] = 0
-
- for x in range(0, count):
- data = parsed_json["list"][x]
- dt = data["dt_txt"] # 2019-10-07 18:00:00
- date = dt.split(" ")[0]
- time = dt.split(" ")[1]
- _ = data["dt"]
- if _ > ts[date]:
- ts[date] = _
- temp = data["main"]["temp"]
- if highs[date] < temp:
- highs[date] = temp
- if temp < lows[date]:
- lows[date] = temp
- wind[date].append(data["wind"]["speed"])
- conditions[date].append(data["weather"][0]["main"])
- if "rain" in data and "3h" in data["rain"]:
- rain[date].append(data["rain"]["3h"])
- else:
- rain[date].append(0)
- if "snow" in data and "3h" in data["snow"]:
- snow[date].append(data["snow"]["3h"])
- else:
- snow[date].append(0)
-
- # {u'clouds': {u'all': 0},
- # u'sys': {u'pod': u'd'},
- # u'dt_txt': u'2019-10-09 21:00:00',
- # u'weather': [
- # {u'main': u'Clear',
- # u'id': 800,
- # u'icon': u'01d',
- # u'description': u'clear sky'}
- # ],
- # u'dt': 1570654800,
- # u'main': {
- # u'temp_kf': 0,
- # u'temp': 54.74,
- # u'grnd_level': 1018.95,
- # u'temp_max': 54.74,
- # u'sea_level': 1026.46,
- # u'humidity': 37,
- # u'pressure': 1026.46,
- # u'temp_min': 54.74
- # },
- # u'wind': {u'speed': 6.31, u'deg': 10.09}}
-
- # Next 5 half-days
- # for x in xrange(0, 5):
- # fcast = parsed_json['forecast']['txt_forecast']['forecastday'][x]
- # text = fcast['fcttext']
- # text = re.subn(r' ([0-9]+)F', r' \1°F', text)[0]
- # f.write('%s | ' % text)
- # f.write('
')
- # f.close()
- # return True
-
- # f.write("\n")
- days_seen = {}
- for date in sorted(highs.keys()):
- today = datetime.fromtimestamp(ts[date])
- formatted_date = today.strftime("%a %e %b")
- if formatted_date in days_seen:
- continue
- days_seen[formatted_date] = True
- num_days = len(list(days_seen.keys()))
-
- days_seen = {}
- for date in sorted(highs.keys()):
- precip = 0.0
- for _ in rain[date]:
- precip += _
- for _ in snow[date]:
- precip += _
-
- today = datetime.fromtimestamp(ts[date])
- formatted_date = today.strftime("%a %e %b")
- if formatted_date in days_seen:
- continue
- days_seen[formatted_date] = True
- f.write('\n' % (100 / num_days))
- f.write("\n")
-
- # Date
- f.write(
- " "
- + formatted_date
- + " | \n"
+
+ """
)
+ count = parsed_json["cnt"]
+
+ ts = {}
+ highs = {}
+ lows = {}
+ wind: Dict[str, List[float]] = {}
+ conditions: Dict[str, List[str]] = {}
+ rain: Dict[str, List[float]] = {}
+ snow: Dict[str, List[float]] = {}
+ for x in range(0, count):
+ data = parsed_json["list"][x]
+ dt = data["dt_txt"] # 2019-10-07 18:00:00
+ date = dt.split(" ")[0]
+ time = dt.split(" ")[1]
+ wind[date] = []
+ conditions[date] = []
+ highs[date] = -99999
+ lows[date] = +99999
+ rain[date] = []
+ snow[date] = []
+ ts[date] = 0
+
+ for x in range(0, count):
+ data = parsed_json["list"][x]
+ dt = data["dt_txt"] # 2019-10-07 18:00:00
+ date = dt.split(" ")[0]
+ time = dt.split(" ")[1]
+ _ = data["dt"]
+ if _ > ts[date]:
+ ts[date] = _
+ temp = data["main"]["temp"]
+ if highs[date] < temp:
+ highs[date] = temp
+ if temp < lows[date]:
+ lows[date] = temp
+ wind[date].append(data["wind"]["speed"])
+ conditions[date].append(data["weather"][0]["main"])
+ if "rain" in data and "3h" in data["rain"]:
+ rain[date].append(data["rain"]["3h"])
+ else:
+ rain[date].append(0)
+ if "snow" in data and "3h" in data["snow"]:
+ snow[date].append(data["snow"]["3h"])
+ else:
+ snow[date].append(0)
+
+ # {u'clouds': {u'all': 0},
+ # u'sys': {u'pod': u'd'},
+ # u'dt_txt': u'2019-10-09 21:00:00',
+ # u'weather': [
+ # {u'main': u'Clear',
+ # u'id': 800,
+ # u'icon': u'01d',
+ # u'description': u'clear sky'}
+ # ],
+ # u'dt': 1570654800,
+ # u'main': {
+ # u'temp_kf': 0,
+ # u'temp': 54.74,
+ # u'grnd_level': 1018.95,
+ # u'temp_max': 54.74,
+ # u'sea_level': 1026.46,
+ # u'humidity': 37,
+ # u'pressure': 1026.46,
+ # u'temp_min': 54.74
+ # },
+ # u'wind': {u'speed': 6.31, u'deg': 10.09}}
+
+ # Next 5 half-days
+ # for x in xrange(0, 5):
+ # fcast = parsed_json['forecast']['txt_forecast']['forecastday'][x]
+ # text = fcast['fcttext']
+ # text = re.subn(r' ([0-9]+)F', r' \1°F', text)[0]
+ # f.write('%s | ' % text)
+ # f.write(' ')
+ # f.close()
+ # return True
+
+ # f.write("\n")
+ days_seen = {}
+ for date in sorted(highs.keys()):
+ today = datetime.fromtimestamp(ts[date])
+ formatted_date = today.strftime("%a %e %b")
+ if formatted_date in days_seen:
+ continue
+ days_seen[formatted_date] = True
+ num_days = len(list(days_seen.keys()))
+
+ days_seen = {}
+ for date in sorted(highs.keys()):
+ precip = 0.0
+ for _ in rain[date]:
+ precip += _
+ for _ in snow[date]:
+ precip += _
+
+ today = datetime.fromtimestamp(ts[date])
+ formatted_date = today.strftime("%a %e %b")
+ if formatted_date in days_seen:
+ continue
+ days_seen[formatted_date] = True
+ f.write(
+ '\n' % (100 / num_days)
+ )
+ f.write("\n")
- # Icon
- f.write(
- ' ![](/icons/weather/%s) | \n'
- % self.pick_icon(conditions[date], rain[date], snow[date])
- )
+ # Date
+ f.write(
+ " "
+ + formatted_date
+ + " | \n"
+ )
- # Low temp
- color = "#000099"
- if lows[date] <= 32.5:
- color = "#009999"
- f.write(
- ' %d°F | \n'
- % (color, int(lows[date]))
- )
+ # Icon
+ f.write(
+ ' ![](/kiosk/images/weather/%s) | \n'
+ % self.pick_icon(conditions[date], rain[date], snow[date])
+ )
- # Total precip
- precip *= 0.0393701
- if precip > 0.025:
+ # Low temp
+ color = "#000099"
+ if lows[date] <= 32.5:
+ color = "#009999"
f.write(
- ' %3.1f" | \n'
- % precip
+ ' %d°F | \n'
+ % (color, int(lows[date]))
)
- else:
- f.write(" | \n")
- # High temp
- color = "#800000"
- if highs[date] >= 80:
- color = "#AA0000"
- f.write(
- ' %d°F | \n'
- % (color, int(highs[date]))
- )
+ # Total precip
+ precip *= 0.0393701
+ if precip > 0.025:
+ f.write(
+ ' %3.1f" | \n'
+ % precip
+ )
+ else:
+ f.write(" | \n")
- # Text "description"
- f.write(
- '%s | \n'
- % self.describe_weather(
- highs[date],
- lows[date],
- wind[date],
- conditions[date],
- rain[date],
- snow[date],
+ # High temp
+ color = "#800000"
+ if highs[date] >= 80:
+ color = "#AA0000"
+ f.write(
+ ' %d°F | \n'
+ % (color, int(highs[date]))
)
- )
- f.write(" \n | \n")
- f.write(" ")
+
+ # Text "description"
+ f.write(
+ '%s | \n'
+ % self.describe_weather(
+ highs[date],
+ lows[date],
+ wind[date],
+ conditions[date],
+ rain[date],
+ snow[date],
+ )
+ )
+ f.write(" \n | \n")
+ f.write("
")
return True
-# x = weather_renderer({"Stevens": 1000},
-# "stevens")
+# x = weather_renderer({"Stevens": 1000}, "stevens")
# x.periodic_render("Stevens")