From 4a2189d828e9526c16c32f80157cc378dec6e70a Mon Sep 17 00:00:00 2001 From: Paul Warren Date: Mon, 30 Dec 2019 15:54:43 +1100 Subject: [PATCH] Add current internal and external temperatures --- bom_rrd.py | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++ esp_time.ino | 25 +++++++++-- 2 files changed, 143 insertions(+), 4 deletions(-) create mode 100755 bom_rrd.py diff --git a/bom_rrd.py b/bom_rrd.py new file mode 100755 index 0000000..6fa7c04 --- /dev/null +++ b/bom_rrd.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python3 + +import xmltodict +import urllib +import datetime +import json +import collections + +import rrdtool + +# BOM Weather XML URL for my area: +# +# see http://www.bom.gov.au/catalogue/data-feeds.shtml +# Adjust aac for your forecast region and the URL as required. + +outside = rrdtool.fetch("/media/media/mqtt/ESP_b5952/temp/c.rrd", "AVERAGE") +rows = outside[2][::-1] +for data in rows: + if data[0] is not None: + outside_temp = data[0] + break + +bedroom = rrdtool.fetch("/media/media/mqtt/ESP_4c7682/temp.rrd", "AVERAGE") +rows = bedroom[2][::-1] +for data in rows: + if data[0] is not None: + bedroom_temp = data[0] + break + + +lounge = rrdtool.fetch("/media/media/mqtt/ESP_b3fe20/temp.rrd", "AVERAGE") +rows = lounge[2][::-1] +for data in rows: + if data[0] is not None: + lounge_temp = data[0] + break + +aac = "NSW_PT254"; +bom_url = "ftp://ftp.bom.gov.au/anon/gen/fwo/IDN11060.xml"; + +bom_icons = { + '1': 'SUNNY.JPG', + '2': 'CLEAR.JPG', + '3': 'PCLOUD.JPG', + '4': 'CLOUDY.JPG', + '6': 'HAZE.JPG', + '8': 'LRAIN.JPG', + '9': 'WIND.JPG', + '10': 'FOG.JPG', + '11': 'SHOWER.JPG', + '12': 'RAIN.JPG', + '13': 'DUST.JPG', + '14': 'FROST.JPG', + '15': 'SNOW.JPG', + '16': 'STORM.JPG', + '17': 'LSHOWE.JPG', + '18': 'HSHOWE.JPG', + '19': 'CYCLON.JPG' +} + + +content = urllib.request.urlopen(bom_url) +xmldict = xmltodict.parse(content.read()) +belco = [a for a in xmldict['product']['forecast']['area'] if a['@aac'] == aac][0] + +new = {} + +#current = a['forecast-period'][0] +weather = {} + +# The first forecast period doesn't always have the temperature and other bits +# I get the overnight low and forecast to substitute when this happens. + +if (type(belco['forecast-period'][0]['element']) == type(collections.OrderedDict())): + night = 1 +else: + night = 0 + +weather['today'] = belco['forecast-period'][0] +weather['tomorrow'] = belco['forecast-period'][1] +weather['day_after'] = belco['forecast-period'][2] + + +if night: + for day in weather.keys(): + new[day] = {} + if (day == 'today'): + new[day]['day'] = 'Tonight' + new[day]['max'] = [a for a in weather['tomorrow']['element'] if a['@type'] == 'air_temperature_minimum'][0]['#text'] + new[day]['icon'] = bom_icons[weather['today']['element']['#text']] + #bom_icons[[a for a in weather['tomorrow']['element'] if a['@type'] == 'forecast_icon_code'][0]['#text']] + else: + new[day]['day'] = datetime.datetime.strptime(weather[day]['@start-time-local'], "%Y-%m-%dT%H:%M:%S%z").strftime("%A") + for el in weather[day]['element']: + if type(el) == type(collections.OrderedDict()): + if el['@type'] == "forecast_icon_code": + new[day]['icon'] = bom_icons[el['#text']] + elif el['@type'] == 'air_temperature_maximum': + new[day]['max'] = el['#text'] + +else: + + for day in weather.keys(): + new[day] = {} + new[day]['day'] = datetime.datetime.strptime(weather[day]['@start-time-local'], "%Y-%m-%dT%H:%M:%S%z").strftime("%A") + + for el in weather[day]['element']: + if type(el) == type(collections.OrderedDict()): + if el['@type'] == "forecast_icon_code": + new[day]['icon'] = bom_icons[el['#text']] + elif el['@type'] == 'air_temperature_maximum': + new[day]['max'] = el['#text'] + + +new['current'] = {} +new['current']['outside'] = outside_temp +new['current']['bedroom'] = bedroom_temp +new['current']['lounge'] = lounge_temp + +with open('bom.json', 'w') as output: + output.write(json.dumps(new)) + output.close() diff --git a/esp_time.ino b/esp_time.ino index 3020002..08a9c41 100644 --- a/esp_time.ino +++ b/esp_time.ino @@ -61,6 +61,12 @@ void ledOn(void) { digitalWrite(led, LOW);} void ledOff(void) { digitalWrite(led, HIGH);} void wait(void) { delay(1500);} + +// globals for the temperature :( +float current_outside; +float current_bedroom; +float current_lounge; + void setup() { pinMode(led, OUTPUT); ledOff(); @@ -225,12 +231,18 @@ void printDateTime(int update_epd) wait(); } - sprintf(buf, "%s %.2d %s %d %s", dayShortStr(weekday(t)), day(t), m, year(t), &tcr -> abbrev); + sprintf(buf, "%s %.2d %s %d Ext: %.2f Int: %.2f", + dayShortStr(weekday(t)), + day(t), + m, + year(t), + current_outside, + current_lounge); Serial.println(buf); if (update_epd > 0) { epd_set_en_font(ASCII64); - epd_disp_string(buf, 150, 225); + epd_disp_string(buf, 5, 225); wait(); } } @@ -263,6 +275,11 @@ void weatherUpdate(void) { const char* day_after_day = day_after["day"]; // "Friday" const char* day_after_icon = day_after["icon"]; // "pcloud.jpg" const char* day_after_max = day_after["max"]; // "33" + + JsonObject current = doc["current"]; + current_outside = current["outside"]; + current_bedroom = current["bedroom"]; + current_lounge = current["lounge"]; Serial.println("Updating EPD"); @@ -292,8 +309,8 @@ void weatherUpdate(void) { wait(); epd_disp_string(day_after_max, 615, 460); wait(); - - + + } else { Serial.print("Error on HTTP Request: "); Serial.println(httpCode);