-<table width=99%% cellspacing=10 border=0>
- <tr>""" % text_location)
- count = parsed_json['cnt']
-
- ts = {}
- highs = {}
- lows = {}
- wind = {}
- conditions = {}
- rain = {}
- snow = {}
- for x in xrange(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 xrange(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('<td style="vertical-align:top;font-size:75%%"><P STYLE="padding:8px;">%s</P></td>' % text)
- #f.write('</tr></table>')
- #f.close()
- #return True
-
- #f.write("<table border=0 cellspacing=10>\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(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('<td width=%d%% style="vertical-align:top;">\n' % (100 / num_days))
- f.write('<table border=0>\n')
-
- # Date
- f.write(' <tr><td colspan=3 height=50><b><center><font size=6>' + formatted_date + '</font></center></b></td></tr>\n')
-
- # Icon
- f.write(' <tr><td colspan=3 height=100><center><img src="/icons/weather/%s" height=125></center></td></tr>\n' %
- self.pick_icon(conditions[date], rain[date], snow[date]))
-
- # Low temp
- color = "#000099"
- if (lows[date] <= 32.5):
- color = "#009999"
- f.write(' <tr><td width=33%% align=left><font color="%s"><b>%d°F </b></font></td>\n' % (
- color, int(lows[date])))
-
- # Total precip
- precip *= 0.0393701
- if (precip > 0.025):
- f.write(' <td width=33%%><center><b><font style="background-color:#dfdfff; color:#003355">%3.1f"</font></b></center></td>\n' % precip)
- else:
- f.write(' <td width=33%> </td>\n')
-
- # High temp
- color = "#800000"
- if (highs[date] >= 80):
- color = "#AA0000"
- f.write(' <td align=right><font color="%s"><b> %d°F</b></font></td></tr>\n' % (
- color, int(highs[date])))
-
- # Text "description"
- f.write('<tr><td colspan=3 style="vertical-align:top;font-size:75%%">%s</td></tr>\n' %
- self.describe_weather(highs[date], lows[date], wind[date], conditions[date], rain[date], snow[date]))
- f.write('</table>\n</td>\n')
- f.write("</tr></table></center>")
+"""
+ )
+ count = parsed_json["cnt"]
+
+ ts = {}
+ highs = {}
+ lows = {}
+ wind: Dict[str, List[float]] = defaultdict(list)
+ conditions: Dict[str, List[str]] = defaultdict(list)
+ rain: Dict[str, List[float]] = defaultdict(list)
+ snow: Dict[str, List[float]] = defaultdict(list)
+ precip: Dict[str, List[float]] = defaultdict(list)
+
+ for x in range(0, count):
+ data = parsed_json["list"][x]
+ dt = data["dt_txt"] # 2019-10-07 18:00:00
+ (date, time) = dt.split(" ")
+ _ = data["dt"]
+ if _ not in ts or _ > ts[date]:
+ ts[date] = _
+ temp = data["main"]["temp"]
+
+ # High and low temp
+ if date not in highs or highs[date] < temp:
+ highs[date] = temp
+ if date not in lows or lows[date] > temp:
+ lows[date] = temp
+
+ # Windspeed and conditions
+ wind[date].append(data["wind"]["speed"])
+ conditions[date].append(data["weather"][0]["main"])
+
+ # 3h precipitation (rain / snow)
+ 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}}
+
+ days_seen = set()
+ for date in sorted(highs.keys()):
+ day = datetime.fromtimestamp(ts[date])
+ formatted_date = day.strftime("%a %e %b")
+ if formatted_date in days_seen:
+ continue
+ days_seen.add(formatted_date)
+ total = len(days_seen)
+
+ first_day = True
+ days_seen = set()
+ for n, date in enumerate(sorted(highs.keys())):
+ if n % 3 == 0:
+ if n > 0:
+ f.write("</div>")
+ f.write('<div STYLE="overflow:hidden; width:100%; height:500px">')
+ remaining = total - n
+ if remaining >= 3:
+ width = "33%"
+ else:
+ width = f"{100/remaining}%"
+
+ aggregate_daily_precip = 0.0
+ for r, s in zip(rain[date], snow[date]):
+ hourly_aggregate = r + s
+
+ # The weather report is always way wrong about Stevens.
+ if self.file_prefix == "stevens":
+ hourly_aggregate *= 3.5
+ aggregate_daily_precip += hourly_aggregate
+ precip[date].append(hourly_aggregate)
+ logger.debug(
+ f"Aggregate precip on {date} was {aggregate_daily_precip} mm"
+ )
+ if first_day:
+ while len(precip[date]) < 8:
+ precip[date].insert(0, 0)
+ first_day = False
+
+ day = datetime.fromtimestamp(ts[date])
+ formatted_date = day.strftime("%a %e %b")
+ if formatted_date in days_seen:
+ continue
+ days_seen.add(formatted_date)
+ f.write(
+ f'<div style="width:{width}; height:500px; float:left"><table>\n'
+ )
+
+ # Date
+ f.write(
+ f"""
+<tr>
+ <td colspan=3 height=50>
+ <center>
+ <font size=7><b>{formatted_date}</b></font>
+ </center>
+ </td>
+</tr>"""
+ )
+
+ # Conditions icon
+ icon = weather_renderer.pick_icon(
+ conditions[date], rain[date], snow[date]
+ )
+ f.write(
+ f"""
+<tr>
+ <td colspan=3 height=100>
+ <center>
+ <img src="/kiosk/images/weather/{icon}" height=145>
+ </center>
+ </td>
+</tr>"""
+ )
+
+ # Low temp -- left
+ color = "#000099"
+ if lows[date] <= 32.5:
+ color = "#009999"
+ f.write(
+ f"""
+<tr>
+ <td width=33% align=left>
+ <font color="{color}" size=6>
+ <b>{int(lows[date])}°F </b>
+ </font>
+ </td>
+"""
+ )
+
+ # Total aggregate_precip in inches (from mm)
+ aggregate_daily_precip /= 25.4
+ if aggregate_daily_precip > 0.001:
+ f.write(
+ f"""
+ <td width=33%>
+ <center>
+ <font style="background-color:#dfdfff; color:#003355" size=6>
+ <b>{aggregate_daily_precip:3.1f}”</b>
+ </font>
+ </center>
+ </td>
+"""
+ )
+ else:
+ f.write(" <td width=33%> </td>\n")
+
+ # High temp + precip chart
+ color = "#800000"
+ if highs[date] >= 80:
+ color = "#AA0000"
+ f.write(
+ f"""
+ <td align=right>
+ <font color="{color}" size=6>
+ <b> {int(highs[date])}°F</b>
+ </font>
+ </td>
+</tr>"""
+ )
+
+ # Precip graph
+ f.write(
+ f"""
+<tr>
+ <td colspan=3 style="vertical-align:top;">
+ <canvas id="myChart{n}" style="width:100%;max-width:400px;height:180px;"></canvas>
+ </td>
+</tr>
+<script>
+var yValues{n} = """
+ )
+ f.write(precip[date].__repr__())
+ f.write(
+ f""";
+var xValues{n} = [ 3, 6, 9, 12, 15, 18, 21, 24 ];
+makePrecipChart("myChart{n}", xValues{n}, yValues{n});
+</script>
+</table>
+</div>
+"""
+ )
+ f.write("</div></center>")