Peek uses the main websocket connection

This commit is contained in:
cschwinne 2021-07-08 02:01:17 +02:00
parent 17d2fb80f2
commit e04b965659
8 changed files with 867 additions and 838 deletions

View File

@ -2,12 +2,24 @@
### Builds after release 0.12.0 ### Builds after release 0.12.0
#### Build 2107080
- Made Peek use the main websocket connection instead of opening a second one
- Temperature usermod fix (from @blazoncek's dev branch)
#### Build 2107070 #### Build 2107070
- More robust initial resource loading in UI - More robust initial resource loading in UI
- Added `getJsonValue()` for usermod config parsing (PR #2061)
- Fixed preset saving over websocket - Fixed preset saving over websocket
- Alpha ESP32 S2 support (filesystem does not work) (PR #2067) - Alpha ESP32 S2 support (filesystem does not work) (PR #2067)
#### Build 2107042
- Updated ArduinoJson to 6.18.1
- Improved Twinkleup effect
- Fixed preset immediately deselecting when set via HTTP API `PL=`
#### Build 2107041 #### Build 2107041
- Restored support for "PL=~" mistakenly removed in 2106300 - Restored support for "PL=~" mistakenly removed in 2106300

View File

@ -42,6 +42,8 @@ class UsermodTemperature : public Usermod {
bool waitingForConversion = false; bool waitingForConversion = false;
// flag set at startup if DS18B20 sensor not found, avoids trying to keep getting // flag set at startup if DS18B20 sensor not found, avoids trying to keep getting
// temperature if flashed to a board without a sensor attached // temperature if flashed to a board without a sensor attached
bool sensorFound = false;
bool enabled = true; bool enabled = true;
// strings to reduce flash memory usage (used more than twice) // strings to reduce flash memory usage (used more than twice)
@ -87,7 +89,9 @@ class UsermodTemperature : public Usermod {
uint8_t deviceAddress[8] = {0,0,0,0,0,0,0,0}; uint8_t deviceAddress[8] = {0,0,0,0,0,0,0,0};
// find out if we have DS18xxx sensor attached // find out if we have DS18xxx sensor attached
oneWire->reset_search(); oneWire->reset_search();
delay(10);
while (oneWire->search(deviceAddress)) { while (oneWire->search(deviceAddress)) {
DEBUG_PRINTLN(F("Found something..."));
if (oneWire->crc8(deviceAddress, 7) == deviceAddress[7]) { if (oneWire->crc8(deviceAddress, 7) == deviceAddress[7]) {
switch (deviceAddress[0]) { switch (deviceAddress[0]) {
case 0x10: // DS18S20 case 0x10: // DS18S20
@ -107,21 +111,23 @@ class UsermodTemperature : public Usermod {
void setup() { void setup() {
int retries = 10; int retries = 10;
// pin retrieved from cfg.json (readFromConfig()) prior to running setup() if (enabled) {
if (!pinManager.allocatePin(temperaturePin,false)) { // config says we are enabled
temperaturePin = -1; // allocation failed DEBUG_PRINTLN(F("Allocating temperature pin..."));
enabled = false; // pin retrieved from cfg.json (readFromConfig()) prior to running setup()
DEBUG_PRINTLN(F("Temperature pin allocation failed.")); if (temperaturePin >= 0 && pinManager.allocatePin(temperaturePin)) {
} else {
if (enabled) {
// config says we are enabled
oneWire = new OneWire(temperaturePin); oneWire = new OneWire(temperaturePin);
if (!oneWire->reset()) if (!oneWire->reset())
enabled = false; // resetting 1-Wire bus yielded an error sensorFound = false; // resetting 1-Wire bus yielded an error
else else
while ((enabled=findSensor()) && retries--) delay(25); // try to find sensor while ((sensorFound=findSensor()) && retries--) delay(25); // try to find sensor
} else {
if (temperaturePin >= 0) DEBUG_PRINTLN(F("Temperature pin allocation failed."));
temperaturePin = -1; // allocation failed
sensorFound = false;
} }
} }
lastMeasurement = millis() - readingInterval + 10000;
initDone = true; initDone = true;
} }
@ -189,7 +195,7 @@ class UsermodTemperature : public Usermod {
JsonArray temp = user.createNestedArray(FPSTR(_name)); JsonArray temp = user.createNestedArray(FPSTR(_name));
//temp.add(F("Loaded.")); //temp.add(F("Loaded."));
if (temperature <= -100) { if (temperature <= -100.0 || (!sensorFound && temperature == -1.0)) {
temp.add(0); temp.add(0);
temp.add(F(" Sensor Error!")); temp.add(F(" Sensor Error!"));
return; return;
@ -249,6 +255,7 @@ class UsermodTemperature : public Usermod {
enabled = top[FPSTR(_enabled)] | enabled; enabled = top[FPSTR(_enabled)] | enabled;
newTemperaturePin = top["pin"] | newTemperaturePin; newTemperaturePin = top["pin"] | newTemperaturePin;
// newTemperaturePin = min(33,max(-1,(int)newTemperaturePin)); // bounds check
degC = top["degC"] | degC; degC = top["degC"] | degC;
readingInterval = top[FPSTR(_readInterval)] | readingInterval/1000; readingInterval = top[FPSTR(_readInterval)] | readingInterval/1000;
readingInterval = min(120,max(10,(int)readingInterval)) * 1000; // convert to ms readingInterval = min(120,max(10,(int)readingInterval)) * 1000; // convert to ms
@ -260,8 +267,10 @@ class UsermodTemperature : public Usermod {
temperaturePin = newTemperaturePin; temperaturePin = newTemperaturePin;
DEBUG_PRINTLN(F(" config loaded.")); DEBUG_PRINTLN(F(" config loaded."));
} else { } else {
// changing parameters from settings page DEBUG_PRINTLN(F(" config (re)loaded."));
// changing paramters from settings page
if (newTemperaturePin != temperaturePin) { if (newTemperaturePin != temperaturePin) {
DEBUG_PRINTLN(F("Re-init temperature."));
// deallocate pin and release memory // deallocate pin and release memory
delete oneWire; delete oneWire;
pinManager.deallocatePin(temperaturePin); pinManager.deallocatePin(temperaturePin);
@ -269,7 +278,6 @@ class UsermodTemperature : public Usermod {
// initialise // initialise
setup(); setup();
} }
DEBUG_PRINTLN(F(" config (re)loaded."));
} }
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features // use "return !top["newestParameter"].isNull();" when updating Usermod with new features
return !top[FPSTR(_parasite)].isNull(); return !top[FPSTR(_parasite)].isNull();

View File

@ -22,7 +22,7 @@ var pJson = {};
var pN = "", pI = 0, pNum = 0; var pN = "", pI = 0, pNum = 0;
var pmt = 1, pmtLS = 0, pmtLast = 0; var pmt = 1, pmtLS = 0, pmtLast = 0;
var lastinfo = {}; var lastinfo = {};
var ws, useWs = false; var ws;
var fxlist = d.getElementById('fxlist'), pallist = d.getElementById('pallist'); var fxlist = d.getElementById('fxlist'), pallist = d.getElementById('pallist');
var cfg = { var cfg = {
theme:{base:"dark", bg:{url:""}, alpha:{bg:0.6,tab:0.8}, color:{bg:""}}, theme:{base:"dark", bg:{url:""}, alpha:{bg:0.6,tab:0.8}, color:{bg:""}},
@ -932,11 +932,12 @@ function makeWS() {
if (ws) return; if (ws) return;
ws = new WebSocket('ws://'+(loc?locip:window.location.hostname)+'/ws'); ws = new WebSocket('ws://'+(loc?locip:window.location.hostname)+'/ws');
ws.onmessage = function(event) { ws.onmessage = function(event) {
var json = JSON.parse(event.data);
if (json.leds) return; //liveview packet
clearTimeout(jsonTimeout); clearTimeout(jsonTimeout);
jsonTimeout = null; jsonTimeout = null;
clearErrorToast(); clearErrorToast();
d.getElementById('connind').style.backgroundColor = "#079"; d.getElementById('connind').style.backgroundColor = "#079";
var json = JSON.parse(event.data);
var info = json.info; var info = json.info;
d.getElementById('buttonNodes').style.display = (info.ndc > 0 && window.innerWidth > 770) ? "block":"none"; d.getElementById('buttonNodes').style.display = (info.ndc > 0 && window.innerWidth > 770) ? "block":"none";
lastinfo = info; lastinfo = info;
@ -1054,15 +1055,18 @@ function requestJson(command, rinfo = true) {
url = `http://${locip}${url}`; url = `http://${locip}${url}`;
} }
var useWs = ((command || rinfo) && ws && ws.readyState === WebSocket.OPEN);
var type = command ? 'post':'get'; var type = command ? 'post':'get';
if (command) if (command)
{ {
command.v = true; //get complete API response command.v = true; //get complete API response
command.time = Math.floor(Date.now() / 1000); command.time = Math.floor(Date.now() / 1000);
req = JSON.stringify(command); req = JSON.stringify(command);
if (req.length > 1000) useWs = false; //do not send very long requests over websocket
} }
if ((command || rinfo) && ws && ws.readyState === WebSocket.OPEN) { if (useWs) {
ws.send(req?req:'{"v":true}'); ws.send(req?req:'{"v":true}');
return; return;
} }
@ -1187,6 +1191,7 @@ function toggleLiveview() {
var url = loc ? `http://${locip}/liveview`:"/liveview"; var url = loc ? `http://${locip}/liveview`:"/liveview";
d.getElementById('liveview').src = (isLv) ? url:"about:blank"; d.getElementById('liveview').src = (isLv) ? url:"about:blank";
d.getElementById('buttonSr').className = (isLv) ? "active":""; d.getElementById('buttonSr').className = (isLv) ? "active":"";
if (!isLv && ws && ws.readyState === WebSocket.OPEN) ws.send('{"lv":false}');
size(); size();
} }

View File

@ -21,18 +21,6 @@
<body> <body>
<div id="canv" /> <div id="canv" />
<script> <script>
console.info("Live-Preview websocket opening");
var socket = new WebSocket("ws://"+document.location.host+"/ws");
socket.onopen = function () {
console.info("Live-Preview websocket is opened");
socket.send("{'lv':true}");
}
socket.onclose = function () { console.info("Live-Preview websocket is closing"); }
socket.onerror = function (event) { console.error("Live-Preview websocket error:", event); }
function updatePreview(leds) { function updatePreview(leds) {
var str = "linear-gradient(90deg,"; var str = "linear-gradient(90deg,";
var len = leds.length; var len = leds.length;
@ -46,7 +34,7 @@
document.getElementById("canv").style.background = str; document.getElementById("canv").style.background = str;
} }
socket.onmessage = function (event) { function getLiveJson(event) {
try { try {
var json = JSON.parse(event.data); var json = JSON.parse(event.data);
if (json && json.leds) { if (json && json.leds) {
@ -54,9 +42,23 @@
} }
} }
catch (err) { catch (err) {
console.error("Live-Preview websocket error:",err); console.error("Live-Preview ws error:",err);
} }
} }
var ws = top.window.ws;
if (ws && ws.readyState === WebSocket.OPEN) {
console.info("Use top WS for peek");
ws.send("{'lv':true}");
} else {
console.info("Peek ws opening");
ws = new WebSocket("ws://"+document.location.host+"/ws");
ws.onopen = function () {
console.info("Peek WS opened");
ws.send("{'lv':true}");
}
}
ws.addEventListener('message',getLiveJson);
</script> </script>
</body> </body>
</html> </html>

View File

@ -85,7 +85,7 @@ charset="utf-8"><meta name="theme-color" content="#222222"><title>
WLED Live Preview</title><style> WLED Live Preview</title><style>
body{margin:0}#canv{background:#000;filter:brightness(175%);width:100%;height:100%;position:absolute} body{margin:0}#canv{background:#000;filter:brightness(175%);width:100%;height:100%;position:absolute}
</style></head><body><div id="canv"><script> </style></head><body><div id="canv"><script>
console.info("Live-Preview websocket opening");var socket=new WebSocket("ws://"+document.location.host+"/ws");function updatePreview(e){var o="linear-gradient(90deg,",n=e.length;for(i=0;i<n;i++){var t=e[i];t.length>6&&(t=t.substring(2)),o+="#"+t,i<n-1&&(o+=",")}o+=")",document.getElementById("canv").style.background=o}socket.onopen=function(){console.info("Live-Preview websocket is opened"),socket.send("{'lv':true}")},socket.onclose=function(){console.info("Live-Preview websocket is closing")},socket.onerror=function(e){console.error("Live-Preview websocket error:",e)},socket.onmessage=function(e){try{var o=JSON.parse(e.data);o&&o.leds&&requestAnimationFrame((function(){updatePreview(o.leds)}))}catch(e){console.error("Live-Preview websocket error:",e)}} function updatePreview(e){var n="linear-gradient(90deg,",o=e.length;for(i=0;i<o;i++){var t=e[i];t.length>6&&(t=t.substring(2)),n+="#"+t,i<o-1&&(n+=",")}n+=")",document.getElementById("canv").style.background=n}function getLiveJson(e){try{var n=JSON.parse(e.data);n&&n.leds&&requestAnimationFrame((function(){updatePreview(n.leds)}))}catch(e){console.error("Live-Preview ws error:",e)}}var ws=top.window.ws;ws&&ws.readyState===WebSocket.OPEN?(console.info("Use top WS for peek"),ws.send("{'lv':true}")):(console.info("Peek ws opening"),(ws=new WebSocket("ws://"+document.location.host+"/ws")).onopen=function(){console.info("Peek WS opened"),ws.send("{'lv':true}")}),ws.addEventListener("message",getLiveJson)
</script></body></html>)====="; </script></body></html>)=====";

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -16,7 +16,6 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
if(type == WS_EVT_CONNECT){ if(type == WS_EVT_CONNECT){
//client connected //client connected
sendDataWs(client); sendDataWs(client);
//client->ping();
} else if(type == WS_EVT_DISCONNECT){ } else if(type == WS_EVT_DISCONNECT){
//client disconnected //client disconnected
if (client->id() == wsLiveClientId) wsLiveClientId = 0; if (client->id() == wsLiveClientId) wsLiveClientId = 0;
@ -24,7 +23,7 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
//data packet //data packet
AwsFrameInfo * info = (AwsFrameInfo*)arg; AwsFrameInfo * info = (AwsFrameInfo*)arg;
if(info->final && info->index == 0 && info->len == len){ if(info->final && info->index == 0 && info->len == len){
//the whole message is in a single frame and we got all of it's data (max. 1450byte) //the whole message is in a single frame and we got all of its data (max. 1450byte)
if(info->opcode == WS_TEXT) if(info->opcode == WS_TEXT)
{ {
bool verboseResponse = false; bool verboseResponse = false;
@ -37,10 +36,11 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
if (root.containsKey("lv")) if (root.containsKey("lv"))
{ {
wsLiveClientId = root["lv"] ? client->id() : 0; wsLiveClientId = root["lv"] ? client->id() : 0;
} else {
fileDoc = &jsonBuffer;
verboseResponse = deserializeState(root);
fileDoc = nullptr;
} }
fileDoc = &jsonBuffer;
verboseResponse = deserializeState(root);
fileDoc = nullptr;
} }
//update if it takes longer than 300ms until next "broadcast" //update if it takes longer than 300ms until next "broadcast"
if (verboseResponse && (millis() - lastInterfaceUpdate < 1700 || !interfaceUpdateCallMode)) sendDataWs(client); if (verboseResponse && (millis() - lastInterfaceUpdate < 1700 || !interfaceUpdateCallMode)) sendDataWs(client);