content template redesign / textbox / various

- Added Signika-SB.ttf and some small bitmap fonts
- Removed calibrib50/60/80/100/120/150 bitmap fonts, as they can be better rendered using truetype. Fallback is in place to auto translate to Signika-SB.ttf with the right size in case it is still used in a json template
- Renamed confusing tag type names to 'M2 + size' and 'M3 + size'. Because the universal firmware, there is no need to tell every subtile type change apart anymore.
- added `textbox` to json templates (https://github.com/jjwbruijn/OpenEPaperLink/wiki/Json-template#paragraph-text)
- redesign of count days/hours
- redesign of RSS feed
- designed Buienradar for more tag sizes
- on a scheduled or user initiated reboot, 'REBOOTING' is sent to the error channel of the websockets just before the connection is dropped
- phased out "hwtype": [] in content_cards.json (new location is in the tagtype json, which contains a list of valid content types)

In case of problems using this commit: keep in mind the heavy caching of the tagtypes in the browser. You might still unknowingly use the old contents.
This commit is contained in:
Nic Limper
2024-01-05 13:59:31 +01:00
parent 00ce785158
commit 29589bc5b0
37 changed files with 400 additions and 201 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,5 +1,5 @@
{
"name": "STGR16000 1.54\"",
"name": "M2 1.54\"",
"width": 152,
"height": 152,
"rotatebuffer": 0,
@@ -16,13 +16,13 @@
"contentids": [ 0, 1, 2, 3, 4, 5, 7, 10, 14, 15, 17, 18, 19, 20, 21],
"template": {
"1": {
"weekday": [ 76, 10, "fonts/calibrib30" ],
"weekday": [ 76, 9, "fonts/calibrib30" ],
"month": [ 76, 120, "fonts/calibrib30" ],
"day": [ 76, 42, "fonts/calibrib100" ]
"day": [ 76, 13, "Signika-SB.ttf", 100 ]
},
"2": {
"fonts": [ "fonts/calibrib120", "fonts/calibrib80", "fonts/calibrib50", "fonts/calibrib50" ],
"xy": [ 76, 83 ]
"fonts": [ "Signika-SB.ttf", 150, 110, 80, 60, 50, 40 ],
"xy": [ 76, 65 ]
},
"4": {
"location": [ 10, 145, "t0_14b_tf" ],
@@ -33,7 +33,7 @@
"umbrella": [ 125, 110, 30 ]
},
"10": {
"title": [ 10, 15, "t0_14b_tf" ],
"title": [ 76, 15, "t0_14b_tf" ],
"pos": [ 76, 20 ]
},
"21": [

View File

@@ -1,5 +1,5 @@
{
"name": "STGR29000 2.9\"",
"name": "M2 2.9\"",
"width": 296,
"height": 128,
"rotatebuffer": 1,
@@ -16,8 +16,12 @@
"contentids": [ 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 15, 16, 17, 18, 19, 20, 21 ],
"template": {
"1": {
"weekday": [148, 10, "fonts/calibrib60"],
"date": [148, 73, "fonts/calibrib50"]
"weekday": [ 148, -3, "Signika-SB.ttf", 60 ],
"date": [ 148, 65, "Signika-SB.ttf", 48 ]
},
"2": {
"fonts": [ "Signika-SB.ttf", 150, 150, 150, 120, 100, 80 ],
"xy": [ 148, 53 ]
},
"16": {
"location": [ 5, 5, "fonts/bahnschrift30" ],
@@ -25,10 +29,6 @@
"cols": [ 1, 125, 12, "glasstown_nbp_tf" ],
"bars": [ 5, 111, 10 ]
},
"2": {
"fonts": ["fonts/calibrib150", "fonts/calibrib150", "fonts/calibrib120", "fonts/calibrib100"],
"xy": [148, 74]
},
"4": {
"location": [5, 5, "fonts/bahnschrift30"],
"wind": [280, 5, "fonts/bahnschrift30"],
@@ -46,14 +46,14 @@
"line": [20, 128]
},
"9": {
"title": [5, 3, "fonts/bahnschrift20"],
"title": [ 2, 0, "bahnschrift20.vlw", 25 ],
"items": 8,
"line": [5, 34, 13],
"font": "glasstown_nbp_tf"
"line": [ 1, 25, "REFSAN12.vlw" ],
"desc": [ 0, 5, "", 1 ]
},
"10": {
"title": [10, 5, "fonts/bahnschrift20"],
"pos": [149, 25]
"title": [149, 5, "fonts/bahnschrift20"],
"pos": [149, 27]
},
"11": {
"title": [5, 2, "fonts/bahnschrift20"],

View File

@@ -1,5 +1,5 @@
{
"name": "STGR420B3N2 4.2\"",
"name": "M2 4.2\"",
"width": 400,
"height": 300,
"rotatebuffer": 0,
@@ -13,21 +13,17 @@
},
"shortlut": 1,
"options": ["button"],
"contentids": [ 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20, 21],
"contentids": [ 0, 1, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20],
"template": {
"1": {
"weekday": [ 200, 25, "fonts/calibrib60" ],
"month": [ 200, 225, "fonts/calibrib60" ],
"day": [ 200, 95, "fonts/calibrib150" ]
},
"2": {
"fonts": [ "fonts/calibrib150", "fonts/calibrib150", "fonts/calibrib150", "fonts/calibrib120" ],
"xy": [ 200, 148 ]
"weekday": [ 200, 0, "Signika-SB.ttf", 70 ],
"month": [ 200, 210, "Signika-SB.ttf", 70 ],
"day": [ 200, 45, "Signika-SB.ttf", 170 ]
},
"4": {
"location": [ 20, 20, "fonts/calibrib30" ],
"wind": [ 90, 83, "fonts/calibrib60" ],
"temp": [ 20, 170, "fonts/calibrib150" ],
"wind": [ 90, 83, "fonts/calibrib50" ],
"temp": [ 20, 170, "fonts/calibrib100" ],
"icon": [ 385, 0, 100, 2 ],
"dir": [ 40, 50, 80 ],
"umbrella": [ 325, 155, 78 ]
@@ -42,14 +38,14 @@
"line": [ 50, 300 ]
},
"9": {
"title": [ 10, 10, "fonts/calibrib30" ],
"items": 12,
"line": [ 10, 60, 20 ],
"font": "7x14_tf"
"title": [ 6, 0, "Signika-SB.ttf", 25 ],
"items": 4,
"line": [ 9, 40, "calibrib16.vlw" ],
"desc": [ 2, 8, "REFSAN12.vlw", 1.2 ]
},
"10": {
"title": [ 10, 10, "fonts/bahnschrift20" ],
"pos": [ 200, 30 ]
"title": [ 200, 10, "fonts/bahnschrift20" ],
"pos": [ 200, 35 ]
},
"11": {
"title": [ 10, 10, "fonts/bahnschrift30" ],

View File

@@ -1,5 +1,5 @@
{
"name": "STGR750BN 7.4\"",
"name": "M2 7.4\"",
"width": 640,
"height": 384,
"rotatebuffer": 0,
@@ -13,21 +13,17 @@
},
"shortlut": 1,
"options": [],
"contentids": [ 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20],
"contentids": [ 0, 1, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20],
"template": {
"1": {
"weekday": [ 200, 25, "fonts/calibrib60" ],
"month": [ 200, 225, "fonts/calibrib60" ],
"day": [ 200, 95, "fonts/calibrib150" ]
},
"2": {
"fonts": [ "fonts/calibrib150", "fonts/calibrib150", "fonts/calibrib150", "fonts/calibrib120" ],
"xy": [ 200, 148 ]
"weekday": [ 320, -5, "Signika-SB.ttf", 100 ],
"month": [ 320, 265, "Signika-SB.ttf", 100 ],
"day": [ 320, 60, "Signika-SB.ttf", 220 ]
},
"4": {
"location": [ 20, 20, "fonts/calibrib30" ],
"wind": [ 90, 83, "fonts/calibrib60" ],
"temp": [ 20, 170, "fonts/calibrib150" ],
"wind": [ 90, 83, "fonts/calibrib30" ],
"temp": [ 20, 170, "fonts/calibrib30" ],
"icon": [ 385, 0, 100, 2 ],
"dir": [ 40, 50, 80 ],
"umbrella": [ 325, 155, 78 ]
@@ -42,14 +38,14 @@
"line": [ 50, 300 ]
},
"9": {
"title": [ 10, 10, "fonts/calibrib30" ],
"items": 12,
"line": [ 10, 60, 20 ],
"font": "7x14_tf"
"title": [ 6, 0, "Signika-SB.ttf", 32 ],
"items": 5,
"line": [ 9, 40, "calibrib16.vlw" ],
"desc": [ 2, 8, "REFSAN12.vlw", 1.2 ]
},
"10": {
"title": [ 10, 10, "fonts/bahnschrift20" ],
"pos": [ 200, 30 ]
"title": [ 320, 10, "fonts/bahnschrift20" ],
"pos": [ 320, 40 ]
},
"11": {
"title": [ 10, 10, "fonts/bahnschrift30" ],

View File

@@ -1,5 +1,5 @@
{
"name": "ST-GR2900L 2.9\" (UC8151)",
"name": "M2 2.9\" (UC8151)",
"width": 296,
"height": 128,
"rotatebuffer": 1,

View File

@@ -1,5 +1,5 @@
{
"name": "EL097H2WRN 9.7\"",
"name": "M3 9.7\"",
"width": 960,
"height": 672,
"rotatebuffer": 0,
@@ -13,6 +13,23 @@
},
"shortlut": 0,
"options": ["button"],
"contentids": [ 0, 1, 2, 3, 4, 8, 16, 9, 7, 19, 10, 11, 21 ],
"usetemplate": 1
"contentids": [ 0, 1, 5, 8, 9, 7, 19, 10, 11 ],
"usetemplate": 1,
"template": {
"1": {
"weekday": [ 480, -5, "Signika-SB.ttf", 160 ],
"month": [ 480, 480, "Signika-SB.ttf", 160 ],
"day": [ 480, 110, "Signika-SB.ttf", 380 ]
},
"9": {
"title": [ 6, 0, "Signika-SB.ttf", 32 ],
"items": 12,
"line": [ 9, 40, "calibrib16.vlw" ],
"desc": [ 2, 8, "REFSAN12.vlw", 1.2 ]
},
"10": {
"title": [ 480, 0, "Signika-SB.ttf", 50 ],
"pos": [ 480, 70 ]
}
}
}

View File

@@ -1,5 +1,5 @@
{
"name": "EL043H3WRA 4.3\"",
"name": "M3 4.3\"",
"width": 522,
"height": 152,
"rotatebuffer": 1,
@@ -13,6 +13,23 @@
},
"shortlut": 0,
"options": ["button"],
"contentids": [ 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20],
"usetemplate": 1
"contentids": [ 0, 1, 2, 3, 4, 5, 7, 8, 9, 11, 17, 18, 19, 20],
"usetemplate": 1,
"template": {
"1": {
"weekday": [ 160, 5, "Signika-SB.ttf", 60 ],
"month": [ 160, 75, "Signika-SB.ttf", 60 ],
"day": [ 422, -27, "Signika-SB.ttf", 170 ]
},
"2": {
"fonts": [ "Signika-SB.ttf", 170, 170, 170, 170, 170, 170 ],
"xy": [ 261, 63 ]
},
"9": {
"title": [ 6, 0, "Signika-SB.ttf", 25 ],
"items": 1,
"line": [ 9, 40, "calibrib16.vlw" ],
"desc": [ 2, 8, "REFSAN12.vlw", 1.2 ]
}
}
}

View File

@@ -0,0 +1,18 @@
{
"name": "M3 1.6\"",
"width": 200,
"height": 200,
"rotatebuffer": 0,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [255, 255, 255],
"black": [0, 0, 0],
"red": [255, 0, 0],
"gray": [150, 150, 150]
},
"shortlut": 0,
"options": ["button"],
"contentids": [ 0, 1, 2, 3, 4, 8, 7, 19, 10, 11, 21 ],
"usetemplate": 0
}

View File

@@ -1,5 +1,5 @@
{
"name": "EL022H3BRA 2.2\"",
"name": "M3 2.2\"",
"width": 296,
"height": 160,
"rotatebuffer": 1,
@@ -13,21 +13,21 @@
},
"shortlut": 0,
"options": ["button", "led"],
"contentids": [ 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20],
"contentids": [ 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20],
"template": {
"1": {
"weekday": [148, 10, "fonts/calibrib60"],
"date": [148, 73, "fonts/calibrib50"]
"weekday": [148, 5, "Signika-SB.ttf", 60],
"date": [148, 75, "Signika-SB.ttf", 50]
},
"2": {
"fonts": [ "Signika-SB.ttf", 150, 150, 110, 80, 60, 50 ],
"xy": [ 76, 68 ]
},
"16": {
"location": [ 5, 5, "fonts/bahnschrift30" ],
"title": [ 247, 11, "glasstown_nbp_tf" ],
"cols": [ 1, 125, 12, "glasstown_nbp_tf" ],
"bars": [ 5, 111, 10 ]
},
"2": {
"fonts": ["fonts/calibrib150", "fonts/calibrib150", "fonts/calibrib120", "fonts/calibrib100"],
"xy": [148, 74]
"cols": [ 1, 155, 12, "glasstown_nbp_tf" ],
"bars": [ 5, 141, 10 ]
},
"4": {
"location": [5, 5, "fonts/bahnschrift30"],
@@ -46,14 +46,14 @@
"line": [20, 128]
},
"9": {
"title": [5, 3, "fonts/bahnschrift20"],
"title": [ 5, 4, "bahnschrift20.vlw", 25 ],
"items": 8,
"line": [5, 34, 13],
"font": "glasstown_nbp_tf"
"line": [ 4, 25, "REFSAN12.vlw" ],
"desc": [ 0, 5, "", 1 ]
},
"10": {
"title": [10, 5, "fonts/bahnschrift20"],
"pos": [149, 25]
"title": [149, 5, "fonts/bahnschrift20"],
"pos": [149, 30]
},
"11": {
"title": [5, 2, "fonts/bahnschrift20"],

View File

@@ -1,5 +1,5 @@
{
"name": "EL029H3WRA 2.9\"",
"name": "M3 2.9\"",
"width": 384,
"height": 168,
"rotatebuffer": 1,
@@ -13,6 +13,32 @@
},
"shortlut": 0,
"options": ["button", "led"],
"contentids": [ 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20],
"usetemplate": 1
"contentids": [ 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20],
"usetemplate": 1,
"template": {
"1": {
"weekday": [ 192, 0, "Signika-SB.ttf", 70 ],
"date": [ 192, 85, "Signika-SB.ttf", 60 ]
},
"2": {
"fonts": [ "Signika-SB.ttf", 150, 150, 110, 80, 60, 50 ],
"xy": [ 76, 72 ]
},
"16": {
"location": [ 5, 5, "fonts/bahnschrift30" ],
"title": [ 335, 11, "glasstown_nbp_tf" ],
"cols": [ 1, 157, 16, "glasstown_nbp_tf" ],
"bars": [ 5, 141, 14 ]
},
"9": {
"title": [ 5, 4, "bahnschrift20.vlw", 25 ],
"items": 8,
"line": [ 4, 25, "REFSAN12.vlw" ],
"desc": [ 0, 5, "", 1 ]
},
"10": {
"title": [ 192, 5, "fonts/bahnschrift20" ],
"pos": [ 192, 30 ]
}
}
}

View File

@@ -0,0 +1,18 @@
{
"name": "M3 4.2\"",
"width": 400,
"height": 300,
"rotatebuffer": 0,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [255, 255, 255],
"black": [0, 0, 0],
"red": [255, 0, 0],
"gray": [150, 150, 150]
},
"shortlut": 1,
"options": ["led"],
"contentids": [ 0, 1, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20 ],
"usetemplate": 2
}

View File

@@ -1,16 +1,33 @@
{
"name": "EL060H3WRA 6.0\"",
"name": "M3 6.0\"",
"width": 600,
"height": 448,
"rotatebuffer": 0,
"bpp": 2,
"colors": 3,
"colortable": {
"white": [255, 255, 255],
"black": [0, 0, 0],
"red": [255, 0, 0],
"gray": [150, 150, 150]
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"gray": [ 150, 150, 150 ]
},
"contentids": [ 0, 1, 2, 3, 4, 8, 16, 9, 7, 19, 10, 11, 21 ],
"usetemplate": 1
"contentids": [ 0, 1, 4, 5, 8, 9, 7, 19, 10, 11 ],
"usetemplate": 1,
"template": {
"1": {
"weekday": [ 300, 0, "Signika-SB.ttf", 110 ],
"month": [ 300, 310, "Signika-SB.ttf", 110 ],
"day": [ 300, 75, "Signika-SB.ttf", 250 ]
},
"10": {
"title": [ 300, 10, "fonts/bahnschrift30" ],
"pos": [ 300, 50 ]
},
"9": {
"title": [ 6, 0, "Signika-SB.ttf", 32 ],
"items": 6,
"line": [ 9, 40, "calibrib16.vlw" ],
"desc": [ 2, 8, "REFSAN12.vlw", 1.2 ]
}
}
}

View File

@@ -1,5 +1,5 @@
{
"name": "EL075H3BRA 7.5\"",
"name": "M3 7.5\"",
"width": 800,
"height": 480,
"rotatebuffer": 0,
@@ -13,6 +13,6 @@
},
"shortlut": 0,
"options": ["button", "led"],
"contentids": [ 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20],
"contentids": [ 0, 1, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20],
"usetemplate": 1
}

View File

@@ -13,6 +13,6 @@
},
"shortlut": 0,
"options": ["led"],
"contentids": [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 ],
"contentids": [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 17, 18, 19, 20 ],
"usetemplate": 1
}

View File

@@ -13,6 +13,6 @@
},
"shortlut": 0,
"options": ["led"],
"contentids": [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 ],
"contentids": [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 17, 18, 19, 20 ],
"usetemplate": 1
}

View File

@@ -13,6 +13,6 @@
},
"shortlut": 0,
"options": ["led"],
"contentids": [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 ],
"contentids": [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 17, 18, 19, 20 ],
"usetemplate": 1
}

View File

@@ -13,7 +13,7 @@
},
"shortlut": 0,
"options": [],
"contentids": [ 0, 1, 2, 3, 4, 8, 16, 9, 7, 19, 10, 11, 21 ],
"contentids": [ 0, 1, 2, 3, 4, 8, 7, 19, 10, 11, 21 ],
"usetemplate": 1,
"template": {
"21": [

View File

@@ -1,19 +1,5 @@
{
"deletefile": [
"/fonts/calibrib62.vlw",
"/fonts/GillSC16.vlw",
"/fonts/GillSC20.vlw",
"/fonts/numbers1-1.vlw",
"/fonts/numbers1-2.vlw",
"/fonts/numbers2-1.vlw",
"/fonts/numbers2-2.vlw",
"/fonts/numbers3-1.vlw",
"/fonts/numbers3-2.vlw",
"/fonts/tw20.vlw",
"/fonts/twbold20.vlw",
"/alignment.jpg",
"/gradient.jpg",
"/demo_image_generator.py",
"/www/content_cards.json",
"/www/favicon.ico",
"/www/index.html",
@@ -27,6 +13,10 @@
"/www/upload-demo.html",
"/fonts/weathericons30.vlw",
"/fonts/weathericons70.vlw",
"/fonts/weathericons78.vlw"
"/fonts/weathericons78.vlw",
"/fonts/calibrib120.vlw",
"/fonts/calibrib150.vlw",
"/fonts/calibrib50.vlw",
"/fonts/calibrib60.vlw"
]
}

Binary file not shown.

View File

@@ -20,6 +20,7 @@ void checkVars();
void drawNew(const uint8_t mac[8], const bool buttonPressed, tagRecord *&taginfo);
bool updateTagImage(String &filename, const uint8_t *dst, uint16_t nextCheckin, tagRecord *&taginfo, imgParam &imageParams);
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);
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);

View File

@@ -16,7 +16,7 @@ lib_deps =
bblanchon/ArduinoJson@^6.19.4
bodmer/TFT_eSPI
https://github.com/Bodmer/TJpg_Decoder.git
https://github.com/garretlab/shoddyxml2
https://github.com/nlimper/shoddyxml2
https://github.com/Bodmer/U8g2_for_TFT_eSPI
https://github.com/nlimper/QRCodeGenerator
fastled/FastLED

View File

@@ -312,7 +312,6 @@ void drawNew(const uint8_t mac[8], const bool buttonPressed, tagRecord *&taginfo
filename = cfgobj["filename"].as<String>();
if (!util::isEmptyOrNull(filename) && !cfgobj["#fetched"].as<bool>()) {
File file = contentFS->open(filename, "r");
if (file) {
if (file.find("<html")) {
@@ -542,6 +541,15 @@ void replaceVariables(String &format) {
void drawString(TFT_eSprite &spr, String content, int16_t posx, int16_t posy, String font, byte align, uint16_t color, uint16_t size, uint16_t bgcolor) {
// drawString(spr,"test",100,10,"bahnschrift30",TC_DATUM,TFT_RED);
replaceVariables(content);
if (font.startsWith("fonts/calibrib")) {
// backwards compitibility
String numericValueStr = font.substring(14);
int calibriSize = numericValueStr.toInt();
if (calibriSize > 30) {
font = "Signika-SB.ttf";
size = calibriSize;
}
}
switch (processFontPath(font)) {
case 1: {
// u8g2 font
@@ -583,19 +591,71 @@ void drawString(TFT_eSprite &spr, String content, int16_t posx, int16_t posy, St
truetype.setTextColor(spr.color16to8(color), spr.color16to8(color));
truetype.textDraw(posx, posy, content);
truetype.end();
// Serial.println("text: '" + content + "' " + String(millis() - t) + "ms");
} break;
case 3: {
// vlw bitmap font
spr.setTextDatum(align);
if (font != "") spr.loadFont(font.substring(1), *contentFS);
spr.setTextColor(color, bgcolor);
spr.setTextWrap(true, false);
spr.drawString(content, posx, posy);
if (font != "") spr.unloadFont();
}
}
}
void drawTextBox(TFT_eSprite &spr, String &content, int16_t &posx, int16_t &posy, int16_t boxwidth, int16_t boxheight, String font, uint16_t color, uint16_t bgcolor, float lineheight) {
replaceVariables(content);
switch (processFontPath(font)) {
case 1: {
// u8g2 font
Serial.println("u8g2 font not implemented for drawStringBox");
} break;
case 2: {
// truetype
Serial.println("truetype font not implemented for drawStringBox");
} break;
case 3: {
// vlw bitmap font
// spr.drawRect(posx, posy, boxwidth, boxheight, TFT_BLACK);
spr.setTextDatum(TL_DATUM);
if (font != "") spr.loadFont(font.substring(1), *contentFS);
spr.setTextWrap(false, false);
spr.setTextColor(color, bgcolor);
int length = content.length();
int startPos = 0;
int startPosY = posy;
while (startPos < length && posy + spr.gFont.yAdvance <= startPosY + boxheight) {
int endPos = startPos;
bool hasspace = false;
while (endPos < length && spr.textWidth(content.substring(startPos, endPos + 1).c_str()) <= boxwidth && content.charAt(endPos) != '\n') {
// Serial.println("try: " + String(startPos) + "-" + String(endPos) + " " + content.substring(startPos, endPos + 1));
if (content.charAt(endPos) == ' ' || content.charAt(endPos) == '-') hasspace = true;
endPos++;
}
while (endPos < length && endPos > startPos && hasspace == true && content.charAt(endPos - 1) != ' ' && content.charAt(endPos - 1) != '-' && content.charAt(endPos) != '\n') {
endPos--;
// Serial.println("backtrack: " + String(startPos) + "-" + String(endPos) + " " + content.substring(startPos, endPos));
}
// Serial.println("result: " + String(startPos) + "-" + String(endPos) + " " + content.substring(startPos, endPos));
// delay(1000);
spr.drawString(content.substring(startPos, endPos), posx, posy);
posy += spr.gFont.yAdvance * lineheight;
if (content.charAt(endPos) == '\n') endPos++;
startPos = endPos;
while (startPos < length && content.charAt(startPos) == ' ') {
startPos++;
}
}
if (font != "") spr.unloadFont();
}
}
}
void initSprite(TFT_eSprite &spr, int w, int h, imgParam &imageParams) {
spr.setColorDepth(8);
spr.createSprite(w, h);
@@ -680,19 +740,18 @@ void drawNumber(String &filename, int32_t count, int32_t thresholdred, tagRecord
getTemplate(loc, 2, taginfo->hwType);
initSprite(spr, imageParams.width, imageParams.height, imageParams);
spr.setTextDatum(MC_DATUM);
uint16_t color = TFT_BLACK;
if (countTemp > thresholdred) {
spr.setTextColor(TFT_RED, TFT_WHITE);
} else {
spr.setTextColor(TFT_BLACK, TFT_WHITE);
color = TFT_RED;
}
String font = loc["fonts"][0].as<String>();
if (count > 99) font = loc["fonts"][1].as<String>();
if (count > 999) font = loc["fonts"][2].as<String>();
if (count > 9999) font = loc["fonts"][3].as<String>();
spr.loadFont(font, *contentFS);
spr.drawString(String(count), loc["xy"][0].as<uint16_t>(), loc["xy"][1].as<uint16_t>());
spr.unloadFont();
uint8_t size = loc["fonts"][1].as<uint16_t>();
if (count > 9) size = loc["fonts"][2].as<uint16_t>();
if (count > 99) size = loc["fonts"][3].as<uint16_t>();
if (count > 999) size = loc["fonts"][4].as<uint16_t>();
if (count > 9999) size = loc["fonts"][5].as<uint16_t>();
if (count > 99999) size = loc["fonts"][6].as<uint16_t>();
drawString(spr, String(count), loc["xy"][0].as<uint16_t>(), loc["xy"][1].as<uint16_t>() - size / 1.8, font, TC_DATUM, color, size);
spr2buffer(spr, filename, imageParams);
spr.deleteSprite();
@@ -920,6 +979,39 @@ int getImgURL(String &filename, String URL, time_t fetched, imgParam &imageParam
rssClass reader;
#endif
void replaceHTMLentities(String &text) {
text.replace("&gt;", ">");
text.replace("&lt;", "<");
text.replace("&quot;", "\"");
text.replace("&apos;", "'");
text.replace("&amp;", "&");
}
void removeHTML(String &text) {
int len = text.length();
bool insideTag = false;
int j = 0;
for (int i = 0; i < len; ++i) {
char c = text[i];
if (c == '<') {
insideTag = true;
} else if (c == '>') {
insideTag = false;
} else if (!insideTag) {
text[j++] = c;
}
}
text.remove(j);
}
void stampTime(TFT_eSprite &spr) {
time_t now;
time(&now);
char timeStr[24];
strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S ", localtime(&now));
drawString(spr, timeStr, spr.width() - 1, 12, "glasstown_nbp_tf", TR_DATUM, TFT_BLACK);
}
bool getRssFeed(String &filename, String URL, String title, tagRecord *&taginfo, imgParam &imageParams) {
#ifdef CONTENT_RSS
// https://github.com/garretlab/shoddyxml2
@@ -928,8 +1020,8 @@ bool getRssFeed(String &filename, String URL, String title, tagRecord *&taginfo,
// https://www.nu.nl/rss/Algemeen
const char *url = URL.c_str();
constexpr const char *tag = "title";
constexpr const int rssArticleSize = 128;
const int rssTitleSize = 255;
const int rssDescSize = 1000;
TFT_eSprite spr = TFT_eSprite(&tft);
U8g2_for_TFT_eSPI u8f;
@@ -938,21 +1030,42 @@ bool getRssFeed(String &filename, String URL, String title, tagRecord *&taginfo,
StaticJsonDocument<512> loc;
getTemplate(loc, 9, taginfo->hwType);
initSprite(spr, imageParams.width, imageParams.height, imageParams);
stampTime(spr);
if (util::isEmptyOrNull(title)) title = "RSS feed";
drawString(spr, title, loc["title"][0], loc["title"][1], loc["title"][2], TL_DATUM, TFT_BLACK);
drawString(spr, title, loc["title"][0], loc["title"][1], loc["title"][2], TL_DATUM, TFT_BLACK, loc["title"][3]);
int16_t posx = loc["line"][0];
int16_t posy = loc["line"][1];
int n = reader.getArticles(url, rssTitleSize, rssDescSize, loc["items"]);
setU8G2Font(loc["font"], u8f);
u8f.setFontMode(0);
u8f.setFontDirection(0);
u8f.setForegroundColor(TFT_BLACK);
u8f.setBackgroundColor(TFT_WHITE);
int n = reader.getArticles(url, tag, rssArticleSize, loc["items"]);
float lineheight = loc["desc"][3].as<float>();
for (int i = 0; i < n; i++) {
u8f.setCursor(loc["line"][0], loc["line"][1].as<int>() + i * loc["line"][2].as<int>());
u8f.print(reader.itemData[i]);
// if (reader.titleData[i] != NULL && *reader.titleData[i] != NULL) {
if (reader.titleData[i] != NULL) {
String title = String(reader.titleData[i]);
replaceHTMLentities(title);
removeHTML(title);
if (!util::isEmptyOrNull(title)) {
drawTextBox(spr, title, posx, posy, imageParams.width - 2 * posx, 100, loc["line"][2], TFT_BLACK);
}
}
// if (reader.descData[i] != NULL && *reader.descData[i] != NULL) {
if (reader.descData[i] != NULL && loc["desc"][2] != "") {
String desc = String(reader.descData[i]);
replaceHTMLentities(desc);
removeHTML(desc);
if (!util::isEmptyOrNull(desc)) {
posy += loc["desc"][0].as<int>();
drawTextBox(spr, desc, posx, posy, imageParams.width - 2 * posx, 100, loc["desc"][2], TFT_BLACK, TFT_WHITE, lineheight);
posy += loc["desc"][1].as<int>();
}
} else {
posy += loc["desc"][1].as<int>();
}
}
reader.clearItemData();
spr2buffer(spr, filename, imageParams);
spr.deleteSprite();
@@ -1070,12 +1183,12 @@ void drawQR(String &filename, String qrcontent, String title, tagRecord *&taginf
StaticJsonDocument<512> loc;
getTemplate(loc, 10, taginfo->hwType);
initSprite(spr, imageParams.width, imageParams.height, imageParams);
drawString(spr, title, loc["title"][0], loc["title"][1], loc["title"][2]);
drawString(spr, title, loc["title"][0], loc["title"][1], loc["title"][2], TC_DATUM, TFT_BLACK, loc["title"][3]);
const int size = qrcode.size;
const int dotsize = int((imageParams.height - loc["pos"][1].as<int>()) / size);
const int xpos = loc["pos"][0].as<int>() - dotsize * size / 2;
const int ypos = loc["pos"][1];
const int ypos = loc["pos"][1].as<int>() + (imageParams.height - loc["pos"][1].as<int>() - dotsize * size) / 2;
for (int y = 0; y < size; y++) {
for (int x = 0; x < size; x++) {
@@ -1121,15 +1234,6 @@ uint8_t drawBuienradar(String &filename, JsonObject &cfgobj, tagRecord *&taginfo
drawString(spr, cfgobj["location"], loc["location"][0], loc["location"][1], loc["location"][2]);
for (int i = 0; i < 295; i += 4) {
int yCoordinates[] = {110, 91, 82, 72, 62, 56, 52};
for (int y : yCoordinates) {
spr.drawPixel(i, y, TFT_BLACK);
}
}
drawString(spr, "Buienradar", loc["title"][0], loc["title"][1], loc["title"][2]);
const auto &bars = loc["bars"];
const auto &cols = loc["cols"];
const int cols0 = cols[0].as<int>();
@@ -1139,6 +1243,18 @@ uint8_t drawBuienradar(String &filename, JsonObject &cfgobj, tagRecord *&taginfo
const int bars0 = bars[0].as<int>();
const int bars1 = bars[1].as<int>();
const int bars2 = bars[2].as<int>();
float factor = (float)bars1 / 111;
Serial.println(factor);
for (int i = 0; i < imageParams.width; i += 4) {
int yCoordinates[] = {1, 20, 29, 39, 49, 55, 59};
for (int y : yCoordinates) {
spr.drawPixel(i, bars1 - (y * factor), TFT_BLACK);
}
}
drawString(spr, "Buienradar", loc["title"][0], loc["title"][1], loc["title"][2]);
for (int i = 0; i < 24; i++) {
const int startPos = i * 11;
uint8_t value = response.substring(startPos, startPos + 3).toInt();
@@ -1156,8 +1272,9 @@ uint8_t drawBuienradar(String &filename, JsonObject &cfgobj, tagRecord *&taginfo
refresh = 20;
}
}
value = value - 70;
spr.fillRect(i * cols2 + bars0, bars1 - (value - 70), bars2, (value - 70), (value > 130 ? TFT_RED : TFT_BLACK));
spr.fillRect(i * cols2 + bars0, bars1 - (value * factor), bars2, value * factor, (value > 50 ? TFT_RED : TFT_BLACK));
if (minutes % 15 == 0) {
drawString(spr, timestring, i * cols2 + cols0, cols1, cols3);
@@ -1382,11 +1499,11 @@ int getJsonTemplateUrl(String &filename, String URL, time_t fetched, String MAC,
}
void drawJsonStream(Stream &stream, String &filename, tagRecord *&taginfo, imgParam &imageParams) {
TFT_eSprite spr = TFT_eSprite(&tft);
TFT_eSprite spr = TFT_eSprite(&tft);
initSprite(spr, imageParams.width, imageParams.height, imageParams);
uint8_t screenCurrentOrientation = 0;
//spr.setRotation(2);
//imageParams.rotatebuffer = imageParams.rotatebuffer + 1;
// spr.setRotation(2);
// imageParams.rotatebuffer = imageParams.rotatebuffer + 1;
DynamicJsonDocument doc(500);
if (stream.find("[")) {
do {
@@ -1405,36 +1522,36 @@ TFT_eSprite spr = TFT_eSprite(&tft);
spr.deleteSprite();
}
void rotateBuffer(uint8_t rotation, uint8_t &currentOrientation, TFT_eSprite &spr, imgParam &imageParams){
rotation = rotation % 4; //First of all, let's be sure that the rotation have a valid value (0, 1, 2 or 3)
if(rotation != currentOrientation){ //If we have a rotation to do, let's do it
int stepToDo = currentOrientation - rotation; //rotation we have to do
void rotateBuffer(uint8_t rotation, uint8_t &currentOrientation, TFT_eSprite &spr, imgParam &imageParams) {
rotation = rotation % 4; // First of all, let's be sure that the rotation have a valid value (0, 1, 2 or 3)
if (rotation != currentOrientation) { // If we have a rotation to do, let's do it
int stepToDo = currentOrientation - rotation; // rotation we have to do
//-2, 2: upside down
//-1, 3: 270° rotation
//-3, 1: 90° rotation
if(abs(stepToDo) == 2){ //If we have to do a 180° rotation:
TFT_eSprite sprCpy = TFT_eSprite(&tft); //We create a new sprite that will act as a buffer
initSprite(sprCpy, spr.width(), spr.height(), imageParams); //initialisation of the new sprite
spr.pushRotated(&sprCpy, 180, TFT_WHITE); //We fill the new sprite with the old one rotated by 180°
spr.fillSprite(TFT_WHITE); //We fill the old one in white as anything that's white will be ignored by the pushRotated function
sprCpy.pushRotated(&spr, 0, TFT_WHITE); //We copy the buffer sprite to the main one
sprCpy.deleteSprite(); //We delete the buffer sprite to avoid memory leak
}else{
if (abs(stepToDo) == 2) { // If we have to do a 180° rotation:
TFT_eSprite sprCpy = TFT_eSprite(&tft); // We create a new sprite that will act as a buffer
initSprite(sprCpy, spr.width(), spr.height(), imageParams); // initialisation of the new sprite
spr.pushRotated(&sprCpy, 180, TFT_WHITE); // We fill the new sprite with the old one rotated by 180°
spr.fillSprite(TFT_WHITE); // We fill the old one in white as anything that's white will be ignored by the pushRotated function
sprCpy.pushRotated(&spr, 0, TFT_WHITE); // We copy the buffer sprite to the main one
sprCpy.deleteSprite(); // We delete the buffer sprite to avoid memory leak
} else {
int angle = 90;
if(stepToDo == -1 || stepToDo == 3){
if (stepToDo == -1 || stepToDo == 3) {
angle = 270;
}
TFT_eSprite sprCpy = TFT_eSprite(&tft);
initSprite(sprCpy, spr.height(), spr.width(), imageParams);
initSprite(sprCpy, spr.height(), spr.width(), imageParams);
spr.pushRotated(&sprCpy, angle, TFT_WHITE);
spr.deleteSprite();
initSprite(spr, sprCpy.width(), sprCpy.height(), imageParams);
sprCpy.pushRotated(&spr, 0, TFT_WHITE);
sprCpy.deleteSprite();
if(imageParams.rotatebuffer==1){
if (imageParams.rotatebuffer == 1) {
imageParams.rotatebuffer = 0;
}else{
} else {
imageParams.rotatebuffer = 1;
}
}
@@ -1450,6 +1567,14 @@ void drawElement(const JsonObject &element, TFT_eSprite &spr, imgParam &imagePar
const String bgcolorstr = textArray[7].as<String>();
const uint16_t bgcolor = (bgcolorstr.length() > 0) ? getColor(bgcolorstr) : TFT_WHITE;
drawString(spr, textArray[2], textArray[0].as<int>(), textArray[1].as<int>(), textArray[3], align, getColor(textArray[4]), size, bgcolor);
} else if (element.containsKey("textbox")) {
const JsonArray &textArray = element["textbox"];
float lineheight = textArray[7].as<float>();
if (lineheight == 0) lineheight = 1;
int16_t posx = textArray[0] | 0;
int16_t posy = textArray[1] | 0;
String text = textArray[4];
drawTextBox(spr, text, posx, posy, textArray[2], textArray[3], textArray[5], getColor(textArray[6]), TFT_WHITE, lineheight);
} else if (element.containsKey("box")) {
const JsonArray &boxArray = element["box"];
spr.fillRect(boxArray[0].as<int>(), boxArray[1].as<int>(), boxArray[2].as<int>(), boxArray[3].as<int>(), getColor(boxArray[4]));
@@ -1641,6 +1766,6 @@ void setU8G2Font(const String &title, U8g2_for_TFT_eSPI &u8f) {
} else if (title == "7x14_tf") {
u8f.setFont(u8g2_font_7x14_tf);
} else if (title == "t0_14b_tf") {
u8f.setFont(u8g2_font_t0_14b_tf);
u8f.setFont(u8g2_font_t0_14b_tf); // not used
}
}

View File

@@ -194,7 +194,6 @@ void updateFirmware(const char* url, const char* expectedMd5, const size_t size)
wsSerial("Reboot system now");
wsSerial("[reboot]");
vTaskDelay(1000 / portTICK_PERIOD_MS);
// ESP.restart();
} else {
wsSerial("Error updating firmware:");
wsSerial(Update.errorString());
@@ -225,7 +224,6 @@ void handleRollback(AsyncWebServerRequest* request) {
wsSerial("Reboot system now");
wsSerial("[reboot]");
vTaskDelay(1000 / portTICK_PERIOD_MS);
// ESP.restart();
} else {
wsSerial("Rollback failed");
request->send(400, "Rollback failed");

View File

@@ -108,6 +108,8 @@ void wsSendSysteminfo() {
// reboot once at night
if (timeinfo.tm_hour == 4 && timeinfo.tm_min == 0 && millis() > 2 * 3600 * 1000) {
logLine("Nightly reboot");
wsErr("REBOOTING");
delay(100);
ws.enable(false);
refreshAllPending();
saveDB("/current/tagDB.json");
@@ -224,7 +226,9 @@ void init_web() {
server.on("/reboot", HTTP_POST, [](AsyncWebServerRequest *request) {
request->send(200, "text/plain", "OK Reboot");
logLine("Reboot request by user");
wsErr("REBOOTING");
delay(100);
ws.enable(false);
refreshAllPending();
saveDB("/current/tagDB.json");
@@ -304,7 +308,7 @@ void init_web() {
// memset(taginfo->md5, 0, 16 * sizeof(uint8_t));
// memset(taginfo->md5pending, 0, 16 * sizeof(uint8_t));
wsSendTaginfo(mac, SYNC_USERCFG);
saveDB("/current/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");

View File

@@ -3,7 +3,6 @@
"id": 0,
"name": "Static image",
"desc": "Shows a static image, from file system, painter or external source. Make sure to resize the image to the correct resolution.",
"hwtype": [],
"param": [
{
"key": "filename",
@@ -74,14 +73,12 @@
"id": 1,
"name": "Current date",
"desc": "Shows the current date",
"hwtype": [],
"param": []
},
{
"id": 2,
"name": "Count days",
"desc": "Counts days, starting with the value below. If the count value gets higher than the threshold, the number is displayed in red, otherwise it's black",
"hwtype": [],
"param": [
{
"key": "counter",
@@ -93,8 +90,7 @@
"key": "thresholdred",
"name": "Threshold",
"desc": "Value is displayed in red if higher than the threshold",
"type": "int",
"hwtype": []
"type": "int"
}
]
},
@@ -102,7 +98,6 @@
"id": 3,
"name": "Count hours",
"desc": "Counts hours, starting with the value below. If the count value gets higher than the threshold, the number is displayed in red, otherwise it's black",
"hwtype": [],
"param": [
{
"key": "counter",
@@ -114,8 +109,7 @@
"key": "thresholdred",
"name": "Threshold",
"desc": "Value is displayed in red if higher than the threshold",
"type": "int",
"hwtype": []
"type": "int"
}
]
},
@@ -123,7 +117,6 @@
"id": 4,
"name": "Current weather",
"desc": "Current weather. Weather data by Open-Meteo.com. Parameters Lat, Lon and Time Zone are filled automatically from the entered location. In case of an ambiguous location, you can alter those manually.",
"hwtype": [],
"param": [
{
"key": "location",
@@ -145,19 +138,19 @@
"key": "#lat",
"name": "Lat",
"desc": "Latitude (set automatic when generating image)",
"type": "text"
"type": "ro"
},
{
"key": "#lon",
"name": "Lon",
"desc": "Longitude (set automatic when generating image)",
"type": "text"
"type": "ro"
},
{
"key": "#tz",
"name": "Time zone",
"desc": "Time zone (set automatic when generating image)",
"type": "text"
"type": "ro"
}
]
},
@@ -165,7 +158,6 @@
"id": 8,
"name": "Weather forecast",
"desc": "Weather forecast for the next five days. Weather data by Open-Meteo.com. Parameters Lat, Lon and Time Zone are filled automatically from the entered location. In case of an ambiguous location, you can alter those manually.",
"hwtype": [],
"param": [
{
"key": "location",
@@ -187,19 +179,19 @@
"key": "#lat",
"name": "Lat",
"desc": "Latitude (set automatic when generating image)",
"type": "text"
"type": "ro"
},
{
"key": "#lon",
"name": "Lon",
"desc": "Longitude (set automatic when generating image)",
"type": "text"
"type": "ro"
},
{
"key": "#tz",
"name": "Time zone",
"desc": "Time zone (set automatic when generating image)",
"type": "text"
"type": "ro"
}
]
},
@@ -207,7 +199,6 @@
"id": 16,
"name": "Buienradar",
"desc": "Dutch rain predictions for the next two hours. Only works for locations in the Netherlands and Belgium.",
"hwtype": [],
"param": [
{
"key": "location",
@@ -233,7 +224,6 @@
"id": 9,
"name": "RSS feed",
"desc": "Gets an RSS feed, and display the first few lines of it",
"hwtype": [],
"param": [
{
"key": "title",
@@ -259,7 +249,6 @@
"id": 7,
"name": "Image URL",
"desc": "Gets an external image and displays it",
"hwtype": [],
"param": [
{
"key": "url",
@@ -279,7 +268,6 @@
"id": 19,
"name": "Json template",
"desc": "Gets an external json template and displays it",
"hwtype": [],
"param": [
{
"key": "url",
@@ -305,7 +293,6 @@
"id": 10,
"name": "QR code",
"desc": "Displayes a full screen QR code",
"hwtype": [],
"param": [
{
"key": "title",
@@ -325,7 +312,6 @@
"id": 11,
"name": "Google calendar",
"desc": "Displays the current and upcoming appointments (next 24 hours) from a Google calendar. To let this work, you need a small Google Apps Script to interface with your calendar. See documentation on github how to do that",
"hwtype": [],
"param": [
{
"key": "title",
@@ -351,7 +337,6 @@
"id": 5,
"name": "Firmware update",
"desc": "To update tag firmware. Make sure you send the right .bin file! You can brick your tag if you send a wrong file.",
"hwtype": [],
"param": [
{
"key": "filename",
@@ -364,14 +349,12 @@
{
"id": 12,
"name": "Remote content",
"desc": "Content is generated by a different Access Point",
"hwtype": []
"desc": "Content is generated by a different Access Point"
},
{
"id": 13,
"name": "Set segments",
"desc": "Used for debugging. Work in progress",
"hwtype": [],
"param": [
{
"key": "line1",
@@ -397,7 +380,6 @@
"id": 14,
"name": "Set NFC URL",
"desc": "Send the URL to the NFC chip. The URL is transmitted to a NFC reader (like your phone) if you hold it next to the tag",
"hwtype": [],
"capabilities": 64,
"param": [
{
@@ -412,7 +394,6 @@
"id": 15,
"name": "Send custom LUT",
"desc": "EXPERIMENTAL. Don't use. YOU RISK DAMAGING YOUR SCREEN.",
"hwtype": [],
"capabilities": 4,
"param": [
{
@@ -427,7 +408,6 @@
"id": 17,
"name": "Send Command",
"desc": "Send a command to a tag to execute; only to be used for tests during development",
"hwtype": [],
"param": [
{
"key": "cmd",
@@ -441,7 +421,6 @@
"id": 18,
"name": "Set Tag Config",
"desc": "Sets tag options. The options you see below are the default options. This may or may not match current tag settings",
"hwtype": [],
"param": [
{
"key": "fastboot",
@@ -537,7 +516,6 @@
"id": 20,
"name": "Display a copy",
"desc": "Mirror the contents of a source tag to this destination tag, regardless of the content. The two tags should be of the same type. Ideally, the destination tag is local to the AP.",
"hwtype": [],
"param": [
{
"key": "mac",
@@ -550,7 +528,6 @@
{
"id": 21,
"name": "Access point info",
"desc": "Displays information about the currently connected access point",
"hwtype": []
"desc": "Displays information about the currently connected access point"
}
]

View File

@@ -843,8 +843,7 @@ function populateSelectTag(hwtype, capabilities) {
let option;
cardconfig.forEach(item => {
const capcheck = item.capabilities ?? 0;
const hwtypeArray = item.hwtype ?? [];
if ((hwtypeArray.includes(hwtype) || tagTypes[hwtype].contentids.includes(item.id)) && (capabilities & capcheck || capcheck == 0)) {
if (tagTypes[hwtype].contentids.includes(item.id) && (capabilities & capcheck || capcheck == 0)) {
option = document.createElement("option");
option.value = item.id;
option.text = item.name;