#include //include the Watchy library #include "settings.h" // stupid static constants #include "DIN_1451_Engschrift_Regular64pt7b.h" #include "DIN_1451_Engschrift_Regular12pt7b.h" #include "heavitas12pt7b.h" // RTC_DATA_ATTR weatherData currentWeather; class WatchFace : public Watchy { //inherit and extend Watchy class using Watchy::Watchy; public: //! Change these if you want light background, dark text uint16_t bg = GxEPD_BLACK; uint16_t fg = GxEPD_WHITE; void drawWatchFace() { //override this method to customize how the watch face looks int16_t x1; int16_t y1; uint16_t w; uint16_t h; String textstring; int16_t lasty; // Flood fill with background // display.fillScreen(bg); // display.fillRoundRect(2,2,196,196,8,bg); // display.fillRoundRect(6,6,188,188,5,fg); display.setFont(&DIN_1451_Engschrift_Regular64pt7b); display.setTextColor(fg); display.setTextWrap(false); drawTime( 183, 92 ); drawBattery( 8, 4 ); display.setFont(&DIN_1451_Engschrift_Regular12pt7b); display.setTextColor(fg); drawSteps( 8, 20 ); drawDate( 8, 140 ); display.setFont(&DIN_1451_Engschrift_Regular12pt7b); display.setTextColor(fg); display.setTextColor(fg); lasty = 120; // weather things weatherData currentWeather = getWeatherData(settings.cityID, settings.weatherUnit, settings.weatherLang, settings.weatherURL, settings.weatherAPIKey, settings.weatherUpdateInterval); textstring = ""; textstring += currentWeather.weatherDescription; display.getTextBounds(textstring, 0, 0, &x1, &y1, &w, &h); display.setCursor(16, lasty); display.print(textstring); lasty += -20; // draw temperature textstring = currentWeather.temperature; if( currentWeather.isMetric ) { textstring += "~ C"; // ~ will be rendered as º } else { textstring += "~ F"; // ~ will be rendered as º } display.getTextBounds(textstring, 0, 0, &x1, &y1, &w, &h); display.setCursor(16, lasty); display.print(textstring); } private: // Draw step counter and footrpints icon // x and y are the top corner void drawSteps(uint8_t x, uint8_t y) { int16_t x1; int16_t y1; uint16_t w; uint16_t h; String textstring; //reset step counter at midnight if(currentTime.Hour == 00 && currentTime.Minute == 00) { sensor.resetStepCounter(); } // Put the feet icon down display.drawBitmap(x, y, png_feet, 32, 32, fg); textstring = "000000"; // prototype 6-digit number display.getTextBounds(textstring, 0, 0, &x1, &y1, &w, &h); // Now we know how wide a 6-digit number would be. We want to right-justify // our number. So figure out how wide 6 digits are, and subtract how wide // our current number is. x = w; //hang on to width textstring = String(sensor.getCounter()); display.getTextBounds(textstring, 0, 0, &x1, &y1, &w, &h); display.setCursor( x + 42 - w, y + 32 ); // add 32 because of icon, right justify display.print(textstring); } //! Draw the battery symbol with its x and y coordinates starting at x,y #define BATTWIDTH 26 void drawBattery( uint8_t x, uint8_t y ) { float batt; // draw battery display.fillRoundRect( x, y, 34, 12, 4, fg ); // overall frame display.fillRoundRect( x+34, y+2, 4, 8, 2, fg ); // nub, to look like battery display.fillRoundRect( x+2, y+2, 30, 8, 3, bg ); // area for battery charge // According to 7_SEG, 3.8 is the voltage floor. Below that is rendered as // flat battery on that watch face. batt = (getBatteryVoltage()-3.3)/0.9; if (batt > 0) { display.fillRoundRect( x+4, y+4, (BATTWIDTH*batt), 4, 2, fg ); // actual charge } } void drawTemperature() { } //! Draw time on the right side of the face. /** * Note that x is the RIGHT margin, not the left. The * numbers are right justified. The y is the top of the * numbers. **/ void drawTime( uint8_t x, uint8_t y ) { int16_t x1; int16_t y1; uint16_t w; uint16_t h; String textstring; // draw hours with leading 0 if( currentTime.Hour < 10 ) { textstring = "0"; } else { textstring = ""; } textstring += currentTime.Hour; display.getTextBounds(textstring, 0, 0, &x1, &y1, &w, &h); display.setCursor( x-w, y ); display.print(textstring); y = y + h + 8; if( currentTime.Minute < 10 ) { textstring = "0"; } else { textstring = ""; } textstring += currentTime.Minute; display.setTextColor(fg); display.getTextBounds(textstring, 0, 0, &x1, &y1, &w, &h); display.setCursor( x-w, y ); display.print(textstring); } #define BOXX (70) #define BOXY (50) void drawDate( uint8_t x, uint8_t y ) { int16_t x1; int16_t y1; uint16_t w; uint16_t h; uint8_t width; uint8_t newx; uint8_t newy; String textstring; // draw box display.fillRoundRect( x, y, BOXX, BOXY, 2, fg ); // overall frame // draw short day name inverted display.setFont(&Heavitas12pt7b); display.setTextColor(bg); textstring = currentTime.Day; display.getTextBounds(textstring, 0, 0, &x1, &y1, &w, &h); h = h/2; // this font seems really tall. // center text in box newx = x + ((BOXX-w) / 2 ); display.setCursor( newx, y + 20 ); display.print(textstring); // draw day textstring = dayShortStr(currentTime.Wday); textstring.toUpperCase(); display.setFont(&Heavitas12pt7b); display.setTextColor(bg); display.getTextBounds(textstring, 0, 0, &x1, &y1, &w, &h); h = h/2; // this font seems really tall. // Start at bottom of box, go up height, plus a small margin newy = y + BOXY - h; // Near bottom of box newx = x + ((BOXX-w) / 2 ); display.setCursor( newx, newy ); display.print(textstring); } }; WatchFace w(settings); //instantiate your watchface void setup() { // Weather settings are in settings.h now w.init(); //call init in setup } void loop() { // this should never run, Watchy deep sleeps after init(); }