mirror of https://github.com/sqfmi/Watchy.git
Native NTP support & bug fixes
- Added native NTP sync support - Fixed bug with WiFi AP not working due to busy lightsleep callback - Removed year offsets and use TimeLib macros for consistencypull/133/head v1.3.0
parent
1bfbc55f4a
commit
12915a48e6
|
@ -70,7 +70,7 @@ void Watchy7SEG::drawDate(){
|
|||
}
|
||||
display.println(currentTime.Day);
|
||||
display.setCursor(5, 150);
|
||||
display.println(currentTime.Year + YEAR_OFFSET);// offset from 1970, since year is stored in uint8_t
|
||||
display.println(tmYearToCalendar(currentTime.Year));// offset from 1970, since year is stored in uint8_t
|
||||
}
|
||||
void Watchy7SEG::drawSteps(){
|
||||
// reset step counter at midnight
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "Watchy",
|
||||
"version": "1.2.12",
|
||||
"version": "1.3.0",
|
||||
"description": "Watchy - An Open Source E-Paper Watch by SQFMI",
|
||||
"authors": [
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name=Watchy
|
||||
version=1.2.12
|
||||
version=1.3.0
|
||||
author=SQFMI
|
||||
maintainer=SQFMI
|
||||
sentence=Watchy - An Open Source E-Paper Watch by SQFMI
|
||||
|
|
|
@ -316,7 +316,7 @@ void Watchy::setTime(){
|
|||
int8_t hour = currentTime.Hour;
|
||||
int8_t day = currentTime.Day;
|
||||
int8_t month = currentTime.Month;
|
||||
int8_t year = currentTime.Year;
|
||||
int8_t year = tmYearToY2k(currentTime.Year);
|
||||
|
||||
int8_t setIndex = SET_HOUR;
|
||||
|
||||
|
@ -452,7 +452,7 @@ void Watchy::setTime(){
|
|||
tmElements_t tm;
|
||||
tm.Month = month;
|
||||
tm.Day = day;
|
||||
tm.Year = year;
|
||||
tm.Year = y2kYearToTm(year);
|
||||
tm.Hour = hour;
|
||||
tm.Minute = minute;
|
||||
tm.Second = 0;
|
||||
|
@ -556,8 +556,9 @@ void Watchy::drawWatchFace(){
|
|||
|
||||
weatherData Watchy::getWeatherData(){
|
||||
if(weatherIntervalCounter >= WEATHER_UPDATE_INTERVAL){ //only update if WEATHER_UPDATE_INTERVAL has elapsed i.e. 30 minutes
|
||||
if(connectWiFi()){//Use Weather API for live data if WiFi is connected
|
||||
HTTPClient http;
|
||||
if(connectWiFi()){
|
||||
RTC.syncNtpTime(); //Sync NTP
|
||||
HTTPClient http; //Use Weather API for live data if WiFi is connected
|
||||
http.setConnectTimeout(3000);//3 second max timeout
|
||||
String weatherQueryURL = String(OPENWEATHERMAP_URL) + String(CITY_NAME) + String(",") + String(COUNTRY_CODE) + String("&units=") + String(TEMP_UNIT) + String("&appid=") + String(OPENWEATHERMAP_APIKEY);
|
||||
http.begin(weatherQueryURL.c_str());
|
||||
|
@ -715,41 +716,43 @@ void Watchy::_bmaConfig(){
|
|||
}
|
||||
|
||||
void Watchy::setupWifi(){
|
||||
WiFiManager wifiManager;
|
||||
wifiManager.resetSettings();
|
||||
wifiManager.setTimeout(WIFI_AP_TIMEOUT);
|
||||
wifiManager.setAPCallback(_configModeCallback);
|
||||
display.setFullWindow();
|
||||
display.fillScreen(GxEPD_BLACK);
|
||||
display.setFont(&FreeMonoBold9pt7b);
|
||||
display.setTextColor(GxEPD_WHITE);
|
||||
if(!wifiManager.autoConnect(WIFI_AP_SSID)) {//WiFi setup failed
|
||||
display.println("Setup failed &");
|
||||
display.println("timed out!");
|
||||
}else{
|
||||
display.println("Connected to");
|
||||
display.println(WiFi.SSID());
|
||||
}
|
||||
display.display(false); //full refresh
|
||||
//turn off radios
|
||||
WiFi.mode(WIFI_OFF);
|
||||
btStop();
|
||||
|
||||
guiState = APP_STATE;
|
||||
display.epd2.setBusyCallback(0); //temporarily disable lightsleep on busy
|
||||
WiFiManager wifiManager;
|
||||
wifiManager.resetSettings();
|
||||
wifiManager.setTimeout(WIFI_AP_TIMEOUT);
|
||||
wifiManager.setAPCallback(_configModeCallback);
|
||||
display.setFullWindow();
|
||||
display.fillScreen(GxEPD_BLACK);
|
||||
display.setFont(&FreeMonoBold9pt7b);
|
||||
display.setTextColor(GxEPD_WHITE);
|
||||
if(!wifiManager.autoConnect(WIFI_AP_SSID)) {//WiFi setup failed
|
||||
display.println("Setup failed &");
|
||||
display.println("timed out!");
|
||||
}else{
|
||||
RTC.syncNtpTime(); //sync ntp
|
||||
display.println("Connected to");
|
||||
display.println(WiFi.SSID());
|
||||
}
|
||||
display.display(false); //full refresh
|
||||
//turn off radios
|
||||
WiFi.mode(WIFI_OFF);
|
||||
btStop();
|
||||
display.epd2.setBusyCallback(displayBusyCallback); //enable lightsleep on busy
|
||||
guiState = APP_STATE;
|
||||
}
|
||||
|
||||
void Watchy::_configModeCallback (WiFiManager *myWiFiManager) {
|
||||
display.setFullWindow();
|
||||
display.fillScreen(GxEPD_BLACK);
|
||||
display.setFont(&FreeMonoBold9pt7b);
|
||||
display.setTextColor(GxEPD_WHITE);
|
||||
display.setCursor(0, 30);
|
||||
display.println("Connect to");
|
||||
display.print("SSID: ");
|
||||
display.println(WIFI_AP_SSID);
|
||||
display.print("IP: ");
|
||||
display.println(WiFi.softAPIP());
|
||||
display.display(false); //full refresh
|
||||
display.setFullWindow();
|
||||
display.fillScreen(GxEPD_BLACK);
|
||||
display.setFont(&FreeMonoBold9pt7b);
|
||||
display.setTextColor(GxEPD_WHITE);
|
||||
display.setCursor(0, 30);
|
||||
display.println("Connect to");
|
||||
display.print("SSID: ");
|
||||
display.println(WIFI_AP_SSID);
|
||||
display.print("IP: ");
|
||||
display.println(WiFi.softAPIP());
|
||||
display.display(false); //full refresh
|
||||
}
|
||||
|
||||
bool Watchy::connectWiFi(){
|
||||
|
|
|
@ -20,7 +20,7 @@ void WatchyRTC::init(){
|
|||
}
|
||||
}
|
||||
|
||||
void WatchyRTC::config(String datetime){
|
||||
void WatchyRTC::config(String datetime){ //String datetime format is YYYY:MM:DD:HH:MM:SS
|
||||
if(rtcType == DS3231){
|
||||
_DSConfig(datetime);
|
||||
}else{
|
||||
|
@ -43,17 +43,11 @@ void WatchyRTC::clearAlarm(){
|
|||
void WatchyRTC::read(tmElements_t &tm){
|
||||
if(rtcType == DS3231){
|
||||
rtc_ds.read(tm);
|
||||
tm.Year = tm.Year - 30; //reset to offset from 2000
|
||||
}else{
|
||||
tm.Year = y2kYearToTm(rtc_pcf.getYear());
|
||||
tm.Month = rtc_pcf.getMonth();
|
||||
if(tm.Month == 0){ //PCF8563 POR sets month = 0 for some reason
|
||||
tm.Month = 1;
|
||||
tm.Year = 21;
|
||||
}else{
|
||||
tm.Year = rtc_pcf.getYear();
|
||||
}
|
||||
tm.Day = rtc_pcf.getDay();
|
||||
tm.Wday = rtc_pcf.getWeekday() + 1;
|
||||
tm.Wday = rtc_pcf.getWeekday() + 1; //TimeLib & DS3231 has Wday range of 1-7, but PCF8563 stores day of week in 0-6 range
|
||||
tm.Hour = rtc_pcf.getHour();
|
||||
tm.Minute = rtc_pcf.getMinute();
|
||||
tm.Second = rtc_pcf.getSecond();
|
||||
|
@ -62,11 +56,14 @@ void WatchyRTC::read(tmElements_t &tm){
|
|||
|
||||
void WatchyRTC::set(tmElements_t tm){
|
||||
if(rtcType == DS3231){
|
||||
tm.Year = tm.Year + 2000 - YEAR_OFFSET_DS;
|
||||
time_t t = makeTime(tm);
|
||||
rtc_ds.set(t);
|
||||
}else{
|
||||
rtc_pcf.setDate(tm.Day, _getDayOfWeek(tm.Day, tm.Month, tm.Year+YEAR_OFFSET_PCF), tm.Month, 0, tm.Year);
|
||||
time_t t = makeTime(tm); //make and break to calculate tm.Wday
|
||||
breakTime(t, tm);
|
||||
//day, weekday, month, century(1=1900, 0=2000), year(0-99)
|
||||
rtc_pcf.setDate(tm.Day, tm.Wday - 1, tm.Month, 0, tmYearToY2k(tm.Year)); //TimeLib & DS3231 has Wday range of 1-7, but PCF8563 stores day of week in 0-6 range
|
||||
//hr, min, sec
|
||||
rtc_pcf.setTime(tm.Hour, tm.Minute, tm.Second);
|
||||
clearAlarm();
|
||||
}
|
||||
|
@ -80,10 +77,10 @@ uint8_t WatchyRTC::temperature(){
|
|||
}
|
||||
}
|
||||
|
||||
void WatchyRTC::_DSConfig(String datetime){
|
||||
void WatchyRTC::_DSConfig(String datetime){ //String datetime is YYYY:MM:DD:HH:MM:SS
|
||||
if(datetime != ""){
|
||||
tmElements_t tm;
|
||||
tm.Year = _getValue(datetime, ':', 0).toInt() - YEAR_OFFSET_DS;//offset from 1970, since year is stored in uint8_t
|
||||
tm.Year = CalendarYrToTm(_getValue(datetime, ':', 0).toInt()); //YYYY - 1970
|
||||
tm.Month = _getValue(datetime, ':', 1).toInt();
|
||||
tm.Day = _getValue(datetime, ':', 2).toInt();
|
||||
tm.Hour = _getValue(datetime, ':', 3).toInt();
|
||||
|
@ -98,30 +95,54 @@ void WatchyRTC::_DSConfig(String datetime){
|
|||
rtc_ds.alarmInterrupt(ALARM_2, true); //enable alarm interrupt
|
||||
}
|
||||
|
||||
void WatchyRTC::_PCFConfig(String datetime){
|
||||
void WatchyRTC::_PCFConfig(String datetime){ //String datetime is YYYY:MM:DD:HH:MM:SS
|
||||
if(datetime != ""){
|
||||
tmElements_t tm;
|
||||
int Year = _getValue(datetime, ':', 0).toInt();
|
||||
int Month = _getValue(datetime, ':', 1).toInt();
|
||||
int Day = _getValue(datetime, ':', 2).toInt();
|
||||
int Hour = _getValue(datetime, ':', 3).toInt();
|
||||
int Minute = _getValue(datetime, ':', 4).toInt();
|
||||
int Second = _getValue(datetime, ':', 5).toInt();
|
||||
tm.Year = CalendarYrToTm(_getValue(datetime, ':', 0).toInt()); //YYYY - 1970
|
||||
tm.Month = _getValue(datetime, ':', 1).toInt();
|
||||
tm.Day = _getValue(datetime, ':', 2).toInt();
|
||||
tm.Hour = _getValue(datetime, ':', 3).toInt();
|
||||
tm.Minute = _getValue(datetime, ':', 4).toInt();
|
||||
tm.Second = _getValue(datetime, ':', 5).toInt();
|
||||
time_t t = makeTime(tm); //make and break to calculate tm.Wday
|
||||
breakTime(t, tm);
|
||||
//day, weekday, month, century(1=1900, 0=2000), year(0-99)
|
||||
rtc_pcf.setDate(Day, _getDayOfWeek(Day, Month, Year), Month, 0, Year - YEAR_OFFSET_PCF);//offset from 2000
|
||||
rtc_pcf.setDate(tm.Day, tm.Wday - 1, tm.Month, 0, tmYearToY2k(tm.Year)); //TimeLib & DS3231 has Wday range of 1-7, but PCF8563 stores day of week in 0-6 range
|
||||
//hr, min, sec
|
||||
rtc_pcf.setTime(Hour, Minute, Second);
|
||||
rtc_pcf.setTime(tm.Hour, tm.Minute, tm.Second);
|
||||
}
|
||||
//on POR event, PCF8563 sets month to 0, which will give an error since months are 1-12
|
||||
clearAlarm();
|
||||
}
|
||||
|
||||
int WatchyRTC::_getDayOfWeek(int d, int m, int y)
|
||||
{
|
||||
static int t[] = { 0, 3, 2, 5, 0, 3,
|
||||
5, 1, 4, 6, 2, 4 };
|
||||
y -= m < 3;
|
||||
return ( y + y / 4 - y / 100 +
|
||||
y / 400 + t[m - 1] + d) % 7;
|
||||
void WatchyRTC::syncNtpTime(){ //NTP sync - call after connecting to WiFi and remember to turn it back off
|
||||
configTime(GMT_OFFSET_SEC, DST_OFFSET_SEC, NTP_SERVER);
|
||||
struct tm timeinfo;
|
||||
if(!getLocalTime(&timeinfo)){
|
||||
return; //NTP sync failed
|
||||
}
|
||||
/****************************************************
|
||||
struct tm
|
||||
{
|
||||
int tm_sec; // Seconds [0,60].
|
||||
int tm_min; // Minutes [0,59].
|
||||
int tm_hour; // Hour [0,23].
|
||||
int tm_mday; // Day of month [1,31].
|
||||
int tm_mon; // Month of year [0,11].
|
||||
int tm_year; // Years since 1900.
|
||||
int tm_wday; // Day of week [0,6] (Sunday =0).
|
||||
int tm_yday; // Day of year [0,365].
|
||||
int tm_isdst; // Daylight Savings flag.
|
||||
}
|
||||
****************************************************/
|
||||
tmElements_t tm;
|
||||
tm.Year = CalendarYrToTm(timeinfo.tm_year + 1900);
|
||||
tm.Month = timeinfo.tm_mon + 1; //tm.Month 1 - 12
|
||||
tm.Day = timeinfo.tm_mday;
|
||||
tm.Hour = timeinfo.tm_hour;
|
||||
tm.Minute = timeinfo.tm_min;
|
||||
tm.Second = timeinfo.tm_sec;
|
||||
set(tm);
|
||||
}
|
||||
|
||||
String WatchyRTC::_getValue(String data, char separator, int index)
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include <DS3232RTC.h>
|
||||
#include <Rtc_Pcf8563.h>
|
||||
#include "config.h"
|
||||
#include "time.h"
|
||||
|
||||
#define DS3231 0
|
||||
#define PCF8563 1
|
||||
|
@ -19,10 +21,11 @@ class WatchyRTC {
|
|||
public:
|
||||
WatchyRTC();
|
||||
void init();
|
||||
void config(String datetime);
|
||||
void config(String datetime); //String datetime format is YYYY:MM:DD:HH:MM:SS
|
||||
void clearAlarm();
|
||||
void read(tmElements_t &tm);
|
||||
void set(tmElements_t tm);
|
||||
void syncNtpTime();
|
||||
uint8_t temperature();
|
||||
private:
|
||||
void _DSConfig(String datetime);
|
||||
|
|
|
@ -48,8 +48,10 @@
|
|||
#define SET_YEAR 2
|
||||
#define SET_MONTH 3
|
||||
#define SET_DAY 4
|
||||
#define YEAR_OFFSET 2000
|
||||
#define HOUR_12_24 24
|
||||
#define NTP_SERVER "pool.ntp.org"
|
||||
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5
|
||||
#define DST_OFFSET_SEC 3600
|
||||
//BLE OTA
|
||||
#define BLE_DEVICE_NAME "Watchy BLE OTA"
|
||||
#define WATCHFACE_NAME "Watchy 7 Segment"
|
||||
|
|
Loading…
Reference in New Issue