initial commit playlist feature with two faces #16
parent
64747c032b
commit
fd43996364
@ -0,0 +1,25 @@
|
||||
#ifndef DATETIME_H
|
||||
#define DATETIME_H
|
||||
|
||||
#include <arduino.h>
|
||||
|
||||
// TODO
|
||||
struct time_struct
|
||||
{
|
||||
char wday[4];
|
||||
char month[4];
|
||||
uint8_t month_num;
|
||||
uint8_t mday;
|
||||
uint8_t mil_hour;
|
||||
uint8_t hour;
|
||||
uint8_t min;
|
||||
uint8_t sec;
|
||||
uint8_t day_offset; // 1st day of the month offset, Monday = 0
|
||||
int year;
|
||||
};
|
||||
|
||||
extern RTC_DATA_ATTR struct time_struct now;
|
||||
|
||||
void setupDateTime();
|
||||
|
||||
#endif
|
@ -0,0 +1,8 @@
|
||||
#ifndef FACE_CALENDAR_H
|
||||
#define FACE_CALENDAR_H
|
||||
|
||||
|
||||
void setupFaceCalendar();
|
||||
void loopFaceCalendar();
|
||||
|
||||
#endif
|
@ -0,0 +1,8 @@
|
||||
#ifndef FACE_WEATHER_H
|
||||
#define FACE_WEATHER_H
|
||||
|
||||
|
||||
void setupFaceWeather();
|
||||
void loopFaceWeather();
|
||||
|
||||
#endif
|
@ -0,0 +1,82 @@
|
||||
#ifndef FACE_WEATHER_ICONS_H
|
||||
#define FACE_WEATHER_ICONS_H
|
||||
|
||||
#include "Arduino.h";
|
||||
|
||||
|
||||
const uint8_t DejaVu_Sans_Bold_11Bitmaps[] PROGMEM = {
|
||||
|
||||
};
|
||||
|
||||
// use: https://github.com/andrei7c4/weatherdisplay/blob/f20317213257c6b7ca471a9bd3dc8963af73d339/app/src/icons.c
|
||||
|
||||
extern const unsigned int icon256_01d[];
|
||||
extern const unsigned int icon256_01n[];
|
||||
extern const unsigned int icon256_02d[];
|
||||
extern const unsigned int icon256_02n[];
|
||||
extern const unsigned int icon256_03d[];
|
||||
extern const unsigned int icon256_04d[];
|
||||
extern const unsigned int icon256_09d[];
|
||||
extern const unsigned int icon256_10d[];
|
||||
extern const unsigned int icon256_11d[];
|
||||
extern const unsigned int icon256_13d[];
|
||||
extern const unsigned int icon256_50d[];
|
||||
extern const unsigned int icon256_50n[];
|
||||
|
||||
extern const unsigned int icon192_01d[];
|
||||
extern const unsigned int icon192_01n[];
|
||||
extern const unsigned int icon192_02d[];
|
||||
extern const unsigned int icon192_02n[];
|
||||
extern const unsigned int icon192_03d[];
|
||||
extern const unsigned int icon192_04d[];
|
||||
extern const unsigned int icon192_09d[];
|
||||
extern const unsigned int icon192_10d[];
|
||||
extern const unsigned int icon192_11d[];
|
||||
extern const unsigned int icon192_13d[];
|
||||
extern const unsigned int icon192_50d[];
|
||||
extern const unsigned int icon192_50n[];
|
||||
|
||||
extern const unsigned int icon128_01d[];
|
||||
extern const unsigned int icon128_01n[];
|
||||
extern const unsigned int icon128_02d[];
|
||||
extern const unsigned int icon128_02n[];
|
||||
extern const unsigned int icon128_03d[];
|
||||
extern const unsigned int icon128_04d[];
|
||||
extern const unsigned int icon128_09d[];
|
||||
extern const unsigned int icon128_10d[];
|
||||
extern const unsigned int icon128_11d[];
|
||||
extern const unsigned int icon128_13d[];
|
||||
extern const unsigned int icon128_50d[];
|
||||
extern const unsigned int icon128_50n[];
|
||||
|
||||
extern const unsigned int icon96_01d[];
|
||||
extern const unsigned int icon96_01n[];
|
||||
extern const unsigned int icon96_02d[];
|
||||
extern const unsigned int icon96_02n[];
|
||||
extern const unsigned int icon96_03d[];
|
||||
extern const unsigned int icon96_04d[];
|
||||
extern const unsigned int icon96_09d[];
|
||||
extern const unsigned int icon96_10d[];
|
||||
extern const unsigned int icon96_11d[];
|
||||
extern const unsigned int icon96_13d[];
|
||||
extern const unsigned int icon96_50d[];
|
||||
extern const unsigned int icon96_50n[];
|
||||
|
||||
extern const unsigned int icon64_01d[];
|
||||
extern const unsigned int icon64_01n[];
|
||||
extern const unsigned int icon64_02d[];
|
||||
extern const unsigned int icon64_02n[];
|
||||
extern const unsigned int icon64_03d[];
|
||||
extern const unsigned int icon64_04d[];
|
||||
extern const unsigned int icon64_09d[];
|
||||
extern const unsigned int icon64_10d[];
|
||||
extern const unsigned int icon64_11d[];
|
||||
extern const unsigned int icon64_13d[];
|
||||
extern const unsigned int icon64_50d[];
|
||||
extern const unsigned int icon64_50n[];
|
||||
|
||||
extern const unsigned int indoorTempIcon40[];
|
||||
extern const unsigned int indoorTempIcon64[];
|
||||
|
||||
|
||||
#endif /* INCLUDE_ICONS_H_ */
|
@ -0,0 +1,7 @@
|
||||
#ifndef PLAYLIST_H
|
||||
#define PLAYLIST_H
|
||||
|
||||
void setupPlaylist();
|
||||
void loopPlaylist();
|
||||
|
||||
#endif
|
@ -0,0 +1,102 @@
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include "datetime.h"
|
||||
|
||||
RTC_DATA_ATTR struct time_struct now; // keep track of time
|
||||
//String time_zone_base = "UTC";
|
||||
const char *ntpServer = "pool.ntp.org";
|
||||
const long gmtOffset_sec = 3600;
|
||||
const int daylightOffset_sec = 3600;
|
||||
|
||||
void printLocalTime();
|
||||
int8_t get_date_dtls(String time_zone);
|
||||
|
||||
|
||||
// TODO refactore complete file
|
||||
|
||||
void setupDateTime()
|
||||
{
|
||||
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
|
||||
printLocalTime();
|
||||
get_date_dtls("");
|
||||
}
|
||||
|
||||
void printLocalTime()
|
||||
{
|
||||
struct tm timeinfo;
|
||||
if (!getLocalTime(&timeinfo))
|
||||
{
|
||||
Serial.println("Failed to obtain time");
|
||||
return;
|
||||
}
|
||||
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
|
||||
}
|
||||
|
||||
// Time APIs
|
||||
int8_t get_date_dtls(String time_zone)
|
||||
{
|
||||
//String time_zone_string = time_zone_base + time_zone;
|
||||
//setenv("TZ", time_zone_string.c_str(), 1);
|
||||
//setenv("TZ", "CET-1CEST,M3.5.0/02,M10.5.0/03", 1);
|
||||
|
||||
struct tm timeinfo;
|
||||
if (!getLocalTime(&timeinfo))
|
||||
{
|
||||
Serial.println("Failed to obtain time");
|
||||
return -1;
|
||||
}
|
||||
time_t epoch = mktime(&timeinfo);
|
||||
|
||||
sscanf(ctime(&epoch), "%s %s %hhd %hhd:%hhd:%hhd %d", now.wday, now.month, &now.mday, &now.mil_hour, &now.min, &now.sec, &now.year);
|
||||
|
||||
now.month_num = timeinfo.tm_mon + 1;
|
||||
// gives offset of first day of the month with respect to Monday
|
||||
//https://www.tondering.dk/claus/cal/chrweek.php#calcdow
|
||||
// 1=Monday to 7=Sunday
|
||||
uint8_t a = (14 - now.month_num) / 12;
|
||||
uint16_t y = now.year - a;
|
||||
uint16_t m = now.month_num + (12 * a) - 2;
|
||||
// change +7 at the end to whatever first day of week you want.
|
||||
// But change the header '"Mon Tue Wed Thu Fri Sat Sun"' as well above.
|
||||
// currently +7 => Monday
|
||||
// +1 => Sunday
|
||||
now.day_offset = (((1 + y + (y / 4) - (y / 100) + (y / 400) + ((31 * m) / 12)) % 7) + 7) % 7;
|
||||
|
||||
// convert to 12 hour
|
||||
if (now.mil_hour > 12)
|
||||
{
|
||||
now.hour = now.mil_hour - 12;
|
||||
}
|
||||
else
|
||||
{
|
||||
now.hour = now.mil_hour;
|
||||
}
|
||||
|
||||
Serial.printf("Time is %d %d:%d:%d on %s on the %d/%d/%d . It is the month of %s. day_offset: %d\n", now.mil_hour, now.hour, now.min, now.sec, now.wday, now.mday, now.month_num, now.year, now.month, now.day_offset);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
int8_t set_time()
|
||||
{
|
||||
|
||||
struct tm t;
|
||||
t.tm_year = 2020 - 1900;
|
||||
t.tm_mon = 1 - 1; // Month, 1 - jan to 12 - dec
|
||||
t.tm_mday = 27; // Day of the month
|
||||
t.tm_hour = 9;
|
||||
t.tm_min = 57;
|
||||
t.tm_sec = 0;
|
||||
t.tm_isdst = -1; // Is DST on? 1 = yes, 0 = no, -1 = unknown
|
||||
|
||||
time_t epoch;
|
||||
epoch = mktime(&t);
|
||||
|
||||
struct timeval now;
|
||||
now.tv_sec = epoch;
|
||||
now.tv_usec = 0;
|
||||
|
||||
struct timezone tz = {-330, 0};
|
||||
return settimeofday(&now, &tz);
|
||||
}
|
||||
*/
|
@ -0,0 +1,155 @@
|
||||
#include "faceCalendar.h"
|
||||
#include "display.h"
|
||||
#include "datetime.h"
|
||||
|
||||
void display_calender();
|
||||
void display_lines();
|
||||
void display_time();
|
||||
|
||||
void setupFaceCalendar()
|
||||
{
|
||||
Serial.println("setupFaceWeather");
|
||||
|
||||
setupDateTime();
|
||||
|
||||
|
||||
display.setRotation(0);
|
||||
display.setFullWindow();
|
||||
display.firstPage();
|
||||
display.fillScreen(GxEPD_WHITE);
|
||||
|
||||
// draw...
|
||||
display_lines();
|
||||
display_calender();
|
||||
display_time();
|
||||
|
||||
Serial.println("displayFlush");
|
||||
display.nextPage();
|
||||
|
||||
|
||||
// https://raw.githubusercontent.com/rgujju/paperdink/master/Images/full.jpg
|
||||
// https://github.com/rgujju/paperdink/blob/master/Software/paperd.ink/GUI.cpp
|
||||
// display_weather
|
||||
}
|
||||
|
||||
void loopFaceCalendar()
|
||||
{
|
||||
}
|
||||
|
||||
void display_lines()
|
||||
{
|
||||
// black area bottom
|
||||
display.fillRect(0, (display.height() / 3) * 2, display.width(), (display.height() / 3), GxEPD_BLACK);
|
||||
|
||||
// vertical lines
|
||||
display.fillRect((display.width() / 4), 0, 5, (display.height() / 3) * 2, GxEPD_BLACK);
|
||||
display.fillRect((display.width() / 4), (display.height() / 3) * 2, 5, (display.height() / 3), GxEPD_WHITE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo make it better :)
|
||||
*/
|
||||
void display_calender()
|
||||
{
|
||||
int16_t x1, y1;
|
||||
uint16_t w, h;
|
||||
display.setFont(&FreeMonoBold9pt7b);
|
||||
display.setTextSize(1);
|
||||
display.setTextColor(GxEPD_BLACK);
|
||||
int16_t calender_base_y = 40;
|
||||
int16_t calender_base_x = 120;
|
||||
display.setCursor(calender_base_x, calender_base_y);
|
||||
display.println("Mon Tue Wed Thu Fri Sat Sun");
|
||||
display.getTextBounds("Mon Tue Wed Thu Fri Sat Sun", calender_base_x, calender_base_y, &x1, &y1, &w, &h);
|
||||
uint8_t num_offset, print_valid = 0;
|
||||
uint8_t day = 1;
|
||||
for (uint8_t j = 0; j <= 5; j++)
|
||||
{
|
||||
for (uint8_t i = 1; i <= 7 && day <= 31; i++)
|
||||
{
|
||||
// you can hack around with this value to align your text properly based on what font, font size etc you are using
|
||||
num_offset = 21; // 21 is what works for me for the first 2 columns
|
||||
if (i >= 3 && i <= 7)
|
||||
{
|
||||
num_offset = 17; // then i need to reduce to 17
|
||||
}
|
||||
if (j == 0 && i == now.day_offset)
|
||||
{
|
||||
// start from the offset in the month, ie which day does 1st of the month lie on
|
||||
print_valid = 1;
|
||||
}
|
||||
if (print_valid)
|
||||
{
|
||||
display.setCursor(calender_base_x + (i * (w / 7)) - num_offset, calender_base_y + ((j + 1) * h) + ((j + 1) * 7));
|
||||
if (day == now.mday)
|
||||
{
|
||||
char str[3];
|
||||
sprintf(str, "%d", day);
|
||||
int16_t x2, y2;
|
||||
uint16_t w2, h2;
|
||||
display.getTextBounds(str, calender_base_x + (i * (w / 7)) - num_offset, calender_base_y + ((j + 1) * h) + ((j + 1) * 7), &x2, &y2, &w2, &h2);
|
||||
display.fillRect(x2 - 4, y2 - 4, w2 + 8, h2 + 8, GxEPD_BLACK);
|
||||
display.setTextColor(GxEPD_WHITE);
|
||||
}
|
||||
else
|
||||
{
|
||||
display.setTextColor(GxEPD_BLACK);
|
||||
}
|
||||
// once the offset is reached, start incrementing
|
||||
display.println(day);
|
||||
day += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// display day
|
||||
display.setTextColor(GxEPD_WHITE);
|
||||
display.setFont(&FreeMonoBold9pt7b); // LARGE_FONT
|
||||
display.setTextSize(1);
|
||||
display.setCursor(33, 250);
|
||||
display.println(now.mday);
|
||||
|
||||
// display month
|
||||
display.setTextColor(GxEPD_WHITE);
|
||||
display.setFont(&FreeMonoBold9pt7b); // MED_FONT
|
||||
display.setTextSize(2);
|
||||
display.setCursor(30, 290);
|
||||
display.println(now.month);
|
||||
}
|
||||
|
||||
void display_time()
|
||||
{
|
||||
int16_t x1, y1;
|
||||
uint16_t w, h;
|
||||
|
||||
//display time
|
||||
display.setFont(&FreeMonoBold9pt7b); // LARGE_FONT
|
||||
display.setTextSize(1);
|
||||
display.setTextColor(GxEPD_BLACK);
|
||||
int16_t time_base_y = 60;
|
||||
int16_t time_base_x = 25;
|
||||
display.getTextBounds("03", time_base_x, time_base_y, &x1, &y1, &w, &h); // 03 is arbitrary text to get the height and width
|
||||
display.fillRect(time_base_x - 10, time_base_y - h - 10, w + 15, time_base_y + h + 10, GxEPD_WHITE);
|
||||
|
||||
display.setCursor(time_base_x, time_base_y);
|
||||
if (now.hour < 10)
|
||||
{
|
||||
display.print("0");
|
||||
display.print(now.hour);
|
||||
}
|
||||
else
|
||||
{
|
||||
display.println(now.hour);
|
||||
}
|
||||
|
||||
display.setCursor(time_base_x, time_base_y + h + 10);
|
||||
if (now.min < 10)
|
||||
{
|
||||
display.print("0");
|
||||
display.print(now.min);
|
||||
}
|
||||
else
|
||||
{
|
||||
display.println(now.min);
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
#include "faceWeather.h"
|
||||
#include <ArduinoJson.h>
|
||||
#include <HTTPClient.h>
|
||||
|
||||
|
||||
void setupFaceWeather()
|
||||
{
|
||||
// https://github.com/andrei7c4/weatherdisplay
|
||||
}
|
||||
|
||||
|
||||
void loopFaceWeather()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
bool loadWeatherData(const char *type)
|
||||
{
|
||||
HTTPClient http;
|
||||
String url = "http://api.openweathermap.org/data/2.5/forecast?"; // weather | forecast
|
||||
url += "id=2766824";
|
||||
url += "&lang=de";
|
||||
url += "&cnt=3";
|
||||
url += "&units=metric";
|
||||
url += "&APPID=883b3c87223430d6f3a399645f8ba12b";
|
||||
// "/data/2.5/" + RequestType + "?q=" + City + "," + Country + "&APPID=" + apikey + "&mode=json&units=" + units + "&lang=" + Language;
|
||||
|
||||
//http.begin(client, server, 80, uri);
|
||||
|
||||
http.begin(url);
|
||||
int httpCode = http.GET();
|
||||
if (httpCode != HTTP_CODE_OK)
|
||||
{
|
||||
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode != HTTP_CODE_OK && httpCode).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO read...
|
||||
|
||||
DynamicJsonDocument doc(1024 * 35);
|
||||
DeserializationError error = deserializeJson(doc, http.getStream());
|
||||
if (error)
|
||||
{
|
||||
Serial.print(F("deserializeJson() failed with code "));
|
||||
Serial.println(error.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
JsonObject root = doc.as<JsonObject>();
|
||||
}
|
||||
|
||||
http.end();
|
||||
}
|
||||
|
||||
*/
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,37 @@
|
||||
#include "playlist.h"
|
||||
#include "settings.h"
|
||||
#include "faceWeather.h"
|
||||
#include "faceCalendar.h"
|
||||
|
||||
|
||||
unsigned long lastSwitch = 0;
|
||||
int64_t timer;
|
||||
|
||||
void setupPlaylist()
|
||||
{
|
||||
Serial.println("setupPlaylist...");
|
||||
lastSwitch = millis();
|
||||
timer = NVS.getInt("playlist.timer") * 1000;
|
||||
if (timer < 30000)
|
||||
{
|
||||
timer = 30000;
|
||||
}
|
||||
|
||||
|
||||
// setup faces
|
||||
//setupFaceWeather();
|
||||
setupFaceCalendar();
|
||||
}
|
||||
|
||||
|
||||
void loopPlaylist()
|
||||
{
|
||||
// return millis() - bootTime >= 60000;
|
||||
if (millis() - lastSwitch >= timer)
|
||||
{
|
||||
lastSwitch = millis();
|
||||
Serial.println("switch face");
|
||||
|
||||
// TODO
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue