mirror of https://github.com/sqfmi/Watchy.git
Compare commits
23 Commits
b90b4a1af1
...
a07903f7b2
Author | SHA1 | Date |
---|---|---|
sqfmi | a07903f7b2 | |
SQFMI | e9854a7fa2 | |
sqfmi | ef2d57f737 | |
sqfmi | fbdaacd287 | |
SQFMI | 99cacd26a9 | |
sqfmi | fddbe504c1 | |
sqfmi | aa3528371d | |
sqfmi | 3ffb0f8697 | |
sqfmi | b786f24240 | |
sqfmi | 2528878570 | |
sqfmi | 1b15c1b5fe | |
Daniel Ansorregui | be185cbd54 | |
Daniel Ansorregui | f369b6f207 | |
Daniel Ansorregui | 8103df1499 | |
Daniel Ansorregui | 84c0cd106c | |
Daniel Ansorregui | 3ce125247d | |
Daniel Ansorregui | f2c0c91a61 | |
Daniel Ansorregui | 2b21e50c2f | |
Sudrien | b84ab91c6b | |
Sean M. Collins | b8eeda70c6 | |
Sean M. Collins | a719bfa116 | |
Sean M. Collins | 459cc2a18f | |
Denis Pitzalis | df5fce8d40 |
|
@ -125,26 +125,29 @@ void Watchy7SEG::drawWeather(){
|
||||||
display.drawBitmap(165, 110, currentWeather.isMetric ? celsius : fahrenheit, 26, 20, DARKMODE ? GxEPD_WHITE : GxEPD_BLACK);
|
display.drawBitmap(165, 110, currentWeather.isMetric ? celsius : fahrenheit, 26, 20, DARKMODE ? GxEPD_WHITE : GxEPD_BLACK);
|
||||||
const unsigned char* weatherIcon;
|
const unsigned char* weatherIcon;
|
||||||
|
|
||||||
//https://openweathermap.org/weather-conditions
|
if(WIFI_CONFIGURED){
|
||||||
if(weatherConditionCode > 801){//Cloudy
|
//https://openweathermap.org/weather-conditions
|
||||||
weatherIcon = cloudy;
|
if(weatherConditionCode > 801){//Cloudy
|
||||||
}else if(weatherConditionCode == 801){//Few Clouds
|
weatherIcon = cloudy;
|
||||||
weatherIcon = cloudsun;
|
}else if(weatherConditionCode == 801){//Few Clouds
|
||||||
}else if(weatherConditionCode == 800){//Clear
|
weatherIcon = cloudsun;
|
||||||
weatherIcon = sunny;
|
}else if(weatherConditionCode == 800){//Clear
|
||||||
}else if(weatherConditionCode >=700){//Atmosphere
|
weatherIcon = sunny;
|
||||||
weatherIcon = atmosphere;
|
}else if(weatherConditionCode >=700){//Atmosphere
|
||||||
}else if(weatherConditionCode >=600){//Snow
|
weatherIcon = atmosphere;
|
||||||
weatherIcon = snow;
|
}else if(weatherConditionCode >=600){//Snow
|
||||||
}else if(weatherConditionCode >=500){//Rain
|
weatherIcon = snow;
|
||||||
weatherIcon = rain;
|
}else if(weatherConditionCode >=500){//Rain
|
||||||
}else if(weatherConditionCode >=300){//Drizzle
|
weatherIcon = rain;
|
||||||
weatherIcon = drizzle;
|
}else if(weatherConditionCode >=300){//Drizzle
|
||||||
}else if(weatherConditionCode >=200){//Thunderstorm
|
weatherIcon = drizzle;
|
||||||
weatherIcon = thunderstorm;
|
}else if(weatherConditionCode >=200){//Thunderstorm
|
||||||
}else if(weatherConditionCode == -1){//chip
|
weatherIcon = thunderstorm;
|
||||||
weatherIcon = chip;
|
}else
|
||||||
}else
|
return;
|
||||||
return;
|
}else{
|
||||||
|
weatherIcon = cputemp;
|
||||||
|
}
|
||||||
|
|
||||||
display.drawBitmap(145, 158, weatherIcon, WEATHER_ICON_WIDTH, WEATHER_ICON_HEIGHT, DARKMODE ? GxEPD_WHITE : GxEPD_BLACK);
|
display.drawBitmap(145, 158, weatherIcon, WEATHER_ICON_WIDTH, WEATHER_ICON_HEIGHT, DARKMODE ? GxEPD_WHITE : GxEPD_BLACK);
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,6 +150,21 @@ const unsigned char thunderstorm[] PROGMEM = {
|
||||||
0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x01,
|
0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
};
|
};
|
||||||
|
// 'cputemp', 48x32px
|
||||||
|
const unsigned char cputemp [] PROGMEM = {
|
||||||
|
0x00, 0x01, 0x8c, 0xe7, 0x00, 0x00, 0x00, 0x01, 0x8c, 0xe7, 0x00, 0x00, 0x00, 0x01, 0x8c, 0xe7,
|
||||||
|
0x00, 0x00, 0x00, 0x01, 0x8c, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
|
||||||
|
0xff, 0xff, 0xe0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x03, 0xef, 0xff, 0xff, 0xef, 0x80,
|
||||||
|
0x03, 0xef, 0xff, 0xff, 0xef, 0x80, 0x03, 0xef, 0xff, 0xff, 0xe7, 0x80, 0x00, 0x0f, 0xff, 0xff,
|
||||||
|
0xe0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x03, 0xef, 0xff, 0xff, 0xef, 0x80, 0x03, 0xef,
|
||||||
|
0xff, 0xff, 0xef, 0x80, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00,
|
||||||
|
0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x03, 0xef, 0xff, 0xff, 0xef, 0x80, 0x03, 0xef, 0xff, 0xff,
|
||||||
|
0xef, 0x80, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x0f,
|
||||||
|
0xff, 0xff, 0xe0, 0x00, 0x03, 0xef, 0xff, 0xff, 0xef, 0x80, 0x03, 0xef, 0xff, 0xff, 0xef, 0x80,
|
||||||
|
0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8c, 0xe7, 0x00, 0x00, 0x00, 0x01,
|
||||||
|
0x8c, 0xe7, 0x00, 0x00, 0x00, 0x01, 0x8c, 0xe7, 0x00, 0x00, 0x00, 0x01, 0x8c, 0xe7, 0x00, 0x00
|
||||||
|
};
|
||||||
// 'steps', 19x23px
|
// 'steps', 19x23px
|
||||||
const unsigned char steps [] PROGMEM = {
|
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,
|
||||||
|
|
|
@ -3,8 +3,18 @@
|
||||||
|
|
||||||
//Weather Settings
|
//Weather Settings
|
||||||
#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
|
#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
|
||||||
|
|
||||||
|
//You can also use LAT,LON for your location instead of CITY_ID, but not both
|
||||||
|
//#define LAT "40.7127" //New York City, Looked up on https://www.latlong.net/
|
||||||
|
//#define LON "-74.0059"
|
||||||
|
|
||||||
|
#ifdef CITY_ID
|
||||||
|
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id={cityID}&lang={lang}&units={units}&appid={apiKey}" //open weather api using city ID
|
||||||
|
#else
|
||||||
|
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&lang={lang}&units={units}&appid={apiKey}" //open weather api using lat lon
|
||||||
|
#endif
|
||||||
|
|
||||||
#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
|
#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
|
||||||
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id=" //open weather api
|
|
||||||
#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
|
#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
|
||||||
#define TEMP_LANG "en"
|
#define TEMP_LANG "en"
|
||||||
#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
|
#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
|
||||||
|
@ -13,7 +23,13 @@
|
||||||
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5 EST, -4 EDT, will be overwritten by weather data
|
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5 EST, -4 EDT, will be overwritten by weather data
|
||||||
|
|
||||||
watchySettings settings{
|
watchySettings settings{
|
||||||
.cityID = CITY_ID,
|
#ifdef CITY_ID
|
||||||
|
.cityID = CITY_ID,
|
||||||
|
#else
|
||||||
|
.cityID = "",
|
||||||
|
.lat = LAT,
|
||||||
|
.lon = LON,
|
||||||
|
#endif
|
||||||
.weatherAPIKey = OPENWEATHERMAP_APIKEY,
|
.weatherAPIKey = OPENWEATHERMAP_APIKEY,
|
||||||
.weatherURL = OPENWEATHERMAP_URL,
|
.weatherURL = OPENWEATHERMAP_URL,
|
||||||
.weatherUnit = TEMP_UNIT,
|
.weatherUnit = TEMP_UNIT,
|
||||||
|
@ -24,4 +40,4 @@ watchySettings settings{
|
||||||
.vibrateOClock = true,
|
.vibrateOClock = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -3,8 +3,18 @@
|
||||||
|
|
||||||
//Weather Settings
|
//Weather Settings
|
||||||
#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
|
#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
|
||||||
|
|
||||||
|
//You can also use LAT,LON for your location instead of CITY_ID, but not both
|
||||||
|
//#define LAT "40.7127" //New York City, Looked up on https://www.latlong.net/
|
||||||
|
//#define LON "-74.0059"
|
||||||
|
|
||||||
|
#ifdef CITY_ID
|
||||||
|
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id={cityID}&lang={lang}&units={units}&appid={apiKey}" //open weather api using city ID
|
||||||
|
#else
|
||||||
|
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&lang={lang}&units={units}&appid={apiKey}" //open weather api using lat lon
|
||||||
|
#endif
|
||||||
|
|
||||||
#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
|
#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
|
||||||
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id=" //open weather api
|
|
||||||
#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
|
#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
|
||||||
#define TEMP_LANG "en"
|
#define TEMP_LANG "en"
|
||||||
#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
|
#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
|
||||||
|
@ -13,7 +23,13 @@
|
||||||
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5 EST, -4 EDT, will be overwritten by weather data
|
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5 EST, -4 EDT, will be overwritten by weather data
|
||||||
|
|
||||||
watchySettings settings{
|
watchySettings settings{
|
||||||
.cityID = CITY_ID,
|
#ifdef CITY_ID
|
||||||
|
.cityID = CITY_ID,
|
||||||
|
#else
|
||||||
|
.cityID = "",
|
||||||
|
.lat = LAT,
|
||||||
|
.lon = LON,
|
||||||
|
#endif
|
||||||
.weatherAPIKey = OPENWEATHERMAP_APIKEY,
|
.weatherAPIKey = OPENWEATHERMAP_APIKEY,
|
||||||
.weatherURL = OPENWEATHERMAP_URL,
|
.weatherURL = OPENWEATHERMAP_URL,
|
||||||
.weatherUnit = TEMP_UNIT,
|
.weatherUnit = TEMP_UNIT,
|
||||||
|
@ -21,6 +37,7 @@ watchySettings settings{
|
||||||
.weatherUpdateInterval = WEATHER_UPDATE_INTERVAL,
|
.weatherUpdateInterval = WEATHER_UPDATE_INTERVAL,
|
||||||
.ntpServer = NTP_SERVER,
|
.ntpServer = NTP_SERVER,
|
||||||
.gmtOffset = GMT_OFFSET_SEC,
|
.gmtOffset = GMT_OFFSET_SEC,
|
||||||
|
.vibrateOClock = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -3,8 +3,18 @@
|
||||||
|
|
||||||
//Weather Settings
|
//Weather Settings
|
||||||
#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
|
#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
|
||||||
|
|
||||||
|
//You can also use LAT,LON for your location instead of CITY_ID, but not both
|
||||||
|
//#define LAT "40.7127" //New York City, Looked up on https://www.latlong.net/
|
||||||
|
//#define LON "-74.0059"
|
||||||
|
|
||||||
|
#ifdef CITY_ID
|
||||||
|
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id={cityID}&lang={lang}&units={units}&appid={apiKey}" //open weather api using city ID
|
||||||
|
#else
|
||||||
|
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&lang={lang}&units={units}&appid={apiKey}" //open weather api using lat lon
|
||||||
|
#endif
|
||||||
|
|
||||||
#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
|
#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
|
||||||
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id=" //open weather api
|
|
||||||
#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
|
#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
|
||||||
#define TEMP_LANG "en"
|
#define TEMP_LANG "en"
|
||||||
#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
|
#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
|
||||||
|
@ -13,7 +23,13 @@
|
||||||
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5 EST, -4 EDT, will be overwritten by weather data
|
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5 EST, -4 EDT, will be overwritten by weather data
|
||||||
|
|
||||||
watchySettings settings{
|
watchySettings settings{
|
||||||
.cityID = CITY_ID,
|
#ifdef CITY_ID
|
||||||
|
.cityID = CITY_ID,
|
||||||
|
#else
|
||||||
|
.cityID = "",
|
||||||
|
.lat = LAT,
|
||||||
|
.lon = LON,
|
||||||
|
#endif
|
||||||
.weatherAPIKey = OPENWEATHERMAP_APIKEY,
|
.weatherAPIKey = OPENWEATHERMAP_APIKEY,
|
||||||
.weatherURL = OPENWEATHERMAP_URL,
|
.weatherURL = OPENWEATHERMAP_URL,
|
||||||
.weatherUnit = TEMP_UNIT,
|
.weatherUnit = TEMP_UNIT,
|
||||||
|
@ -21,6 +37,7 @@ watchySettings settings{
|
||||||
.weatherUpdateInterval = WEATHER_UPDATE_INTERVAL,
|
.weatherUpdateInterval = WEATHER_UPDATE_INTERVAL,
|
||||||
.ntpServer = NTP_SERVER,
|
.ntpServer = NTP_SERVER,
|
||||||
.gmtOffset = GMT_OFFSET_SEC,
|
.gmtOffset = GMT_OFFSET_SEC,
|
||||||
|
.vibrateOClock = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -3,8 +3,18 @@
|
||||||
|
|
||||||
//Weather Settings
|
//Weather Settings
|
||||||
#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
|
#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
|
||||||
|
|
||||||
|
//You can also use LAT,LON for your location instead of CITY_ID, but not both
|
||||||
|
//#define LAT "40.7127" //New York City, Looked up on https://www.latlong.net/
|
||||||
|
//#define LON "-74.0059"
|
||||||
|
|
||||||
|
#ifdef CITY_ID
|
||||||
|
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id={cityID}&lang={lang}&units={units}&appid={apiKey}" //open weather api using city ID
|
||||||
|
#else
|
||||||
|
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&lang={lang}&units={units}&appid={apiKey}" //open weather api using lat lon
|
||||||
|
#endif
|
||||||
|
|
||||||
#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
|
#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
|
||||||
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id=" //open weather api
|
|
||||||
#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
|
#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
|
||||||
#define TEMP_LANG "en"
|
#define TEMP_LANG "en"
|
||||||
#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
|
#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
|
||||||
|
@ -13,7 +23,13 @@
|
||||||
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5 EST, -4 EDT, will be overwritten by weather data
|
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5 EST, -4 EDT, will be overwritten by weather data
|
||||||
|
|
||||||
watchySettings settings{
|
watchySettings settings{
|
||||||
.cityID = CITY_ID,
|
#ifdef CITY_ID
|
||||||
|
.cityID = CITY_ID,
|
||||||
|
#else
|
||||||
|
.cityID = "",
|
||||||
|
.lat = LAT,
|
||||||
|
.lon = LON,
|
||||||
|
#endif
|
||||||
.weatherAPIKey = OPENWEATHERMAP_APIKEY,
|
.weatherAPIKey = OPENWEATHERMAP_APIKEY,
|
||||||
.weatherURL = OPENWEATHERMAP_URL,
|
.weatherURL = OPENWEATHERMAP_URL,
|
||||||
.weatherUnit = TEMP_UNIT,
|
.weatherUnit = TEMP_UNIT,
|
||||||
|
@ -21,6 +37,7 @@ watchySettings settings{
|
||||||
.weatherUpdateInterval = WEATHER_UPDATE_INTERVAL,
|
.weatherUpdateInterval = WEATHER_UPDATE_INTERVAL,
|
||||||
.ntpServer = NTP_SERVER,
|
.ntpServer = NTP_SERVER,
|
||||||
.gmtOffset = GMT_OFFSET_SEC,
|
.gmtOffset = GMT_OFFSET_SEC,
|
||||||
|
.vibrateOClock = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -3,8 +3,18 @@
|
||||||
|
|
||||||
//Weather Settings
|
//Weather Settings
|
||||||
#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
|
#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
|
||||||
|
|
||||||
|
//You can also use LAT,LON for your location instead of CITY_ID, but not both
|
||||||
|
//#define LAT "40.7127" //New York City, Looked up on https://www.latlong.net/
|
||||||
|
//#define LON "-74.0059"
|
||||||
|
|
||||||
|
#ifdef CITY_ID
|
||||||
|
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id={cityID}&lang={lang}&units={units}&appid={apiKey}" //open weather api using city ID
|
||||||
|
#else
|
||||||
|
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&lang={lang}&units={units}&appid={apiKey}" //open weather api using lat lon
|
||||||
|
#endif
|
||||||
|
|
||||||
#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
|
#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
|
||||||
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id=" //open weather api
|
|
||||||
#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
|
#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
|
||||||
#define TEMP_LANG "en"
|
#define TEMP_LANG "en"
|
||||||
#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
|
#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
|
||||||
|
@ -13,7 +23,13 @@
|
||||||
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5 EST, -4 EDT, will be overwritten by weather data
|
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5 EST, -4 EDT, will be overwritten by weather data
|
||||||
|
|
||||||
watchySettings settings{
|
watchySettings settings{
|
||||||
.cityID = CITY_ID,
|
#ifdef CITY_ID
|
||||||
|
.cityID = CITY_ID,
|
||||||
|
#else
|
||||||
|
.cityID = "",
|
||||||
|
.lat = LAT,
|
||||||
|
.lon = LON,
|
||||||
|
#endif
|
||||||
.weatherAPIKey = OPENWEATHERMAP_APIKEY,
|
.weatherAPIKey = OPENWEATHERMAP_APIKEY,
|
||||||
.weatherURL = OPENWEATHERMAP_URL,
|
.weatherURL = OPENWEATHERMAP_URL,
|
||||||
.weatherUnit = TEMP_UNIT,
|
.weatherUnit = TEMP_UNIT,
|
||||||
|
@ -24,4 +40,4 @@ watchySettings settings{
|
||||||
.vibrateOClock = true,
|
.vibrateOClock = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -3,8 +3,18 @@
|
||||||
|
|
||||||
//Weather Settings
|
//Weather Settings
|
||||||
#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
|
#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
|
||||||
|
|
||||||
|
//You can also use LAT,LON for your location instead of CITY_ID, but not both
|
||||||
|
//#define LAT "40.7127" //New York City, Looked up on https://www.latlong.net/
|
||||||
|
//#define LON "-74.0059"
|
||||||
|
|
||||||
|
#ifdef CITY_ID
|
||||||
|
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id={cityID}&lang={lang}&units={units}&appid={apiKey}" //open weather api using city ID
|
||||||
|
#else
|
||||||
|
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&lang={lang}&units={units}&appid={apiKey}" //open weather api using lat lon
|
||||||
|
#endif
|
||||||
|
|
||||||
#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
|
#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
|
||||||
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id=" //open weather api
|
|
||||||
#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
|
#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
|
||||||
#define TEMP_LANG "en"
|
#define TEMP_LANG "en"
|
||||||
#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
|
#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
|
||||||
|
@ -13,7 +23,13 @@
|
||||||
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5 EST, -4 EDT, will be overwritten by weather data
|
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5 EST, -4 EDT, will be overwritten by weather data
|
||||||
|
|
||||||
watchySettings settings{
|
watchySettings settings{
|
||||||
.cityID = CITY_ID,
|
#ifdef CITY_ID
|
||||||
|
.cityID = CITY_ID,
|
||||||
|
#else
|
||||||
|
.cityID = "",
|
||||||
|
.lat = LAT,
|
||||||
|
.lon = LON,
|
||||||
|
#endif
|
||||||
.weatherAPIKey = OPENWEATHERMAP_APIKEY,
|
.weatherAPIKey = OPENWEATHERMAP_APIKEY,
|
||||||
.weatherURL = OPENWEATHERMAP_URL,
|
.weatherURL = OPENWEATHERMAP_URL,
|
||||||
.weatherUnit = TEMP_UNIT,
|
.weatherUnit = TEMP_UNIT,
|
||||||
|
@ -21,6 +37,7 @@ watchySettings settings{
|
||||||
.weatherUpdateInterval = WEATHER_UPDATE_INTERVAL,
|
.weatherUpdateInterval = WEATHER_UPDATE_INTERVAL,
|
||||||
.ntpServer = NTP_SERVER,
|
.ntpServer = NTP_SERVER,
|
||||||
.gmtOffset = GMT_OFFSET_SEC,
|
.gmtOffset = GMT_OFFSET_SEC,
|
||||||
|
.vibrateOClock = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -3,8 +3,18 @@
|
||||||
|
|
||||||
//Weather Settings
|
//Weather Settings
|
||||||
#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
|
#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
|
||||||
|
|
||||||
|
//You can also use LAT,LON for your location instead of CITY_ID, but not both
|
||||||
|
//#define LAT "40.7127" //New York City, Looked up on https://www.latlong.net/
|
||||||
|
//#define LON "-74.0059"
|
||||||
|
|
||||||
|
#ifdef CITY_ID
|
||||||
|
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id={cityID}&lang={lang}&units={units}&appid={apiKey}" //open weather api using city ID
|
||||||
|
#else
|
||||||
|
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&lang={lang}&units={units}&appid={apiKey}" //open weather api using lat lon
|
||||||
|
#endif
|
||||||
|
|
||||||
#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
|
#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
|
||||||
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id=" //open weather api
|
|
||||||
#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
|
#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
|
||||||
#define TEMP_LANG "en"
|
#define TEMP_LANG "en"
|
||||||
#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
|
#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
|
||||||
|
@ -13,7 +23,13 @@
|
||||||
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5 EST, -4 EDT, will be overwritten by weather data
|
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5 EST, -4 EDT, will be overwritten by weather data
|
||||||
|
|
||||||
watchySettings settings{
|
watchySettings settings{
|
||||||
.cityID = CITY_ID,
|
#ifdef CITY_ID
|
||||||
|
.cityID = CITY_ID,
|
||||||
|
#else
|
||||||
|
.cityID = "",
|
||||||
|
.lat = LAT,
|
||||||
|
.lon = LON,
|
||||||
|
#endif
|
||||||
.weatherAPIKey = OPENWEATHERMAP_APIKEY,
|
.weatherAPIKey = OPENWEATHERMAP_APIKEY,
|
||||||
.weatherURL = OPENWEATHERMAP_URL,
|
.weatherURL = OPENWEATHERMAP_URL,
|
||||||
.weatherUnit = TEMP_UNIT,
|
.weatherUnit = TEMP_UNIT,
|
||||||
|
@ -21,6 +37,7 @@ watchySettings settings{
|
||||||
.weatherUpdateInterval = WEATHER_UPDATE_INTERVAL,
|
.weatherUpdateInterval = WEATHER_UPDATE_INTERVAL,
|
||||||
.ntpServer = NTP_SERVER,
|
.ntpServer = NTP_SERVER,
|
||||||
.gmtOffset = GMT_OFFSET_SEC,
|
.gmtOffset = GMT_OFFSET_SEC,
|
||||||
|
.vibrateOClock = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -3,8 +3,18 @@
|
||||||
|
|
||||||
//Weather Settings
|
//Weather Settings
|
||||||
#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
|
#define CITY_ID "5128581" //New York City https://openweathermap.org/current#cityid
|
||||||
|
|
||||||
|
//You can also use LAT,LON for your location instead of CITY_ID, but not both
|
||||||
|
//#define LAT "40.7127" //New York City, Looked up on https://www.latlong.net/
|
||||||
|
//#define LON "-74.0059"
|
||||||
|
|
||||||
|
#ifdef CITY_ID
|
||||||
|
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id={cityID}&lang={lang}&units={units}&appid={apiKey}" //open weather api using city ID
|
||||||
|
#else
|
||||||
|
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&lang={lang}&units={units}&appid={apiKey}" //open weather api using lat lon
|
||||||
|
#endif
|
||||||
|
|
||||||
#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
|
#define OPENWEATHERMAP_APIKEY "f058fe1cad2afe8e2ddc5d063a64cecb" //use your own API key :)
|
||||||
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id=" //open weather api
|
|
||||||
#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
|
#define TEMP_UNIT "metric" //metric = Celsius , imperial = Fahrenheit
|
||||||
#define TEMP_LANG "en"
|
#define TEMP_LANG "en"
|
||||||
#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
|
#define WEATHER_UPDATE_INTERVAL 30 //must be greater than 5, measured in minutes
|
||||||
|
@ -13,7 +23,13 @@
|
||||||
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5 EST, -4 EDT, will be overwritten by weather data
|
#define GMT_OFFSET_SEC 3600 * -5 //New York is UTC -5 EST, -4 EDT, will be overwritten by weather data
|
||||||
|
|
||||||
watchySettings settings{
|
watchySettings settings{
|
||||||
.cityID = CITY_ID,
|
#ifdef CITY_ID
|
||||||
|
.cityID = CITY_ID,
|
||||||
|
#else
|
||||||
|
.cityID = "",
|
||||||
|
.lat = LAT,
|
||||||
|
.lon = LON,
|
||||||
|
#endif
|
||||||
.weatherAPIKey = OPENWEATHERMAP_APIKEY,
|
.weatherAPIKey = OPENWEATHERMAP_APIKEY,
|
||||||
.weatherURL = OPENWEATHERMAP_URL,
|
.weatherURL = OPENWEATHERMAP_URL,
|
||||||
.weatherUnit = TEMP_UNIT,
|
.weatherUnit = TEMP_UNIT,
|
||||||
|
@ -21,6 +37,7 @@ watchySettings settings{
|
||||||
.weatherUpdateInterval = WEATHER_UPDATE_INTERVAL,
|
.weatherUpdateInterval = WEATHER_UPDATE_INTERVAL,
|
||||||
.ntpServer = NTP_SERVER,
|
.ntpServer = NTP_SERVER,
|
||||||
.gmtOffset = GMT_OFFSET_SEC,
|
.gmtOffset = GMT_OFFSET_SEC,
|
||||||
|
.vibrateOClock = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Watchy",
|
"name": "Watchy",
|
||||||
"version": "1.4.8",
|
"version": "1.4.9",
|
||||||
"description": "Watchy - An Open Source E-Paper Watch by SQFMI",
|
"description": "Watchy - An Open Source E-Paper Watch by SQFMI",
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name=Watchy
|
name=Watchy
|
||||||
version=1.4.8
|
version=1.4.9
|
||||||
author=SQFMI
|
author=SQFMI
|
||||||
maintainer=SQFMI
|
maintainer=SQFMI
|
||||||
sentence=Watchy - An Open Source E-Paper Watch by SQFMI
|
sentence=Watchy - An Open Source E-Paper Watch by SQFMI
|
||||||
|
|
126
src/Display.cpp
126
src/Display.cpp
|
@ -15,11 +15,44 @@
|
||||||
// Link: https://github.com/sqfmi/Watchy
|
// Link: https://github.com/sqfmi/Watchy
|
||||||
|
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
WatchyDisplay::WatchyDisplay(int16_t cs, int16_t dc, int16_t rst, int16_t busy) :
|
RTC_DATA_ATTR bool displayFullInit = true;
|
||||||
GxEPD2_EPD(cs, dc, rst, busy, HIGH, 10000000, WIDTH, HEIGHT, panel, hasColor, hasPartialUpdate, hasFastPartialUpdate)
|
|
||||||
|
void WatchyDisplay::busyCallback(const void *) {
|
||||||
|
gpio_wakeup_enable((gpio_num_t)DISPLAY_BUSY, GPIO_INTR_LOW_LEVEL);
|
||||||
|
esp_sleep_enable_gpio_wakeup();
|
||||||
|
esp_light_sleep_start();
|
||||||
|
}
|
||||||
|
|
||||||
|
WatchyDisplay::WatchyDisplay() :
|
||||||
|
GxEPD2_EPD(DISPLAY_CS, DISPLAY_DC, DISPLAY_RES, DISPLAY_BUSY, HIGH, 10000000, WIDTH, HEIGHT, panel, hasColor, hasPartialUpdate, hasFastPartialUpdate)
|
||||||
{
|
{
|
||||||
selectSPI(SPI, SPISettings(20000000, MSBFIRST, SPI_MODE0)); // Set SPI to 20Mhz (default is 4Mhz)
|
// Setup callback and SPI by default
|
||||||
|
selectSPI(SPI, SPISettings(20000000, MSBFIRST, SPI_MODE0));
|
||||||
|
setBusyCallback(busyCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WatchyDisplay::initWatchy() {
|
||||||
|
// Watchy default initialization
|
||||||
|
init(0, displayFullInit, 2, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WatchyDisplay::asyncPowerOn() {
|
||||||
|
// This is expensive if unused
|
||||||
|
if (!waitingPowerOn && !_hibernating) {
|
||||||
|
_InitDisplay();
|
||||||
|
_PowerOnAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WatchyDisplay::setDarkBorder(bool dark) {
|
||||||
|
if (_hibernating) return;
|
||||||
|
darkBorder = dark;
|
||||||
|
_startTransfer();
|
||||||
|
_transferCommand(0x3C); // BorderWavefrom
|
||||||
|
_transfer(dark ? 0x02 : 0x05);
|
||||||
|
_endTransfer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WatchyDisplay::clearScreen(uint8_t value)
|
void WatchyDisplay::clearScreen(uint8_t value)
|
||||||
|
@ -324,31 +357,52 @@ void WatchyDisplay::_setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint1
|
||||||
_endTransfer();
|
_endTransfer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WatchyDisplay::_PowerOnAsync()
|
||||||
|
{
|
||||||
|
if (_power_is_on)
|
||||||
|
return;
|
||||||
|
_startTransfer();
|
||||||
|
_transferCommand(0x22);
|
||||||
|
_transfer(0xf8);
|
||||||
|
_transferCommand(0x20);
|
||||||
|
_endTransfer();
|
||||||
|
waitingPowerOn = true;
|
||||||
|
_power_is_on = true;
|
||||||
|
}
|
||||||
|
|
||||||
void WatchyDisplay::_PowerOn()
|
void WatchyDisplay::_PowerOn()
|
||||||
{
|
{
|
||||||
if (!_power_is_on)
|
if (waitingPowerOn)
|
||||||
{
|
{
|
||||||
_startTransfer();
|
waitingPowerOn = false;
|
||||||
_transferCommand(0x22);
|
|
||||||
_transfer(0xf8);
|
|
||||||
_transferCommand(0x20);
|
|
||||||
_endTransfer();
|
|
||||||
_waitWhileBusy("_PowerOn", power_on_time);
|
_waitWhileBusy("_PowerOn", power_on_time);
|
||||||
}
|
}
|
||||||
|
if (_power_is_on)
|
||||||
|
return;
|
||||||
|
_startTransfer();
|
||||||
|
_transferCommand(0x22);
|
||||||
|
_transfer(0xf8);
|
||||||
|
_transferCommand(0x20);
|
||||||
|
_endTransfer();
|
||||||
|
_waitWhileBusy("_PowerOn", power_on_time);
|
||||||
_power_is_on = true;
|
_power_is_on = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WatchyDisplay::_PowerOff()
|
void WatchyDisplay::_PowerOff()
|
||||||
{
|
{
|
||||||
if (_power_is_on)
|
if (waitingPowerOn)
|
||||||
{
|
{
|
||||||
_startTransfer();
|
waitingPowerOn = false;
|
||||||
_transferCommand(0x22);
|
_waitWhileBusy("_PowerOn", power_on_time);
|
||||||
_transfer(0x83);
|
|
||||||
_transferCommand(0x20);
|
|
||||||
_endTransfer();
|
|
||||||
_waitWhileBusy("_PowerOff", power_off_time);
|
|
||||||
}
|
}
|
||||||
|
if (!_power_is_on)
|
||||||
|
return;
|
||||||
|
_startTransfer();
|
||||||
|
_transferCommand(0x22);
|
||||||
|
_transfer(0x83);
|
||||||
|
_transferCommand(0x20);
|
||||||
|
_endTransfer();
|
||||||
|
_waitWhileBusy("_PowerOff", power_off_time);
|
||||||
_power_is_on = false;
|
_power_is_on = false;
|
||||||
_using_partial_mode = false;
|
_using_partial_mode = false;
|
||||||
}
|
}
|
||||||
|
@ -356,23 +410,54 @@ void WatchyDisplay::_PowerOff()
|
||||||
void WatchyDisplay::_InitDisplay()
|
void WatchyDisplay::_InitDisplay()
|
||||||
{
|
{
|
||||||
if (_hibernating) _reset();
|
if (_hibernating) _reset();
|
||||||
_writeCommand(0x12); // soft reset
|
|
||||||
_waitWhileBusy("_SoftReset", 10); // 10ms max according to specs
|
// No need to soft reset, the Display goes to same state after hard reset
|
||||||
|
// _writeCommand(0x12); // soft reset
|
||||||
|
// _waitWhileBusy("_SoftReset", 10); // 10ms max according to specs*/
|
||||||
|
|
||||||
_startTransfer();
|
_startTransfer();
|
||||||
_transferCommand(0x01); // Driver output control
|
_transferCommand(0x01); // Driver output control
|
||||||
_transfer(0xC7);
|
_transfer(0xC7);
|
||||||
_transfer(0x00);
|
_transfer(0x00);
|
||||||
_transfer(0x00);
|
_transfer(0x00);
|
||||||
_transferCommand(0x3C); // BorderWavefrom
|
|
||||||
_transfer(darkBorder ? 0x02 : 0x05);
|
if (reduceBoosterTime) {
|
||||||
|
// SSD1675B controller datasheet
|
||||||
|
_transferCommand(0x0C); // BOOSTER_SOFT_START_CONTROL
|
||||||
|
// Set the driving strength of GDR for all phases to maximun 0b111 -> 0xF
|
||||||
|
// Set the minimum off time of GDR to minimum 0x4 (values below sould be same)
|
||||||
|
_transfer(0xF4); // Phase1 Default value 0x8B
|
||||||
|
_transfer(0xF4); // Phase2 Default value 0x9C
|
||||||
|
_transfer(0xF4); // Phase3 Default value 0x96
|
||||||
|
_transfer(0x00); // Duration of phases, Default 0xF = 0b00 11 11 (40ms Phase 1/2, 10ms Phase 3)
|
||||||
|
}
|
||||||
|
|
||||||
_transferCommand(0x18); // Read built-in temperature sensor
|
_transferCommand(0x18); // Read built-in temperature sensor
|
||||||
_transfer(0x80);
|
_transfer(0x80);
|
||||||
_endTransfer();
|
_endTransfer();
|
||||||
|
|
||||||
|
setDarkBorder(darkBorder);
|
||||||
|
|
||||||
_setPartialRamArea(0, 0, WIDTH, HEIGHT);
|
_setPartialRamArea(0, 0, WIDTH, HEIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WatchyDisplay::_reset()
|
||||||
|
{
|
||||||
|
// Call default method if not configured the same way
|
||||||
|
if (_rst < 0 || !_pulldown_rst_mode) {
|
||||||
|
GxEPD2_EPD::_reset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
digitalWrite(_rst, LOW);
|
||||||
|
pinMode(_rst, OUTPUT);
|
||||||
|
delay(_reset_duration);
|
||||||
|
pinMode(_rst, INPUT_PULLUP);
|
||||||
|
// Tested calling _powerOn() inmediately, and works ok, no need to sleep
|
||||||
|
// delay(_reset_duration > 10 ? _reset_duration : 0);
|
||||||
|
_hibernating = false;
|
||||||
|
}
|
||||||
|
|
||||||
void WatchyDisplay::_Init_Full()
|
void WatchyDisplay::_Init_Full()
|
||||||
{
|
{
|
||||||
_InitDisplay();
|
_InitDisplay();
|
||||||
|
@ -395,6 +480,7 @@ void WatchyDisplay::_Update_Full()
|
||||||
_transferCommand(0x20);
|
_transferCommand(0x20);
|
||||||
_endTransfer();
|
_endTransfer();
|
||||||
_waitWhileBusy("_Update_Full", full_refresh_time);
|
_waitWhileBusy("_Update_Full", full_refresh_time);
|
||||||
|
displayFullInit = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WatchyDisplay::_Update_Part()
|
void WatchyDisplay::_Update_Part()
|
||||||
|
|
|
@ -34,7 +34,13 @@ class WatchyDisplay : public GxEPD2_EPD
|
||||||
static const uint16_t full_refresh_time = 2600; // ms, e.g. 2509602us
|
static const uint16_t full_refresh_time = 2600; // ms, e.g. 2509602us
|
||||||
static const uint16_t partial_refresh_time = 500; // ms, e.g. 457282us
|
static const uint16_t partial_refresh_time = 500; // ms, e.g. 457282us
|
||||||
// constructor
|
// constructor
|
||||||
WatchyDisplay(int16_t cs, int16_t dc, int16_t rst, int16_t busy);
|
WatchyDisplay();
|
||||||
|
void initWatchy();
|
||||||
|
void setDarkBorder(bool darkBorder);
|
||||||
|
void asyncPowerOn();
|
||||||
|
void _PowerOnAsync();
|
||||||
|
bool waitingPowerOn = false;
|
||||||
|
static void busyCallback(const void *);
|
||||||
// methods (virtual)
|
// methods (virtual)
|
||||||
// Support for Bitmaps (Sprites) to Controller Buffer and to Screen
|
// Support for Bitmaps (Sprites) to Controller Buffer and to Screen
|
||||||
void clearScreen(uint8_t value = 0xFF); // init controller memory and screen (default white)
|
void clearScreen(uint8_t value = 0xFF); // init controller memory and screen (default white)
|
||||||
|
@ -69,6 +75,8 @@ class WatchyDisplay : public GxEPD2_EPD
|
||||||
void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
|
void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0)
|
||||||
|
|
||||||
bool darkBorder = false; // adds a dark border outside the normal screen area
|
bool darkBorder = false; // adds a dark border outside the normal screen area
|
||||||
|
|
||||||
|
static constexpr bool reduceBoosterTime = true; // Saves ~200ms
|
||||||
private:
|
private:
|
||||||
void _writeScreenBuffer(uint8_t command, uint8_t value);
|
void _writeScreenBuffer(uint8_t command, uint8_t value);
|
||||||
void _writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
|
void _writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false);
|
||||||
|
@ -83,5 +91,7 @@ class WatchyDisplay : public GxEPD2_EPD
|
||||||
void _Update_Full();
|
void _Update_Full();
|
||||||
void _Update_Part();
|
void _Update_Part();
|
||||||
|
|
||||||
|
void _reset();
|
||||||
|
|
||||||
void _transferCommand(uint8_t command);
|
void _transferCommand(uint8_t command);
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
WatchyRTC Watchy::RTC;
|
WatchyRTC Watchy::RTC;
|
||||||
GxEPD2_BW<WatchyDisplay, WatchyDisplay::HEIGHT> Watchy::display(
|
GxEPD2_BW<WatchyDisplay, WatchyDisplay::HEIGHT> Watchy::display(
|
||||||
WatchyDisplay(DISPLAY_CS, DISPLAY_DC, DISPLAY_RES, DISPLAY_BUSY));
|
WatchyDisplay{});
|
||||||
|
|
||||||
RTC_DATA_ATTR int guiState;
|
RTC_DATA_ATTR int guiState;
|
||||||
RTC_DATA_ATTR int menuIndex;
|
RTC_DATA_ATTR int menuIndex;
|
||||||
|
@ -11,7 +11,6 @@ RTC_DATA_ATTR bool WIFI_CONFIGURED;
|
||||||
RTC_DATA_ATTR bool BLE_CONFIGURED;
|
RTC_DATA_ATTR bool BLE_CONFIGURED;
|
||||||
RTC_DATA_ATTR weatherData currentWeather;
|
RTC_DATA_ATTR weatherData currentWeather;
|
||||||
RTC_DATA_ATTR int weatherIntervalCounter = -1;
|
RTC_DATA_ATTR int weatherIntervalCounter = -1;
|
||||||
RTC_DATA_ATTR bool displayFullInit = true;
|
|
||||||
RTC_DATA_ATTR long gmtOffset = 0;
|
RTC_DATA_ATTR long gmtOffset = 0;
|
||||||
RTC_DATA_ATTR bool alreadyInMenu = true;
|
RTC_DATA_ATTR bool alreadyInMenu = true;
|
||||||
RTC_DATA_ATTR tmElements_t bootTime;
|
RTC_DATA_ATTR tmElements_t bootTime;
|
||||||
|
@ -22,11 +21,8 @@ void Watchy::init(String datetime) {
|
||||||
Wire.begin(SDA, SCL); // init i2c
|
Wire.begin(SDA, SCL); // init i2c
|
||||||
RTC.init();
|
RTC.init();
|
||||||
|
|
||||||
// Init the display here for all cases, if unused, it will do nothing
|
// Init the display since is almost sure we will use it
|
||||||
display.epd2.selectSPI(SPI, SPISettings(20000000, MSBFIRST, SPI_MODE0)); // Set SPI to 20Mhz (default is 4Mhz)
|
display.epd2.initWatchy();
|
||||||
display.init(0, displayFullInit, 10,
|
|
||||||
true); // 10ms by spec, and fast pulldown reset
|
|
||||||
display.epd2.setBusyCallback(displayBusyCallback);
|
|
||||||
|
|
||||||
switch (wakeup_reason) {
|
switch (wakeup_reason) {
|
||||||
case ESP_SLEEP_WAKEUP_EXT0: // RTC Alarm
|
case ESP_SLEEP_WAKEUP_EXT0: // RTC Alarm
|
||||||
|
@ -63,22 +59,14 @@ void Watchy::init(String datetime) {
|
||||||
RTC.read(bootTime);
|
RTC.read(bootTime);
|
||||||
showWatchFace(false); // full update on reset
|
showWatchFace(false); // full update on reset
|
||||||
vibMotor(75, 4);
|
vibMotor(75, 4);
|
||||||
|
// For some reason, seems to be enabled on first boot
|
||||||
|
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
deepSleep();
|
deepSleep();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Watchy::displayBusyCallback(const void *) {
|
|
||||||
gpio_wakeup_enable((gpio_num_t)DISPLAY_BUSY, GPIO_INTR_LOW_LEVEL);
|
|
||||||
esp_sleep_enable_gpio_wakeup();
|
|
||||||
esp_light_sleep_start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Watchy::deepSleep() {
|
void Watchy::deepSleep() {
|
||||||
display.hibernate();
|
display.hibernate();
|
||||||
if (displayFullInit) // For some reason, seems to be enabled on first boot
|
|
||||||
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
|
|
||||||
displayFullInit = false; // Notify not to init it again
|
|
||||||
RTC.clearAlarm(); // resets the alarm flag in the RTC
|
RTC.clearAlarm(); // resets the alarm flag in the RTC
|
||||||
|
|
||||||
// Set GPIOs 0-39 to input to avoid power leaking out
|
// Set GPIOs 0-39 to input to avoid power leaking out
|
||||||
|
@ -322,19 +310,18 @@ void Watchy::showAbout() {
|
||||||
display.setTextColor(GxEPD_WHITE);
|
display.setTextColor(GxEPD_WHITE);
|
||||||
display.setCursor(0, 20);
|
display.setCursor(0, 20);
|
||||||
|
|
||||||
//Library Version
|
|
||||||
display.print("LibVer: ");
|
display.print("LibVer: ");
|
||||||
display.println(WATCHY_LIB_VER);
|
display.println(WATCHY_LIB_VER);
|
||||||
//RTC Type
|
|
||||||
const char *RTC_HW[3] = {"<UNKNOWN>", "DS3231", "PCF8563"};
|
const char *RTC_HW[3] = {"<UNKNOWN>", "DS3231", "PCF8563"};
|
||||||
display.print("RTC: ");
|
display.print("RTC: ");
|
||||||
display.println(RTC_HW[RTC.rtcType]); // 0 = UNKNOWN, 1 = DS3231, 2 = PCF8563
|
display.println(RTC_HW[RTC.rtcType]); // 0 = UNKNOWN, 1 = DS3231, 2 = PCF8563
|
||||||
//Battery Level
|
|
||||||
display.print("Batt: ");
|
display.print("Batt: ");
|
||||||
float voltage = getBatteryVoltage();
|
float voltage = getBatteryVoltage();
|
||||||
display.print(voltage);
|
display.print(voltage);
|
||||||
display.println("V");
|
display.println("V");
|
||||||
//Uptime
|
|
||||||
display.print("Uptime: ");
|
display.print("Uptime: ");
|
||||||
RTC.read(currentTime);
|
RTC.read(currentTime);
|
||||||
time_t b = makeTime(bootTime);
|
time_t b = makeTime(bootTime);
|
||||||
|
@ -343,19 +330,22 @@ void Watchy::showAbout() {
|
||||||
//int seconds = (totalSeconds % 60);
|
//int seconds = (totalSeconds % 60);
|
||||||
int minutes = (totalSeconds % 3600) / 60;
|
int minutes = (totalSeconds % 3600) / 60;
|
||||||
int hours = (totalSeconds % 86400) / 3600;
|
int hours = (totalSeconds % 86400) / 3600;
|
||||||
int days = (totalSeconds % (86400 * 30)) / 86400;
|
int days = (totalSeconds % (86400 * 30)) / 86400;
|
||||||
display.print(days);
|
display.print(days);
|
||||||
display.print("d");
|
display.print("d");
|
||||||
display.print(hours);
|
display.print(hours);
|
||||||
display.print("h");
|
display.print("h");
|
||||||
display.print(minutes);
|
display.print(minutes);
|
||||||
display.println("m");
|
display.println("m");
|
||||||
//WiFi Info
|
if(WIFI_CONFIGURED){
|
||||||
display.print("IP: ");
|
display.print("SSID: ");
|
||||||
display.println(WiFi.localIP());
|
display.println(WiFi.SSID());
|
||||||
display.println("MAC Address:");
|
display.println("IP: ");
|
||||||
display.println(WiFi.macAddress());
|
display.println(WiFi.localIP());
|
||||||
|
WiFi.mode(WIFI_OFF);
|
||||||
|
}else{
|
||||||
|
display.println("WiFi Not Setup");
|
||||||
|
}
|
||||||
display.display(false); // full refresh
|
display.display(false); // full refresh
|
||||||
|
|
||||||
guiState = APP_STATE;
|
guiState = APP_STATE;
|
||||||
|
@ -613,6 +603,8 @@ void Watchy::showAccelerometer() {
|
||||||
|
|
||||||
void Watchy::showWatchFace(bool partialRefresh) {
|
void Watchy::showWatchFace(bool partialRefresh) {
|
||||||
display.setFullWindow();
|
display.setFullWindow();
|
||||||
|
// At this point it is sure we are going to update
|
||||||
|
display.epd2.asyncPowerOn();
|
||||||
drawWatchFace();
|
drawWatchFace();
|
||||||
display.display(partialRefresh); // partial refresh
|
display.display(partialRefresh); // partial refresh
|
||||||
guiState = WATCHFACE_STATE;
|
guiState = WATCHFACE_STATE;
|
||||||
|
@ -633,12 +625,12 @@ void Watchy::drawWatchFace() {
|
||||||
}
|
}
|
||||||
|
|
||||||
weatherData Watchy::getWeatherData() {
|
weatherData Watchy::getWeatherData() {
|
||||||
return getWeatherData(settings.cityID, settings.weatherUnit,
|
return _getWeatherData(settings.cityID, settings.lat, settings.lon,
|
||||||
settings.weatherLang, settings.weatherURL,
|
settings.weatherUnit, settings.weatherLang, settings.weatherURL,
|
||||||
settings.weatherAPIKey, settings.weatherUpdateInterval);
|
settings.weatherAPIKey, settings.weatherUpdateInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
weatherData Watchy::getWeatherData(String cityID, String units, String lang,
|
weatherData Watchy::_getWeatherData(String cityID, String lat, String lon, String units, String lang,
|
||||||
String url, String apiKey,
|
String url, String apiKey,
|
||||||
uint8_t updateInterval) {
|
uint8_t updateInterval) {
|
||||||
currentWeather.isMetric = units == String("metric");
|
currentWeather.isMetric = units == String("metric");
|
||||||
|
@ -651,9 +643,16 @@ weatherData Watchy::getWeatherData(String cityID, String units, String lang,
|
||||||
if (connectWiFi()) {
|
if (connectWiFi()) {
|
||||||
HTTPClient http; // Use Weather API for live data if WiFi is connected
|
HTTPClient http; // Use Weather API for live data if WiFi is connected
|
||||||
http.setConnectTimeout(3000); // 3 second max timeout
|
http.setConnectTimeout(3000); // 3 second max timeout
|
||||||
String weatherQueryURL = url + cityID + String("&units=") + units +
|
String weatherQueryURL = url;
|
||||||
String("&lang=") + lang + String("&appid=") +
|
if(cityID != ""){
|
||||||
apiKey;
|
weatherQueryURL.replace("{cityID}", cityID);
|
||||||
|
}else{
|
||||||
|
weatherQueryURL.replace("{lat}", lat);
|
||||||
|
weatherQueryURL.replace("{lon}", lon);
|
||||||
|
}
|
||||||
|
weatherQueryURL.replace("{units}", units);
|
||||||
|
weatherQueryURL.replace("{lang}", lang);
|
||||||
|
weatherQueryURL.replace("{apiKey}", apiKey);
|
||||||
http.begin(weatherQueryURL.c_str());
|
http.begin(weatherQueryURL.c_str());
|
||||||
int httpResponseCode = http.GET();
|
int httpResponseCode = http.GET();
|
||||||
if (httpResponseCode == 200) {
|
if (httpResponseCode == 200) {
|
||||||
|
@ -663,24 +662,27 @@ weatherData Watchy::getWeatherData(String cityID, String units, String lang,
|
||||||
currentWeather.weatherConditionCode =
|
currentWeather.weatherConditionCode =
|
||||||
int(responseObject["weather"][0]["id"]);
|
int(responseObject["weather"][0]["id"]);
|
||||||
currentWeather.weatherDescription =
|
currentWeather.weatherDescription =
|
||||||
JSONVar::stringify(responseObject["weather"][0]["main"]);
|
JSONVar::stringify(responseObject["weather"][0]["main"]);
|
||||||
currentWeather.external = true;
|
currentWeather.external = true;
|
||||||
// sync NTP during weather API call and use timezone of city
|
breakTime((time_t)(int)responseObject["sys"]["sunrise"], currentWeather.sunrise);
|
||||||
|
breakTime((time_t)(int)responseObject["sys"]["sunset"], currentWeather.sunset);
|
||||||
|
// sync NTP during weather API call and use timezone of lat & lon
|
||||||
gmtOffset = int(responseObject["timezone"]);
|
gmtOffset = int(responseObject["timezone"]);
|
||||||
syncNTP(gmtOffset);
|
syncNTP(gmtOffset);
|
||||||
} else {
|
} else {
|
||||||
// http error, use internal temperature sensor
|
// http error
|
||||||
currentWeather.temperature = currentWeather.isMetric ? (uint8_t)sensor.readTemperature() : (uint8_t)sensor.readTemperatureF();
|
|
||||||
currentWeather.weatherConditionCode = -1;
|
|
||||||
currentWeather.external = false;
|
|
||||||
}
|
}
|
||||||
http.end();
|
http.end();
|
||||||
// turn off radios
|
// turn off radios
|
||||||
WiFi.mode(WIFI_OFF);
|
WiFi.mode(WIFI_OFF);
|
||||||
btStop();
|
btStop();
|
||||||
} else { // No WiFi, use internal temperature sensor
|
} else { // No WiFi, use internal temperature sensor
|
||||||
currentWeather.temperature = currentWeather.isMetric ? (uint8_t)sensor.readTemperature() : (uint8_t)sensor.readTemperatureF();
|
uint8_t temperature = sensor.readTemperature(); // celsius
|
||||||
currentWeather.weatherConditionCode = -1;
|
if (!currentWeather.isMetric) {
|
||||||
|
temperature = temperature * 9. / 5. + 32.; // fahrenheit
|
||||||
|
}
|
||||||
|
currentWeather.temperature = temperature;
|
||||||
|
currentWeather.weatherConditionCode = 800;
|
||||||
currentWeather.external = false;
|
currentWeather.external = false;
|
||||||
}
|
}
|
||||||
weatherIntervalCounter = 0;
|
weatherIntervalCounter = 0;
|
||||||
|
@ -840,8 +842,8 @@ void Watchy::setupWifi() {
|
||||||
// turn off radios
|
// turn off radios
|
||||||
WiFi.mode(WIFI_OFF);
|
WiFi.mode(WIFI_OFF);
|
||||||
btStop();
|
btStop();
|
||||||
display.epd2.setBusyCallback(displayBusyCallback); // enable lightsleep on
|
// enable lightsleep on busy
|
||||||
// busy
|
display.epd2.setBusyCallback(WatchyDisplay::busyCallback);
|
||||||
guiState = APP_STATE;
|
guiState = APP_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,11 +23,15 @@ typedef struct weatherData {
|
||||||
bool isMetric;
|
bool isMetric;
|
||||||
String weatherDescription;
|
String weatherDescription;
|
||||||
bool external;
|
bool external;
|
||||||
|
tmElements_t sunrise;
|
||||||
|
tmElements_t sunset;
|
||||||
} weatherData;
|
} weatherData;
|
||||||
|
|
||||||
typedef struct watchySettings {
|
typedef struct watchySettings {
|
||||||
// Weather Settings
|
// Weather Settings
|
||||||
String cityID;
|
String cityID;
|
||||||
|
String lat;
|
||||||
|
String lon;
|
||||||
String weatherAPIKey;
|
String weatherAPIKey;
|
||||||
String weatherURL;
|
String weatherURL;
|
||||||
String weatherUnit;
|
String weatherUnit;
|
||||||
|
@ -51,7 +55,6 @@ public:
|
||||||
explicit Watchy(const watchySettings &s) : settings(s) {} // constructor
|
explicit Watchy(const watchySettings &s) : settings(s) {} // constructor
|
||||||
void init(String datetime = "");
|
void init(String datetime = "");
|
||||||
void deepSleep();
|
void deepSleep();
|
||||||
static void displayBusyCallback(const void *);
|
|
||||||
float getBatteryVoltage();
|
float getBatteryVoltage();
|
||||||
void vibMotor(uint8_t intervalMs = 100, uint8_t length = 20);
|
void vibMotor(uint8_t intervalMs = 100, uint8_t length = 20);
|
||||||
|
|
||||||
|
@ -70,8 +73,6 @@ public:
|
||||||
void setupWifi();
|
void setupWifi();
|
||||||
bool connectWiFi();
|
bool connectWiFi();
|
||||||
weatherData getWeatherData();
|
weatherData getWeatherData();
|
||||||
weatherData getWeatherData(String cityID, String units, String lang,
|
|
||||||
String url, String apiKey, uint8_t updateInterval);
|
|
||||||
void updateFWBegin();
|
void updateFWBegin();
|
||||||
|
|
||||||
void showWatchFace(bool partialRefresh);
|
void showWatchFace(bool partialRefresh);
|
||||||
|
@ -85,6 +86,8 @@ private:
|
||||||
uint16_t len);
|
uint16_t len);
|
||||||
static uint16_t _writeRegister(uint8_t address, uint8_t reg, uint8_t *data,
|
static uint16_t _writeRegister(uint8_t address, uint8_t reg, uint8_t *data,
|
||||||
uint16_t len);
|
uint16_t len);
|
||||||
|
weatherData _getWeatherData(String cityID, String lat, String lon, String units, String lang,
|
||||||
|
String url, String apiKey, uint8_t updateInterval);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern RTC_DATA_ATTR int guiState;
|
extern RTC_DATA_ATTR int guiState;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#define CONFIG_H
|
#define CONFIG_H
|
||||||
|
|
||||||
// Versioning
|
// Versioning
|
||||||
#define WATCHY_LIB_VER "1.4.8"
|
#define WATCHY_LIB_VER "1.4.9"
|
||||||
|
|
||||||
//pins
|
//pins
|
||||||
#if !defined(ARDUINO_WATCHY_V10) && !defined(ARDUINO_WATCHY_V15) && !defined(ARDUINO_WATCHY_V20)
|
#if !defined(ARDUINO_WATCHY_V10) && !defined(ARDUINO_WATCHY_V15) && !defined(ARDUINO_WATCHY_V20)
|
||||||
|
|
Loading…
Reference in New Issue