overhaul of contentmanager, 4.2" layouts, bugfixes

- added Swedish å Å to Bahnschrift20 and 30
- option to turn dither on/off in 'static image'
- major overhaul of contentmanager.cpp, content is now generated from json template.
- fallback to 1bpp for 4.2" when no psram
- added 4.2" content layouts
- fixed small apconfig bug
- pause content generation for 60 seconds after crash, to prevent uncontrollable boot loop
This commit is contained in:
Nic Limper
2023-06-08 15:41:15 +02:00
parent 9d07df27f0
commit c68b582be7
18 changed files with 445 additions and 506 deletions

View File

@@ -0,0 +1,129 @@
{
"1": {
"0": {
"weekday": [ 76, 10, "fonts/calibrib30" ],
"month": [ 76, 120, "fonts/calibrib30" ],
"day": [ 76, 42, "fonts/calibrib100" ]
},
"1": {
"weekday": [ 148, 10, "fonts/calibrib60" ],
"date": [ 148, 73, "fonts/calibrib50" ]
},
"2": {
"weekday": [ 200, 25, "fonts/calibrib60" ],
"month": [ 200, 225, "fonts/calibrib60" ],
"day": [ 200, 95, "fonts/calibrib150" ]
}
},
"2": {
"0": {
"fonts": [ "fonts/calibrib120", "fonts/calibrib80", "fonts/calibrib50", "fonts/calibrib50" ],
"xy": [ 76, 83 ]
},
"1": {
"fonts": [ "fonts/calibrib150", "fonts/calibrib150", "fonts/calibrib120", "fonts/calibrib100" ],
"xy": [ 148, 74 ]
},
"2": {
"fonts": [ "fonts/calibrib150", "fonts/calibrib150", "fonts/calibrib150", "fonts/calibrib120" ],
"xy": [ 200, 148 ]
}
},
"4": {
"0": {
"location": [ 10, 130, 2 ],
"wind": [ 140, 10, "fonts/bahnschrift30" ],
"temp": [ 10, 10, "fonts/bahnschrift30" ],
"icon": [ 33, 33, "fonts/weathericons78" ],
"dir": [ 100, -2, "fonts/weathericons30" ],
"umbrella": [ 115, 110 ]
},
"1": {
"location": [ 5, 5, "fonts/bahnschrift30" ],
"wind": [ 280, 5, "fonts/bahnschrift30" ],
"temp": [ 5, 65, "fonts/bahnschrift70" ],
"icon": [ 185, 32, "fonts/weathericons70" ],
"dir": [ 240, -3, "fonts/weathericons30" ],
"umbrella": [ 190, 0 ]
},
"2": {
"location": [ 20, 20, "fonts/calibrib30" ],
"wind": [ 290, 83, "fonts/calibrib60" ],
"temp": [ 20, 170, "fonts/calibrib150" ],
"icon": [ 100, 50, "fonts/weathericons78" ],
"dir": [ 220, 50, "fonts/weathericons78" ],
"umbrella": [ 330, 10 ]
}
},
"8": {
"1": {
"location": [ 5, 0, 2 ],
"column": [ 5, 59 ],
"day": [ 30, 18, "fonts/twcondensed20", 41, 108 ],
"icon": [ 12, 58, "fonts/weathericons30" ],
"wind": [ 17, 25 ],
"line": [ 20, 128 ]
},
"2": {
"location": [ 10, 10, "fonts/calibrib30" ],
"column": [ 6, 66 ],
"day": [ 33, 60, "fonts/bahnschrift20", 104, 230 ],
"rain": [ 34, 260 ],
"icon": [ 15, 145, "fonts/weathericons30" ],
"wind": [ 17, 90 ],
"line": [ 50, 300 ]
}
},
"9": {
"1": {
"title": [ 5, 3, "fonts/bahnschrift20" ],
"items": 8,
"line": [ 5, 34, 13 ],
"font": "glasstown_nbp_tf"
},
"2": {
"title": [ 10, 10, "fonts/calibrib30" ],
"items": 12,
"line": [ 10, 60, 20 ],
"font": "7x14_tf"
}
},
"10": {
"0": {
"title": [ 10, 3, 2 ],
"pos": [ 76, 20 ]
},
"1": {
"title": [ 10, 5, "fonts/bahnschrift20" ],
"pos": [ 149, 25 ]
},
"2": {
"title": [ 10, 10, "fonts/bahnschrift20" ],
"pos": [ 200, 30 ]
}
},
"11": {
"1": {
"title": [ 5, 2, "fonts/bahnschrift20" ],
"date": [ 290, 2 ],
"items": 7,
"red": [ 0, 21, 296, 14 ],
"line": [ 5, 32, 15, "t0_14b_tf", 50 ]
},
"2": {
"title": [ 10, 10, "fonts/bahnschrift30" ],
"date": [ 390, 10 ],
"items": 12,
"red": [ 0, 48, 400, 17 ],
"line": [ 10, 61, 18, "7x14_tf", 60 ]
}
},
"16": {
"1": {
"location": [ 5, 5, "fonts/bahnschrift30" ],
"title": [ 247, 11, "glasstown_nbp_tf" ],
"cols": [ 1, 125, 12 ],
"bars": [ 5, 111, 10 ]
}
}
}

View File

@@ -21,6 +21,16 @@
"name": "TimeToLive",
"desc": "Amount (minutes) that this image will stay valid. The tag might not respond meanwhile",
"type": "int"
},
{
"key": "dither",
"name": "Dithering",
"desc": "Turn halftone dithering on or off. Turn it on when displaying photos. For texts, you better leave if off",
"type": "select",
"options": {
"0": "off",
"1": "on"
}
}
]
},

View File

@@ -105,7 +105,7 @@ Latency will be around 40 seconds.">
<th>alias</th>
<th>tags</th>
<th>ch</th>
<th>fw ver</th>
<th>AP ver</th>
</tr>
</table>
</p>

View File

@@ -487,6 +487,15 @@ function contentselected() {
input.type = "text";
input.disabled = true;
break;
case 'select':
input = document.createElement("select");
for (const key in element.options) {
const optionElement = document.createElement("option");
optionElement.value = key;
optionElement.text = element.options[key];
input.appendChild(optionElement);
}
break;
}
input.id = 'opt' + element.key;
input.title = element.desc;

View File

@@ -2,6 +2,7 @@
#include <LittleFS.h>
#include <TFT_eSPI.h>
#include "U8g2_for_TFT_eSPI.h"
#include "makeimage.h"
#include "tag_db.h"
@@ -18,7 +19,7 @@ void contentRunner();
void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo);
bool updateTagImage(String &filename, uint8_t *dst, uint16_t nextCheckin, tagRecord *&taginfo, imgParam &imageParams);
void drawString(TFT_eSprite &spr, String content, uint16_t posx, uint16_t posy, String font, byte align = 0, uint16_t color = TFT_BLACK);
void initSprite(TFT_eSprite &spr, int w, int h);
void initSprite(TFT_eSprite &spr, int w, int h, imgParam &imageParams);
void drawDate(String &filename, tagRecord *&taginfo, imgParam &imageParams);
void drawNumber(String &filename, int32_t count, int32_t thresholdred, tagRecord *&taginfo, imgParam &imageParams);
void drawWeather(String &filename, JsonObject &cfgobj, tagRecord *&taginfo, imgParam &imageParams);
@@ -35,4 +36,6 @@ int windSpeedToBeaufort(float windSpeed);
String windDirectionIcon(int degrees);
void getLocation(JsonObject &cfgobj);
void prepareNFCReq(uint8_t* dst, const char* url);
void prepareLUTreq(uint8_t *dst, String input);
void prepareLUTreq(uint8_t *dst, String input);
void getTemplate(JsonDocument &json, const char *filePath, uint8_t id, uint8_t hwtype);
void setU8G2Font(const String &title, U8g2_for_TFT_eSPI &u8f);

View File

@@ -8,6 +8,7 @@ struct imgParam {
uint8_t dataType;
bool dither;
bool grayLut = false;
uint8_t bpp = 8;
char segments[12];
uint16_t symbols;

File diff suppressed because it is too large Load Diff

View File

@@ -19,10 +19,22 @@
#include "udp.h"
#include "web.h"
void delayedStart(void* parameter) {
vTaskDelay(30000 / portTICK_PERIOD_MS);
Serial.println("Resuming content generation");
wsLog("resuming content generation");
config.runStatus = RUNSTATUS_RUN;
vTaskDelete(NULL);
}
void timeTask(void* parameter) {
config.runStatus = RUNSTATUS_RUN;
esp_reset_reason_t resetReason = esp_reset_reason();
// if (resetReason == ESP_RST_PANIC) config.runStatus = RUNSTATUS_PAUSE;
if (resetReason == ESP_RST_PANIC) {
Serial.println("Panic! Pausing content generation for 60 seconds");
config.runStatus = RUNSTATUS_PAUSE;
xTaskCreate(delayedStart, "delaystart", 2000, NULL, 2, NULL);
}
while (1) {
time_t now;
time(&now);

View File

@@ -37,9 +37,10 @@ void jpg2buffer(String filein, String fileout, imgParam &imageParams) {
#endif
spr.createSprite(w, h);
if (spr.getPointer() == nullptr) {
//no heap space for 8bpp, fallback to 1bpp
wsErr("fallback to 1bpp");
wsErr("low on memory. Fallback to 1bpp");
spr.setColorDepth(1);
spr.setBitmapColor(TFT_WHITE, TFT_BLACK);
imageParams.bpp = 1;
spr.createSprite(w, h);
}
if (spr.getPointer() == nullptr) {
@@ -105,6 +106,7 @@ void spr2buffer(TFT_eSprite &spr, String &fileout, imgParam &imageParams) {
Serial.println("rendering with gray");
}
int num_colors = palette.size();
if (imageParams.bpp == 1) num_colors = 2;
Color color;
Error *error_bufferold = new Error[bufw + 4];
Error *error_buffernew = new Error[bufw + 4];

View File

@@ -260,13 +260,14 @@ void clearPending(tagRecord* taginfo) {
void initAPconfig() {
LittleFS.begin(true);
DynamicJsonDocument APconfig(150);
DynamicJsonDocument APconfig(500);
File configFile = LittleFS.open("/current/apconfig.json", "r");
if (configFile) {
DeserializationError error = deserializeJson(APconfig, configFile);
if (error) {
configFile.close();
Serial.println("failed to read apconfig.json. Using default config");
Serial.println(error.c_str());
}
configFile.close();
}
@@ -280,7 +281,7 @@ void initAPconfig() {
void saveAPconfig() {
fs::File configFile = LittleFS.open("/current/apconfig.json", "w");
DynamicJsonDocument APconfig(150);
DynamicJsonDocument APconfig(500);
APconfig["channel"] = config.channel;
APconfig["alias"] = config.alias;
APconfig["led"] = config.led;