diff --git a/lib/obp60task/OBP60Extensions.cpp b/lib/obp60task/OBP60Extensions.cpp index 282a1e2..5fa9521 100644 --- a/lib/obp60task/OBP60Extensions.cpp +++ b/lib/obp60task/OBP60Extensions.cpp @@ -11,6 +11,7 @@ #include "Pagedata.h" #include "OBP60Hardware.h" #include "OBP60Extensions.h" +#include "imglib.h" // Character sets #include "Ubuntu_Bold8pt7b.h" @@ -404,4 +405,44 @@ void generatorGraphic(uint x, uint y, int pcolor, int bcolor){ getdisplay().print("G"); } -#endif \ No newline at end of file +// Function to handle HTTP image request +void doImageRequest(GwApi *api, int *pageno, const PageStruct pages[MAX_PAGE_NUMBER], AsyncWebServerRequest *request) { + GwLog *logger = api->getLogger(); + + String imgformat = api->getConfig()->getConfigItem(api->getConfig()->imageFormat,true)->asString(); + imgformat.toLowerCase(); + String filename = "Page" + String(*pageno) + "_" + pages[*pageno].description->pageName + "." + imgformat; + + logger->logDebug(GwLog::LOG,"handle image request [%s]: %s", imgformat, filename); + + uint8_t *fb = getdisplay().getBuffer(); // EPD framebuffer + std::vector imageBuffer; // image in webserver transferbuffer + String mimetype; + + if (imgformat == "gif") { + // GIF is commpressed with LZW, so small + mimetype = "image/gif"; + if (!createGIF(fb, &imageBuffer, GxEPD_WIDTH, GxEPD_HEIGHT)) { + logger->logDebug(GwLog::LOG,"GIF creation failed: Hashtable init error!"); + return; + } + } + else if (imgformat == "bmp") { + // Microsoft BMP bitmap + mimetype = "image/bmp"; + createBMP(fb, &imageBuffer, GxEPD_WIDTH, GxEPD_HEIGHT); + } + else { + // PBM simple portable bitmap + mimetype = "image/x-portable-bitmap"; + createPBM(fb, &imageBuffer, GxEPD_WIDTH, GxEPD_HEIGHT); + } + + AsyncWebServerResponse *response = request->beginResponse_P(200, mimetype, (const uint8_t*)imageBuffer.data(), imageBuffer.size()); + response->addHeader("Content-Disposition", "inline; filename=" + filename); + request->send(response); + + imageBuffer.clear(); +} + +#endif diff --git a/lib/obp60task/OBP60Extensions.h b/lib/obp60task/OBP60Extensions.h index e02cd8b..0c7c117 100644 --- a/lib/obp60task/OBP60Extensions.h +++ b/lib/obp60task/OBP60Extensions.h @@ -70,4 +70,6 @@ void solarGraphic(uint x, uint y, int pcolor, int bcolor); // S void generatorGraphic(uint x, uint y, int pcolor, int bcolor); // Generator graphic with fill level void startLedTask(GwApi *api); -#endif \ No newline at end of file +void doImageRequest(GwApi *api, int *pageno, const PageStruct pages[MAX_PAGE_NUMBER], AsyncWebServerRequest *request); + +#endif diff --git a/lib/obp60task/OBP60Hardware.h b/lib/obp60task/OBP60Hardware.h index 7f0abe2..f450790 100644 --- a/lib/obp60task/OBP60Hardware.h +++ b/lib/obp60task/OBP60Hardware.h @@ -39,11 +39,6 @@ #define OBP_SPI_DIN 48 #define SHOW_TIME 6000 // Show time in [ms] for logo and WiFi QR code #define FULL_REFRESH_TIME 600 // Refresh cycle time in [s][600...3600] for full display update (very important healcy function) - #define MAX_PAGE_NUMBER 10 // Max number of pages for show data - #define FONT1 "Ubuntu_Bold8pt7b" - #define FONT2 "Ubuntu_Bold24pt7b" - #define FONT3 "Ubuntu_Bold32pt7b" - #define FONT4 "DSEG7Classic_BoldItalic80pt7b" // GPS (NEO-6M, NEO-M8N, ATGM336H) #define OBP_GPS_RX 2 diff --git a/lib/obp60task/Pagedata.h b/lib/obp60task/Pagedata.h index f4374c3..526d9b5 100644 --- a/lib/obp60task/Pagedata.h +++ b/lib/obp60task/Pagedata.h @@ -4,6 +4,8 @@ #include #include +#define MAX_PAGE_NUMBER 10 // Max number of pages for show data + typedef std::vector ValueList; typedef struct{ String pageName; @@ -114,6 +116,13 @@ class PageDescription{ } }; +class PageStruct{ + public: + Page *page=NULL; + PageData parameters; + PageDescription *description=NULL; +}; + // Structure for formated boat values typedef struct{ double value; diff --git a/lib/obp60task/config.json b/lib/obp60task/config.json index ca57f33..bac0db1 100644 --- a/lib/obp60task/config.json +++ b/lib/obp60task/config.json @@ -898,6 +898,22 @@ "obp60":"true" } }, + { + "name": "imageFormat", + "label": "Screenshot Format", + "type": "list", + "default":"PBM", + "description": "Graphics file format for screenshots [GIF|PBM|BMP]", + "list": [ + {"l":"Compressed image (GIF)","v":"GIF"}, + {"l":"Portable bitmap (PBM)","v":"PBM"}, + {"l":"Windows bitmap (BMP)","v":"BMP"} + ], + "category":"OBP60 Pages", + "capabilities": { + "obp60":"true" + } + }, { "name": "page1type", "label": "Type", diff --git a/lib/obp60task/obp60task.cpp b/lib/obp60task/obp60task.cpp index 3b4c52d..7f65bbc 100644 --- a/lib/obp60task/obp60task.cpp +++ b/lib/obp60task/obp60task.cpp @@ -183,13 +183,6 @@ class PageList{ } }; -class PageStruct{ - public: - Page *page=NULL; - PageData parameters; - PageDescription *description=NULL; -}; - /** * this function will add all the pages we know to the pagelist * each page should have defined a registerXXXPage variable of type @@ -353,6 +346,10 @@ void OBP60Task(GwApi *api){ // Init pages int numPages=1; PageStruct pages[MAX_PAGE_NUMBER]; + // Set start page + int pageNumber = int(api->getConfig()->getConfigItem(api->getConfig()->startPage,true)->asInt()) - 1; + int lastPage=pageNumber; + BoatValueList boatValues; //all the boat values for the api query //commonData.distanceformat=config->getString(xxx); //add all necessary data to common data @@ -395,6 +392,11 @@ void OBP60Task(GwApi *api){ pages[i].parameters.values.push_back(value); } } + + api->registerRequestHandler("screenshot", [api, &pageNumber, pages](AsyncWebServerRequest *request) { + doImageRequest(api, &pageNumber, pages, request); + }); + //now we have prepared the page data //we start a separate task that will fetch our keys... MyData allParameters; @@ -431,9 +433,6 @@ void OBP60Task(GwApi *api){ GwApi::BoatValue *hdop = boatValues.findValueOrCreate("HDOP"); // Load GpsHDOP LOG_DEBUG(GwLog::LOG,"obp60task: start mainloop"); - // Set start page - int pageNumber = int(api->getConfig()->getConfigItem(api->getConfig()->startPage,true)->asInt()) - 1; - int lastPage=pageNumber; commonData.time = boatValues.findValueOrCreate("GPST"); // Load GpsTime commonData.date = boatValues.findValueOrCreate("GPSD"); // Load GpsTime diff --git a/lib/obp60task/platformio.ini b/lib/obp60task/platformio.ini index dc919a9..14bd788 100644 --- a/lib/obp60task/platformio.ini +++ b/lib/obp60task/platformio.ini @@ -23,8 +23,9 @@ lib_deps = blemasle/MCP23017@2.0.0 adafruit/Adafruit BusIO@1.5.0 adafruit/Adafruit GFX Library@1.11.9 - zinggjm/GxEPD2@1.5.8 + #zinggjm/GxEPD2@1.5.8 #https://github.com/ZinggJM/GxEPD2 + https://github.com/thooge/GxEPD2 sstaub/Ticker@4.4.0 adafruit/Adafruit BMP280 Library@2.6.2 adafruit/Adafruit BME280 Library@2.2.2