Add current internal and external temperatures
This commit is contained in:
parent
2cfdcd7be1
commit
4a2189d828
2 changed files with 143 additions and 4 deletions
122
bom_rrd.py
Executable file
122
bom_rrd.py
Executable file
|
@ -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()
|
25
esp_time.ino
25
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);
|
||||
|
|
Loading…
Reference in a new issue