This commit is contained in:
parent
4e3800e332
commit
b0e5d281e0
6 changed files with 91 additions and 14 deletions
|
@ -17,6 +17,7 @@ lib_deps =
|
||||||
GxEPD2
|
GxEPD2
|
||||||
Time
|
Time
|
||||||
NTPClient
|
NTPClient
|
||||||
|
ArduinoJson
|
||||||
|
|
||||||
lib_ldf_mode = deep+
|
lib_ldf_mode = deep+
|
||||||
board_build.partitions = min_spiffs.csv
|
board_build.partitions = min_spiffs.csv
|
||||||
|
|
15
src/Icons.h
15
src/Icons.h
|
@ -2,11 +2,22 @@
|
||||||
|
|
||||||
namespace Icons
|
namespace Icons
|
||||||
{
|
{
|
||||||
const unsigned char steps [] PROGMEM = {
|
// 19x23
|
||||||
|
const unsigned char steps[] PROGMEM = {
|
||||||
0x00, 0x03, 0xc0, 0x00, 0x07, 0xe0, 0x00, 0x07, 0xe0, 0x00, 0x0f, 0xe0, 0x78, 0x0f, 0xe0, 0xfc,
|
0x00, 0x03, 0xc0, 0x00, 0x07, 0xe0, 0x00, 0x07, 0xe0, 0x00, 0x0f, 0xe0, 0x78, 0x0f, 0xe0, 0xfc,
|
||||||
0x0f, 0xe0, 0xfc, 0x0f, 0xe0, 0xfc, 0x0f, 0xe0, 0xfe, 0x0f, 0xe0, 0xfe, 0x07, 0xc0, 0xfe, 0x07,
|
0x0f, 0xe0, 0xfc, 0x0f, 0xe0, 0xfc, 0x0f, 0xe0, 0xfe, 0x0f, 0xe0, 0xfe, 0x07, 0xc0, 0xfe, 0x07,
|
||||||
0xc0, 0xfe, 0x07, 0x80, 0xfe, 0x00, 0x00, 0x7c, 0x0e, 0x00, 0x7c, 0x0f, 0x80, 0x7c, 0x1f, 0x80,
|
0xc0, 0xfe, 0x07, 0x80, 0xfe, 0x00, 0x00, 0x7c, 0x0e, 0x00, 0x7c, 0x0f, 0x80, 0x7c, 0x1f, 0x80,
|
||||||
0x20, 0x1f, 0x00, 0x06, 0x0f, 0x00, 0x3e, 0x0e, 0x00, 0x3e, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x1e,
|
0x20, 0x1f, 0x00, 0x06, 0x0f, 0x00, 0x3e, 0x0e, 0x00, 0x3e, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x1e,
|
||||||
0x00, 0x00, 0x1e, 0x00, 0x00
|
0x00, 0x00, 0x1e, 0x00, 0x00
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
// 29x23
|
||||||
|
const unsigned char city[] PROGMEM = {
|
||||||
|
0x00, 0x07, 0xf8, 0x00, 0x00, 0x07, 0xfc, 0x00, 0x00, 0x07, 0xfc, 0x00, 0x0e, 0x07, 0x1c, 0x00,
|
||||||
|
0x1f, 0x87, 0x1c, 0x00, 0x3f, 0xc7, 0x1c, 0xc0, 0x3f, 0xc7, 0xfc, 0xc0, 0x3f, 0xc7, 0x1c, 0xc0,
|
||||||
|
0x7f, 0xc7, 0x1c, 0xc0, 0x7f, 0xe7, 0x1f, 0xf8, 0xff, 0xe7, 0xff, 0xf8, 0xff, 0xe7, 0x1e, 0x38,
|
||||||
|
0xff, 0xe7, 0x1e, 0x38, 0xff, 0xe7, 0x1e, 0x38, 0x06, 0x07, 0x1e, 0x38, 0x06, 0x07, 0xff, 0xf8,
|
||||||
|
0x06, 0x07, 0xfe, 0x38, 0x06, 0x07, 0xfe, 0x38, 0x06, 0x07, 0xfe, 0x38, 0x06, 0x07, 0xff, 0xf8,
|
||||||
|
0x06, 0x07, 0xff, 0xf8, 0x06, 0x07, 0xff, 0xf8, 0x06, 0x07, 0xff, 0xf8
|
||||||
|
};
|
||||||
|
}
|
|
@ -18,6 +18,8 @@ void WatchFace::InitBoot()
|
||||||
m_features.wifi.Disconnect();
|
m_features.wifi.Disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static_cast<WatchFacePages::Weather *>(m_pages[1].get())->Resync();
|
||||||
|
|
||||||
for (auto & page : m_pages) {
|
for (auto & page : m_pages) {
|
||||||
page->InitBoot();
|
page->InitBoot();
|
||||||
}
|
}
|
||||||
|
@ -118,6 +120,9 @@ void WatchFace::DrawWatchFace(bool partialRefresh)
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pages[m_watchFacePage]->DrawPage(partialRefresh);
|
m_pages[m_watchFacePage]->DrawPage(partialRefresh);
|
||||||
|
|
||||||
|
// Resync weather on matter what
|
||||||
|
static_cast<WatchFacePages::Weather *>(m_pages[1].get())->Resync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WatchFace::SetupVolatileMenuStuff()
|
void WatchFace::SetupVolatileMenuStuff()
|
||||||
|
|
|
@ -102,7 +102,6 @@ void WatchFacePages::Clock::DrawBatteryIcon()
|
||||||
m_display.setFont(&FreeSans9pt7b);
|
m_display.setFont(&FreeSans9pt7b);
|
||||||
m_display.setTextColor(GxEPD_BLACK);
|
m_display.setTextColor(GxEPD_BLACK);
|
||||||
|
|
||||||
|
|
||||||
int16_t y;
|
int16_t y;
|
||||||
uint16_t w, h;
|
uint16_t w, h;
|
||||||
m_display.getTextBounds(oss.str().c_str(), 0, 0, &x, &y, &w, &h);
|
m_display.getTextBounds(oss.str().c_str(), 0, 0, &x, &y, &w, &h);
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
#include "Weather.h"
|
#include "Weather.h"
|
||||||
#include "../SevenSegment.h"
|
#include "../SevenSegment.h"
|
||||||
#include "../Icons.h"
|
#include "../Icons.h"
|
||||||
|
#include <Fonts/FreeSans9pt7b.h>
|
||||||
|
#include <Fonts/FreeSansBold9pt7b.h>
|
||||||
#include <Fonts/FreeSans12pt7b.h>
|
#include <Fonts/FreeSans12pt7b.h>
|
||||||
|
#include <HTTPClient.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
RTC_DATA_ATTR uint64_t WatchFacePages::Weather::m_lastSyncTime = 0;
|
RTC_DATA_ATTR uint64_t WatchFacePages::Weather::m_lastSyncTime = 0;
|
||||||
RTC_DATA_ATTR int WatchFacePages::Weather::m_lastCalculatedDay = 0XFFFFFFFF;
|
RTC_DATA_ATTR int WatchFacePages::Weather::m_lastCalculatedDay = 0XFFFFFFFF;
|
||||||
|
RTC_DATA_ATTR float WatchFacePages::Weather::m_locationLat = 0.0f;
|
||||||
|
RTC_DATA_ATTR float WatchFacePages::Weather::m_locationLon = 0.0f;
|
||||||
|
RTC_DATA_ATTR char WatchFacePages::Weather::m_locationCity[128];
|
||||||
|
|
||||||
WatchFacePages::Weather::Weather(WatchyDisplay & display, WatchFeatures::WatchFeatures & features)
|
WatchFacePages::Weather::Weather(WatchyDisplay & display, WatchFeatures::WatchFeatures & features)
|
||||||
: m_display(display), m_features(features)
|
: m_display(display), m_features(features)
|
||||||
|
@ -21,6 +28,11 @@ void WatchFacePages::Weather::InitWake()
|
||||||
|
|
||||||
void WatchFacePages::Weather::DrawPage(bool partialRefresh)
|
void WatchFacePages::Weather::DrawPage(bool partialRefresh)
|
||||||
{
|
{
|
||||||
|
Serial.println("Weather:DrawPage");
|
||||||
|
if (m_lastSyncTime == 0) {
|
||||||
|
Resync();
|
||||||
|
}
|
||||||
|
|
||||||
m_display.setFullWindow();
|
m_display.setFullWindow();
|
||||||
m_display.fillScreen(GxEPD_WHITE);
|
m_display.fillScreen(GxEPD_WHITE);
|
||||||
m_display.setTextColor(GxEPD_BLACK);
|
m_display.setTextColor(GxEPD_BLACK);
|
||||||
|
@ -34,23 +46,69 @@ void WatchFacePages::Weather::DrawPage(bool partialRefresh)
|
||||||
m_display.print("Have not synced");
|
m_display.print("Have not synced");
|
||||||
m_display.display(partialRefresh);
|
m_display.display(partialRefresh);
|
||||||
return;
|
return;
|
||||||
} else if (m_features.rtc.GetTimestamp() - m_lastSyncTime > 86400) {
|
|
||||||
m_display.setFont(&FreeSans12pt7b);
|
|
||||||
m_display.setCursor(20, 110);
|
|
||||||
m_display.print("Last sync > 1 day");
|
|
||||||
m_display.display(partialRefresh);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool weatherOutdated = false;
|
||||||
|
|
||||||
|
if (m_features.rtc.GetTimestamp() - m_lastSyncTime > 86400) {
|
||||||
|
weatherOutdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_display.setFont(&FreeSansBold9pt7b);
|
||||||
|
int16_t x, y;
|
||||||
|
uint16_t w, h;
|
||||||
|
|
||||||
|
m_display.drawBitmap(5, 5, Icons::city, 29, 23, GxEPD_BLACK);
|
||||||
|
|
||||||
|
m_display.setCursor(39, 21);
|
||||||
|
m_display.print(m_locationCity);
|
||||||
|
m_display.display(partialRefresh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WatchFacePages::Weather::Resync()
|
void WatchFacePages::Weather::Resync()
|
||||||
{
|
{
|
||||||
uint64_t currentTime = m_features.rtc.GetTimestamp();
|
uint64_t currentTime = m_features.rtc.GetTimestamp();
|
||||||
|
|
||||||
if(m_lastSyncTime == 0 || currentTime - m_lastSyncTime > WEATHER_UPDATE_INTERVAL) {
|
if(m_lastSyncTime > 0 && currentTime - m_lastSyncTime < WEATHER_UPDATE_INTERVAL) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if(!m_features.wifi.Connect()) {
|
if(!m_features.wifi.Connect()) {
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
HTTPClient client;
|
||||||
|
client.setConnectTimeout(3000); // 3 second max timeout
|
||||||
|
|
||||||
|
client.begin("http://ip-api.com/json/");
|
||||||
|
int httpCode = client.GET();
|
||||||
|
if (httpCode != 200) {
|
||||||
|
m_features.wifi.Disconnect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String payload = client.getString();
|
||||||
|
client.end();
|
||||||
|
|
||||||
|
DynamicJsonDocument json(1024);
|
||||||
|
DeserializationError error = deserializeJson(json, payload);
|
||||||
|
if (error) {
|
||||||
|
m_features.wifi.Disconnect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!json.containsKey("lat") || !json.containsKey("lon")) {
|
||||||
|
m_features.wifi.Disconnect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string location = json["city"].as<std::string>();
|
||||||
|
location = location.substr(0, 127);
|
||||||
|
memcpy(m_locationCity, location.c_str(), location.length());
|
||||||
|
m_locationCity[location.length()] = '\0';
|
||||||
|
m_locationLat = json["lat"];
|
||||||
|
m_locationLon = json["lon"];
|
||||||
|
m_features.wifi.Disconnect();
|
||||||
|
|
||||||
|
m_lastSyncTime = currentTime;
|
||||||
}
|
}
|
|
@ -5,6 +5,7 @@
|
||||||
#include "Page.h"
|
#include "Page.h"
|
||||||
#include "../WatchyDisplay.h"
|
#include "../WatchyDisplay.h"
|
||||||
#include "../WatchFeatures/WatchFeatures.h"
|
#include "../WatchFeatures/WatchFeatures.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace WatchFacePages
|
namespace WatchFacePages
|
||||||
{
|
{
|
||||||
|
@ -18,12 +19,14 @@ public:
|
||||||
void InitBoot() override;
|
void InitBoot() override;
|
||||||
void InitWake() override;
|
void InitWake() override;
|
||||||
void DrawPage(bool partialRefresh = false) override;
|
void DrawPage(bool partialRefresh = false) override;
|
||||||
|
void Resync();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Resync();
|
|
||||||
|
|
||||||
WatchyDisplay & m_display;
|
WatchyDisplay & m_display;
|
||||||
WatchFeatures::WatchFeatures & m_features;
|
WatchFeatures::WatchFeatures & m_features;
|
||||||
static RTC_DATA_ATTR uint64_t m_lastSyncTime;
|
static RTC_DATA_ATTR uint64_t m_lastSyncTime;
|
||||||
static RTC_DATA_ATTR int m_lastCalculatedDay;
|
static RTC_DATA_ATTR int m_lastCalculatedDay;
|
||||||
|
static RTC_DATA_ATTR char m_locationCity[128];
|
||||||
|
static RTC_DATA_ATTR float m_locationLat, m_locationLon;
|
||||||
};
|
};
|
Loading…
Reference in a new issue