diff --git a/esp32_fw/data/alignment.bmp b/esp32_fw/data/alignment.bmp
new file mode 100644
index 00000000..3e302cbe
Binary files /dev/null and b/esp32_fw/data/alignment.bmp differ
diff --git a/esp32_fw/data/bmp24bpp-h.bmp b/esp32_fw/data/bmp24bpp-h.bmp
deleted file mode 100644
index 6ba63e19..00000000
Binary files a/esp32_fw/data/bmp24bpp-h.bmp and /dev/null differ
diff --git a/esp32_fw/data/bmp24bpp-v.bmp b/esp32_fw/data/bmp24bpp-v.bmp
deleted file mode 100644
index 3306c811..00000000
Binary files a/esp32_fw/data/bmp24bpp-v.bmp and /dev/null differ
diff --git a/esp32_fw/data/fonts/bahnschrift30.vlw b/esp32_fw/data/fonts/bahnschrift30.vlw
new file mode 100644
index 00000000..9c3ee829
Binary files /dev/null and b/esp32_fw/data/fonts/bahnschrift30.vlw differ
diff --git a/esp32_fw/data/fonts/bahnschrift70.vlw b/esp32_fw/data/fonts/bahnschrift70.vlw
new file mode 100644
index 00000000..3c516de3
Binary files /dev/null and b/esp32_fw/data/fonts/bahnschrift70.vlw differ
diff --git a/esp32_fw/data/fonts/bahnschrift80.vlw b/esp32_fw/data/fonts/bahnschrift80.vlw
new file mode 100644
index 00000000..84d11fff
Binary files /dev/null and b/esp32_fw/data/fonts/bahnschrift80.vlw differ
diff --git a/esp32_fw/data/fonts/calibrib30.vlw b/esp32_fw/data/fonts/calibrib30.vlw
new file mode 100644
index 00000000..f2da8ab3
Binary files /dev/null and b/esp32_fw/data/fonts/calibrib30.vlw differ
diff --git a/esp32_fw/data/fonts/calibrib35.vlw b/esp32_fw/data/fonts/calibrib35.vlw
new file mode 100644
index 00000000..f6a1d70d
Binary files /dev/null and b/esp32_fw/data/fonts/calibrib35.vlw differ
diff --git a/esp32_fw/data/fonts/calibrib40.vlw b/esp32_fw/data/fonts/calibrib40.vlw
new file mode 100644
index 00000000..4ed81027
Binary files /dev/null and b/esp32_fw/data/fonts/calibrib40.vlw differ
diff --git a/esp32_fw/data/calibrib50.vlw b/esp32_fw/data/fonts/calibrib50.vlw
similarity index 100%
rename from esp32_fw/data/calibrib50.vlw
rename to esp32_fw/data/fonts/calibrib50.vlw
diff --git a/esp32_fw/data/calibrib62.vlw b/esp32_fw/data/fonts/calibrib62.vlw
similarity index 100%
rename from esp32_fw/data/calibrib62.vlw
rename to esp32_fw/data/fonts/calibrib62.vlw
diff --git a/esp32_fw/data/numbers1-1.vlw b/esp32_fw/data/fonts/numbers1-1.vlw
similarity index 100%
rename from esp32_fw/data/numbers1-1.vlw
rename to esp32_fw/data/fonts/numbers1-1.vlw
diff --git a/esp32_fw/data/numbers1-2.vlw b/esp32_fw/data/fonts/numbers1-2.vlw
similarity index 100%
rename from esp32_fw/data/numbers1-2.vlw
rename to esp32_fw/data/fonts/numbers1-2.vlw
diff --git a/esp32_fw/data/numbers2-1.vlw b/esp32_fw/data/fonts/numbers2-1.vlw
similarity index 100%
rename from esp32_fw/data/numbers2-1.vlw
rename to esp32_fw/data/fonts/numbers2-1.vlw
diff --git a/esp32_fw/data/numbers2-2.vlw b/esp32_fw/data/fonts/numbers2-2.vlw
similarity index 100%
rename from esp32_fw/data/numbers2-2.vlw
rename to esp32_fw/data/fonts/numbers2-2.vlw
diff --git a/esp32_fw/data/numbers3-1.vlw b/esp32_fw/data/fonts/numbers3-1.vlw
similarity index 100%
rename from esp32_fw/data/numbers3-1.vlw
rename to esp32_fw/data/fonts/numbers3-1.vlw
diff --git a/esp32_fw/data/numbers3-2.vlw b/esp32_fw/data/fonts/numbers3-2.vlw
similarity index 100%
rename from esp32_fw/data/numbers3-2.vlw
rename to esp32_fw/data/fonts/numbers3-2.vlw
diff --git a/esp32_fw/data/fonts/weathericons30.vlw b/esp32_fw/data/fonts/weathericons30.vlw
new file mode 100644
index 00000000..7e69ede5
Binary files /dev/null and b/esp32_fw/data/fonts/weathericons30.vlw differ
diff --git a/esp32_fw/data/fonts/weathericons78.vlw b/esp32_fw/data/fonts/weathericons78.vlw
new file mode 100644
index 00000000..a1d9d0b6
Binary files /dev/null and b/esp32_fw/data/fonts/weathericons78.vlw differ
diff --git a/esp32_fw/data/jpeg-h.jpg b/esp32_fw/data/jpeg-h.jpg
deleted file mode 100644
index 3d03dfd8..00000000
Binary files a/esp32_fw/data/jpeg-h.jpg and /dev/null differ
diff --git a/esp32_fw/data/jpeg-v.jpg b/esp32_fw/data/jpeg-v.jpg
deleted file mode 100644
index 47878836..00000000
Binary files a/esp32_fw/data/jpeg-v.jpg and /dev/null differ
diff --git a/esp32_fw/data/www/edit.html b/esp32_fw/data/www/edit.html
new file mode 100644
index 00000000..f5b566f5
--- /dev/null
+++ b/esp32_fw/data/www/edit.html
@@ -0,0 +1,777 @@
+
+
+
+
+
+ ESP Editor
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/esp32_fw/data/index.html b/esp32_fw/data/www/index.html
similarity index 86%
rename from esp32_fw/data/index.html
rename to esp32_fw/data/www/index.html
index 9cd7fc7a..3fe0987e 100644
--- a/esp32_fw/data/index.html
+++ b/esp32_fw/data/www/index.html
@@ -7,6 +7,7 @@
Solum - alternative proto AP
+
@@ -24,10 +25,10 @@
@@ -37,8 +38,8 @@
-
-
+
+
@@ -58,6 +59,7 @@
diff --git a/esp32_fw/data/main.css b/esp32_fw/data/www/main.css
similarity index 96%
rename from esp32_fw/data/main.css
rename to esp32_fw/data/www/main.css
index 183074a4..1627b3dd 100644
--- a/esp32_fw/data/main.css
+++ b/esp32_fw/data/www/main.css
@@ -65,16 +65,21 @@ label {
flex-wrap: wrap;
}
+.filebutton {
+ padding:2px 5px;
+ background-color: #cccccc;
+ text-decoration: none;
+ color: black;
+}
+
+.editbtn {
+ float:right;
+}
+
.columns div {
flex: 1;
}
-.actionbox div div {
- padding: 5px;
- margin: 5px;
- background-color: white;
-}
-
input {
border: solid 1px #666666;
padding: 4px;
@@ -239,6 +244,9 @@ ul.messages li.new {
animation-timing-function: ease-in-out;
}
+.error {
+ color: red;
+}
@media(max-width: 460px) {
diff --git a/esp32_fw/data/main.js b/esp32_fw/data/www/main.js
similarity index 94%
rename from esp32_fw/data/main.js
rename to esp32_fw/data/www/main.js
index c3e3881b..1e122901 100644
--- a/esp32_fw/data/main.js
+++ b/esp32_fw/data/www/main.js
@@ -1,7 +1,7 @@
const $ = document.querySelector.bind(document);
const contentModes = ["static image", "current date", "counting days", "counting hours", "current weather", "firmware update", "memo text", "image url"];
-const models = ["unknown type", "1.54\" 152x152px", "2.9\" 296x128px", "4.2\" 400x300px"];
+const models = ["1.54\" 152x152px", "2.9\" 296x128px", "4.2\" 400x300px"];
const contentModeOptions = [];
contentModeOptions[0] = ["filename","timetolive"];
contentModeOptions[1] = [];
@@ -42,7 +42,10 @@ function connect() {
console.log(event.data);
const msg = JSON.parse(event.data);
if (msg.logMsg) {
- showMessage(msg.logMsg);
+ showMessage(msg.logMsg,false);
+ }
+ if (msg.errMsg) {
+ showMessage(msg.errMsg,true);
}
if (msg.tags) {
processTags(msg.tags);
@@ -226,11 +229,15 @@ function contentselected() {
});
}
-function showMessage(message) {
+function showMessage(message,iserr) {
const messages = $('#messages');
var date = new Date(),
time = date.toLocaleTimeString('en-US', {hour12: false, hour: '2-digit', minute:'2-digit', second:'2-digit'});
- messages.insertAdjacentHTML("afterbegin", ''+htmlEncode(time+' '+message)+'');
+ if (iserr) {
+ messages.insertAdjacentHTML("afterbegin", '' + htmlEncode(time + ' ' + message) + '');
+ } else {
+ messages.insertAdjacentHTML("afterbegin", ''+htmlEncode(time+' '+message)+'');
+ }
}
function htmlEncode(input) {
diff --git a/esp32_fw/include/contentmanager.h b/esp32_fw/include/contentmanager.h
index 64fe7a25..6ccbbef9 100644
--- a/esp32_fw/include/contentmanager.h
+++ b/esp32_fw/include/contentmanager.h
@@ -9,7 +9,11 @@
void contentRunner();
void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo);
bool updateTagImage(String &filename, uint8_t *dst, uint16_t nextCheckin);
-void drawDate(String &filename);
-void drawNumber(String &filename, int32_t count, int32_t thresholdred);
+void drawDate(String &filename, tagRecord *&taginfo);
+void drawNumber(String &filename, int32_t count, int32_t thresholdred, tagRecord *&taginfo);
+void drawWeather(String &filename, String location, tagRecord *&taginfo);
bool getImgURL(String &filename, String URL, time_t fetched);
-char *formatHttpDate(time_t t);
\ No newline at end of file
+char *formatHttpDate(time_t t);
+String urlEncode(const char *msg);
+int windSpeedToBeaufort(float windSpeed);
+String windDirectionIcon(int degrees);
diff --git a/esp32_fw/include/settings.h b/esp32_fw/include/settings.h
index 117bb857..4f9ce696 100644
--- a/esp32_fw/include/settings.h
+++ b/esp32_fw/include/settings.h
@@ -24,6 +24,9 @@
// this determines how long images will be cached;
#define PENDING_DATA_TIMEOUT 60
+#define SOLUM_154_033 0
+#define SOLUM_29_033 1
+#define SOLUM_42_033 2
// flasher options
#define CUSTOM_MAC_HDR 0x0000
diff --git a/esp32_fw/include/web.h b/esp32_fw/include/web.h
index 7badb987..524234df 100644
--- a/esp32_fw/include/web.h
+++ b/esp32_fw/include/web.h
@@ -7,7 +7,8 @@ void init_web();
void doImageUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final);
extern void webSocketSendProcess(void *parameter);
-void wsString(String text);
+void wsLog(String text);
+void wsErr(String text);
void wsSendTaginfo(uint8_t mac[6]);
void wsSendSysteminfo();
diff --git a/esp32_fw/src/SPIFFSEditor.cpp b/esp32_fw/src/SPIFFSEditor.cpp
index 42e8d375..e301ecbc 100644
--- a/esp32_fw/src/SPIFFSEditor.cpp
+++ b/esp32_fw/src/SPIFFSEditor.cpp
@@ -2,396 +2,9 @@
#include
-// File: edit.htm.gz, Size: 4151
-#define edit_htm_gz_len 4151
-const uint8_t edit_htm_gz[] PROGMEM = {
- 0x1F, 0x8B, 0x08, 0x08, 0xB8, 0x94, 0xB1, 0x59, 0x00, 0x03, 0x65, 0x64, 0x69, 0x74, 0x2E, 0x68,
- 0x74, 0x6D, 0x00, 0xB5, 0x3A, 0x0B, 0x7B, 0xDA, 0xB8, 0xB2, 0x7F, 0xC5, 0x71, 0xCF, 0x66, 0xED,
- 0x83, 0x31, 0x90, 0xA4, 0xD9, 0xD6, 0xC4, 0xC9, 0x42, 0x92, 0x36, 0x6D, 0xF3, 0x6A, 0x80, 0xB6,
- 0x69, 0x4F, 0xEE, 0x7E, 0xC2, 0x16, 0xA0, 0xC6, 0x96, 0x5D, 0x5B, 0x0E, 0x49, 0x59, 0xFE, 0xFB,
- 0x9D, 0x91, 0x6C, 0xB0, 0x09, 0x69, 0x77, 0xCF, 0xBD, 0xBB, 0xDD, 0x2D, 0x92, 0x46, 0x33, 0x9A,
- 0x19, 0xCD, 0x53, 0xDE, 0xBD, 0x8D, 0xA3, 0x8B, 0xC3, 0xFE, 0xF5, 0xE5, 0xB1, 0x36, 0x11, 0x61,
- 0xB0, 0xBF, 0x87, 0x7F, 0x6B, 0x01, 0xE1, 0x63, 0x97, 0xF2, 0xFD, 0x3D, 0xC1, 0x44, 0x40, 0xF7,
- 0x8F, 0x7B, 0x97, 0xDA, 0xB1, 0xCF, 0x44, 0x94, 0xEC, 0x35, 0xD4, 0xCA, 0x5E, 0x2A, 0x1E, 0x02,
- 0xAA, 0x85, 0xD4, 0x67, 0xC4, 0x4D, 0xBD, 0x84, 0xC2, 0x66, 0xDB, 0x0B, 0x67, 0xDF, 0xEB, 0x8C,
- 0xFB, 0xF4, 0xDE, 0xD9, 0x6E, 0x36, 0xDB, 0x71, 0x94, 0x32, 0xC1, 0x22, 0xEE, 0x90, 0x61, 0x1A,
- 0x05, 0x99, 0xA0, 0xED, 0x80, 0x8E, 0x84, 0xF3, 0x3C, 0xBE, 0x6F, 0x0F, 0xA3, 0xC4, 0xA7, 0x89,
- 0xD3, 0x8A, 0xEF, 0x35, 0x00, 0x31, 0x5F, 0x7B, 0xB6, 0xB3, 0xB3, 0xD3, 0x1E, 0x12, 0xEF, 0x76,
- 0x9C, 0x44, 0x19, 0xF7, 0xEB, 0x5E, 0x14, 0x44, 0x89, 0xF3, 0x6C, 0xF4, 0x1C, 0xFF, 0xB4, 0x7D,
- 0x96, 0xC6, 0x01, 0x79, 0x70, 0x78, 0xC4, 0x29, 0xE0, 0xDE, 0xD7, 0xD3, 0x09, 0xF1, 0xA3, 0xA9,
- 0xD3, 0xD4, 0x9A, 0x5A, 0xAB, 0x09, 0x44, 0x92, 0xF1, 0x90, 0x18, 0x4D, 0x0B, 0xFF, 0xD8, 0x3B,
- 0x66, 0x7B, 0x14, 0x71, 0x51, 0x4F, 0xD9, 0x77, 0xEA, 0xB4, 0xB6, 0xE0, 0x34, 0x39, 0x1D, 0x91,
- 0x90, 0x05, 0x0F, 0x4E, 0x4A, 0x78, 0x5A, 0x4F, 0x69, 0xC2, 0x46, 0x6A, 0x79, 0x4A, 0xD9, 0x78,
- 0x22, 0x9C, 0xDF, 0x9A, 0xCD, 0x39, 0xF0, 0xAF, 0x65, 0xC1, 0x2C, 0x60, 0x29, 0x20, 0xA3, 0x78,
- 0xEA, 0x3C, 0x11, 0xC5, 0x4E, 0x53, 0xB1, 0xDE, 0x6C, 0x87, 0x24, 0x19, 0x33, 0x0E, 0x83, 0x98,
- 0xF8, 0x3E, 0xE3, 0x63, 0x47, 0xA1, 0x05, 0x6C, 0xB6, 0x90, 0x36, 0xA1, 0x01, 0x11, 0xEC, 0x8E,
- 0xB6, 0x43, 0xC6, 0xEB, 0x53, 0xE6, 0x8B, 0x89, 0xB3, 0x0B, 0x3C, 0xB6, 0xBD, 0x2C, 0x49, 0x41,
- 0xA6, 0x38, 0x62, 0x5C, 0xD0, 0x44, 0xA2, 0xA5, 0x31, 0xE1, 0xB3, 0x5C, 0x54, 0x54, 0x40, 0x21,
- 0x27, 0xE3, 0x01, 0xE3, 0xB4, 0x3E, 0x0C, 0x22, 0xEF, 0x76, 0x71, 0xD2, 0x6E, 0x7C, 0x9F, 0x9F,
- 0xE5, 0x4C, 0xA2, 0x3B, 0x9A, 0xCC, 0x96, 0xEA, 0x92, 0xD8, 0x15, 0x60, 0x85, 0x34, 0xA5, 0x74,
- 0x6E, 0x8B, 0xBB, 0x0C, 0xA0, 0x96, 0xFC, 0x05, 0x29, 0x17, 0xFC, 0x2F, 0x45, 0x5A, 0x11, 0x5C,
- 0xA1, 0x30, 0x1E, 0x67, 0x62, 0xF6, 0xF8, 0x2A, 0xA3, 0x98, 0x78, 0x4C, 0x3C, 0xA0, 0xFC, 0xB0,
- 0x6D, 0x86, 0xBA, 0x04, 0xAC, 0x24, 0x24, 0x81, 0x86, 0x3A, 0xD7, 0x3E, 0xD0, 0xC4, 0x27, 0x9C,
- 0x58, 0x9D, 0x84, 0x91, 0xC0, 0xEA, 0x2D, 0xB5, 0x5E, 0x0F, 0xA3, 0xEF, 0xF5, 0x0C, 0xC6, 0x30,
- 0x0F, 0xA8, 0x27, 0x94, 0x92, 0xE1, 0x1E, 0x86, 0xB7, 0x4C, 0x3C, 0x06, 0x3C, 0x5A, 0x28, 0xA9,
- 0x4B, 0x2A, 0x69, 0xA2, 0x2E, 0xB0, 0x25, 0xD5, 0x83, 0x1C, 0x4B, 0xC9, 0x95, 0x50, 0xF5, 0x61,
- 0x24, 0x44, 0x14, 0x4A, 0x93, 0x5B, 0x08, 0xAC, 0x49, 0xAB, 0x79, 0xF1, 0xE8, 0x46, 0xD6, 0x6B,
- 0xBF, 0x44, 0xBE, 0x0D, 0x7A, 0x15, 0xCC, 0x23, 0x41, 0x9D, 0x04, 0x6C, 0xCC, 0x9D, 0x90, 0xF9,
- 0x7E, 0x40, 0x4B, 0x56, 0xEB, 0x64, 0x49, 0x60, 0xF8, 0x44, 0x10, 0x87, 0x85, 0x64, 0x4C, 0x1B,
- 0x31, 0x1F, 0x03, 0x34, 0xA5, 0xBB, 0x3B, 0x16, 0xFB, 0xD0, 0xBD, 0xB8, 0x9A, 0x36, 0xDF, 0xBD,
- 0x1E, 0x47, 0x1D, 0xF8, 0xE7, 0xBC, 0x37, 0x98, 0x1C, 0x0F, 0xC6, 0x30, 0xEA, 0xE2, 0xB4, 0xF3,
- 0xFE, 0xB0, 0xF3, 0x1E, 0x7E, 0x0E, 0x5B, 0xB5, 0xAF, 0xA3, 0x6F, 0xB8, 0xD0, 0x7D, 0xED, 0x77,
- 0xFB, 0x83, 0xE3, 0x4E, 0xE7, 0x5D, 0xE3, 0xCD, 0xF9, 0xF4, 0xE3, 0xBB, 0x5D, 0x04, 0x77, 0x83,
- 0xE6, 0xD5, 0x87, 0x49, 0x73, 0xB0, 0xF5, 0x32, 0xF4, 0x4F, 0xFC, 0x89, 0x17, 0x0E, 0x3A, 0xEF,
- 0x3F, 0x5E, 0xDD, 0x5D, 0x87, 0x83, 0x71, 0xEF, 0x63, 0x6B, 0xF2, 0x79, 0xEB, 0x43, 0xEF, 0xF3,
- 0xC7, 0x57, 0xB7, 0xF4, 0xD3, 0xC9, 0xDB, 0xCF, 0xFD, 0x29, 0x20, 0x1C, 0x45, 0xBD, 0xC1, 0x55,
- 0xF7, 0x43, 0x77, 0xFC, 0xB9, 0xEB, 0x1D, 0xDF, 0x0F, 0x83, 0xF3, 0xEE, 0xEB, 0xCE, 0xB0, 0xB3,
- 0xE5, 0x51, 0x3A, 0xEE, 0x5F, 0x75, 0xB3, 0x37, 0xEF, 0x2E, 0xC6, 0x8C, 0x4D, 0x7A, 0x9F, 0xCF,
- 0xFB, 0xDE, 0xE1, 0xF3, 0xD3, 0xC1, 0x49, 0x87, 0x4D, 0xCE, 0xDF, 0x5E, 0x35, 0x6F, 0x5F, 0xBF,
- 0x3B, 0x3C, 0xF2, 0xAE, 0xDF, 0x5E, 0xEF, 0x1E, 0x6D, 0x37, 0x7E, 0xFB, 0xED, 0xCC, 0xBF, 0x60,
- 0xBC, 0x7F, 0xF7, 0xBD, 0x33, 0x3E, 0x9C, 0xBE, 0x78, 0x48, 0xFB, 0x93, 0x37, 0x77, 0xBC, 0xF1,
- 0x21, 0xFA, 0xFA, 0xE6, 0xE1, 0x0C, 0xFE, 0xBB, 0xBC, 0xAC, 0x0D, 0x7B, 0xAD, 0x74, 0xF0, 0xFE,
- 0xCD, 0x87, 0xAD, 0xF4, 0xE5, 0xF3, 0xB8, 0x7B, 0x74, 0x74, 0x17, 0x0E, 0x2F, 0x1B, 0xA1, 0x7F,
- 0x3B, 0x12, 0x2F, 0xB6, 0x45, 0x7C, 0x3D, 0xCE, 0x3E, 0x7F, 0x7B, 0xFE, 0x76, 0xD2, 0xB8, 0xA0,
- 0xE4, 0x7A, 0x52, 0x7B, 0xF8, 0xFE, 0xF0, 0x62, 0xD2, 0x3F, 0xB9, 0x3B, 0x0F, 0xC8, 0xFD, 0xF9,
- 0xB9, 0xF7, 0x3D, 0xAC, 0x05, 0xE4, 0xE5, 0x45, 0x3F, 0x20, 0x49, 0x6B, 0xE0, 0x77, 0x1A, 0xB5,
- 0xC3, 0xAD, 0xCE, 0x8E, 0x48, 0xAE, 0x0E, 0xF9, 0xD1, 0xF6, 0xD7, 0xDE, 0x8B, 0x6E, 0xB7, 0x15,
- 0x0D, 0xBF, 0x6D, 0xBD, 0xBE, 0xDD, 0x7D, 0x3D, 0xD8, 0x7D, 0x3F, 0x7C, 0xDF, 0xE9, 0xED, 0x74,
- 0x07, 0xE4, 0xBA, 0xF7, 0xBE, 0x33, 0xDA, 0x19, 0x4E, 0x26, 0xEF, 0xDE, 0xF5, 0x5F, 0xF9, 0x9D,
- 0xEF, 0x49, 0xE7, 0x62, 0xDA, 0xB9, 0x3F, 0x1E, 0x74, 0x4E, 0x6A, 0xEF, 0x8E, 0xCF, 0x9A, 0xAD,
- 0xDE, 0xF5, 0xF6, 0xF8, 0x6C, 0x77, 0xDA, 0x4D, 0x8F, 0x3B, 0xEF, 0xBB, 0xCD, 0xF1, 0xDB, 0x5A,
- 0x48, 0x3E, 0x47, 0x87, 0xDB, 0xE3, 0x37, 0xBB, 0xEC, 0xF2, 0x9A, 0x74, 0xDE, 0x74, 0xDF, 0xA6,
- 0xEC, 0x2A, 0x3C, 0x19, 0x34, 0x3B, 0x9D, 0xD3, 0x0B, 0xFA, 0xEA, 0x70, 0x9B, 0xBC, 0xDB, 0xF2,
- 0x3E, 0x82, 0xFE, 0x07, 0x9F, 0xE8, 0x6F, 0xB5, 0xCE, 0xF4, 0xA2, 0x19, 0x78, 0x2F, 0x69, 0xFF,
- 0xE4, 0xBA, 0x2F, 0x6F, 0xE7, 0x38, 0x78, 0xD5, 0xBF, 0xED, 0x65, 0xEF, 0xC3, 0xC3, 0x43, 0x53,
- 0xE3, 0x51, 0x3D, 0xA1, 0x31, 0x25, 0xA2, 0x1C, 0xAE, 0x16, 0xFE, 0x01, 0xB6, 0xB5, 0xB4, 0xC2,
- 0xDC, 0x4F, 0x05, 0xBD, 0x17, 0x75, 0x9F, 0x7A, 0x51, 0x42, 0xE4, 0x1E, 0x40, 0xA0, 0x09, 0x9A,
- 0xD8, 0xFC, 0x77, 0x19, 0x3F, 0x35, 0x15, 0x3F, 0x35, 0xC2, 0x7D, 0xCD, 0x28, 0x1C, 0x01, 0x83,
- 0x87, 0x4F, 0xEF, 0x98, 0x47, 0xEB, 0x31, 0xBB, 0xA7, 0x41, 0x5D, 0x22, 0x3B, 0x4D, 0x73, 0x26,
- 0xFD, 0xAD, 0xD8, 0x46, 0x38, 0x98, 0x9A, 0xA4, 0x5A, 0x2C, 0xF8, 0x5F, 0x89, 0x47, 0x21, 0xB0,
- 0x81, 0xCB, 0x84, 0xF8, 0xAB, 0x7C, 0x27, 0x4A, 0xEA, 0xC3, 0x6C, 0x3C, 0x62, 0xF7, 0xE0, 0xD0,
- 0x23, 0xC6, 0x99, 0xA0, 0x5A, 0x2B, 0x9D, 0xFF, 0x5E, 0x90, 0xB9, 0xA5, 0x0F, 0xA3, 0x84, 0x84,
- 0x34, 0xD5, 0xFE, 0x22, 0x99, 0xD9, 0x28, 0x89, 0xC2, 0x65, 0x10, 0x99, 0x8B, 0xA8, 0x34, 0x99,
- 0xCF, 0x9F, 0x65, 0x71, 0x10, 0x11, 0x10, 0x73, 0x4D, 0xE4, 0x50, 0xF1, 0x34, 0x91, 0x6E, 0xB5,
- 0x88, 0xAB, 0xB9, 0x9B, 0x6D, 0xA1, 0x5B, 0x96, 0xDD, 0x7A, 0x6B, 0x67, 0xE9, 0xBA, 0x75, 0xB9,
- 0x17, 0xE3, 0xFD, 0x9A, 0x4C, 0x81, 0xF1, 0xA0, 0x14, 0xEE, 0x9E, 0x09, 0x50, 0xE9, 0x13, 0x87,
- 0xCB, 0x43, 0xF2, 0xC8, 0xB0, 0x60, 0x40, 0x05, 0xEA, 0x96, 0x8C, 0xD4, 0x85, 0x24, 0xB0, 0x6F,
- 0xFE, 0x8C, 0xCA, 0xBC, 0x67, 0x3D, 0x8B, 0x13, 0xB8, 0x0D, 0x3A, 0xFD, 0x11, 0xCD, 0x42, 0xA6,
- 0x2A, 0x6D, 0x45, 0x53, 0x65, 0xBC, 0x5C, 0x84, 0x65, 0xDA, 0x93, 0xBC, 0x16, 0xA4, 0x1F, 0x4B,
- 0x05, 0xE0, 0x05, 0x37, 0xCF, 0x91, 0x9B, 0x1F, 0x6A, 0x75, 0x7B, 0xF7, 0x97, 0x9C, 0x87, 0x9D,
- 0xE6, 0x2F, 0x73, 0x3B, 0xDF, 0x5B, 0xA4, 0xE4, 0x56, 0x13, 0xFE, 0x29, 0x32, 0xEF, 0x8B, 0x25,
- 0x0B, 0xC3, 0xE7, 0xF8, 0xA7, 0x60, 0x10, 0xE9, 0x94, 0x80, 0xDB, 0x3B, 0x2F, 0x5F, 0xF8, 0xC3,
- 0x02, 0x98, 0x0B, 0xF6, 0x24, 0x3C, 0x21, 0x3E, 0xCB, 0x52, 0xE7, 0x79, 0xF3, 0x97, 0x5C, 0x9F,
- 0x5B, 0x3B, 0x28, 0xFB, 0xE2, 0x2E, 0x71, 0xB2, 0xB4, 0xD8, 0x34, 0x66, 0x5C, 0xDB, 0x4A, 0x35,
- 0xBC, 0x6F, 0x92, 0x2C, 0x0C, 0xB3, 0x92, 0xED, 0xE7, 0xBF, 0x2F, 0x4D, 0x13, 0xF7, 0xCF, 0x9A,
- 0xBF, 0xCC, 0x44, 0x02, 0xD9, 0x64, 0x04, 0xB9, 0xC6, 0x49, 0x22, 0x41, 0x04, 0x35, 0x9A, 0xE6,
- 0x1C, 0x84, 0x5B, 0x03, 0xD8, 0xDE, 0x6D, 0xFA, 0x74, 0x6C, 0xCE, 0xE7, 0x7B, 0x0D, 0x99, 0xD7,
- 0xA0, 0x6C, 0xF1, 0x12, 0x16, 0x8B, 0xFD, 0x51, 0xC6, 0x3D, 0xE4, 0x41, 0x1B, 0x53, 0x83, 0x9A,
- 0xB3, 0x84, 0x8A, 0x2C, 0xE1, 0x9A, 0x1F, 0x79, 0x19, 0x1A, 0xBB, 0x3D, 0xA6, 0xE2, 0x58, 0xD9,
- 0x7D, 0xF7, 0xE1, 0x8D, 0x0F, 0x3B, 0xE6, 0x0B, 0x04, 0x6F, 0x2D, 0x02, 0x38, 0x30, 0x9C, 0x97,
- 0xE3, 0x54, 0xF6, 0x43, 0x82, 0x01, 0x22, 0xEF, 0xE8, 0x83, 0x41, 0x2D, 0xB1, 0x40, 0xA4, 0x36,
- 0xAE, 0x1B, 0xC5, 0x2E, 0x80, 0x71, 0x73, 0x76, 0x07, 0x4A, 0x20, 0x2E, 0xFD, 0x22, 0x6E, 0x2C,
- 0xE6, 0x72, 0xF8, 0x69, 0xE7, 0xBB, 0xC9, 0x1E, 0x3B, 0xA8, 0xB7, 0x1C, 0xB2, 0xCF, 0x0E, 0x5A,
- 0xE0, 0x5E, 0x65, 0x6E, 0xE4, 0xB9, 0xAF, 0x58, 0x40, 0x07, 0xB9, 0xC3, 0xE1, 0x31, 0x48, 0x6C,
- 0xB1, 0x85, 0x28, 0xE2, 0x5B, 0xCD, 0xE6, 0x86, 0x4B, 0x0F, 0x48, 0x00, 0x39, 0xCC, 0xD0, 0x8F,
- 0xAF, 0xAE, 0x2E, 0xAE, 0xBE, 0xE8, 0x35, 0x5A, 0xD3, 0x6F, 0x1C, 0x4D, 0xAF, 0x71, 0xD3, 0x11,
- 0x76, 0x42, 0x47, 0x09, 0x4D, 0x27, 0x97, 0x44, 0x4C, 0x8C, 0xD4, 0xBE, 0x23, 0x41, 0x56, 0x16,
- 0x84, 0xA1, 0xDC, 0xC8, 0xA2, 0x70, 0x39, 0x9D, 0x6A, 0xAF, 0x40, 0xCD, 0x47, 0x90, 0xEA, 0xDA,
- 0xC2, 0x26, 0x71, 0x4C, 0xB9, 0x6F, 0xE8, 0x31, 0x20, 0xEA, 0x16, 0x35, 0xAD, 0x84, 0x7E, 0xCB,
- 0x68, 0x2A, 0x52, 0x1B, 0x2C, 0xD7, 0xD0, 0x2F, 0x07, 0x7D, 0xDD, 0xD2, 0x1B, 0xE8, 0x47, 0x3A,
- 0xF0, 0x46, 0xCC, 0x39, 0x52, 0x89, 0x5C, 0xD0, 0xA4, 0x3E, 0xCC, 0xC0, 0xA0, 0xB8, 0x6E, 0xB6,
- 0x23, 0x9B, 0x71, 0x4E, 0x93, 0x93, 0xFE, 0xD9, 0xA9, 0xAB, 0x5F, 0x29, 0x46, 0xB4, 0x53, 0x28,
- 0x48, 0x74, 0x4B, 0x5E, 0x51, 0x7E, 0xC8, 0xE1, 0x84, 0x05, 0xBE, 0x11, 0x99, 0x6D, 0x24, 0xE1,
- 0x49, 0x12, 0xB2, 0x40, 0x01, 0x0A, 0x9E, 0x2D, 0x1E, 0x62, 0xEA, 0xEA, 0x23, 0x50, 0x86, 0x6E,
- 0x79, 0x76, 0x98, 0x05, 0x82, 0xC5, 0x01, 0x75, 0x37, 0x5A, 0x30, 0xE3, 0x60, 0x41, 0xAE, 0x8E,
- 0xB9, 0x19, 0x61, 0xCC, 0x77, 0x75, 0x15, 0xA1, 0xF2, 0xB8, 0xB6, 0xEE, 0x14, 0x4F, 0x9D, 0x92,
- 0x56, 0x4E, 0x49, 0xCB, 0xB8, 0x4A, 0xE0, 0x34, 0x3F, 0x18, 0xC3, 0x3C, 0xCE, 0xD4, 0x51, 0x05,
- 0xCC, 0xA7, 0x23, 0x02, 0x9C, 0x7C, 0x40, 0x6D, 0xBA, 0x7A, 0x63, 0xDD, 0x41, 0xA9, 0x3A, 0xC8,
- 0xAF, 0x6A, 0xC4, 0x2F, 0x6B, 0x44, 0xDD, 0xEE, 0x3A, 0x64, 0x5F, 0x21, 0x07, 0x55, 0xE4, 0xA0,
- 0x8C, 0x7C, 0x28, 0x8D, 0x64, 0x1D, 0x72, 0xA0, 0x90, 0x93, 0x8A, 0x88, 0x89, 0x14, 0x51, 0x85,
- 0xBD, 0x3A, 0x6A, 0x13, 0x05, 0xD2, 0xAD, 0xA4, 0x22, 0x66, 0x62, 0x83, 0x97, 0x92, 0x61, 0x40,
- 0x7D, 0x77, 0xA3, 0x09, 0x33, 0x2C, 0xB6, 0xDD, 0xAD, 0xE6, 0x9A, 0x33, 0x12, 0x75, 0x46, 0x56,
- 0x65, 0x30, 0x2B, 0x33, 0xA8, 0xF5, 0xC8, 0x1D, 0xD5, 0xD6, 0x31, 0x98, 0x99, 0x56, 0x60, 0x47,
- 0xDC, 0x0B, 0x98, 0x77, 0xEB, 0x2E, 0xBD, 0xC5, 0x9C, 0xB1, 0x85, 0x85, 0x5A, 0x5C, 0x06, 0xBA,
- 0x01, 0x94, 0x5E, 0x8B, 0xA5, 0x7C, 0x80, 0xFA, 0x9E, 0x5B, 0xD9, 0x5A, 0x02, 0xDC, 0xA6, 0xF7,
- 0xD4, 0x3B, 0x8C, 0xC2, 0x90, 0xA0, 0xED, 0xA6, 0xC0, 0x41, 0x3E, 0xD1, 0xCD, 0xB9, 0x15, 0xAD,
- 0xC5, 0x79, 0xC2, 0x45, 0x2C, 0x7F, 0x3D, 0x8B, 0x23, 0x03, 0x5C, 0xCE, 0xF5, 0x6C, 0xD4, 0x61,
- 0x6A, 0x83, 0x1E, 0xC7, 0x62, 0xF2, 0x13, 0x17, 0x2A, 0x0C, 0x54, 0xA2, 0x7C, 0x69, 0xDE, 0x58,
- 0x0B, 0x91, 0x56, 0x7C, 0xEA, 0xA2, 0xB7, 0xE2, 0x54, 0xA8, 0xBC, 0x8A, 0x5D, 0x9A, 0x4B, 0x1D,
- 0x94, 0x61, 0xB9, 0xBD, 0x2F, 0xA0, 0xFA, 0x7C, 0x0E, 0xE7, 0x01, 0xFF, 0x13, 0x68, 0xF9, 0xE8,
- 0x5F, 0x17, 0x60, 0xC9, 0xA3, 0x34, 0x78, 0x8B, 0xBB, 0x0D, 0xE3, 0xC0, 0xF9, 0x8F, 0x6D, 0x7C,
- 0xF9, 0x1F, 0xFB, 0xA6, 0x66, 0x9A, 0x07, 0xFF, 0x6A, 0x48, 0x0D, 0x1B, 0xC2, 0xFC, 0xD2, 0xBA,
- 0xB1, 0x08, 0x80, 0xED, 0x7F, 0x9B, 0xFF, 0xB1, 0x25, 0xB8, 0x02, 0x6B, 0xDF, 0x45, 0x90, 0x49,
- 0xF0, 0x24, 0x34, 0xB0, 0x68, 0xA4, 0x91, 0xCD, 0x4D, 0x43, 0xB8, 0xA4, 0x72, 0x8D, 0x35, 0x51,
- 0xD3, 0x6D, 0x88, 0x53, 0x50, 0x5B, 0xAC, 0x04, 0xBF, 0x3E, 0x24, 0x7A, 0x15, 0x5B, 0x17, 0x00,
- 0xC9, 0x3D, 0xCA, 0x0C, 0x3D, 0x22, 0x97, 0x52, 0xCB, 0x0C, 0x02, 0x42, 0xA7, 0x89, 0xE7, 0x2A,
- 0xAD, 0x1D, 0x14, 0x30, 0x17, 0xA2, 0xE0, 0xBC, 0x1C, 0x2D, 0x15, 0xEA, 0xAA, 0xFD, 0x17, 0x0A,
- 0xA3, 0xD6, 0x12, 0x8A, 0x04, 0x31, 0xAD, 0xD8, 0x79, 0xC6, 0x72, 0x75, 0x4C, 0x59, 0xBA, 0x35,
- 0x59, 0x5D, 0x96, 0xAD, 0x04, 0xAE, 0x2F, 0x8D, 0xFE, 0xD7, 0x3D, 0x16, 0x8E, 0xB5, 0x12, 0x3F,
- 0xF8, 0x97, 0xFB, 0x2B, 0x46, 0xE4, 0xCD, 0x3F, 0xBC, 0x21, 0x70, 0x05, 0xA6, 0x41, 0x6D, 0x1E,
- 0x4D, 0x0D, 0xB3, 0xF6, 0xAB, 0xAE, 0x49, 0x8A, 0xAE, 0x1E, 0x92, 0xFB, 0xBC, 0xA7, 0xC4, 0x8C,
- 0xD7, 0xD6, 0x70, 0x5E, 0xB4, 0x28, 0xF9, 0x82, 0xEC, 0xE6, 0x48, 0x26, 0xA2, 0xB6, 0x56, 0x64,
- 0x52, 0xD5, 0xCA, 0xE8, 0x5A, 0x63, 0xFF, 0xD7, 0x4A, 0x40, 0xB7, 0x98, 0xBA, 0x4E, 0x15, 0x8C,
- 0xB3, 0x00, 0x1C, 0x93, 0x3E, 0x1D, 0x69, 0x03, 0x26, 0x03, 0x75, 0x35, 0x46, 0x5A, 0x81, 0xC1,
- 0xCC, 0x03, 0xC3, 0x2B, 0xFB, 0xF3, 0x1E, 0x16, 0xBF, 0xFB, 0x97, 0xAA, 0xAA, 0x81, 0xD4, 0x8B,
- 0x33, 0x5D, 0x59, 0x59, 0xD5, 0x4B, 0xE0, 0xD2, 0x08, 0xA0, 0x5B, 0x8B, 0x3C, 0x3A, 0x8C, 0xFC,
- 0x87, 0x52, 0xF6, 0x4D, 0xBB, 0x0F, 0x87, 0x01, 0x49, 0xD3, 0x73, 0xB8, 0x01, 0x43, 0xF7, 0x42,
- 0x50, 0xB8, 0xB2, 0xC2, 0xFD, 0xE6, 0xE6, 0x66, 0x15, 0x29, 0xA1, 0x21, 0x14, 0xDB, 0x8A, 0x2B,
- 0xF0, 0x49, 0xD3, 0xF1, 0x81, 0x30, 0x18, 0xD2, 0x1A, 0xC6, 0xF0, 0x25, 0xE3, 0x47, 0x5C, 0x71,
- 0xF4, 0xF4, 0x22, 0xA6, 0xFC, 0x33, 0xDC, 0x95, 0x32, 0xCB, 0x1A, 0xAD, 0xA6, 0x68, 0xFA, 0x8F,
- 0xD8, 0x3E, 0xCA, 0x0D, 0x76, 0xC1, 0x7A, 0xBA, 0x56, 0xA1, 0xFC, 0x9F, 0x61, 0xB9, 0x94, 0x28,
- 0xD6, 0x70, 0x9C, 0x40, 0x80, 0x5A, 0xC3, 0x31, 0xC4, 0x1A, 0x41, 0x17, 0xFC, 0x26, 0x6B, 0xF9,
- 0xCD, 0xFE, 0x19, 0x7E, 0x97, 0x76, 0x1E, 0x15, 0x25, 0x91, 0xAA, 0xAF, 0x50, 0x02, 0x9F, 0xDD,
- 0xE9, 0xA6, 0x15, 0xB9, 0x55, 0x0A, 0x50, 0x1B, 0x46, 0x41, 0xD0, 0x8F, 0xE2, 0x83, 0x27, 0xD6,
- 0x9D, 0xC5, 0x7A, 0x31, 0xC8, 0xD9, 0x5C, 0x6E, 0xB1, 0xBC, 0xB5, 0x44, 0x4F, 0xA1, 0xEC, 0x5F,
- 0x4B, 0x15, 0x01, 0x3F, 0x23, 0x8B, 0x7B, 0xAC, 0xD4, 0xA5, 0x36, 0x28, 0x0F, 0x56, 0x3F, 0xD5,
- 0x3C, 0xCB, 0x5F, 0xCC, 0xAE, 0x6B, 0x51, 0x9B, 0xC0, 0x38, 0x57, 0x92, 0x8B, 0x4A, 0xB2, 0xC8,
- 0x13, 0x01, 0xA8, 0x58, 0xC7, 0x2E, 0xC4, 0x4D, 0x6B, 0x7A, 0x7C, 0xBF, 0x5C, 0x83, 0xC2, 0xDF,
- 0xF5, 0xD5, 0x12, 0x33, 0x08, 0xC4, 0xD3, 0x95, 0x4B, 0x29, 0x5F, 0x37, 0x29, 0x8A, 0x0E, 0x62,
- 0x47, 0xA3, 0x51, 0x4A, 0xC5, 0x47, 0x0C, 0x49, 0x56, 0xB2, 0x98, 0x9F, 0xC8, 0x90, 0x04, 0x8C,
- 0x45, 0x3C, 0x8C, 0xB2, 0x94, 0x46, 0x99, 0xA8, 0xA4, 0x16, 0x63, 0x21, 0xCC, 0x5E, 0xFA, 0xE7,
- 0x9F, 0x8B, 0xC9, 0x7E, 0x5A, 0x0B, 0x96, 0xD3, 0xEB, 0x3D, 0xBF, 0x34, 0xD9, 0xF7, 0x6B, 0x89,
- 0xB9, 0x7A, 0xE9, 0xFF, 0x67, 0x4B, 0x21, 0x65, 0x4B, 0xF1, 0xB0, 0x54, 0x2E, 0x62, 0x62, 0x29,
- 0xE6, 0xC9, 0x82, 0x91, 0x97, 0x7C, 0x16, 0x0D, 0x1A, 0x2B, 0x25, 0x55, 0x9E, 0x97, 0x7D, 0x95,
- 0x43, 0x40, 0x59, 0x71, 0xE5, 0x35, 0x11, 0x06, 0x34, 0xE0, 0x63, 0x64, 0xF2, 0x41, 0xEB, 0xA7,
- 0xD1, 0x94, 0x26, 0x87, 0x24, 0xA5, 0x06, 0x24, 0xCD, 0x65, 0xDC, 0x41, 0xA8, 0xE9, 0x04, 0xEB,
- 0x76, 0x6D, 0x6E, 0x12, 0x05, 0xCE, 0x33, 0x77, 0xC4, 0xB1, 0x26, 0x03, 0xF9, 0xB2, 0xCA, 0x09,
- 0xD4, 0xC6, 0xBE, 0x12, 0xA4, 0x3E, 0x52, 0x25, 0xA8, 0x61, 0x5A, 0xD0, 0x76, 0xC0, 0x35, 0x5F,
- 0x26, 0x51, 0x4C, 0xC6, 0xB2, 0x07, 0x83, 0x35, 0x74, 0x0F, 0xA4, 0x66, 0x6D, 0x34, 0x91, 0x60,
- 0xA9, 0x73, 0x29, 0xFC, 0x66, 0xD9, 0xC2, 0x70, 0x4B, 0x57, 0xC9, 0xB0, 0xBD, 0xF4, 0xA5, 0x35,
- 0x59, 0x83, 0xE0, 0x0B, 0x6C, 0x62, 0xE0, 0x1E, 0x68, 0x64, 0xF2, 0x7B, 0x00, 0x77, 0x6B, 0xB6,
- 0xA3, 0x3D, 0xD6, 0x8E, 0x6A, 0x35, 0x53, 0x55, 0xE9, 0xAE, 0x0B, 0x6D, 0x4E, 0x74, 0x23, 0x0B,
- 0x4B, 0x10, 0xAA, 0x9A, 0x59, 0x0C, 0x38, 0x1B, 0x81, 0xAA, 0xBA, 0xC0, 0x11, 0xD6, 0x98, 0x66,
- 0xA9, 0x23, 0xF1, 0x97, 0x1D, 0xC9, 0x13, 0xB5, 0x07, 0x95, 0xF5, 0x05, 0xD4, 0x31, 0xAB, 0x25,
- 0x86, 0x30, 0xD3, 0x29, 0x13, 0xDE, 0x04, 0x03, 0x90, 0x07, 0x5A, 0xD5, 0x05, 0x14, 0xB5, 0x8E,
- 0x1C, 0x4D, 0x44, 0xB8, 0x1C, 0x05, 0xF9, 0xF0, 0x6B, 0x9A, 0x0F, 0xBC, 0xB4, 0x18, 0xDD, 0x97,
- 0x80, 0x50, 0xD2, 0xE6, 0xE0, 0x88, 0x8F, 0xF2, 0x21, 0xF4, 0xB2, 0x05, 0x9D, 0x02, 0x58, 0xFC,
- 0xC6, 0x71, 0x3E, 0x8A, 0x27, 0xC5, 0x68, 0x42, 0xEF, 0x17, 0x78, 0x51, 0x01, 0xF5, 0xA9, 0xEE,
- 0x28, 0x1B, 0xDB, 0x68, 0xCE, 0xF3, 0x41, 0x6B, 0x29, 0x7F, 0xF0, 0xFF, 0x28, 0x7F, 0xCC, 0xC7,
- 0x85, 0x34, 0x71, 0x31, 0x1A, 0xB3, 0x42, 0x96, 0x61, 0x18, 0xFF, 0x90, 0x93, 0xA4, 0xD4, 0x13,
- 0x97, 0x7A, 0x5A, 0xF1, 0xB3, 0xB6, 0x53, 0x98, 0x8E, 0x31, 0xAA, 0xF8, 0xE3, 0xC8, 0xF6, 0xF0,
- 0xF7, 0x3C, 0xF2, 0x65, 0x6D, 0x69, 0x5A, 0xA1, 0x31, 0x82, 0x3A, 0x57, 0x37, 0xCB, 0x7E, 0x9A,
- 0xFD, 0xB7, 0xAD, 0xE8, 0xD1, 0xF1, 0xE9, 0x71, 0xFF, 0xB8, 0x5C, 0x38, 0x23, 0xE7, 0x25, 0x93,
- 0x8A, 0x2B, 0x5D, 0xFA, 0xB2, 0x22, 0x80, 0x02, 0x1B, 0x45, 0x01, 0x7B, 0xDD, 0xDC, 0x54, 0x7E,
- 0xF1, 0xB6, 0x77, 0x71, 0x6E, 0xC7, 0x24, 0x01, 0x8F, 0x24, 0x15, 0xE6, 0xC2, 0x82, 0x44, 0xF9,
- 0xE0, 0xD7, 0xC7, 0xA5, 0x72, 0x5D, 0x7E, 0x61, 0x70, 0xC4, 0xDC, 0x52, 0xA7, 0xA9, 0x7E, 0x78,
- 0xE2, 0x62, 0x5D, 0x99, 0xBF, 0x04, 0x41, 0x72, 0x1A, 0x2D, 0x13, 0x55, 0x11, 0x67, 0x46, 0xE5,
- 0x30, 0x2F, 0xEE, 0xB2, 0x75, 0x0D, 0xD3, 0xC8, 0xB4, 0xC4, 0x84, 0xA5, 0xE5, 0x46, 0xA5, 0x12,
- 0x14, 0xFE, 0xA2, 0xB6, 0xE7, 0x8B, 0x91, 0x24, 0xB7, 0x5A, 0x73, 0xAB, 0x6F, 0x41, 0x2A, 0x3E,
- 0x58, 0x04, 0x23, 0x66, 0x39, 0xDB, 0x16, 0x77, 0xA3, 0x43, 0xEE, 0x61, 0x5C, 0x7F, 0xBA, 0x35,
- 0x78, 0xD2, 0x3C, 0x79, 0x61, 0x9E, 0xFC, 0xB1, 0x7B, 0x2E, 0x1C, 0x45, 0xF9, 0xDA, 0xE2, 0x98,
- 0xF6, 0x10, 0x58, 0xBB, 0x6D, 0x2F, 0x7D, 0x18, 0x20, 0xD2, 0x83, 0xCB, 0x00, 0xF4, 0x63, 0x58,
- 0xFF, 0x4A, 0xEE, 0x88, 0x7A, 0x09, 0xAA, 0xA2, 0xAD, 0x73, 0x54, 0xD8, 0xEE, 0xFD, 0x81, 0xA3,
- 0xF2, 0xCE, 0x65, 0x18, 0x48, 0x97, 0xC3, 0x92, 0x37, 0x8B, 0x75, 0xC1, 0x61, 0x19, 0x31, 0x64,
- 0x6C, 0x00, 0xE3, 0xCD, 0x5D, 0x49, 0x13, 0xD5, 0x1C, 0xB4, 0xF0, 0x1B, 0x08, 0x8A, 0x4F, 0x39,
- 0xCE, 0x9A, 0x38, 0xAD, 0x62, 0x72, 0xC5, 0x23, 0xC8, 0x4A, 0x67, 0x89, 0xC0, 0x6E, 0x10, 0x0D,
- 0x0D, 0x7C, 0x64, 0x9A, 0xA1, 0xB6, 0x1D, 0x3E, 0x37, 0xD7, 0xBC, 0xD9, 0x54, 0xFA, 0x4B, 0x62,
- 0x79, 0xD5, 0xB0, 0x8B, 0x1C, 0x56, 0xCC, 0x75, 0x7D, 0x1F, 0xF4, 0xA3, 0x4E, 0x29, 0xAF, 0x48,
- 0xA4, 0x53, 0xD1, 0x83, 0xC4, 0x86, 0xA2, 0x41, 0xBE, 0x91, 0x40, 0x44, 0x72, 0x4A, 0x33, 0x5D,
- 0xC7, 0xCA, 0xD2, 0x0B, 0x28, 0x49, 0x7A, 0xB2, 0x73, 0x95, 0x49, 0x6B, 0x25, 0x06, 0xFE, 0xC8,
- 0xD7, 0xF0, 0xC7, 0xA1, 0xD0, 0xA3, 0x83, 0x9B, 0x49, 0x2B, 0x83, 0xA4, 0x23, 0x64, 0x83, 0xA9,
- 0x37, 0xE4, 0xBB, 0xA8, 0x2D, 0x2F, 0xCB, 0xB4, 0x16, 0x50, 0x70, 0x71, 0x83, 0xBB, 0x11, 0x30,
- 0x52, 0x5A, 0xC4, 0x9E, 0x94, 0xA8, 0xC7, 0x8F, 0x10, 0x1F, 0x53, 0x4A, 0x20, 0x06, 0x20, 0xA6,
- 0x40, 0xD0, 0xA7, 0x42, 0x8A, 0x54, 0xE6, 0x92, 0x53, 0x2A, 0x20, 0xCA, 0x48, 0xCD, 0xE2, 0xC1,
- 0x85, 0x78, 0xD4, 0x46, 0xD6, 0x80, 0xFD, 0xDC, 0xBD, 0x73, 0x33, 0xDE, 0x90, 0x68, 0x09, 0x56,
- 0x36, 0x3D, 0x9A, 0xA6, 0x52, 0x5C, 0x54, 0xC7, 0x19, 0xF8, 0xA8, 0xA1, 0x03, 0x5A, 0x23, 0x84,
- 0x11, 0x1E, 0x84, 0x8A, 0x01, 0x40, 0x7F, 0x42, 0xC3, 0x1C, 0x22, 0x70, 0x08, 0x20, 0x82, 0xA0,
- 0x7F, 0x49, 0x0D, 0xF7, 0x64, 0x05, 0xC9, 0xF8, 0xD8, 0x6D, 0x35, 0xF0, 0x9D, 0x66, 0x95, 0xEC,
- 0x20, 0xA5, 0xBD, 0x68, 0x24, 0xFA, 0x64, 0x98, 0x1A, 0x50, 0x00, 0xAC, 0xD9, 0x01, 0xA0, 0x1E,
- 0x24, 0x5E, 0x63, 0x2B, 0x3F, 0xEF, 0x04, 0x2A, 0xBB, 0x00, 0xAB, 0xBB, 0x8E, 0x87, 0x5F, 0x39,
- 0x4F, 0x19, 0xA7, 0x39, 0x26, 0x00, 0x7B, 0x93, 0x68, 0x7A, 0x99, 0x30, 0x2E, 0xCE, 0x64, 0x1B,
- 0x6A, 0x6C, 0xB4, 0xE4, 0xF5, 0xA9, 0x87, 0x15, 0x79, 0x3F, 0xC5, 0x8B, 0xCB, 0x0C, 0xF3, 0xBA,
- 0x53, 0x79, 0x77, 0xB1, 0x86, 0x70, 0x21, 0x50, 0x66, 0x38, 0xB3, 0x29, 0x74, 0xB0, 0xFA, 0xA1,
- 0x48, 0x82, 0x7A, 0x4F, 0xB7, 0x42, 0xE2, 0xC1, 0x44, 0xED, 0x81, 0xF9, 0xDC, 0xC2, 0xD8, 0xE1,
- 0x94, 0x83, 0x5A, 0x0A, 0xB5, 0x02, 0x45, 0xC6, 0x95, 0xCD, 0x98, 0x35, 0x1D, 0x6A, 0x58, 0x88,
- 0x61, 0xE0, 0xAF, 0xFE, 0x05, 0x0F, 0x1E, 0x1C, 0xC8, 0x55, 0x3F, 0xE1, 0x23, 0xE3, 0x7E, 0xF4,
- 0x23, 0x3E, 0x3E, 0xAF, 0xF0, 0xF1, 0x79, 0x1D, 0x1F, 0xB4, 0xAA, 0x3C, 0x98, 0x0C, 0x80, 0xEC,
- 0x19, 0xE1, 0x64, 0x4C, 0x13, 0x58, 0xC0, 0x43, 0x50, 0x25, 0x7F, 0x8B, 0xB3, 0x84, 0xFE, 0x98,
- 0xB3, 0xDE, 0x84, 0x8D, 0xC4, 0x23, 0xFE, 0x8A, 0xD5, 0xFF, 0x82, 0x4B, 0x3C, 0x70, 0x3D, 0x97,
- 0x79, 0x6D, 0x5A, 0x49, 0x28, 0x3F, 0x7E, 0x2B, 0x91, 0x7E, 0xE4, 0x42, 0x78, 0xA9, 0x38, 0xC8,
- 0xDF, 0xB7, 0xF4, 0x00, 0xBC, 0x11, 0xF8, 0x29, 0x35, 0x75, 0xBC, 0x0B, 0xA5, 0xFC, 0x29, 0x30,
- 0x64, 0xA8, 0xC0, 0x47, 0xDD, 0xD9, 0xDC, 0x12, 0xAE, 0x01, 0x8A, 0xF1, 0xA3, 0x29, 0xB0, 0xEA,
- 0xC9, 0x02, 0xD7, 0x9E, 0x40, 0x26, 0x04, 0x91, 0xE0, 0x48, 0xC8, 0xA7, 0x8D, 0x2F, 0x07, 0x9B,
- 0x37, 0x35, 0xC8, 0x43, 0x2E, 0xFC, 0x98, 0x2E, 0x0C, 0x36, 0x6F, 0xFE, 0x6D, 0x36, 0xC6, 0xCC,
- 0x5A, 0x76, 0xA4, 0x96, 0x4C, 0xF6, 0xF4, 0x0B, 0xBF, 0x71, 0x09, 0x48, 0x5D, 0x49, 0x78, 0x45,
- 0x34, 0x03, 0x6B, 0x43, 0x61, 0xE1, 0x07, 0xFF, 0x47, 0x09, 0xF8, 0x91, 0x9E, 0x07, 0xCE, 0xBD,
- 0xE6, 0x3D, 0x5E, 0x2F, 0x3E, 0x85, 0xE9, 0x56, 0xE9, 0xC1, 0x4A, 0xC7, 0xEF, 0x53, 0x3A, 0x76,
- 0x59, 0xA2, 0x14, 0x4A, 0x14, 0x59, 0x88, 0x1A, 0x6A, 0x50, 0x0E, 0x51, 0x98, 0x89, 0x17, 0xCD,
- 0x81, 0x02, 0x9B, 0x73, 0x34, 0x5B, 0x3A, 0x02, 0x0F, 0xF4, 0xF5, 0x45, 0xEE, 0xFC, 0x74, 0x76,
- 0x7A, 0x22, 0x44, 0x7C, 0xA5, 0x62, 0x22, 0xD0, 0xAA, 0x2E, 0x2C, 0x2F, 0xCF, 0x9C, 0x89, 0xE4,
- 0xA1, 0x28, 0x75, 0x30, 0x31, 0x28, 0x87, 0xFE, 0x74, 0x31, 0xFC, 0x0A, 0x71, 0xD6, 0xD0, 0xCF,
- 0x52, 0x48, 0x58, 0x5B, 0x36, 0xA2, 0xF7, 0xFB, 0x97, 0xF6, 0xAE, 0xDD, 0x84, 0xBA, 0x00, 0xB4,
- 0x0A, 0x69, 0x19, 0xEE, 0x7D, 0xFE, 0xB7, 0x90, 0xB7, 0xFF, 0x1E, 0x32, 0x83, 0xA8, 0x95, 0x42,
- 0x58, 0x2A, 0xF0, 0xAB, 0xB8, 0x93, 0x24, 0x9A, 0x4A, 0xB4, 0xE3, 0x24, 0xC1, 0x4B, 0xE9, 0x43,
- 0x85, 0xA2, 0x0D, 0x61, 0x31, 0xA5, 0x89, 0xE6, 0x47, 0x34, 0xD5, 0x78, 0x24, 0xB4, 0x34, 0x8B,
- 0x63, 0x68, 0x5C, 0x56, 0xF4, 0x61, 0xEB, 0xC5, 0xEB, 0xCB, 0xFB, 0x8C, 0x66, 0xD4, 0xCF, 0x97,
- 0x69, 0x52, 0xD1, 0x0B, 0x56, 0x50, 0xDF, 0x10, 0xEE, 0x7E, 0xB9, 0xC9, 0xEB, 0xA9, 0x8C, 0x73,
- 0x8C, 0xA2, 0x1B, 0x2D, 0x35, 0x07, 0xE9, 0x26, 0x40, 0xD5, 0xE5, 0x59, 0x10, 0xCC, 0xDB, 0x2B,
- 0xB4, 0xA0, 0xF1, 0x8A, 0x44, 0x24, 0x9F, 0xCB, 0x67, 0x7F, 0xE4, 0xC9, 0xA9, 0xE2, 0x82, 0x50,
- 0xF2, 0x54, 0xA9, 0x36, 0xAD, 0x0D, 0x63, 0x83, 0x6A, 0x8C, 0xA7, 0x82, 0x70, 0x0F, 0xAF, 0x51,
- 0xE9, 0xC2, 0x2C, 0x6A, 0x29, 0xDC, 0xDE, 0x46, 0x5F, 0xCB, 0x6D, 0xE9, 0x89, 0x7C, 0x2A, 0x25,
- 0xE3, 0xAE, 0xAE, 0x63, 0x55, 0x45, 0xB1, 0x3E, 0x25, 0x61, 0x5A, 0x26, 0x5B, 0x54, 0x06, 0x26,
- 0x77, 0x0B, 0x70, 0x9B, 0x06, 0x29, 0x1C, 0xBD, 0x7E, 0x7F, 0xCE, 0x46, 0xD1, 0xCE, 0x11, 0x80,
- 0x69, 0xC5, 0x3E, 0x93, 0xD7, 0xE0, 0x24, 0xCC, 0x73, 0x07, 0x32, 0xE9, 0x4A, 0x03, 0x0E, 0xA9,
- 0x98, 0x44, 0xFE, 0x81, 0x7E, 0xA0, 0x3B, 0x3A, 0xFC, 0xBB, 0x09, 0x35, 0x47, 0xCD, 0xA5, 0xD0,
- 0xA4, 0xFA, 0x74, 0x70, 0xF5, 0x06, 0xC2, 0x53, 0x0C, 0xA5, 0x01, 0x17, 0x50, 0x34, 0xD7, 0x74,
- 0x7C, 0x7A, 0x7D, 0x0C, 0x29, 0xC8, 0x7F, 0x21, 0x37, 0x66, 0xBB, 0xAA, 0x6C, 0xB8, 0xF3, 0xEA,
- 0x75, 0x56, 0x2E, 0x03, 0x7A, 0x61, 0x8C, 0x58, 0x0F, 0x29, 0x7E, 0xFB, 0x7B, 0xF4, 0x9E, 0x8D,
- 0x15, 0xD2, 0x6A, 0x5D, 0x6F, 0xCE, 0x76, 0x90, 0x67, 0x89, 0xD5, 0x43, 0x2C, 0x70, 0x97, 0x1F,
- 0x29, 0x59, 0x95, 0x35, 0xDC, 0xF6, 0x48, 0x10, 0xE0, 0xC7, 0x5A, 0x03, 0x1B, 0x6A, 0x22, 0xB2,
- 0xD4, 0x42, 0x22, 0x29, 0x08, 0x90, 0xD2, 0x3E, 0x84, 0x39, 0xD3, 0x92, 0x65, 0x86, 0xB2, 0xA1,
- 0xBC, 0xFF, 0xC5, 0x9A, 0xA3, 0x64, 0x46, 0xE8, 0xCE, 0xF9, 0x6C, 0x73, 0x53, 0xD8, 0x85, 0x99,
- 0x18, 0x05, 0x52, 0x8A, 0x01, 0x1C, 0x9A, 0x7D, 0x68, 0x2D, 0x8C, 0xB2, 0x90, 0x58, 0xAB, 0x3D,
- 0xD2, 0xB6, 0x51, 0x55, 0x03, 0x54, 0x7C, 0x46, 0x01, 0x03, 0xCE, 0xB2, 0x24, 0x80, 0xA8, 0x8B,
- 0x39, 0xBA, 0xB2, 0x2D, 0xC5, 0xBA, 0xD0, 0x84, 0x0E, 0xEC, 0x67, 0xC8, 0x12, 0x95, 0x97, 0xAD,
- 0xA2, 0x27, 0x12, 0xC5, 0x77, 0x95, 0x9E, 0xC8, 0x6F, 0xE5, 0x84, 0xAA, 0xC8, 0x77, 0x88, 0x2F,
- 0x13, 0x5C, 0xD4, 0xD1, 0x13, 0xA0, 0x24, 0x83, 0x52, 0x34, 0x60, 0x2A, 0x2C, 0x37, 0xEE, 0xEB,
- 0xD3, 0xE9, 0xB4, 0x8E, 0xDF, 0x6A, 0xEB, 0x70, 0x82, 0xB2, 0x02, 0x5F, 0x5F, 0xC7, 0x21, 0x47,
- 0x15, 0x58, 0xF8, 0x6E, 0xE1, 0xAC, 0xBA, 0xE8, 0x42, 0x7F, 0x2B, 0xDE, 0xD4, 0xAA, 0xD2, 0x59,
- 0xE1, 0x73, 0x79, 0xDB, 0x7B, 0x3B, 0x2B, 0x20, 0x32, 0xC4, 0xAF, 0xB2, 0x90, 0x69, 0x20, 0x0D,
- 0x3B, 0xE5, 0x46, 0x56, 0x25, 0x85, 0x65, 0x5C, 0xB0, 0xE3, 0x2C, 0x9D, 0x18, 0x33, 0x60, 0xDD,
- 0x11, 0x96, 0xD2, 0x95, 0x43, 0x2D, 0x65, 0xB7, 0x0E, 0xB7, 0x0A, 0xFB, 0x70, 0x30, 0x83, 0x94,
- 0x79, 0xFB, 0xF3, 0x4F, 0x39, 0x5B, 0xDE, 0xF6, 0x92, 0x62, 0x71, 0xE1, 0xF3, 0xFC, 0xA9, 0x35,
- 0xAF, 0x69, 0xA5, 0xD1, 0xAF, 0xC4, 0x97, 0xBD, 0x46, 0xFE, 0x19, 0x3B, 0xFF, 0x9C, 0xAD, 0x81,
- 0xB1, 0x43, 0x23, 0x2A, 0xDC, 0x4C, 0x8C, 0xEA, 0x2F, 0x34, 0xE6, 0x63, 0x79, 0x29, 0xBF, 0x2D,
- 0xA0, 0x54, 0xA9, 0xD3, 0x68, 0x78, 0x3E, 0xFF, 0x9A, 0x42, 0x19, 0x1D, 0x65, 0xFE, 0x28, 0x20,
- 0x09, 0xC5, 0x82, 0xA3, 0x41, 0xBE, 0x92, 0xFB, 0x46, 0xC0, 0x86, 0x69, 0x03, 0x93, 0x6D, 0xCB,
- 0xDE, 0xB2, 0x77, 0x71, 0x64, 0x7F, 0x4D, 0xF7, 0x57, 0x4F, 0xD8, 0x5F, 0x34, 0x69, 0x58, 0x0B,
- 0xE7, 0xB5, 0xAB, 0x8A, 0x4D, 0x6A, 0x83, 0xFB, 0xC4, 0xA7, 0x70, 0x3D, 0x6F, 0xB3, 0xCC, 0xB6,
- 0x1A, 0xE4, 0x5F, 0x60, 0xD4, 0x31, 0xBA, 0x95, 0x2F, 0x92, 0xF4, 0x81, 0x7B, 0x18, 0x5B, 0x17,
- 0x54, 0x26, 0x70, 0x49, 0xD5, 0x87, 0x34, 0xB9, 0xD3, 0x9C, 0x2F, 0x39, 0xC3, 0xB7, 0x3C, 0xA8,
- 0x03, 0xE4, 0x37, 0x9C, 0x72, 0x39, 0xB0, 0xBF, 0x07, 0x5D, 0x33, 0x2A, 0x41, 0x79, 0xB1, 0x26,
- 0x9B, 0xE6, 0x7C, 0x02, 0x82, 0x01, 0x70, 0xB1, 0xA3, 0x48, 0xCD, 0x2B, 0xCB, 0x98, 0x9B, 0x57,
- 0x96, 0x54, 0xE2, 0x5F, 0x59, 0xCC, 0xDB, 0x9F, 0xFC, 0xDB, 0x4C, 0xF9, 0x7F, 0x5B, 0x28, 0x36,
- 0x32, 0xF9, 0xE1, 0x09, 0xF7, 0x56, 0x3F, 0x45, 0xAD, 0x47, 0x51, 0xBB, 0xF7, 0xFF, 0x17, 0x53,
- 0xE8, 0x9D, 0x36, 0x92, 0x29, 0x00, 0x00};
-
#define SPIFFS_MAXLENGTH_FILEPATH 32
-const char *excludeListFile = "/.exclude.files";
-typedef struct ExcludeListS {
- char *item;
- ExcludeListS *next;
-} ExcludeList;
-
-static ExcludeList *excludes = NULL;
-
-static bool matchWild(const char *pattern, const char *testee) {
- const char *nxPat = NULL;
- const char *nxTst = NULL;
-
- while (*testee) {
- if ((*pattern == '?') || (*pattern == *testee)) {
- ++pattern;
- ++testee;
- continue;
- }
- if (*pattern == '*') {
- nxPat = pattern++;
- nxTst = testee;
- continue;
- }
- if (nxPat) {
- pattern = nxPat + 1;
- testee = ++nxTst;
- continue;
- }
- return false;
- }
- while (*pattern == '*') {
- ++pattern;
- }
- return (*pattern == 0);
-}
-
-static bool addExclude(const char *item) {
- size_t len = strlen(item);
- if (!len) {
- return false;
- }
- ExcludeList *e = (ExcludeList *)malloc(sizeof(ExcludeList));
- if (!e) {
- return false;
- }
- e->item = (char *)malloc(len + 1);
- if (!e->item) {
- free(e);
- return false;
- }
- memcpy(e->item, item, len + 1);
- e->next = excludes;
- excludes = e;
- return true;
-}
-
-static void loadExcludeList(fs::FS &_fs, const char *filename) {
- static char linebuf[SPIFFS_MAXLENGTH_FILEPATH];
- fs::File excludeFile;
- if (filename[0] != '/') {
- excludeFile = _fs.open("/" + ((String)filename), "r");
- } else {
- excludeFile = _fs.open(filename, "r");
- }
- if (!excludeFile) {
- // addExclude("/*.js.gz");
- return;
- }
-#ifdef ESP32
- if (excludeFile.isDirectory()) {
- excludeFile.close();
- return;
- }
-#endif
- if (excludeFile.size() > 0) {
- uint8_t idx;
- bool isOverflowed = false;
- while (excludeFile.available()) {
- linebuf[0] = '\0';
- idx = 0;
- int lastChar;
- do {
- lastChar = excludeFile.read();
- if (lastChar != '\r') {
- linebuf[idx++] = (char)lastChar;
- }
- } while ((lastChar >= 0) && (lastChar != '\n') && (idx < SPIFFS_MAXLENGTH_FILEPATH));
-
- if (isOverflowed) {
- isOverflowed = (lastChar != '\n');
- continue;
- }
- isOverflowed = (idx >= SPIFFS_MAXLENGTH_FILEPATH);
- linebuf[idx - 1] = '\0';
- if (!addExclude(linebuf)) {
- excludeFile.close();
- return;
- }
- }
- }
- excludeFile.close();
-}
-
-static bool isExcluded(fs::FS &_fs, const char *filename) {
- if (excludes == NULL) {
- loadExcludeList(_fs, excludeListFile);
- }
- ExcludeList *e = excludes;
- while (e) {
- if (matchWild(e->item, filename)) {
- return true;
- }
- e = e->next;
- }
- return false;
-}
-
-// WEB HANDLER IMPLEMENTATION
-
-#ifdef ESP32
SPIFFSEditor::SPIFFSEditor(const fs::FS &fs, const String &username, const String &password)
-#else
-SPIFFSEditor::SPIFFSEditor(const String &username, const String &password, const fs::FS &fs)
-#endif
: _fs(fs), _username(username), _password(password), _authenticated(false), _startTime(0) {
}
@@ -406,24 +19,20 @@ bool SPIFFSEditor::canHandle(AsyncWebServerRequest *request) {
if (!request->_tempFile) {
return false;
}
-#ifdef ESP32
if (request->_tempFile.isDirectory()) {
request->_tempFile.close();
return false;
}
-#endif
}
if (request->hasParam("download")) {
request->_tempFile = _fs.open("/" + request->arg("download"), "r");
if (!request->_tempFile) {
return false;
}
-#ifdef ESP32
if (request->_tempFile.isDirectory()) {
request->_tempFile.close();
return false;
}
-#endif
}
request->addInterestingHeader("If-Modified-Since");
return true;
@@ -442,46 +51,22 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request) {
if (request->method() == HTTP_GET) {
if (request->hasParam("list")) {
const String path = request->getParam("list")->value();
-#ifdef ESP32
+
File dir = _fs.open(path);
-#else
- Dir dir = _fs.openDir(path);
-#endif
String output = "[";
-#ifdef ESP32
File file = dir.openNextFile();
while (file) {
-#else
- while (dir.next()) {
- fs::File entry = dir.openFile("r");
-#endif
- if (isExcluded(_fs, file.name())) {
-#ifdef ESP32
- file = dir.openNextFile();
-#endif
- continue;
- }
if (output != "[") {
output += ',';
}
- output += "{\"type\":\"";
- output += "file";
- output += "\",\"name\":\"";
- output += file.name();
- output += "\",\"size\":";
- output += file.size();
- output += ",\"ver\":";
- output += file.getLastWrite();
- output += "}";
-#ifdef ESP32
+ if (file.isDirectory()) {
+ output += "{\"type\":\"dir\",\"name\":\"" + String(file.name()) + "\",\"size\":" + file.size() + "}";
+ } else {
+ output += "{\"type\":\"file\",\"name\":\"" + String(file.name()) + "\",\"size\":" + file.size() + "}";
+ }
file = dir.openNextFile();
-#else
- file.close();
-#endif
}
-#ifdef ESP32
dir.close();
-#endif
output += "]";
request->send(200, "application/json", output);
} else if (request->hasParam("edit") || request->hasParam("download")) {
@@ -491,8 +76,7 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request) {
if (request->header("If-Modified-Since").equals(buildTime)) {
request->send(304);
} else {
- AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", edit_htm_gz, edit_htm_gz_len);
- response->addHeader("Content-Encoding", "gzip");
+ AsyncWebServerResponse *response = request->beginResponse(_fs, "/www/edit.html");
response->addHeader("Last-Modified", buildTime);
request->send(response);
}
diff --git a/esp32_fw/src/contentmanager.cpp b/esp32_fw/src/contentmanager.cpp
index 32970c2f..7fa8d864 100644
--- a/esp32_fw/src/contentmanager.cpp
+++ b/esp32_fw/src/contentmanager.cpp
@@ -56,7 +56,7 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
deserializeJson(doc, taginfo->modeConfigJson);
JsonObject cfgobj = doc.as();
- Serial.println("Updating " + dst + " mode " + String(taginfo->contentMode) + " nextupdate " + String(taginfo->nextupdate));
+ wsLog("Updating " + dst + " mode " + String(taginfo->contentMode));
taginfo->nextupdate = now + 600;
switch (taginfo->contentMode) {
@@ -67,7 +67,7 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
if (prepareDataAvail(&filename, DATATYPE_IMGRAW, mac, cfgobj["timetolive"].as())) {
cfgobj["#fetched"] = true;
} else {
- wsString("Error accessing " + filename);
+ wsErr("Error accessing " + filename);
}
taginfo->nextupdate = 3216153600;
}
@@ -75,21 +75,17 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
case Today:
- Serial.println("heap voor drawDate: " + String(ESP.getFreeHeap()));
- drawDate(filename);
- Serial.println("heap na drawDate: " + String(ESP.getFreeHeap()));
+ drawDate(filename, taginfo);
// updateTagImage(filename, mac, (midnight - now) / 60 - 10);
- updateTagImage(filename, mac, 60);
+ updateTagImage(filename, mac, 0);
taginfo->nextupdate = midnight;
break;
case CountDays:
if (buttonPressed) cfgobj["counter"] = 0;
- Serial.println("heap voor drawnumber: " + String(ESP.getFreeHeap()));
- drawNumber(filename, (int32_t)cfgobj["counter"], (int32_t)cfgobj["thresholdred"]);
- Serial.println("heap na drawnumber: " + String(ESP.getFreeHeap()));
- updateTagImage(filename, mac, 60);
+ drawNumber(filename, (int32_t)cfgobj["counter"], (int32_t)cfgobj["thresholdred"], taginfo);
+ updateTagImage(filename, mac, (buttonPressed?0:60));
cfgobj["counter"] = (int32_t)cfgobj["counter"] + 1;
taginfo->nextupdate = midnight;
break;
@@ -97,12 +93,10 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
case CountHours:
if (buttonPressed) cfgobj["counter"] = 0;
- Serial.println("heap voor drawnumber: " + String(ESP.getFreeHeap()));
- drawNumber(filename, (int32_t)cfgobj["counter"], (int32_t)cfgobj["thresholdred"]);
- Serial.println("heap na drawnumber: " + String(ESP.getFreeHeap()));
+ drawNumber(filename, (int32_t)cfgobj["counter"], (int32_t)cfgobj["thresholdred"], taginfo);
// updateTagImage(&filename, mac, (3600 - now % 3600) / 60);
// taginfo->nextupdate = now + 3600 - (now % 3600);
- updateTagImage(filename, mac, 3);
+ updateTagImage(filename, mac, (buttonPressed?0:3));
cfgobj["counter"] = (int32_t)cfgobj["counter"] + 1;
taginfo->nextupdate = now + 300;
break;
@@ -110,6 +104,13 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
case Weather:
// https://open-meteo.com/
+ // https://geocoding-api.open-meteo.com/v1/search?name=eindhoven
+ // https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41¤t_weather=true
+ // https://github.com/erikflowers/weather-icons
+
+ drawWeather(filename, cfgobj["location"], taginfo);
+ updateTagImage(filename, mac, 0);
+ taginfo->nextupdate = now + 900;
break;
case Firmware:
@@ -119,7 +120,7 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
if (prepareDataAvail(&filename, DATATYPE_UPDATE, mac, cfgobj["timetolive"].as())) {
cfgobj["#fetched"] = true;
} else {
- wsString("Error accessing " + filename);
+ wsErr("Error accessing " + filename);
}
cfgobj["filename"]="";
taginfo->nextupdate = 3216153600;
@@ -149,8 +150,7 @@ bool updateTagImage(String &filename, uint8_t *dst, uint16_t nextCheckin) {
return true;
}
-void drawDate(String &filename) {
-
+void drawDate(String &filename, tagRecord *&taginfo) {
TFT_eSPI tft = TFT_eSPI();
TFT_eSprite spr = TFT_eSprite(&tft);
time_t now;
@@ -161,59 +161,291 @@ void drawDate(String &filename) {
String Maand[] = {"januari", "februari", "maart", "april", "mei", "juni","juli", "augustus", "september", "oktober", "november", "december"};
int weekday_number = timeinfo.tm_wday;
int month_number = timeinfo.tm_mon;
+ long w,h;
LittleFS.begin();
- long w = 296, h = 128; // mag staand of liggend
- spr.createSprite(w, h);
- if (spr.getPointer() == nullptr) {
- Serial.println("Failed to create sprite in drawDate");
+
+ if (taginfo->model == SOLUM_29_033) {
+ w = 296;
+ h = 128;
+ spr.createSprite(w, h);
+ if (spr.getPointer() == nullptr) {
+ wsErr("Failed to create sprite in drawDate");
+ }
+ spr.setColorDepth(8);
+ spr.fillSprite(TFT_WHITE);
+ spr.setTextDatum(TC_DATUM);
+ spr.loadFont("fonts/calibrib62", LittleFS);
+ spr.setTextColor(TFT_RED, TFT_WHITE);
+ spr.drawString(Dag[timeinfo.tm_wday], w / 2, 10);
+ spr.loadFont("fonts/calibrib50", LittleFS);
+ spr.setTextColor(TFT_BLACK, TFT_WHITE);
+ spr.drawString(String(timeinfo.tm_mday) + " " + Maand[timeinfo.tm_mon], w / 2, 73);
+ spr.unloadFont();
+ } else if (taginfo->model == SOLUM_154_033) {
+ w = 154;
+ h = 154;
+ spr.createSprite(w, h);
+ if (spr.getPointer() == nullptr) {
+ wsErr("Failed to create sprite in drawDate");
+ }
+ spr.setColorDepth(8);
+ spr.fillSprite(TFT_WHITE);
+ spr.setTextDatum(TC_DATUM);
+ spr.loadFont("fonts/calibrib30", LittleFS);
+ spr.setTextColor(TFT_BLACK, TFT_WHITE);
+ spr.drawString(Dag[timeinfo.tm_wday], w / 2, 10);
+ spr.drawString(String(Maand[timeinfo.tm_mon]), w / 2, 120);
+ spr.unloadFont();
+ spr.loadFont("fonts/numbers2-1", LittleFS);
+ spr.setTextColor(TFT_RED, TFT_WHITE);
+ spr.drawString(String(timeinfo.tm_mday), w / 2, 42);
+ spr.unloadFont();
}
- spr.setColorDepth(8);
- spr.fillSprite(TFT_WHITE);
- spr.setTextDatum(TC_DATUM);
- spr.loadFont("calibrib62", LittleFS);
- spr.setTextColor(TFT_RED, TFT_WHITE);
- spr.drawString(Dag[timeinfo.tm_wday], w / 2, 10);
- spr.loadFont("calibrib50", LittleFS);
- spr.setTextColor(TFT_BLACK, TFT_WHITE);
- spr.drawString(String(timeinfo.tm_mday) + " " + Maand[timeinfo.tm_mon], w / 2, 73);
- spr.unloadFont();
spr2grays(spr, w, h, filename);
spr.deleteSprite();
}
-void drawNumber(String &filename, int32_t count, int32_t thresholdred) {
+void drawNumber(String &filename, int32_t count, int32_t thresholdred, tagRecord *&taginfo) {
TFT_eSPI tft = TFT_eSPI();
TFT_eSprite spr = TFT_eSprite(&tft);
LittleFS.begin();
- long w = 296, h = 128;
- spr.createSprite(w, h);
- if (spr.getPointer() == nullptr) {
- Serial.println("Failed to create sprite in drawNumber");
- }
spr.setColorDepth(8);
- spr.fillSprite(TFT_WHITE);
- spr.setTextDatum(MC_DATUM);
- if (count > thresholdred) {
- spr.setTextColor(TFT_RED, TFT_WHITE);
- } else {
- spr.setTextColor(TFT_BLACK, TFT_WHITE);
+ long w, h;
+
+ if (taginfo->model == SOLUM_29_033) {
+ w = 296;
+ h = 128;
+ spr.createSprite(w, h);
+ if (spr.getPointer() == nullptr) {
+ wsErr("Failed to create sprite in drawNumber");
+ }
+ spr.fillSprite(TFT_WHITE);
+ spr.setTextDatum(MC_DATUM);
+ if (count > thresholdred) {
+ spr.setTextColor(TFT_RED, TFT_WHITE);
+ } else {
+ spr.setTextColor(TFT_BLACK, TFT_WHITE);
+ }
+ String font = "fonts/numbers1-2";
+ if (count > 999) font = "fonts/numbers2-2";
+ if (count > 9999) font = "fonts/numbers3-2";
+ spr.loadFont(font, LittleFS);
+ spr.drawString(String(count), w / 2, h / 2 + 10);
+ spr.unloadFont();
+ } else if (taginfo->model == SOLUM_154_033) {
+ w = 154;
+ h = 154;
+ spr.createSprite(w, h);
+ if (spr.getPointer() == nullptr) {
+ wsErr("Failed to create sprite in drawNumber");
+ }
+ spr.fillSprite(TFT_WHITE);
+ spr.setTextDatum(MC_DATUM);
+ if (count > thresholdred) {
+ spr.setTextColor(TFT_RED, TFT_WHITE);
+ } else {
+ spr.setTextColor(TFT_BLACK, TFT_WHITE);
+ }
+ String font = "fonts/numbers1-1";
+ if (count > 99) font = "fonts/numbers2-1";
+ if (count > 999) font = "fonts/numbers3-1";
+ spr.loadFont(font, LittleFS);
+ spr.drawString(String(count), w / 2, h / 2 + 10);
+ spr.unloadFont();
}
- String font = "numbers1-2";
- if (count>999) font="numbers2-2";
- if (count>9999) font="numbers3-2";
- spr.loadFont(font, LittleFS);
- spr.drawString(String(count), w/2, h/2+10);
- spr.unloadFont();
spr2grays(spr, w, h, filename);
spr.deleteSprite();
}
+void drawWeather(String &filename, String location, tagRecord *&taginfo) {
+
+ TFT_eSPI tft = TFT_eSPI();
+ TFT_eSprite spr = TFT_eSprite(&tft);
+
+ wsLog("get weather");
+ HTTPClient http;
+ http.begin("https://geocoding-api.open-meteo.com/v1/search?name=" + urlEncode(location.c_str()) + "&count=1");
+ http.setTimeout(5000); // timeout in ms
+ int httpCode = http.GET();
+ if (httpCode == 200) {
+
+ StaticJsonDocument<1000> doc;
+ DeserializationError error = deserializeJson(doc, http.getStream());
+ http.end();
+
+ http.begin("https://api.open-meteo.com/v1/forecast?latitude=" + doc["results"][0]["latitude"].as() + "&longitude=" + doc["results"][0]["longitude"].as() + "¤t_weather=true&windspeed_unit=ms&timezone=" + doc["results"][0]["timezone"].as());
+ http.setTimeout(5000); // timeout in ms
+ int httpCode = http.GET();
+
+ if (httpCode == 200) {
+
+ StaticJsonDocument<200> filter;
+ filter["current_weather"]["temperature"] = true;
+ filter["current_weather"]["windspeed"] = true;
+ filter["current_weather"]["winddirection"] = true;
+ filter["current_weather"]["weathercode"] = true;
+
+ doc.clear();
+ DeserializationError error = deserializeJson(doc, http.getString(), DeserializationOption::Filter(filter));
+ if (error) {
+ Serial.println(F("deserializeJson() failed: "));
+ Serial.println(error.c_str());
+ }
+
+ auto temperature = doc["current_weather"]["temperature"].as();
+ auto windspeed = doc["current_weather"]["windspeed"].as();
+ auto winddirection = doc["current_weather"]["winddirection"].as();
+
+ uint8_t weathercode = doc["current_weather"]["weathercode"].as();
+ if (weathercode > 40) weathercode -= 40;
+ int wind = windSpeedToBeaufort(windspeed);
+
+ String weatherIcons[] = {"\uf00d", "\uf00c", "\uf002", "\uf013", "\uf013", "\uf014", "-", "-", "\uf014", "-", "-",
+ "\uf01a", "-", "\uf01a", "-", "\uf01a", "\uf017", "\uf017", "-", "-", "-",
+ "\uf019", "-", "\uf019", "-", "\uf019", "\uf015", "\uf015", "-", "-", "-",
+ "\uf01b", "-", "\uf01b", "-", "\uf01b", "-", "\uf076", "-", "-", "\uf01a",
+ "\uf01a", "\uf01a", "-", "-", "\uf064", "\uf064", "-", "-", "-", "-",
+ "-", "-", "-", "-", "\uf01e", "\uf01d", "-", "-", "\uf01e"};
+ if (1==0) { //nacht
+ weatherIcons[0] = "\0uf02e";
+ weatherIcons[1] = "\0uf083";
+ weatherIcons[2] = "\0uf086";
+ }
+
+ String windIcons[] = {"\uf0b7", "\uf0b8", "\uf0b9", "\uf0ba", "\uf0bb", "\uf0bc", "\uf0bd", "\uf0be", "\uf0bf", "\uf0c0", "\uf0c1", "\uf0c2", "\uf0c3"};
+
+ doc.clear();
+
+ LittleFS.begin();
+ spr.setColorDepth(8);
+ tft.setTextWrap(false,false);
+
+ long w, h;
+
+ if (taginfo->model == SOLUM_29_033) {
+ w = 296;
+ h = 128;
+ spr.createSprite(w, h);
+ if (spr.getPointer() == nullptr) {
+ wsErr("Failed to create sprite in drawWeather");
+ }
+ spr.fillSprite(TFT_WHITE);
+ spr.setTextDatum(TL_DATUM);
+
+ spr.loadFont("fonts/bahnschrift30", LittleFS);
+ spr.setTextColor(TFT_BLACK, TFT_WHITE);
+ spr.drawString(location, 10, 10);
+ spr.unloadFont();
+
+ spr.loadFont("fonts/bahnschrift70", LittleFS);
+ if (temperature < 0) {
+ spr.setTextColor(TFT_RED, TFT_WHITE);
+ } else {
+ spr.setTextColor(TFT_BLACK, TFT_WHITE);
+ }
+ char tmpOutput[5];
+ dtostrf(temperature, 2, 1, tmpOutput);
+ spr.drawString(String(tmpOutput), 5, 65);
+ spr.unloadFont();
+
+ spr.loadFont("fonts/weathericons78", LittleFS);
+ if (weathercode == 55 || weathercode == 65 || weathercode == 75 || weathercode == 82 || weathercode == 86 || weathercode == 95 || weathercode == 99) {
+ spr.setTextColor(TFT_RED, TFT_WHITE);
+ } else {
+ spr.setTextColor(TFT_BLACK, TFT_WHITE);
+ }
+ spr.setTextColor(TFT_BLACK, TFT_WHITE);
+ spr.setCursor(185, 20);
+ spr.printToSprite(weatherIcons[weathercode]);
+ spr.unloadFont();
+
+ spr.loadFont("fonts/weathericons30", LittleFS);
+ if (wind > 4) {
+ spr.setTextColor(TFT_RED, TFT_WHITE);
+ } else {
+ spr.setTextColor(TFT_BLACK, TFT_WHITE);
+ }
+ spr.setCursor(255, 0);
+ spr.printToSprite(windIcons[wind]);
+
+ spr.setTextColor(TFT_BLACK, TFT_WHITE);
+ spr.setCursor(230, -5);
+ spr.printToSprite(windDirectionIcon(winddirection));
+ if (weathercode > 10) {
+ spr.setTextColor(TFT_RED, TFT_WHITE);
+ spr.setCursor(190, 0);
+ spr.printToSprite("\uf084");
+ }
+ } else if (taginfo->model == SOLUM_154_033) {
+ w = 154;
+ h = 154;
+
+ spr.createSprite(w, h);
+ if (spr.getPointer() == nullptr) {
+ wsErr("Failed to create sprite in drawWeather");
+ }
+ spr.fillSprite(TFT_WHITE);
+ spr.setTextDatum(TL_DATUM);
+
+ spr.setTextFont(2);
+ spr.setTextColor(TFT_BLACK, TFT_WHITE);
+ spr.drawString(location, 10, 130);
+
+ spr.loadFont("fonts/bahnschrift30", LittleFS);
+ if (temperature < 0) {
+ spr.setTextColor(TFT_RED, TFT_WHITE);
+ } else {
+ spr.setTextColor(TFT_BLACK, TFT_WHITE);
+ }
+ char tmpOutput[5];
+ dtostrf(temperature, 2, 1, tmpOutput);
+ spr.drawString(String(tmpOutput), 10, 10);
+ spr.unloadFont();
+
+ spr.loadFont("fonts/weathericons78", LittleFS);
+ if (weathercode == 55 || weathercode == 65 || weathercode == 75 || weathercode == 82 || weathercode == 86 || weathercode == 95 || weathercode == 99) {
+ spr.setTextColor(TFT_RED, TFT_WHITE);
+ } else {
+ spr.setTextColor(TFT_BLACK, TFT_WHITE);
+ }
+ spr.setTextColor(TFT_BLACK, TFT_WHITE);
+ spr.setCursor(35, 25);
+ spr.printToSprite(weatherIcons[weathercode]);
+ spr.unloadFont();
+
+ spr.loadFont("fonts/weathericons30", LittleFS);
+ if (wind > 4) {
+ spr.setTextColor(TFT_RED, TFT_WHITE);
+ } else {
+ spr.setTextColor(TFT_BLACK, TFT_WHITE);
+ }
+ spr.setCursor(115, -5);
+ spr.printToSprite(windIcons[wind]);
+
+ spr.setTextColor(TFT_BLACK, TFT_WHITE);
+ spr.setCursor(90, -5);
+ spr.printToSprite(windDirectionIcon(winddirection));
+ if (weathercode > 10) {
+ spr.setTextColor(TFT_RED, TFT_WHITE);
+ spr.setCursor(115, 110);
+ spr.printToSprite("\uf084");
+ }
+ }
+
+ spr.unloadFont();
+ spr2grays(spr, w, h, filename);
+ spr.deleteSprite();
+ }
+ }
+ http.end();
+}
+
bool getImgURL(String &filename, String URL, time_t fetched) {
// https://images.klari.net/kat-bw29.jpg
@@ -233,7 +465,11 @@ bool getImgURL(String &filename, String URL, time_t fetched) {
jpg2grays(filename, filename);
}
} else {
- Serial.println("http " + String(httpCode));
+ if (httpCode!=304) {
+ wsErr("http " + URL + " " + String(httpCode));
+ } else {
+ wsLog("http " + URL + " " + String(httpCode));
+ }
}
http.end();
return (httpCode == 200);
@@ -246,3 +482,41 @@ char *formatHttpDate(time_t t) {
strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S GMT", timeinfo);
return buf;
}
+
+String urlEncode(const char *msg) {
+ const char *hex = "0123456789ABCDEF";
+ String encodedMsg = "";
+
+ while (*msg != '\0') {
+ if (
+ ('a' <= *msg && *msg <= 'z') || ('A' <= *msg && *msg <= 'Z') || ('0' <= *msg && *msg <= '9') || *msg == '-' || *msg == '_' || *msg == '.' || *msg == '~') {
+ encodedMsg += *msg;
+ } else {
+ encodedMsg += '%';
+ encodedMsg += hex[(unsigned char)*msg >> 4];
+ encodedMsg += hex[*msg & 0xf];
+ }
+ msg++;
+ }
+ return encodedMsg;
+}
+
+int windSpeedToBeaufort(float windSpeed) {
+ int beaufort = 0;
+ float speeds[] = {0.3, 1.5, 3.3, 5.5, 8, 10.8, 13.9, 17.2, 20.8, 24.5, 28.5, 32.7};
+ for (int i = 0; i < 12; i++) {
+ if (windSpeed >= speeds[i]) {
+ beaufort = i + 1;
+ }
+ }
+ return beaufort;
+}
+
+String windDirectionIcon(int degrees) {
+ String directions[] = {"\uf044", "\uf088", "\uf04d", "\uf057", "\uf058", "\uf087", "\uf048", "\uf043"};
+ int index = (degrees + 22) / 45;
+ if (index >= 8) {
+ index = 0;
+ }
+ return directions[index];
+}
diff --git a/esp32_fw/src/main.cpp b/esp32_fw/src/main.cpp
index e46ea598..0f8f2aa2 100644
--- a/esp32_fw/src/main.cpp
+++ b/esp32_fw/src/main.cpp
@@ -31,11 +31,11 @@ void setup() {
Serial.begin(115200);
Serial.print(">\n");
- configTzTime("CET-1CEST,M3.5.0,M10.5.0/3", "europe.pool.ntp.org", "time.nist.gov");
+ configTzTime("CET-1CEST,M3.5.0,M10.5.0/3", "0.nl.pool.ntp.org", "europe.pool.ntp.org", "time.nist.gov");
// https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
init_web();
- loadDB("/tagDB.json");
+ loadDB("/current/tagDB.json");
xTaskCreate(timeTask, "timed tasks", 10000, NULL, 2, NULL);
xTaskCreate(zbsRxTask, "zbsRX Process", 10000, NULL, 2, NULL);
diff --git a/esp32_fw/src/makeimage.cpp b/esp32_fw/src/makeimage.cpp
index 7d23a013..1d6762db 100644
--- a/esp32_fw/src/makeimage.cpp
+++ b/esp32_fw/src/makeimage.cpp
@@ -4,6 +4,7 @@
#include
#include
#include
+#include
TFT_eSPI tft = TFT_eSPI();
TFT_eSprite spr = TFT_eSprite(&tft);
@@ -22,7 +23,7 @@ void jpg2grays(String filein, String fileout) {
spr.createSprite(w, h);
if (spr.getPointer() == nullptr) {
- Serial.println("Failed to create sprite in jpg2grays");
+ wsErr("Failed to create sprite in jpg2grays");
}
spr.setColorDepth(8);
spr.fillSprite(TFT_WHITE);
diff --git a/esp32_fw/src/newproto.cpp b/esp32_fw/src/newproto.cpp
index 4df7f8ac..99d0ddfd 100644
--- a/esp32_fw/src/newproto.cpp
+++ b/esp32_fw/src/newproto.cpp
@@ -71,12 +71,11 @@ bool prepareDataAvail(String* filename, uint8_t dataType, uint8_t* dst, uint16_t
if (hdr.width == 296 && hdr.height == 128) {
//sorry, can't rotate
Serial.println("when using BMP files, remember to only use 128px width and 296px height");
- wsString("when using BMP files, remember to only use 128px width and 296px height");
+ wsErr("when using BMP files, remember to only use 128px width and 296px height");
return false;
}
if (hdr.sig[0] == 'B' && hdr.sig[1] == 'M' && hdr.bpp == 24) {
Serial.println("converting 24bpp bmp to grays");
- wsString("converting 24bpp bmp to grays");
char fileout[64];
sprintf(fileout, "/temp/%02X%02X%02X%02X%02X%02X.bmp\0", dst[5], dst[4], dst[3], dst[2], dst[1], dst[0]);
bmp2grays(*filename,(String)fileout);
@@ -88,7 +87,6 @@ bool prepareDataAvail(String* filename, uint8_t dataType, uint8_t* dst, uint16_t
if (filename->endsWith(".jpg") || filename->endsWith(".JPG")) {
Serial.println("converting jpg to grays");
- wsString("converting jpg to grays");
char fileout[64];
sprintf(fileout, "/temp/%02X%02X%02X%02X%02X%02X.bmp\0", dst[5], dst[4], dst[3], dst[2], dst[1], dst[0]);
jpg2grays(*filename, (String)fileout);
@@ -114,7 +112,7 @@ bool prepareDataAvail(String* filename, uint8_t dataType, uint8_t* dst, uint16_t
taginfo = tagRecord::findByMAC(mac);
if (taginfo != nullptr) {
if (memcmp(md5bytes, taginfo->md5pending, 16) == 0) {
- wsString("new image is the same as current image. not updating tag.");
+ Serial.println("new image is the same as current image. not updating tag.");
wsSendTaginfo(mac);
return false;
}
@@ -156,7 +154,7 @@ bool prepareDataAvail(String* filename, uint8_t dataType, uint8_t* dst, uint16_t
}
dstfile.close();
- wsString("new image pending: " + String(dst_path));
+ wsLog("new image pending: " + String(dst_path));
if (taginfo != nullptr) {
taginfo->pending = true;
taginfo->CheckinInMinPending = nextCheckin + 1;
@@ -164,7 +162,7 @@ bool prepareDataAvail(String* filename, uint8_t dataType, uint8_t* dst, uint16_t
}
}
else {
- Serial.println("firmware upload pending");
+ wsLog("firmware upload pending");
}
file.close();
@@ -211,7 +209,7 @@ void processBlockRequest(struct espBlockRequest* br) {
sendBlock(pd->data + (br->blockId * BLOCK_DATA_SIZE), len);
char buffer[64];
sprintf(buffer, "< Block Request received for MD5 %llu, block %d\n\0", br->ver, br->blockId);
- wsString((String)buffer);
+ wsLog((String)buffer);
Serial.printf("blockId);
}
@@ -220,7 +218,7 @@ void processXferComplete(struct espXferComplete* xfc) {
uint8_t src[8];
*((uint64_t*)src) = swap64(*((uint64_t*)xfc->src));
sprintf(buffer, "< %02X%02X%02X%02X%02X%02X reports xfer complete\n\0", src[2], src[3], src[4], src[5], src[6], src[7]);
- wsString((String)buffer);
+ wsLog((String)buffer);
Serial.print(buffer);
uint8_t mac[6];
memcpy(mac, src + 2, sizeof(mac));
@@ -270,12 +268,12 @@ void processDataReq(struct espAvailDataReq* eadr) {
time_t now;
time(&now);
taginfo->lastseen = now;
+ //taginfo->model = eadr->adr.hwType;
taginfo->expectedNextCheckin = now + 300;
taginfo->button = (eadr->adr.wakeupReason==WAKEUP_REASON_GPIO);
Serial.printf("t=%d, lqi=%d, rssi=%d, ", eadr->adr.temperature, eadr->adr.lastPacketLQI, eadr->adr.lastPacketRSSI);
Serial.printf("hwtype=%d, reason=%d, volt=%d", eadr->adr.hwType,eadr->adr.wakeupReason,eadr->adr.batteryMv);
sprintf(buffer, "", 4) == 0) {
Serial.print(">SYNC BURST\n");
- wsString(">SYNC BURST");
RXState = ZBS_RX_WAIT_HEADER;
}
if (strncmp(cmdbuffer, "XFC>", 4) == 0) {
diff --git a/esp32_fw/src/web.cpp b/esp32_fw/src/web.cpp
index 5b8618a3..cb60af77 100644
--- a/esp32_fw/src/web.cpp
+++ b/esp32_fw/src/web.cpp
@@ -143,14 +143,22 @@ void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType
}
}
-void wsString(String text) {
- DynamicJsonDocument doc(100);
+void wsLog(String text) {
+ StaticJsonDocument<500> doc;
doc["logMsg"] = text;
xSemaphoreTake(wsMutex, portMAX_DELAY);
ws.textAll(doc.as());
xSemaphoreGive(wsMutex);
}
+void wsErr(String text) {
+ StaticJsonDocument<500> doc;
+ doc["errMsg"] = text;
+ xSemaphoreTake(wsMutex, portMAX_DELAY);
+ ws.textAll(doc.as());
+ xSemaphoreGive(wsMutex);
+}
+
void wsSendSysteminfo() {
DynamicJsonDocument doc(250);
JsonObject sys = doc.createNestedObject("sys");
@@ -181,11 +189,6 @@ void wsSendTaginfo(uint8_t mac[6]) {
void init_web() {
LittleFS.begin(true);
- if (!LittleFS.exists("/.exclude.files")) {
- Serial.println("littlefs exclude.files aanmaken");
- File f = LittleFS.open("/.exclude.files", "w");
- f.close();
- }
if (!LittleFS.exists("/current")) {
LittleFS.mkdir("/current");
}
@@ -214,8 +217,9 @@ void init_web() {
ESP.restart();
});
- server.serveStatic("/", LittleFS, "/").setDefaultFile("index.htm");
-
+ server.serveStatic("/current", LittleFS, "/current/");
+ server.serveStatic("/", LittleFS, "/www/").setDefaultFile("index.html");
+
server.on(
"/imgupload", HTTP_POST, [](AsyncWebServerRequest *request) {
request->send(200);
@@ -282,7 +286,7 @@ void init_web() {
taginfo->model = atoi(request->getParam("model", true)->value().c_str());
taginfo->nextupdate = 0;
wsSendTaginfo(mac);
- saveDB("/tagDB.json");
+ saveDB("/current/tagDB.json");
request->send(200, "text/plain", "Ok, saved");
} else {
request->send(200, "text/plain", "Error while saving: mac not found");