auto switch done, calendar & weather nearly done #16

pull/1/head
Thomas Ballmann 4 years ago
parent 0f29a82542
commit 332f3a7d6c

@ -16,6 +16,6 @@ struct datetime_struct : tm
extern RTC_DATA_ATTR struct datetime_struct now;
void setupDateTime();
bool setupDateTime();
#endif

File diff suppressed because it is too large Load Diff

@ -1,7 +1,14 @@
#ifndef PLAYLIST_H
#define PLAYLIST_H
#include <WString.h>
void setupPlaylist();
void loopPlaylist();
void PlaylistNextFace();
String PlaylistGetCurrentFace();
int32_t PlaylistGetRemainingTimeMs();
void PlaylistResetTimer();
#endif

@ -0,0 +1,8 @@
#ifndef TOOLS_H
#define TOOLS_H
#define EVERY_N_SECONDS(t) for (static uint16_t _lasttime; \
(uint16_t)((uint16_t)millis() - _lasttime) >= (t * 1000); \
_lasttime += (t * 1000))
#endif

@ -1,10 +1,11 @@
#include "app.h"
#include "SPIFFS.h"
#include "ESPAsyncWebServer.h"
#include "AsyncJson.h"
//#include "AsyncJson.h"
#include "ArduinoJson.h"
#include "settings.h"
#include "device.h"
#include "playlist.h"
AsyncWebServer server(80);
@ -56,7 +57,10 @@ void setupApp()
doc["device"]["heap"] = ESP.getFreeHeap();
doc["device"]["bootCycle"] = deviceGetBootCount();
doc["device"]["screen"]["width"] = 640;
doc["device"]["height"]["screen"] = 384;
doc["device"]["screen"]["height"] = 384;
doc["playlist"]["current"] = PlaylistGetCurrentFace();
doc["playlist"]["remaining"] = PlaylistGetRemainingTimeMs() / 1000;
JsonArray capability = doc.createNestedArray("capability");
capability.add("png");

@ -28,13 +28,13 @@ int getNumberOfDays(int month, int year)
return 30;
}
void setupDateTime()
bool setupDateTime()
{
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
if (!getLocalTime(&now))
{
Serial.println("Failed to obtain time");
return;
return false;
}
Serial.println(&now, "%A, %B %d %Y %H:%M:%S");
@ -48,4 +48,6 @@ void setupDateTime()
uint16_t y = (now.tm_year + 1900) - a;
uint16_t m = now.month_num + (12 * a) - 2;
now.day_offset = (((1 + y + (y / 4) - (y / 100) + (y / 400) + ((31 * m) / 12)) % 7) + 7) % 7;
return true;
}

@ -3,16 +3,19 @@
#include "datetime.h"
#include "SPIFFS.h"
#include "pngle.h"
#include "tools.h"
#include <Fonts/FreeMono12pt7b.h> // weekday - month year
#include <Fonts/FreeSansBold24pt7b.h> // current day
void downloadRandomePicture();
void display_calender();
void display_picture();
void display_time();
void on_draw2(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t rgba[4]);
using std::uint8_t;
// TODO use dynamic display width
static constexpr int MAX_WIDTH = 640 - 250;
static constexpr int MAX_HEIGHT = 384;
static int16_t curRowDelta[MAX_WIDTH + 1];
@ -20,9 +23,15 @@ static int16_t nextRowDelta[MAX_WIDTH + 1];
void setupFaceCalendar()
{
Serial.println("setupFaceWeather");
}
void loopFaceCalendar()
{
EVERY_N_SECONDS(300)
{
Serial.println("TODO download new image");
}
setupDateTime();
display.setRotation(0);
display.setFullWindow();
@ -30,24 +39,18 @@ void setupFaceCalendar()
display.fillScreen(GxEPD_WHITE);
// draw...
//display_time();
display_picture();
display_calender();
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
void downloadRandomePicture()
{
// https://images.unsplash.com/photo-1580886349729-1bd109928600?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjExMDM0OH0&w=640&h=200&fm=png&fit=crop
// https://images.unsplash.com/photo-1580886349729-1bd109928600?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjExMDM0OH0&w=390&h=384&fm=png&fit=crop&colorquant=2
// final filter: &w=390&h=384&fm=png&fit=crop&duotone=000000,FFFFFF
// display_weather
}
void loopFaceCalendar()
{
}
void display_calender()
@ -126,7 +129,6 @@ void display_picture()
pngle_t *pngle = pngle_new();
pngle_set_draw_callback(pngle, on_draw2);
//File file = SPIFFS.open("/blackPNG.png", "r");
File file = SPIFFS.open("/calendarPhoto.png", "r");
if (!file)
{
@ -151,14 +153,13 @@ void display_picture()
}
/**
* Floyd-Steinberg-Algorithmus
* render picture
*/
void on_draw2(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t rgba[4])
{
uint8_t r = rgba[0]; // 0 - 255
uint8_t g = rgba[1]; // 0 - 255
uint8_t b = rgba[2]; // 0 - 255
//uint8_t a = rgba[3]; // 0: fully transparent, 255: fully opaque
int16_t gray = round(r * 0.3 + g * 0.59 + b * 0.11);
int16_t blackOrWhite;
@ -181,7 +182,9 @@ void on_draw2(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, uint32_t h, ui
int err = oldPixel - newPixel;
if (x > 0)
{
nextRowDelta[x - 1] += err * 3 / 16;
}
nextRowDelta[x] += err * 5 / 16;
nextRowDelta[x + 1] += err * 1 / 16;
curRowDelta[x + 1] += err * 7 / 16;

@ -1,16 +1,107 @@
#include "faceWeather.h"
#include <ArduinoJson.h>
#include <HTTPClient.h>
#include "faceWeather.h"
#include "faceWeatherIcons.h"
#include "display.h"
#include <Fonts/FreeSansBold24pt7b.h> // current day
// TODO use theme color
void display_current();
void display_forecast();
void setupFaceWeather()
{
// https://github.com/andrei7c4/weatherdisplay
}
void loopFaceWeather()
{
display.setRotation(0);
display.setFullWindow();
display.firstPage();
display.fillScreen(GxEPD_BLACK);
display.setTextColor(GxEPD_WHITE);
display.setTextSize(1);
display_current();
display_forecast();
display.nextPage();
}
void display_current()
{
// temperature
display.setFont(&FreeSansBold24pt7b);
display.setTextSize(2);
display.setCursor(50, 120);
display.println("");
// icon
const uint *icon = getIconById("02n", 192); // 192
if (icon)
{
display.drawBitmap(272, 30, (uint8_t *)icon + 4, icon[0], icon[1], GxEPD_WHITE);
}
// text
display.setTextSize(1);
display.setCursor(400, 300);
//display.println("Ein paar Wolken");
// high
display.setTextSize(1);
display.setCursor(500, 30);
display.println("");
// low
display.setCursor(500, 60);
display.println("-3°");
}
void display_forecast()
{
const uint *icon;
// line forecast
//display.drawLine(0, 250, 640, 250, GxEPD_WHITE);
display.drawRect(0, 250, 640, 2, GxEPD_WHITE);
display.drawLine(210, 250, 210, 384, GxEPD_WHITE);
display.drawLine(420, 250, 420, 384, GxEPD_WHITE);
// 210 per block
// day +1
icon = getIconById("03d", 96);
if (icon)
{
display.drawBitmap(0 +57, 260, (uint8_t *)icon + 4, icon[0], icon[1], GxEPD_WHITE);
}
// day +2
icon = getIconById("09d", 96);
if (icon)
{
display.drawBitmap(210 +57, 260, (uint8_t *)icon + 4, icon[0], icon[1], GxEPD_WHITE);
}
// day +3
icon = getIconById("13d", 96);
if (icon)
{
display.drawBitmap(410 +57, 260, (uint8_t *)icon + 4, icon[0], icon[1], GxEPD_WHITE);
}
}

File diff suppressed because it is too large Load Diff

@ -3,35 +3,91 @@
#include "faceWeather.h"
#include "faceCalendar.h"
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
typedef void (*Face)();
typedef Face FaceList[];
typedef struct
{
Face face;
String name;
} FaceAndName;
typedef FaceAndName FaceAndNameList[];
// List of faces to cycle through
FaceAndNameList faces = {
{loopFaceWeather, "Weather"},
{loopFaceCalendar, "Calendar"},
};
const uint8_t faceCount = ARRAY_SIZE(faces);
unsigned long lastSwitch = 0;
int64_t timer;
int32_t timer;
uint8_t currentFaceIndex = 0;
//bool autoplayEnabled = false;
void setupPlaylist()
{
Serial.println("setupPlaylist...");
lastSwitch = millis();
// load timer
timer = NVS.getInt("playlist.timer") * 1000;
if (timer < 30000)
{
timer = 30000;
}
// setup faces
//setupFaceWeather();
setupFaceWeather();
setupFaceCalendar();
}
//Serial.print(" Timeout is: ");
//Serial.print(timer);
//Serial.println("");
// force instant update
lastSwitch = millis() - timer;
}
void loopPlaylist()
{
// return millis() - bootTime >= 60000;
if (millis() - lastSwitch >= timer)
if (PlaylistGetRemainingTimeMs() <= 0) // && autoplayEnabled
{
lastSwitch = millis();
Serial.println("switch face");
PlaylistResetTimer();
PlaylistNextFace();
// TODO
Serial.println("switch face: " + faces[currentFaceIndex].name);
faces[currentFaceIndex].face();
}
}
void PlaylistNextFace()
{
currentFaceIndex++;
// wrap around at the ends
if (currentFaceIndex < 0)
{
currentFaceIndex = faceCount - 1;
}
if (currentFaceIndex >= faceCount)
{
currentFaceIndex = 0;
}
}
String PlaylistGetCurrentFace()
{
return faces[currentFaceIndex].name;
}
int32_t PlaylistGetRemainingTimeMs()
{
return timer - (millis() - lastSwitch);
}
void PlaylistResetTimer()
{
lastSwitch = millis();
}
Loading…
Cancel
Save