mirror of
https://github.com/OpenEPaperLink/OpenEPaperLink.git
synced 2026-03-21 10:06:07 +01:00
segmented tags content
This commit is contained in:
@@ -30,7 +30,8 @@
|
||||
"hwtype": [
|
||||
0,
|
||||
1,
|
||||
2
|
||||
2,
|
||||
240
|
||||
],
|
||||
"param": []
|
||||
},
|
||||
@@ -41,7 +42,8 @@
|
||||
"hwtype": [
|
||||
0,
|
||||
1,
|
||||
2
|
||||
2,
|
||||
240
|
||||
],
|
||||
"param": [
|
||||
{
|
||||
@@ -54,7 +56,12 @@
|
||||
"key": "thresholdred",
|
||||
"name": "Threshold",
|
||||
"desc": "Value is displayed in red if higher than the threshold",
|
||||
"type": "int"
|
||||
"type": "int",
|
||||
"hwtype": [
|
||||
0,
|
||||
1,
|
||||
2
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -65,7 +72,8 @@
|
||||
"hwtype": [
|
||||
0,
|
||||
1,
|
||||
2
|
||||
2,
|
||||
240
|
||||
],
|
||||
"param": [
|
||||
{
|
||||
@@ -78,7 +86,12 @@
|
||||
"key": "thresholdred",
|
||||
"name": "Threshold",
|
||||
"desc": "Value is displayed in red if higher than the threshold",
|
||||
"type": "int"
|
||||
"type": "int",
|
||||
"hwtype": [
|
||||
0,
|
||||
1,
|
||||
2
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -89,7 +102,8 @@
|
||||
"hwtype": [
|
||||
0,
|
||||
1,
|
||||
2
|
||||
2,
|
||||
240
|
||||
],
|
||||
"param": [
|
||||
{
|
||||
@@ -254,7 +268,8 @@
|
||||
"hwtype": [
|
||||
0,
|
||||
1,
|
||||
2
|
||||
2,
|
||||
240
|
||||
],
|
||||
"param": [
|
||||
{
|
||||
@@ -265,6 +280,12 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "remote AP",
|
||||
"desc": "Content is generated by a remote Access Point",
|
||||
"hwtype": []
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "Set segments",
|
||||
@@ -282,19 +303,13 @@
|
||||
{
|
||||
"key": "line2",
|
||||
"name": "line 2",
|
||||
"desc": "8888",
|
||||
"desc": "88",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"key": "line3",
|
||||
"name": "line 3",
|
||||
"desc": "88",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"key": "symbols",
|
||||
"name": "symbols",
|
||||
"desc": "",
|
||||
"desc": "8888",
|
||||
"type": "text"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -83,4 +83,17 @@ struct APlist {
|
||||
uint16_t version;
|
||||
} __packed;
|
||||
|
||||
struct TagInfo {
|
||||
uint8_t mac[6];
|
||||
char alias[32];
|
||||
uint32_t lastseen;
|
||||
uint32_t nextupdate;
|
||||
bool pending;
|
||||
uint32_t expectedNextCheckin;
|
||||
uint8_t hwType;
|
||||
uint8_t wakeupReason;
|
||||
uint8_t capabilities;
|
||||
uint16_t pendingIdle;
|
||||
} __packed;
|
||||
|
||||
#pragma pack(pop)
|
||||
@@ -17,7 +17,7 @@ struct contentTypes {
|
||||
|
||||
void contentRunner();
|
||||
void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo);
|
||||
bool updateTagImage(String &filename, uint8_t *dst, uint16_t nextCheckin, imgParam &imageParams);
|
||||
bool updateTagImage(String &filename, uint8_t *dst, uint16_t nextCheckin, tagRecord *&taginfo, imgParam &imageParams);
|
||||
void drawString(TFT_eSprite &spr, String content, uint16_t posx, uint16_t posy, String font, byte align = 0, uint16_t color = TFT_BLACK);
|
||||
void initSprite(TFT_eSprite &spr, int w, int h);
|
||||
void drawDate(String &filename, tagRecord *&taginfo, imgParam &imageParams);
|
||||
|
||||
@@ -7,6 +7,9 @@ struct imgParam {
|
||||
bool hasRed;
|
||||
uint8_t dataType;
|
||||
bool dither;
|
||||
char segments[12];
|
||||
uint16_t symbols;
|
||||
bool invert;
|
||||
};
|
||||
|
||||
void spr2buffer(TFT_eSprite &spr, String &fileout, imgParam &imageParams);
|
||||
|
||||
@@ -8,11 +8,11 @@ extern void prepareIdleReq(uint8_t* dst, uint16_t nextCheckin);
|
||||
extern bool prepareDataAvail(String* filename, uint8_t dataType, uint8_t* dst, uint16_t nextCheckin);
|
||||
extern void prepareExternalDataAvail(struct pendingData* pending, IPAddress remoteIP);
|
||||
extern void processXferComplete(struct espXferComplete* xfc, bool local);
|
||||
extern void processXferTimeout(struct espXferComplete* xfc,bool local);
|
||||
extern void processXferTimeout(struct espXferComplete* xfc, bool local);
|
||||
extern void processDataReq(struct espAvailDataReq* adr, bool local);
|
||||
|
||||
extern bool sendAPSegmentedData(uint8_t* dst, String data, uint16_t icons, bool inverted);
|
||||
extern bool showAPSegmentedInfo(uint8_t* dst);
|
||||
extern bool sendAPSegmentedData(uint8_t* dst, String data, uint16_t icons, bool inverted, bool local);
|
||||
extern bool showAPSegmentedInfo(uint8_t* dst, bool local);
|
||||
|
||||
void refreshAllPending();
|
||||
void setAPchannel();
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
class tagRecord {
|
||||
public:
|
||||
uint16_t nextCheckinpending;
|
||||
tagRecord() : mac{0}, alias(""), lastseen(0), nextupdate(0), contentMode(0), pending(false), md5{0}, md5pending{0}, expectedNextCheckin(0), modeConfigJson(""), LQI(0), RSSI(0), temperature(0), batteryMv(0), hwType(0), wakeupReason(0), capabilities(0), lastfullupdate(0), isExternal(false), pendingIdle(0),
|
||||
filename(""), data(nullptr), len(0) {}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ enum contentModes {
|
||||
QRcode,
|
||||
Calendar,
|
||||
RemoteAP,
|
||||
SegStatic,
|
||||
};
|
||||
|
||||
void contentRunner() {
|
||||
@@ -103,6 +104,9 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
|
||||
imageParams.dataType = DATATYPE_IMG_RAW_1BPP;
|
||||
imageParams.dither = true;
|
||||
|
||||
imageParams.invert = false;
|
||||
imageParams.symbols = 0;
|
||||
|
||||
switch (taginfo->contentMode) {
|
||||
case Image:
|
||||
|
||||
@@ -124,7 +128,7 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
|
||||
|
||||
drawDate(filename, taginfo, imageParams);
|
||||
taginfo->nextupdate = midnight;
|
||||
updateTagImage(filename, mac, (midnight - now) / 60 - 10, imageParams);
|
||||
updateTagImage(filename, mac, (midnight - now) / 60 - 10, taginfo, imageParams);
|
||||
break;
|
||||
|
||||
case CountDays:
|
||||
@@ -132,7 +136,7 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
|
||||
if (buttonPressed) cfgobj["counter"] = 0;
|
||||
drawNumber(filename, (int32_t)cfgobj["counter"], (int32_t)cfgobj["thresholdred"], taginfo, imageParams);
|
||||
taginfo->nextupdate = midnight;
|
||||
updateTagImage(filename, mac, (buttonPressed ? 0 : 15), imageParams);
|
||||
updateTagImage(filename, mac, (buttonPressed ? 0 : 15), taginfo, imageParams);
|
||||
cfgobj["counter"] = (int32_t)cfgobj["counter"] + 1;
|
||||
break;
|
||||
|
||||
@@ -141,7 +145,7 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
|
||||
if (buttonPressed) cfgobj["counter"] = 0;
|
||||
drawNumber(filename, (int32_t)cfgobj["counter"], (int32_t)cfgobj["thresholdred"], taginfo, imageParams);
|
||||
taginfo->nextupdate = now + 3600;
|
||||
updateTagImage(filename, mac, (buttonPressed ? 0 : 5), imageParams);
|
||||
updateTagImage(filename, mac, (buttonPressed ? 0 : 5), taginfo, imageParams);
|
||||
cfgobj["counter"] = (int32_t)cfgobj["counter"] + 1;
|
||||
break;
|
||||
|
||||
@@ -154,14 +158,14 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
|
||||
|
||||
drawWeather(filename, cfgobj, taginfo, imageParams);
|
||||
taginfo->nextupdate = now + 3600;
|
||||
updateTagImage(filename, mac, 15, imageParams);
|
||||
updateTagImage(filename, mac, 15, taginfo, imageParams);
|
||||
break;
|
||||
|
||||
case Forecast:
|
||||
|
||||
drawForecast(filename, cfgobj, taginfo, imageParams);
|
||||
taginfo->nextupdate = now + 3 * 3600;
|
||||
updateTagImage(filename, mac, 15, imageParams);
|
||||
updateTagImage(filename, mac, 15, taginfo, imageParams);
|
||||
break;
|
||||
|
||||
case Firmware:
|
||||
@@ -185,14 +189,14 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
|
||||
|
||||
drawIdentify(filename, taginfo, imageParams);
|
||||
taginfo->nextupdate = now + 12 * 3600;
|
||||
updateTagImage(filename, mac, 0, imageParams);
|
||||
updateTagImage(filename, mac, 0, taginfo, imageParams);
|
||||
break;
|
||||
|
||||
case ImageUrl:
|
||||
|
||||
if (getImgURL(filename, cfgobj["url"], (time_t)cfgobj["#fetched"], imageParams, dst)) {
|
||||
taginfo->nextupdate = now + 60 * (cfgobj["interval"].as<int>() < 5 ? 5 : cfgobj["interval"].as<int>());
|
||||
updateTagImage(filename, mac, cfgobj["interval"].as<int>(), imageParams);
|
||||
updateTagImage(filename, mac, cfgobj["interval"].as<int>(), taginfo, imageParams);
|
||||
cfgobj["#fetched"] = now;
|
||||
} else {
|
||||
taginfo->nextupdate = now + 300;
|
||||
@@ -203,7 +207,7 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
|
||||
|
||||
if (getRssFeed(filename, cfgobj["url"], cfgobj["title"], taginfo, imageParams)) {
|
||||
taginfo->nextupdate = now + 60 * (cfgobj["interval"].as<int>() < 5 ? 5 : cfgobj["interval"].as<int>());
|
||||
updateTagImage(filename, mac, cfgobj["interval"].as<int>(), imageParams);
|
||||
updateTagImage(filename, mac, cfgobj["interval"].as<int>(), taginfo, imageParams);
|
||||
} else {
|
||||
taginfo->nextupdate = now + 300;
|
||||
}
|
||||
@@ -213,14 +217,14 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
|
||||
|
||||
drawQR(filename, cfgobj["qr-content"], cfgobj["title"], taginfo, imageParams);
|
||||
taginfo->nextupdate = now + 12 * 3600;
|
||||
updateTagImage(filename, mac, 0, imageParams);
|
||||
updateTagImage(filename, mac, 0, taginfo, imageParams);
|
||||
break;
|
||||
|
||||
case Calendar:
|
||||
|
||||
if (getCalFeed(filename, cfgobj["apps_script_url"], cfgobj["title"], taginfo, imageParams)) {
|
||||
taginfo->nextupdate = now + 60 * (cfgobj["interval"].as<int>() < 5 ? 5 : cfgobj["interval"].as<int>());
|
||||
updateTagImage(filename, mac, cfgobj["interval"].as<int>(), imageParams);
|
||||
updateTagImage(filename, mac, cfgobj["interval"].as<int>(), taginfo, imageParams);
|
||||
} else {
|
||||
taginfo->nextupdate = now + 300;
|
||||
}
|
||||
@@ -230,14 +234,25 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
|
||||
|
||||
taginfo->nextupdate = 3216153600;
|
||||
break;
|
||||
|
||||
case SegStatic:
|
||||
|
||||
sprintf(buffer, "%-4.4s%-2.2s%-4.4s", cfgobj["line1"].as<const char *>(), cfgobj["line2"].as<const char *>(), cfgobj["line3"].as<const char *>());
|
||||
sendAPSegmentedData(mac, (String)buffer, 0x0000, false, (taginfo->isExternal == false));
|
||||
taginfo->nextupdate = 3216153600;
|
||||
break;
|
||||
}
|
||||
|
||||
taginfo->modeConfigJson = doc.as<String>();
|
||||
}
|
||||
|
||||
bool updateTagImage(String &filename, uint8_t *dst, uint16_t nextCheckin, imgParam &imageParams) {
|
||||
if (imageParams.hasRed) imageParams.dataType = DATATYPE_IMG_RAW_2BPP;
|
||||
prepareDataAvail(&filename, imageParams.dataType, dst, nextCheckin);
|
||||
bool updateTagImage(String &filename, uint8_t *dst, uint16_t nextCheckin, tagRecord *&taginfo, imgParam &imageParams) {
|
||||
if (taginfo->hwType == SOLUM_SEG_UK) {
|
||||
sendAPSegmentedData(dst, (String)imageParams.segments, imageParams.symbols, imageParams.invert, (taginfo->isExternal == false));
|
||||
} else {
|
||||
if (imageParams.hasRed) imageParams.dataType = DATATYPE_IMG_RAW_2BPP;
|
||||
prepareDataAvail(&filename, imageParams.dataType, dst, nextCheckin);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -265,8 +280,6 @@ void initSprite(TFT_eSprite &spr, int w, int h) {
|
||||
}
|
||||
|
||||
void drawDate(String &filename, tagRecord *&taginfo, imgParam &imageParams) {
|
||||
TFT_eSPI tft = TFT_eSPI();
|
||||
TFT_eSprite spr = TFT_eSprite(&tft);
|
||||
time_t now;
|
||||
time(&now);
|
||||
struct tm timeinfo;
|
||||
@@ -274,7 +287,16 @@ void drawDate(String &filename, tagRecord *&taginfo, imgParam &imageParams) {
|
||||
|
||||
int weekday_number = timeinfo.tm_wday;
|
||||
int month_number = timeinfo.tm_mon;
|
||||
int year_number = timeinfo.tm_year + 1900;
|
||||
|
||||
if (taginfo->hwType == SOLUM_SEG_UK) {
|
||||
sprintf(imageParams.segments, "%2d%2d%-2.2s%04d", timeinfo.tm_mday, month_number + 1, languageDays[getCurrentLanguage()][timeinfo.tm_wday], year_number);
|
||||
imageParams.symbols = 0x04;
|
||||
return;
|
||||
}
|
||||
|
||||
TFT_eSPI tft = TFT_eSPI();
|
||||
TFT_eSprite spr = TFT_eSprite(&tft);
|
||||
LittleFS.begin();
|
||||
|
||||
if (taginfo->hwType == SOLUM_29_033) {
|
||||
@@ -299,6 +321,30 @@ void drawDate(String &filename, tagRecord *&taginfo, imgParam &imageParams) {
|
||||
}
|
||||
|
||||
void drawNumber(String &filename, int32_t count, int32_t thresholdred, tagRecord *&taginfo, imgParam &imageParams) {
|
||||
|
||||
if (taginfo->hwType == SOLUM_SEG_UK) {
|
||||
imageParams.symbols = 0x00;
|
||||
if (count > 19999) {
|
||||
sprintf(imageParams.segments, "over flow");
|
||||
} else {
|
||||
if (count > 9999) {
|
||||
imageParams.symbols = 0x02;
|
||||
if (taginfo->contentMode == CountHours) {
|
||||
sprintf(imageParams.segments, "%04d hour", count - 10000);
|
||||
} else {
|
||||
sprintf(imageParams.segments, "%04d days", count - 10000);
|
||||
}
|
||||
} else {
|
||||
if (taginfo->contentMode == CountHours) {
|
||||
sprintf(imageParams.segments, "%4d hour", count);
|
||||
} else {
|
||||
sprintf(imageParams.segments, "%4d days", count);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
TFT_eSPI tft = TFT_eSPI();
|
||||
TFT_eSprite spr = TFT_eSprite(&tft);
|
||||
LittleFS.begin();
|
||||
@@ -354,11 +400,8 @@ void drawNumber(String &filename, int32_t count, int32_t thresholdred, tagRecord
|
||||
}
|
||||
|
||||
void drawWeather(String &filename, JsonObject &cfgobj, tagRecord *&taginfo, imgParam &imageParams) {
|
||||
TFT_eSPI tft = TFT_eSPI();
|
||||
TFT_eSprite spr = TFT_eSprite(&tft);
|
||||
|
||||
wsLog("get weather");
|
||||
// icons: https://erikflowers.github.io/weather-icons/
|
||||
|
||||
getLocation(cfgobj);
|
||||
HTTPClient http;
|
||||
@@ -389,23 +432,44 @@ void drawWeather(String &filename, JsonObject &cfgobj, tagRecord *&taginfo, imgP
|
||||
auto windspeed = doc["current_weather"]["windspeed"].as<int>();
|
||||
auto winddirection = doc["current_weather"]["winddirection"].as<int>();
|
||||
uint8_t weathercode = doc["current_weather"]["weathercode"].as<int>();
|
||||
uint8_t isday = doc["current_weather"]["is_day"].as<int>();
|
||||
if (weathercode > 40) weathercode -= 40;
|
||||
int wind = windSpeedToBeaufort(windspeed);
|
||||
|
||||
doc.clear();
|
||||
|
||||
if (taginfo->hwType == SOLUM_SEG_UK) {
|
||||
String weatherText[] = {"sun", "sun", "sun", "cldy", "cldy", "fog", "", "", "fog", "", "",
|
||||
"drzl", "", "drzl", "", "drzl", "ice", "ice", "", "", "",
|
||||
"rain", "", "rain", "", "rain", "ice", "ice", "", "", "",
|
||||
"snow", "", "snow", "", "snow", "", "snow", "", "", "rain",
|
||||
"rain", "rain", "", "", "snow", "snow", "", "", "", "",
|
||||
"", "", "", "", "strm", "hail", "", "", "hail"};
|
||||
if (temperature < -9.9) {
|
||||
sprintf(imageParams.segments, "%3d^%2d%-4.4s", static_cast<int>(temperature), wind, weatherText[weathercode].c_str());
|
||||
imageParams.symbols = 0x00;
|
||||
} else {
|
||||
sprintf(imageParams.segments, "%3d^%2d%-4.4s", static_cast<int>(temperature * 10), wind, weatherText[weathercode].c_str());
|
||||
imageParams.symbols = 0x04;
|
||||
}
|
||||
http.end();
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
if (isday == 0) {
|
||||
weatherIcons[0] = "\0uf02e";
|
||||
weatherIcons[1] = "\0uf083";
|
||||
weatherIcons[2] = "\0uf086";
|
||||
}
|
||||
|
||||
doc.clear();
|
||||
|
||||
TFT_eSPI tft = TFT_eSPI();
|
||||
TFT_eSprite spr = TFT_eSprite(&tft);
|
||||
LittleFS.begin();
|
||||
tft.setTextWrap(false, false);
|
||||
|
||||
|
||||
@@ -208,50 +208,51 @@ void prepareExternalDataAvail(struct pendingData* pending, IPAddress remoteIP) {
|
||||
return;
|
||||
}
|
||||
if (taginfo->isExternal == false) {
|
||||
LittleFS.begin();
|
||||
if (pending->availdatainfo.dataType != DATATYPE_UK_SEGMENTED) {
|
||||
LittleFS.begin();
|
||||
|
||||
char buffer[64];
|
||||
sprintf(buffer, "%02X%02X%02X%02X%02X%02X\0", src[2], src[3], src[4], src[5], src[6], src[7]);
|
||||
String filename = "/current/" + (String)buffer + ".pending";
|
||||
String imageUrl = "http://" + remoteIP.toString() + filename;
|
||||
wsLog("GET " + imageUrl);
|
||||
HTTPClient http;
|
||||
http.begin(imageUrl);
|
||||
int httpCode = http.GET();
|
||||
if (httpCode == 200) {
|
||||
File file = LittleFS.open(filename, "w");
|
||||
http.writeToStream(&file);
|
||||
file.close();
|
||||
}
|
||||
http.end();
|
||||
|
||||
fs::File file = LittleFS.open(filename);
|
||||
uint32_t filesize = file.size();
|
||||
if (filesize == 0) {
|
||||
file.close();
|
||||
wsErr("File has size 0. " + filename);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t md5bytes[16];
|
||||
{
|
||||
MD5Builder md5;
|
||||
md5.begin();
|
||||
md5.addStream(file, filesize);
|
||||
md5.calculate();
|
||||
md5.getBytes(md5bytes);
|
||||
}
|
||||
|
||||
char buffer[64];
|
||||
sprintf(buffer, "%02X%02X%02X%02X%02X%02X\0", src[2], src[3], src[4], src[5], src[6], src[7]);
|
||||
String filename = "/current/" + (String)buffer + ".pending";
|
||||
String imageUrl = "http://" + remoteIP.toString() + filename;
|
||||
wsLog("GET " + imageUrl);
|
||||
HTTPClient http;
|
||||
http.begin(imageUrl);
|
||||
int httpCode = http.GET();
|
||||
if (httpCode == 200) {
|
||||
File file = LittleFS.open(filename, "w");
|
||||
http.writeToStream(&file);
|
||||
file.close();
|
||||
taginfo->filename = filename;
|
||||
taginfo->len = filesize;
|
||||
clearPending(taginfo);
|
||||
taginfo->pending = true;
|
||||
memcpy(taginfo->md5pending, md5bytes, sizeof(md5bytes));
|
||||
}
|
||||
http.end();
|
||||
|
||||
fs::File file = LittleFS.open(filename);
|
||||
uint32_t filesize = file.size();
|
||||
if (filesize == 0) {
|
||||
file.close();
|
||||
wsErr("File has size 0. " + filename);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t md5bytes[16];
|
||||
{
|
||||
MD5Builder md5;
|
||||
md5.begin();
|
||||
md5.addStream(file, filesize);
|
||||
md5.calculate();
|
||||
md5.getBytes(md5bytes);
|
||||
}
|
||||
|
||||
file.close();
|
||||
sendDataAvail(pending);
|
||||
|
||||
taginfo->filename = filename;
|
||||
taginfo->len = filesize;
|
||||
clearPending(taginfo);
|
||||
taginfo->pending = true;
|
||||
memcpy(taginfo->md5pending, md5bytes, sizeof(md5bytes));
|
||||
taginfo->contentMode = 12;
|
||||
taginfo->nextupdate = 3216153600;
|
||||
sendDataAvail(pending);
|
||||
|
||||
wsSendTaginfo(mac);
|
||||
}
|
||||
@@ -456,10 +457,10 @@ void setAPchannel() {
|
||||
}
|
||||
}
|
||||
|
||||
bool sendAPSegmentedData(uint8_t* dst, String data, uint16_t icons, bool inverted) {
|
||||
bool sendAPSegmentedData(uint8_t* dst, String data, uint16_t icons, bool inverted, bool local) {
|
||||
struct pendingData pending = {0};
|
||||
memcpy(pending.targetMac, dst, 8);
|
||||
pending.availdatainfo.dataType = 0x51;
|
||||
pending.availdatainfo.dataType = DATATYPE_UK_SEGMENTED;
|
||||
pending.availdatainfo.dataSize = icons << 16;
|
||||
memcpy((void*)&(pending.availdatainfo.dataVer), data.c_str(), 10);
|
||||
pending.availdatainfo.dataTypeArgument = inverted;
|
||||
@@ -470,13 +471,18 @@ bool sendAPSegmentedData(uint8_t* dst, String data, uint16_t icons, bool inverte
|
||||
*((uint64_t*)srcc) = swap64(*((uint64_t*)dst));
|
||||
sprintf(buffer, ">AP Segmented Data %02X%02X%02X%02X%02X%02X%02X%02X\n\0", srcc[0], srcc[1], srcc[2], srcc[3], srcc[4], srcc[5], srcc[6], srcc[7]);
|
||||
Serial.print(buffer);
|
||||
return sendDataAvail(&pending);
|
||||
if (local) {
|
||||
return sendDataAvail(&pending);
|
||||
} else {
|
||||
udpsync.netSendDataAvail(&pending);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool showAPSegmentedInfo(uint8_t* dst) {
|
||||
bool showAPSegmentedInfo(uint8_t* dst, bool local) {
|
||||
struct pendingData pending = {0};
|
||||
memcpy(pending.targetMac, dst, 8);
|
||||
pending.availdatainfo.dataType = 0x51;
|
||||
pending.availdatainfo.dataType = DATATYPE_UK_SEGMENTED;
|
||||
pending.availdatainfo.dataSize = 0x00;
|
||||
pending.availdatainfo.dataVer = 0x00;
|
||||
pending.availdatainfo.dataTypeArgument = 0;
|
||||
@@ -487,5 +493,10 @@ bool showAPSegmentedInfo(uint8_t* dst) {
|
||||
*((uint64_t*)srcc) = swap64(*((uint64_t*)dst));
|
||||
sprintf(buffer, ">SDA %02X%02X%02X%02X%02X%02X%02X%02X\n\0", srcc[0], srcc[1], srcc[2], srcc[3], srcc[4], srcc[5], srcc[6], srcc[7]);
|
||||
Serial.print(buffer);
|
||||
return sendDataAvail(&pending);
|
||||
if (local) {
|
||||
return sendDataAvail(&pending);
|
||||
} else {
|
||||
udpsync.netSendDataAvail(&pending);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -533,12 +533,12 @@ void ShowAPInfo() {
|
||||
}
|
||||
|
||||
void notifySegmentedFlash() {
|
||||
sendAPSegmentedData(apInfo.mac, (String) "Fl ash", 0x0800, false);
|
||||
sendAPSegmentedData(apInfo.mac, (String) "Fl ash", 0x0800, false, true);
|
||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||
#if (FLASHER_AP_POWER == -1)
|
||||
sendAPSegmentedData(apInfo.mac, (String) "If done", 0x0800, false);
|
||||
sendAPSegmentedData(apInfo.mac, (String) "If done", 0x0800, false, true);
|
||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||
sendAPSegmentedData(apInfo.mac, (String) "RE boot", 0x0800, false);
|
||||
sendAPSegmentedData(apInfo.mac, (String) "RE boot", 0x0800, false, true);
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
#endif
|
||||
}
|
||||
@@ -560,14 +560,13 @@ void checkWaitPowerCycle() {
|
||||
void segmentedShowIp() {
|
||||
IPAddress IP = WiFi.localIP();
|
||||
char temp[12];
|
||||
sprintf(temp, "%03d IP %03d", IP[0], IP[1]);
|
||||
sendAPSegmentedData(apInfo.mac, (String) "IP Addr", 0x0200, true);
|
||||
sendAPSegmentedData(apInfo.mac, (String) "IP Addr", 0x0200, true, true);
|
||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||
sprintf(temp, "%03d IP %03d", IP[0], IP[1]);
|
||||
sendAPSegmentedData(apInfo.mac, (String)temp, 0x0200, true);
|
||||
sendAPSegmentedData(apInfo.mac, (String)temp, 0x0200, true, true);
|
||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||
sprintf(temp, "%03d IP %03d", IP[2], IP[3]);
|
||||
sendAPSegmentedData(apInfo.mac, (String)temp, 0x0200, true);
|
||||
sendAPSegmentedData(apInfo.mac, (String)temp, 0x0200, true, true);
|
||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
@@ -639,7 +638,7 @@ void APTask(void* parameter) {
|
||||
|
||||
if (apInfo.type == SOLUM_SEG_UK) {
|
||||
segmentedShowIp();
|
||||
showAPSegmentedInfo(apInfo.mac);
|
||||
showAPSegmentedInfo(apInfo.mac, true);
|
||||
}
|
||||
|
||||
uint16_t fsversion;
|
||||
@@ -694,7 +693,7 @@ void APTask(void* parameter) {
|
||||
ShowAPInfo();
|
||||
if (apInfo.type == SOLUM_SEG_UK) {
|
||||
segmentedShowIp();
|
||||
showAPSegmentedInfo(apInfo.mac);
|
||||
showAPSegmentedInfo(apInfo.mac, true);
|
||||
}
|
||||
} else {
|
||||
Serial.printf("Failed to bring up the AP after successful flashing... That's not supposed to happen!\n");
|
||||
|
||||
@@ -339,7 +339,7 @@ void init_web() {
|
||||
|
||||
server.onNotFound([](AsyncWebServerRequest *request) {
|
||||
if (request->url() == "/" || request->url() == "index.htm") {
|
||||
request->send(200, "text/html", "-");
|
||||
request->send(200, "text/html", "index.html not found. Did you forget to upload the littlefs partition?");
|
||||
return;
|
||||
}
|
||||
request->send(404);
|
||||
|
||||
@@ -63,7 +63,7 @@ static uint8_t charDecode(uint8_t c) {
|
||||
0b11000010,
|
||||
0b00011100,
|
||||
0b00000110,
|
||||
0b00000000,
|
||||
0b10101100,
|
||||
0b10001100,
|
||||
0b10001110,
|
||||
0b01111100,
|
||||
@@ -73,7 +73,7 @@ static uint8_t charDecode(uint8_t c) {
|
||||
0b00011110,
|
||||
0b10000110,
|
||||
0b10010110,
|
||||
0b11000110,
|
||||
0b01011010,
|
||||
0b10001000,
|
||||
0b11011010,
|
||||
0b01101110,
|
||||
@@ -92,7 +92,7 @@ static uint8_t charDecode(uint8_t c) {
|
||||
0b11000010,
|
||||
0b00011100,
|
||||
0b00010110,
|
||||
0b00000000,
|
||||
0b10101100,
|
||||
0b11110100,
|
||||
0b11110110,
|
||||
0b01111100,
|
||||
@@ -102,7 +102,7 @@ static uint8_t charDecode(uint8_t c) {
|
||||
0b00011110,
|
||||
0b11010110,
|
||||
0b10010110,
|
||||
0b11000110,
|
||||
0b01011010,
|
||||
0b10001000,
|
||||
0b11011010,
|
||||
0b01101110,
|
||||
@@ -147,7 +147,7 @@ static uint8_t charDecode(uint8_t c) {
|
||||
case 0x5F: // _
|
||||
return 0b00000010;
|
||||
case 0x5E: // ^
|
||||
return 0b01110000;
|
||||
return 0b01111000;
|
||||
case 0x3D: // =
|
||||
return 0b00001010;
|
||||
case 0x23: // #
|
||||
|
||||
Reference in New Issue
Block a user