Working 3 day temperature forecast

This commit is contained in:
Paul Warren 2019-11-23 20:21:10 +11:00
parent 1ae9ebaafb
commit 738447212b
3 changed files with 152 additions and 31 deletions

59
darksky.py Executable file
View File

@ -0,0 +1,59 @@
#!/usr/bin/env python3
#
# Pulls out only the required pieces for the esp_time.ino arduino program
# the ESP8266 doesn't have enough RAM to parse the whole JSON object.
# substitue in api_key, run this and place the output at a web server
# adjust ds_url in esp_time.ino to point at that web server!
import json
import urllib.request
ds_url = "https://api.darksky.net/forecast/";
ds_ll = "/-35.135,149.61";
ds_opts = "?units=auto"
api_key = "PUT YOUR API KEY HERE"
contents = urllib.request.urlopen(ds_url + api_key + ds_ll + ds_opts)
d = json.load(contents)
new = {}
current = d['currently']
today = d['daily']['data'][0]
tomorrow = d['daily']['data'][1]
day_after = d['daily']['data'][2]
new['current'] = {}
new['current']['temp'] = current['temperature']
new['current']['icon'] = current['icon']
new['today'] = {}
new['today']['max'] = today['temperatureMax']
new['today']['icon'] = today['icon']
new['tomorrow'] = {}
new['tomorrow']['max'] = tomorrow['temperatureMax']
new['tomorrow']['icon'] = tomorrow['icon']
new['day_after'] = {}
new['day_after']['max'] = day_after['temperatureMax']
new['day_after']['icon'] = day_after['icon']
with open('darksky.json', 'w') as output:
output.write(json.dumps(new))
output.close()
# OWM
# for forecast in d['list']:
# utcDate = datetime.datetime.strptime(forecast['dt_txt']+"+0000", "%Y-%m-%d %H:%M:%S%z")
# utcDate.replace(tzinfo=UTC)
# print("********")
# print(utcDate)
# print(utcDate.astimezone(local))
# print(forecast['weather'][0]['description'], forecast['weather'][0]['icon'], forecast['main']['temp'])

View File

@ -8,10 +8,12 @@
#include <WiFiUdp.h> #include <WiFiUdp.h>
#include <NTPClient.h> #include <NTPClient.h>
#include <Timezone.h> #include <Timezone.h>
#include <ArduinoJson.h>
#include "epd.h" #include "epd.h"
#include "credential.h" #include "credential.h"
// Weather bits // Weather bits
// Australian BOM bits, Belconnen is mine. // Australian BOM bits, Belconnen is mine.
@ -20,10 +22,13 @@
//const char* bom_url = "ftp://ftp.bom.gov.au/anon/gen/fwo/IDN11060.xml"; //const char* bom_url = "ftp://ftp.bom.gov.au/anon/gen/fwo/IDN11060.xml";
// openweathermap, api_key from credential.h // openweathermap, api_key from credential.h
// // const String owm_url = "http://api.openweathermap.org/data/2.5/weather?q=Belconnen,AU&units=metric&APPID=";
// Maybe try String types?
const String owm_url = "http://api.openweathermap.org/data/2.5/weather?q=Belconnen,AU&APPID=";
// DarkSky API key from credential.h
// substitute decimal latitude and longitude in ds_ll
const String ds_url = "http://pwarren.id.au/darksky/darksky.json";
bool ds_done = false;
// Timezone bits // Timezone bits
@ -35,11 +40,10 @@ TimeChangeRule *tcr;
// Network clients // Network clients
WiFiUDP ntpUDP; WiFiUDP ntpUDP;
HTTPClient http; HTTPClient http;
NTPClient timeClient(ntpUDP, "raspberrypi.lan", 0, 60000); //use internal ntp server, update every 10 minutes NTPClient timeClient(ntpUDP, "raspberrypi.lan", 0, 60000); //use internal ntp server, update every 10 minutes
//NTPClient timeClient(ntpUDP, "au.pool.ntp.org", 0, 60000); //use internal ntp server, update every 10 minutes
// defined in "credentials.h" // defined in "credentials.h"
const char* ssid = ssid_name; // The SSID (name) of your Wi-Fi network const char* ssid = ssid_name; // The SSID (name) of your Wi-Fi network
@ -47,14 +51,14 @@ const char* password = ssid_pass; // The password of the Wi-Fi network
const int led = LED_BUILTIN; const int led = LED_BUILTIN;
// Font width
int dwidth = 185;
// yes this seems backwards but it works... // yes this seems backwards but it works...
void ledOn(void) { digitalWrite(led, LOW);} void ledOn(void) { digitalWrite(led, LOW);}
void ledOff(void) { digitalWrite(led, HIGH);} void ledOff(void) { digitalWrite(led, HIGH);}
void wait(void) { delay(1500);} void wait(void) { delay(1500);}
// Font width
int dwidth = 185;
void setup() { void setup() {
pinMode(led, OUTPUT); pinMode(led, OUTPUT);
ledOff(); ledOff();
@ -78,7 +82,9 @@ void setup() {
timeClient.begin(); timeClient.begin();
ntpUpdate(); ntpUpdate();
epd_clear(); epd_clear();
weatherUpdate();
printDateTime(1); printDateTime(1);
epd_update();
ledOff(); ledOff();
} }
@ -104,8 +110,9 @@ void wifi() {
} }
void ntpUpdate() { void ntpUpdate() {
timeClient.update(); if (timeClient.update()) {
setTime(timeClient.getEpochTime()); setTime(timeClient.getEpochTime());
}
} }
@ -151,12 +158,11 @@ void disp_digit(int digit, int xpos){
epd_disp_bitmap("9.JPG", dpos, ypos); epd_disp_bitmap("9.JPG", dpos, ypos);
break; break;
} }
delay(500);
} }
void disp_time(int hours, int minutes) { void disp_time(int hours, int minutes) {
epd_clear();
// first digit of hours // first digit of hours
if (hours > 19) { if (hours > 19) {
disp_digit(2, 1); disp_digit(2, 1);
@ -172,6 +178,7 @@ void disp_time(int hours, int minutes) {
disp_digit(hours, 2); disp_digit(hours, 2);
epd_disp_bitmap("COLO.JPG", 2 * dwidth, 0); epd_disp_bitmap("COLO.JPG", 2 * dwidth, 0);
delay(500);
// first minutes digit // first minutes digit
if (minutes > 49) { if (minutes > 49) {
@ -195,7 +202,7 @@ void disp_time(int hours, int minutes) {
// second minutes digit // second minutes digit
disp_digit(minutes, 4); disp_digit(minutes, 4);
} }
@ -203,10 +210,9 @@ void printDateTime(int update_epd)
{ {
char buf[64]; char buf[64];
time_t t; time_t t;
t = ausET.toLocal(now(), &tcr); t = ausET.toLocal(now(), &tcr);
char m[4]; // temporary storage for month string (DateStrings.cpp uses shared buffer) char m[4]; // temporary storage for month string (DateStrings.cpp uses shared buffer)
strcpy(m, monthShortStr(month(t))); strcpy(m, monthShortStr(month(t)));
@ -215,6 +221,7 @@ void printDateTime(int update_epd)
if (update_epd > 0) { if (update_epd > 0) {
disp_time(hour(t), minute(t)); disp_time(hour(t), minute(t));
wait();
} }
sprintf(buf, "%s %.2d %s %d %s", dayShortStr(weekday(t)), day(t), m, year(t), &tcr -> abbrev); sprintf(buf, "%s %.2d %s %d %s", dayShortStr(weekday(t)), day(t), m, year(t), &tcr -> abbrev);
@ -222,29 +229,77 @@ void printDateTime(int update_epd)
if (update_epd > 0) { if (update_epd > 0) {
epd_set_en_font(ASCII64); epd_set_en_font(ASCII64);
epd_disp_string(buf, 150, 290); epd_disp_string(buf, 150, 225);
epd_update(); delay(500);
delay(1500);
Serial.println("Screen Updated"); Serial.println("Screen Updated");
} }
} }
void weatherUpdate(void) { void weatherUpdate(void) {
const size_t capacity = 4*JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(4) + 150;
DynamicJsonBuffer jsonBuffer(capacity);
http.begin(owm_url + api_key); time_t t;
char buf[96] = {};
const char* nstr = "Now";
const char* tstr = "Today";
const char* tmstr = "Tomorrow";
http.begin(ds_url);
int httpCode = http.GET(); int httpCode = http.GET();
if (httpCode > 0) { if (httpCode > 0) {
JsonObject& root = jsonBuffer.parseObject(http.getString());
if (!root.success()) {
Serial.print(F("parseObject() failed: "));
return;
}
float current_temp = root["current"]["temp"];
const char* current_icon = root["current"]["icon"];
float today_max = root["today"]["max"];
const char* today_icon = root["today"]["icon"];
float tomorrow_max = root["tomorrow"]["max"];
const char* tomorrow_icon = root["tomorrow"]["icon"];
float day_after_max = root["day_after"]["max"];
const char* day_after_icon = root["day_after"]["icon"];
String payload = http.getString();
Serial.println(httpCode); epd_set_en_font(ASCII64);
Serial.println(payload);
//Today
t = ausET.toLocal(now());
epd_disp_string(dayStr(weekday(t)), 0, 536);
delay(500);
(String(today_max, 1)).toCharArray(buf,64);
epd_disp_string(buf, 0, 472);
delay(500);
//Tomorrow
t = ausET.toLocal(now() + 86400, &tcr);
epd_disp_string(dayStr(weekday(t)), 267, 536);
delay(500);
(String(tomorrow_max, 1)).toCharArray(buf,64);
epd_disp_string(buf, 267, 472);
delay(500);
//Day after Tomorrow
t = ausET.toLocal(now() + 86400 + 86400);
epd_disp_string(dayStr(weekday(t)), 533, 536);
delay(500);
(String(day_after_max, 1)).toCharArray(buf,64);
epd_disp_string(buf, 533, 472);
delay(500);
} else { } else {
Serial.print("Error on HTTP Request: "); Serial.print("Error on HTTP Request: ");
Serial.println(httpCode); Serial.println(httpCode);
http.end();
} }
http.end();
} }
void loop() { void loop() {
@ -257,20 +312,22 @@ void loop() {
} }
ntpUpdate(); ntpUpdate();
//weatherUpdate();
if (second(now()) >= 49) { if (second(now()) >= 55) {
epd_wakeup(); epd_wakeup();
while (second(now()) != 0) { while (second(now()) != 57) {
delay(500); delay(500);
} }
epd_clear();
weatherUpdate();
printDateTime(1); printDateTime(1);
delay(4000); epd_update();
delay(5000);
epd_enter_stopmode(); epd_enter_stopmode();
} }
sleep_seconds = 49 - second(now()); sleep_seconds = 55 - second(now());
Serial.print("Sleeping for: "); Serial.print("Sleeping for: ");
Serial.println(sleep_seconds); Serial.println(sleep_seconds);

View File

@ -25,6 +25,11 @@ void setup() {
epd_wakeup(); epd_wakeup();
delay(1500); delay(1500);
epd_set_memory(MEM_TF); epd_set_memory(MEM_TF);
epd_disp_bitmap("0.jpg", 0, 0);
epd_disp_bitmap("9.jpg", 185,0);
Serial.println("Attempting to display 0 and 9");
epd_update();
delay(10000);
epd_load_pic(); epd_load_pic();
epd_set_memory(MEM_NAND); epd_set_memory(MEM_NAND);
delay(1500); delay(1500);