Added missing ir.json error type.

Hopefully fix for WS virtual disconnects.
WS debugging info.
This commit is contained in:
Blaz Kristan 2021-07-25 22:44:26 +02:00
parent c66cffd6a6
commit 392df6ba72
10 changed files with 897 additions and 839 deletions

View File

@ -214,6 +214,7 @@
#define ERR_FS_BEGIN 10 // Could not init filesystem (no partition?)
#define ERR_FS_QUOTA 11 // The FS is full or the maximum file size is reached
#define ERR_FS_PLOAD 12 // It was attempted to load a preset that does not exist
#define ERR_FS_IRLOAD 12 // Loading of ir.json failed
#define ERR_FS_GENERAL 19 // A general unspecified filesystem error occured
#define ERR_OVERTEMP 30 // An attached temperature sensor has measured above threshold temperature (not implemented)
#define ERR_OVERCURRENT 31 // An attached current sensor has measured a current above the threshold (not implemented)

View File

@ -242,9 +242,10 @@ function onLoad()
loadPalettesData();
loadFX(function() {
loadPresets(function() {
loadInfo(function() {
requestJson({'v':true});
});
makeWS();
// loadInfo(function() {
// requestJson({'v':true});
// });
});
});
});
@ -261,6 +262,11 @@ function onLoad()
sl.addEventListener('touchstart', toggleBubble);
sl.addEventListener('touchend', toggleBubble);
}
// Check for UI update WS handler
if (!ws || ws.readyState !== WebSocket.OPEN) {
setTimeout(function(){loadInfo(function(){requestJson({'v':true});})},250)
}
}
function updateTablinks(tabI)
@ -292,7 +298,15 @@ function showToast(text, error = false)
timeout = setTimeout(function(){ x.className = x.className.replace("show", ""); }, 2900);
}
function showErrorToast() {showToast('Connection to light failed!', true);}
function showErrorToast()
{
if (ws && ws.readyState === WebSocket.OPEN) {
ws.close();
ws = null;
}
showToast('Connection to light failed!', true);
}
function clearErrorToast() {gId("toast").className = gId("toast").className.replace("error", "");}
function getRuntimeStr(rt)
@ -1010,7 +1024,7 @@ function updatePA(scrollto=false)
function updateUI(scrollto=false)
{
noWS = (!ws || ws.readyState === WebSocket.CLOSED);
// noWS = (!ws || ws.readyState === WebSocket.CLOSED);
gId('buttonPower').className = (isOn) ? "active":"";
gId('buttonNl').className = (nlA) ? "active":"";
@ -1079,12 +1093,24 @@ function makeWS() {
if (json.leds) return; //liveview packet
clearTimeout(jsonTimeout);
jsonTimeout = null;
lastUpdate = new Date();
clearErrorToast();
gId('connind').style.backgroundColor = "#079";
// json object should contain json.info AND json.state (but may not)
var info = json.info;
if (info) {
var name = info.name;
lastinfo = info;
gId('namelabel').innerHTML = name;
//if (name === "Dinnerbone") d.documentElement.style.transform = "rotate(180deg)";
if (info.live) name = "(Live) " + name;
if (loc) name = "(L) " + name;
d.title = name;
isRgbw = info.leds.wv;
ledCount = info.leds.count;
syncTglRecv = info.str;
maxSeg = info.leds.maxseg;
pmt = info.fs.pmt;
showNodes();
if (isInfo) {
populateInfo(info);
@ -1099,6 +1125,10 @@ function makeWS() {
gId('connind').style.backgroundColor = "#831";
ws = null;
}
ws.onopen = function(event) {
ws.send("{'v':true}");
reqsLegal = true;
}
}
function reconnectWS() {// Create UI update WS handler
@ -1171,6 +1201,9 @@ function readState(s,command=false)
case 12:
errstr = "Preset not found.";
break;
case 13:
errstr = "Missing IR.json.";
break;
case 19:
errstr = "A filesystem error has occured.";
break;
@ -1190,7 +1223,6 @@ function requestJson(command)
{
gId('connind').style.backgroundColor = "#a90";
if (command && !reqsLegal) return; //stop post requests from chrome onchange event on page restore
lastUpdate = new Date();
if (!jsonTimeout) jsonTimeout = setTimeout(showErrorToast, 3000);
if (!command) command = {'v':true};
var req = null;
@ -1211,6 +1243,7 @@ function requestJson(command)
// }
if (useWs) {
ws.send(req?req:'{"v":true}');
return;
}
@ -1229,6 +1262,7 @@ function requestJson(command)
.then(json => {
clearTimeout(jsonTimeout);
jsonTimeout = null;
lastUpdate = new Date();
clearErrorToast();
gId('connind').style.backgroundColor = "#070";
if (!json) { showToast('Empty response', true); return; }

View File

@ -73,13 +73,14 @@
Factory reset: <input type="checkbox" name="RS"><br>
All settings and presets will be erased.<br><br>
HTTP traffic is unencrypted. An attacker in the same network can intercept form data!
<hr>
<a class="btn" href="/presets.json?download" target="download-frame">Backup presets</a><br>
<h3>Backup & Restore</h3>
<a class="btn lnk" href="/presets.json?download" target="download-frame">Backup presets</a><br>
<div id="presets">Restore presets:<input type="file" name="data" accept=".json"> <input type="button" value="Upload" onclick="uploadFile(d.Sf.data,'/presets.json');"><br></div>
<a class="btn" href="/cfg.json?download" target="download-frame">Backup configuration</a><br>
<a class="btn lnk" href="/cfg.json?download" target="download-frame">Backup configuration</a><br>
<div id="presets">Restore configuration:<input type="file" name="data2" accept=".json"> <input type="button" value="Upload" onclick="uploadFile(d.Sf.data2,'/cfg.json');"><br></div>
<div style="color: #fa0;">WARNING!<br>Restoring presets/configuration will OVERWRITE current presets/configuration.<br>
<div style="color: #fa0;">&#9888; Restoring presets/configuration will OVERWRITE your current presets/configuration.<br>
Incorrect configuration may require factory reset or re-flashing of ESP.</div>
For security reasons, passwords are not backed up.
<hr>
<h3>Software Update</h3>
<button type="button" onclick="U()">Manual OTA Update</button><br>

View File

@ -29,6 +29,9 @@ button, .btn {
background-color:#222;
z-index:1;
}
.lnk {
border: 0;
}
.helpB {
text-align: left;
position: absolute;

View File

@ -6,7 +6,7 @@
*/
// Autogenerated from wled00/data/style.css, do not edit!!
const char PAGE_settingsCss[] PROGMEM = R"=====(<style>body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%%;margin:0}hr{border-color:#666}.btn,button{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;border-radius:24px;display:inline-block;font-size:20px;margin:12px 8px 8px;padding:8px 12px;min-width:48px;cursor:pointer;text-decoration:none}.toprow{top:0;position:sticky;background-color:#222;z-index:1}.helpB{text-align:left;position:absolute;width:60px}input{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.5ch solid #333}input[type=text]{font-size:medium}input[type=number]{width:4em;font-size:medium;margin:2px}input[type=number].xxl{width:100px}input[type=number].xl{width:85px}input[type=number].l{width:63px}input[type=number].m{width:56px}input[type=number].s{width:49px}input[type=number].xs{width:42px}select{margin:2px;font-size:medium}input[type=checkbox]{transform:scale(2);margin-right:10px}select{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.5ch solid #333}td{padding:2px}.d5{width:4.5em!important}#toast{opacity:0;background-color:#444;border-radius:5px;bottom:64px;color:#fff;font-size:17px;padding:16px;pointer-events:none;position:fixed;text-align:center;z-index:5;transform:translateX(-50%%);max-width:90%%;left:50%%}#toast.show{opacity:1;background-color:#264;animation:fadein .5s,fadein .5s 2.5s reverse}#toast.error{opacity:1;background-color:#b21;animation:fadein .5s}</style>)=====";
const char PAGE_settingsCss[] PROGMEM = R"=====(<style>body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%%;margin:0}hr{border-color:#666}.btn,button{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;border-radius:24px;display:inline-block;font-size:20px;margin:12px 8px 8px;padding:8px 12px;min-width:48px;cursor:pointer;text-decoration:none}.toprow{top:0;position:sticky;background-color:#222;z-index:1}.lnk{border:0}.helpB{text-align:left;position:absolute;width:60px}input{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.5ch solid #333}input[type=text]{font-size:medium}input[type=number]{width:4em;font-size:medium;margin:2px}input[type=number].xxl{width:100px}input[type=number].xl{width:85px}input[type=number].l{width:63px}input[type=number].m{width:56px}input[type=number].s{width:49px}input[type=number].xs{width:42px}select{margin:2px;font-size:medium}input[type=checkbox]{transform:scale(2);margin-right:10px}select{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.5ch solid #333}td{padding:2px}.d5{width:4.5em!important}#toast{opacity:0;background-color:#444;border-radius:5px;bottom:64px;color:#fff;font-size:17px;padding:16px;pointer-events:none;position:fixed;text-align:center;z-index:5;transform:translateX(-50%%);max-width:90%%;left:50%%}#toast.show{opacity:1;background-color:#264;animation:fadein .5s,fadein .5s 2.5s reverse}#toast.error{opacity:1;background-color:#b21;animation:fadein .5s}</style>)=====";
// Autogenerated from wled00/data/settings.htm, do not edit!!
@ -394,21 +394,21 @@ Disable OTA when not in use, otherwise an attacker can reflash device software!
<br><br>Factory reset: <input type="checkbox" name="RS"><br>
All settings and presets will be erased.<br><br>
HTTP traffic is unencrypted. An attacker in the same network can intercept form data!
<hr><a class="btn" href="/presets.json?download" target="download-frame">
Backup presets</a><br><div id="presets">Restore presets:<input type="file"
name="data" accept=".json"> <input type="button" value="Upload"
onclick='uploadFile(d.Sf.data,"/presets.json")'><br></div><a class="btn"
href="/cfg.json?download" target="download-frame">Backup configuration</a><br>
<div id="presets">Restore configuration:<input type="file" name="data2"
accept=".json"> <input type="button" value="Upload"
<h3>Backup & Restore</h3><a class="btn lnk" href="/presets.json?download"
target="download-frame">Backup presets</a><br><div id="presets">Restore presets:
<input type="file" name="data" accept=".json"> <input type="button"
value="Upload" onclick='uploadFile(d.Sf.data,"/presets.json")'><br></div><a
class="btn lnk" href="/cfg.json?download" target="download-frame">
Backup configuration</a><br><div id="presets">Restore configuration:<input
type="file" name="data2" accept=".json"> <input type="button" value="Upload"
onclick='uploadFile(d.Sf.data2,"/cfg.json")'><br></div><div style="color:#fa0">
WARNING!<br>
Restoring presets/configuration will OVERWRITE current presets/configuration.
&#9888; Restoring presets/configuration will OVERWRITE your current presets/configuration.
<br>Incorrect configuration may require factory reset or re-flashing of ESP.
</div><hr><h3>Software Update</h3><button type="button" onclick="U()">
Manual OTA Update</button><br>Enable ArduinoOTA: <input type="checkbox"
name="AO"><br><hr><h3>About</h3><a href="https://github.com/Aircoookie/WLED/"
target="_blank">WLED</a> version 0.13.0-bl2<br><br><a
</div>For security reasons, passwords are not backed up.<hr><h3>Software Update
</h3><button type="button" onclick="U()">Manual OTA Update</button><br>
Enable ArduinoOTA: <input type="checkbox" name="AO"><br><hr><h3>About</h3><a
href="https://github.com/Aircoookie/WLED/" target="_blank">WLED</a>
version 0.13.0-bl2<br><br><a
href="https://github.com/Aircoookie/WLED/wiki/Contributors-and-credits"
target="_blank">Contributors, dependencies and special thanks</a><br>
A huge thank you to everyone who helped me create WLED!<br><br>

File diff suppressed because it is too large Load Diff

View File

@ -572,7 +572,7 @@ void decodeIRJson(uint32_t code)
sprintf_P(objKey, PSTR("\"0x%lX\":"), (unsigned long)code);
errorFlag = readObjectFromFile("/ir.json", objKey, &irDoc) ? ERR_NONE : ERR_FS_PLOAD;
errorFlag = readObjectFromFile("/ir.json", objKey, &irDoc) ? ERR_NONE : ERR_FS_IRLOAD;
fdo = irDoc.as<JsonObject>();
lastValidCode = 0;
if (!errorFlag)

View File

@ -416,7 +416,7 @@ void serializeState(JsonObject root, bool forPreset, bool includeBri, bool segme
}
if (!forPreset) {
if (errorFlag) root[F("error")] = errorFlag;
if (errorFlag) {root[F("error")] = errorFlag; errorFlag = ERR_NONE;}
root[F("ps")] = currentPreset;
root[F("pl")] = currentPlaylist;

View File

@ -8,7 +8,7 @@
*/
// version code in format yymmddb (b = daily build)
#define VERSION 2107231
#define VERSION 2107251
//uncomment this if you have a "my_config.h" file you'd like to use
//#define WLED_USE_MY_CONFIG

View File

@ -16,9 +16,11 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
if(type == WS_EVT_CONNECT){
//client connected
sendDataWs(client);
DEBUG_PRINTLN(F("WS client connected."));
} else if(type == WS_EVT_DISCONNECT){
//client disconnected
if (client->id() == wsLiveClientId) wsLiveClientId = 0;
DEBUG_PRINTLN(F("WS client disconnected."));
} else if(type == WS_EVT_DATA){
//data packet
AwsFrameInfo * info = (AwsFrameInfo*)arg;
@ -34,7 +36,7 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
if (error || root.isNull()) return;
#ifdef WLED_DEBUG
DEBUG_PRINTLN(F("Serialized WS:"));
DEBUG_PRINT(F("Incoming WS: "));
serializeJson(root,Serial);
DEBUG_PRINTLN();
#endif
@ -75,12 +77,15 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
}
}
}
DEBUG_PRINTLN(F("WS multipart message."));
}
} else if(type == WS_EVT_ERROR){
//error was received from the other end
DEBUG_PRINTLN(F("WS error."));
} else if(type == WS_EVT_PONG){
//pong message was received (in response to a ping request maybe)
DEBUG_PRINTLN(F("WS pong."));
}
}
@ -90,7 +95,6 @@ void sendDataWs(AsyncWebSocketClient * client)
if (!ws.count()) return;
AsyncWebSocketMessageBuffer * buffer;
DEBUG_PRINTLN(F("Sending WS data."));
{ //scope JsonDocument so it releases its buffer
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
JsonObject state = doc.createNestedObject("state");
@ -100,13 +104,22 @@ void sendDataWs(AsyncWebSocketClient * client)
size_t len = measureJson(doc);
buffer = ws.makeBuffer(len);
if (!buffer) return; //out of memory
/*
#ifdef WLED_DEBUG
DEBUG_PRINT(F("Outgoing WS: "));
serializeJson(doc,Serial);
DEBUG_PRINTLN();
#endif
*/
serializeJson(doc, (char *)buffer->get(), len +1);
}
DEBUG_PRINT(F("Sending WS data "));
if (client) {
client->text(buffer);
DEBUG_PRINTLN(F("to a single client."));
} else {
ws.textAll(buffer);
DEBUG_PRINTLN(F("to multiple clients."));
}
}