added sunrise/sunset/moon phase to date display

This commit is contained in:
Nic Limper
2025-04-12 19:51:57 +02:00
parent eb00a1d9c4
commit b313d07669
5 changed files with 104 additions and 14 deletions

View File

@@ -1,6 +1,7 @@
#include <Arduino.h>
#include <LittleFS.h>
#include <TFT_eSPI.h>
#include <time.h>
#include "makeimage.h"
#include "tag_db.h"
@@ -21,7 +22,7 @@ bool updateTagImage(String &filename, const uint8_t *dst, uint16_t nextCheckin,
void drawString(TFT_eSprite &spr, String content, int16_t posx, int16_t posy, String font, byte align = 0, uint16_t color = TFT_BLACK, uint16_t size = 30, uint16_t bgcolor = TFT_WHITE);
void drawTextBox(TFT_eSprite &spr, String &content, int16_t &posx, int16_t &posy, int16_t boxwidth, int16_t boxheight, String font, uint16_t color = TFT_BLACK, uint16_t bgcolor = TFT_WHITE, float lineheight = 1, byte align = TL_DATUM);
void initSprite(TFT_eSprite &spr, int w, int h, imgParam &imageParams);
void drawDate(String &filename, tagRecord *&taginfo, imgParam &imageParams);
void drawDate(String &filename, JsonObject &cfgobj, tagRecord *&taginfo, imgParam &imageParams);
void drawNumber(String &filename, int32_t count, int32_t thresholdred, tagRecord *&taginfo, imgParam &imageParams);
void drawWeather(String &filename, JsonObject &cfgobj, const tagRecord *taginfo, imgParam &imageParams);
void drawForecast(String &filename, JsonObject &cfgobj, const tagRecord *taginfo, imgParam &imageParams);

View File

@@ -336,7 +336,7 @@ void drawNew(const uint8_t mac[8], tagRecord *&taginfo) {
case 1: // Today
drawDate(filename, taginfo, imageParams);
drawDate(filename, cfgobj, taginfo, imageParams);
taginfo->nextupdate = util::getMidnightTime();
updateTagImage(filename, mac, (taginfo->nextupdate - now) / 60 - 10, taginfo, imageParams);
break;
@@ -790,7 +790,41 @@ void initSprite(TFT_eSprite &spr, int w, int h, imgParam &imageParams) {
spr.fillSprite(TFT_WHITE);
}
void drawDate(String &filename, tagRecord *&taginfo, imgParam &imageParams) {
String utf8FromCodepoint(uint16_t cp) {
char buf[4] = {0};
if (cp < 0x80) {
buf[0] = cp;
} else if (cp < 0x800) {
buf[0] = 0xC0 | (cp >> 6);
buf[1] = 0x80 | (cp & 0x3F);
} else {
buf[0] = 0xE0 | ((cp >> 12) & 0x0F);
buf[1] = 0x80 | ((cp >> 6) & 0x3F);
buf[2] = 0x80 | (cp & 0x3F);
}
return String(buf);
}
String formatUtcToLocal(const String &s) {
int h, m, ss = 0;
if (sscanf(s.c_str(), "%d:%d:%d", &h, &m, &ss) < 2 || h > 23 || m > 59 || ss > 59)
return "-";
time_t n = time(nullptr);
struct tm tm = *localtime(&n);
tm.tm_hour = h;
tm.tm_min = m;
tm.tm_sec = ss;
time_t utc = mktime(&tm) - _timezone + (tm.tm_isdst ? 3600 : 0);
localtime_r(&utc, &tm);
char buf[6];
snprintf(buf, 6, "%02d:%02d", tm.tm_hour, tm.tm_min);
return buf;
}
void drawDate(String &filename, JsonObject &cfgobj, tagRecord *&taginfo, imgParam &imageParams) {
time_t now;
time(&now);
struct tm timeinfo;
@@ -811,19 +845,48 @@ void drawDate(String &filename, tagRecord *&taginfo, imgParam &imageParams) {
TFT_eSprite spr = TFT_eSprite(&tft);
initSprite(spr, imageParams.width, imageParams.height, imageParams);
const auto &date = loc["date"];
const auto &weekday = loc["weekday"];
if (date) {
auto date = loc["date"];
auto weekday = loc["weekday"];
const auto &month = loc["month"];
const auto &day = loc["day"];
if (cfgobj["location"]) {
const String lat = cfgobj["#lat"];
const String lon = cfgobj["#lon"];
JsonDocument doc;
const bool success = util::httpGetJson("https://api.farmsense.net/v1/daylengths/?d=" + String(now) + "&lat=" + lat + "&lon=" + lon + "&tz=UTC", doc, 5000);
if (success && loc["sunrise"].is<JsonArray>()) {
String sunrise = formatUtcToLocal(doc[0]["Sunrise"]);
String sunset = formatUtcToLocal(doc[0]["Sunset"]);
const auto &sunriseicon = loc["sunrise"];
const auto &sunseticon = loc["sunset"];
drawString(spr, String("\uF046 "), sunriseicon[0], sunriseicon[1].as<int>(), "/fonts/weathericons.ttf", TR_DATUM, TFT_BLACK, sunriseicon[3]);
drawString(spr, String("\uF047 "), sunseticon[0], sunseticon[1].as<int>(), "/fonts/weathericons.ttf", TR_DATUM, TFT_BLACK, sunseticon[3]);
drawString(spr, sunrise, sunriseicon[0], sunriseicon[1], sunriseicon[2], TL_DATUM, TFT_BLACK, sunriseicon[3]);
drawString(spr, sunset, sunseticon[0], sunseticon[1], sunseticon[2], TL_DATUM, TFT_BLACK, sunseticon[3]);
const bool success = util::httpGetJson("https://api.farmsense.net/v1/moonphases/?d=" + String(now), doc, 5000);
if (success && loc["moonicon"].is<JsonArray>()) {
uint8_t moonage = doc[0]["Index"].as<int>();
const auto &moonicon = loc["moonicon"];
uint16_t moonIconId = 0xf095 + moonage;
String moonIcon = utf8FromCodepoint(moonIconId);
drawString(spr, moonIcon, moonicon[0], moonicon[1], "/fonts/weathericons.ttf", TC_DATUM, TFT_BLACK, moonicon[2]);
}
date = loc["altdate"];
weekday = loc["altweekday"];
}
}
if (date.is<JsonArray>()) {
drawString(spr, languageDays[timeinfo.tm_wday], weekday[0], weekday[1], weekday[2], TC_DATUM, imageParams.highlightColor, weekday[3]);
drawString(spr, String(timeinfo.tm_mday) + " " + languageMonth[timeinfo.tm_mon], date[0], date[1], date[2], TC_DATUM, TFT_BLACK, date[3]);
} else {
const auto &month = loc["month"];
const auto &day = loc["day"];
drawString(spr, languageDays[timeinfo.tm_wday], weekday[0], weekday[1], weekday[2], TC_DATUM, TFT_BLACK, weekday[3]);
drawString(spr, String(languageMonth[timeinfo.tm_mon]), month[0], month[1], month[2], TC_DATUM, TFT_BLACK, month[3]);
drawString(spr, String(timeinfo.tm_mday), day[0], day[1], day[2], TC_DATUM, imageParams.highlightColor, day[3]);
}
spr2buffer(spr, filename, imageParams);
spr.deleteSprite();
}

View File

@@ -44,8 +44,27 @@
{
"id": 1,
"name": "Current date",
"desc": "Shows the current date",
"param": [ ]
"desc": "Shows the current date. In some templates, the sunrise and sunset times are shown as well, when you fill in your location.",
"param": [
{
"key": "location",
"name": "Location",
"desc": "Name of the city. This is used to lookup the lat/long data, and to display as the title",
"type": "geoselect"
},
{
"key": "#lat",
"name": "Lat",
"desc": "Latitude (set automatic when generating image)",
"type": "ro"
},
{
"key": "#lon",
"name": "Lon",
"desc": "Longitude (set automatic when generating image)",
"type": "ro"
}
]
},
{
"id": 2,

View File

@@ -1,5 +1,5 @@
{
"version": 3,
"version": 4,
"name": "M3 2.7\"",
"width": 300,
"height": 200,
@@ -16,8 +16,15 @@
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20, 21, 27 ],
"template": {
"1": {
"weekday": [ 150, 25, "Signika-SB.ttf", 60 ],
"date": [ 150, 100, "Signika-SB.ttf", 48 ]
"weekday": [ 150, -5, "Signika-SB.ttf", 60 ],
"day": [ 150, 37, "Signika-SB.ttf", 100 ],
"month": [ 150, 125, "Signika-SB.ttf", 60 ],
"altweekday": [ 150, -5, "Signika-SB.ttf", 60 ],
"altdate": [ 150, 65, "Signika-SB.ttf", 54 ],
"moonicon": [ 150, 115, 62 ],
"sunrise": [ 50, 140, "Signika-SB.ttf", 28 ],
"sunset": [ 220, 140, "Signika-SB.ttf", 28 ]
},
"2": {
"fonts": [ "Signika-SB.ttf", 200, 200, 170, 120, 100, 80 ],