From 8352e5811d48cc40346238b60a67e2d6a69e7fe3 Mon Sep 17 00:00:00 2001 From: Nic Limper Date: Wed, 22 Mar 2023 23:23:36 +0100 Subject: [PATCH] QR content card --- esp32_fw/data/www/index.html | 1 + esp32_fw/data/www/main.js | 3 +- esp32_fw/include/contentmanager.h | 1 + esp32_fw/src/contentmanager.cpp | 54 +++++++++++++++++++++++++++++-- 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/esp32_fw/data/www/index.html b/esp32_fw/data/www/index.html index d67668e7..337e9c9e 100644 --- a/esp32_fw/data/www/index.html +++ b/esp32_fw/data/www/index.html @@ -34,6 +34,7 @@ +

diff --git a/esp32_fw/data/www/main.js b/esp32_fw/data/www/main.js index c4982801..51de5f1e 100644 --- a/esp32_fw/data/www/main.js +++ b/esp32_fw/data/www/main.js @@ -8,7 +8,7 @@ const WAKEUP_REASON_FIRSTBOOT = 0xFC; const WAKEUP_REASON_NETWORK_SCAN = 0xFD; const WAKEUP_REASON_WDT_RESET = 0xFE; -const contentModes = ["Static image", "Current date", "Counting days", "Counting hours", "Current weather", "Firmware update", "Memo text", "Image url", "Weather forecast","RSS feed"]; +const contentModes = ["Static image", "Current date", "Counting days", "Counting hours", "Current weather", "Firmware update", "Memo text", "Image url", "Weather forecast", "RSS feed", "QR code"]; const models = ["1.54\" 152x152px", "2.9\" 296x128px", "4.2\" 400x300px"]; const displaySizeLookup = { 0: [152, 152], 1: [128, 296], 2: [400, 300] }; const colorTable = { 0: [255, 255, 255], 1: [0, 0, 0], 2: [255, 0, 0], 3: [255, 0, 0] }; @@ -23,6 +23,7 @@ contentModeOptions[6] = ["text"]; contentModeOptions[7] = ["url","interval"]; contentModeOptions[8] = ["location"]; contentModeOptions[9] = ["title", "url", "interval"]; +contentModeOptions[10] = ["title", "qr-content"]; const imageQueue = []; let isProcessing = false; diff --git a/esp32_fw/include/contentmanager.h b/esp32_fw/include/contentmanager.h index 3a2d1978..5b5bcb48 100644 --- a/esp32_fw/include/contentmanager.h +++ b/esp32_fw/include/contentmanager.h @@ -27,6 +27,7 @@ void drawForecast(String &filename, String location, tagRecord *&taginfo, imgPar void drawIdentify(String &filename, tagRecord *&taginfo, imgParam &imageParams); bool getImgURL(String &filename, String URL, time_t fetched, imgParam &imageParams); bool getRSSfeed(String &filename, String URL, String title, tagRecord *&taginfo, imgParam &imageParams); +void drawQR(String &filename, String qrcontent, String title, tagRecord *&taginfo, imgParam &imageParams); char *formatHttpDate(time_t t); String urlEncode(const char *msg); int windSpeedToBeaufort(float windSpeed); diff --git a/esp32_fw/src/contentmanager.cpp b/esp32_fw/src/contentmanager.cpp index f16f6db4..c2317fd2 100644 --- a/esp32_fw/src/contentmanager.cpp +++ b/esp32_fw/src/contentmanager.cpp @@ -3,7 +3,6 @@ #include #include #include -#include "newproto.h" #include #include #include @@ -12,6 +11,8 @@ #include "U8g2_for_TFT_eSPI.h" #include "commstructs.h" #include "makeimage.h" +#include "newproto.h" +#include "qrcode.h" #include "web.h" #define PAL_BLACK 0 @@ -29,6 +30,7 @@ enum contentModes { ImageUrl, Forecast, RSSFeed, + QRcode, }; void contentRunner() { @@ -185,7 +187,14 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) { taginfo->nextupdate = now + 300; } break; - } + + case QRcode: + + drawQR(filename, cfgobj["qr-content"], cfgobj["title"], taginfo, imageParams); + taginfo->nextupdate = now + 12 * 3600; + updateTagImage(filename, mac, 0, imageParams); + break; + } taginfo->modeConfigJson = doc.as(); } @@ -635,6 +644,47 @@ bool getRSSfeed(String &filename, String URL, String title, tagRecord *&taginfo, return true; } +void drawQR(String &filename, String qrcontent, String title, tagRecord *&taginfo, imgParam &imageParams) { + TFT_eSPI tft = TFT_eSPI(); + TFT_eSprite spr = TFT_eSprite(&tft); + LittleFS.begin(); + + const char *text = qrcontent.c_str(); + QRCode qrcode; + uint8_t qrcodeData[qrcode_getBufferSize(2)]; + // https://github.com/ricmoo/QRCode + qrcode_initText(&qrcode, qrcodeData, 2, ECC_MEDIUM, text); + int size = qrcode.size; + int xpos = 0, ypos = 0, dotsize = 1; + + if (taginfo->hwType == SOLUM_29_033) { + initSprite(spr, 296, 128); + drawString(spr, title, 10, 5, "fonts/bahnschrift20"); + dotsize = int((128 - 25) / size); + xpos = 149 - dotsize*size /2; + ypos = 25; + } else if (taginfo->hwType == SOLUM_154_033) { + initSprite(spr, 152, 152); + spr.setTextFont(2); + spr.setTextColor(PAL_BLACK, PAL_WHITE); + spr.drawString(title, 10, 5); + dotsize = int((152 - 20) / size); + xpos = 76 - dotsize*size / 2; + ypos = 20; + } + + for (int y = 0; y < size; y++) { + for (int x = 0; x < size; x++) { + if (qrcode_getModule(&qrcode, x, y)) { + spr.fillRect(xpos + x * dotsize, ypos + y * dotsize, dotsize, dotsize, PAL_BLACK); + } + } + } + + spr2buffer(spr, filename, imageParams); + spr.deleteSprite(); +} + char *formatHttpDate(time_t t) { static char buf[40]; struct tm *timeinfo;