Live mainseg improvements

Make override work in mainseg mode
Move unfreeze on turn on from UI to JSON parser
Fix mainseg not unfreezing on timeout
This commit is contained in:
cschwinne 2022-04-01 00:59:19 +02:00
parent ae90aa4ccc
commit 958cd35e21
9 changed files with 2279 additions and 2261 deletions

View File

@ -867,11 +867,12 @@ input[type=number]::-webkit-outer-spin-button {
.frz {
left: 36px;
position: absolute;
top: -2px;
top: 0px;
cursor: pointer;
padding: 8px;
}
/* TODO expanded does not seem to apply to .frz, what is this for? */
.expanded .frz {
display: none;
}

View File

@ -137,7 +137,7 @@
<div id="Effects" class="tabcontent">
<p class="labels">Effect speed</p>
<div class="staytop">
<i class="icons slider-icon" style="cursor: pointer;" onclick="tglFreeze()">&#xe325;</i>
<i class="icons slider-icon" style="cursor: pointer;" title="Freeze" onclick="tglFreeze()">&#xe325;</i>
<div class="sliderwrap il">
<input id="sliderSpeed" class="noslide" onchange="setSpeed()" oninput="updateTrail(this)" max="255" min="0" type="range" value="128" />
<output class="sliderbubble hidden"></output>

View File

@ -585,7 +585,7 @@ function populateSegments(s)
<input type="checkbox" id="seg${i}sel" onchange="selSeg(${i})" ${inst.sel ? "checked":""}>
<span class="checkmark schk"></span>
</label>
<i class="icons e-icon frz" id="seg${i}frz" onclick="event.preventDefault();tglFreeze(${i});">&#x${inst.frz ? (li.live && li.liveseg==i?'e410':'e0e8') : 'e325'};</i>
<i class="icons e-icon frz" id="seg${i}frz" onclick="event.preventDefault();tglFreeze(${i});" style="display:${inst.frz?"inline":"none"}">&#x${li.live && li.liveseg==i?'e410':'e325'};</i>
<div class="segname">
<div class="segntxt" onclick="selSegEx(${i})">${inst.n ? inst.n : "Segment "+i}</div>
<i class="icons edit-icon ${expanded[i] ? "expanded":""}" id="seg${i}nedit" onclick="tglSegn(${i})">&#xe2c6;</i>
@ -1254,11 +1254,6 @@ function requestJson(command, rinfo = true) {
function togglePower() {
isOn = !isOn;
var obj = {"on": isOn};
if (isOn && lastinfo && lastinfo.live && lastinfo.liveseg>=0) {
obj.live = false;
obj.seg = [];
obj.seg[0] ={"id": lastinfo.liveseg, "frz": false};
}
requestJson(obj);
}
@ -1650,7 +1645,11 @@ function setSegBri(s){
function tglFreeze(s=null)
{
var obj = {"seg": {"frz": "t"}}; // toggle
if (s!==null) obj.seg.id = s;
if (s!==null) {
obj.seg.id = s;
// if live segment, enter live override (which also unfreezes)
if (lastinfo && s==lastinfo.liveseg && lastinfo.live) obj = {"lor":1};
}
requestJson(obj);
}

View File

@ -34,7 +34,7 @@ void handleDDPPacket(e131_packet_t* p) {
realtimeLock(realtimeTimeoutMs, REALTIME_MODE_DDP);
if (!realtimeOverride || (realtimeMode && useMainSegmentOnly)) {
if (!realtimeOverride) {
for (uint16_t i = start; i < stop; i++) {
setRealtimePixel(i, data[c], data[c+1], data[c+2], 0);
c+=3;
@ -115,7 +115,7 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, byte protocol){
if (uni != e131Universe) return;
if (dmxChannels-DMXAddress+1 < 3) return;
realtimeLock(realtimeTimeoutMs, mde);
if (realtimeOverride && !(realtimeMode && useMainSegmentOnly)) return;
if (realtimeOverride) return;
wChannel = (dmxChannels-DMXAddress+1 > 3) ? e131_data[DMXAddress+3] : 0;
for (uint16_t i = 0; i < totalLen; i++)
setRealtimePixel(i, e131_data[DMXAddress+0], e131_data[DMXAddress+1], e131_data[DMXAddress+2], wChannel);
@ -125,7 +125,7 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, byte protocol){
if (uni != e131Universe) return;
if (dmxChannels-DMXAddress+1 < 4) return;
realtimeLock(realtimeTimeoutMs, mde);
if (realtimeOverride && !(realtimeMode && useMainSegmentOnly)) return;
if (realtimeOverride) return;
wChannel = (dmxChannels-DMXAddress+1 > 4) ? e131_data[DMXAddress+4] : 0;
if (DMXOldDimmer != e131_data[DMXAddress+0]) {
DMXOldDimmer = e131_data[DMXAddress+0];
@ -176,7 +176,7 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, byte protocol){
bool is4Chan = (DMXMode == DMX_MODE_MULTIPLE_RGBW);
const uint16_t dmxChannelsPerLed = is4Chan ? 4 : 3;
const uint16_t ledsPerUniverse = is4Chan ? MAX_4_CH_LEDS_PER_UNIVERSE : MAX_3_CH_LEDS_PER_UNIVERSE;
if (realtimeOverride && !(realtimeMode && useMainSegmentOnly)) return;
if (realtimeOverride) return;
uint16_t previousLeds, dmxOffset;
if (previousUniverses == 0) {
if (dmxChannels-DMXAddress < 1) return;

View File

@ -206,6 +206,7 @@ bool updateVal(const String* req, const char* key, byte* val, byte minv=0, byte
void notify(byte callMode, bool followUp=false);
uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, byte *buffer, uint8_t bri=255, bool isRGBW=false);
void realtimeLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC);
void exitRealtime();
void handleNotifications();
void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w);
void refreshNodeList();

File diff suppressed because it is too large Load Diff

View File

@ -243,6 +243,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
{
bool stateResponse = root[F("v")] | false;
bool onBefore = bri;
getVal(root["bri"], &bri);
bool on = root["on"] | (bri > 0);
@ -250,6 +251,15 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
if (root["on"].is<const char*>() && root["on"].as<const char*>()[0] == 't') toggleOnOff();
if (bri && !onBefore) { // unfreeze all segments when turning on
for (uint8_t s=0; s < strip.getMaxSegments(); s++) {
strip.getSegment(s).setOption(SEG_OPTION_FREEZE, false, s);
}
if (realtimeMode && !realtimeOverride && useMainSegmentOnly) { // keep live segment frozen if live
strip.getMainSegment().setOption(SEG_OPTION_FREEZE, true, strip.getMainSegmentId());
}
}
int tr = -1;
if (!presetId || currentPlaylist < 0) { //do not apply transition time from preset if playlist active, as it would override playlist transition times
tr = root[F("transition")] | -1;
@ -296,6 +306,9 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
realtimeOverride = root[F("lor")] | realtimeOverride;
if (realtimeOverride > 2) realtimeOverride = REALTIME_OVERRIDE_ALWAYS;
if (realtimeMode && useMainSegmentOnly) {
strip.getMainSegment().setOption(SEG_OPTION_FREEZE, !realtimeOverride, strip.getMainSegmentId());
}
if (root.containsKey("live")) {
if (root["live"].as<bool>()) {
@ -303,11 +316,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
jsonTransitionOnce = true;
realtimeLock(65000);
} else {
if (realtimeOverride == REALTIME_OVERRIDE_ONCE) realtimeOverride = REALTIME_OVERRIDE_NONE;
strip.setBrightness(scaledBri(bri));
realtimeTimeout = 0; //cancel realtime mode immediately
realtimeMode = REALTIME_MODE_INACTIVE; // inform UI immediatelly
realtimeIP[0] = 0;
exitRealtime();
}
}

View File

@ -934,6 +934,9 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
if (pos > 0) {
realtimeOverride = getNumVal(&req, pos);
if (realtimeOverride > 2) realtimeOverride = REALTIME_OVERRIDE_ALWAYS;
if (realtimeMode && useMainSegmentOnly) {
strip.getMainSegment().setOption(SEG_OPTION_FREEZE, !realtimeOverride, strip.getMainSegmentId());
}
}
pos = req.indexOf(F("RB"));

View File

@ -140,7 +140,7 @@ void notify(byte callMode, bool followUp)
void realtimeLock(uint32_t timeoutMs, byte md)
{
if (!realtimeMode) {
if (!realtimeMode && !realtimeOverride) {
uint16_t stop, start;
if (useMainSegmentOnly) {
WS2812FX::Segment& mainseg = strip.getMainSegment();
@ -152,30 +152,41 @@ void realtimeLock(uint32_t timeoutMs, byte md)
stop = strip.getLengthTotal();
}
// clear strip/segment
if (useMainSegmentOnly || !realtimeOverride) for (uint16_t i = start; i < stop; i++) strip.setPixelColor(i,0,0,0,0);
// if WLED was off and using main segment only, turn non-main segments off
for (uint16_t i = start; i < stop; i++) strip.setPixelColor(i,0,0,0,0);
// if WLED was off and using main segment only, freeze non-main segments so they stay off
if (useMainSegmentOnly && bri == 0) {
for (uint8_t s=0; s < strip.getMaxSegments(); s++) {
if (s != strip.getMainSegmentId()) strip.getSegment(s).setOption(SEG_OPTION_ON, false, s);
else strip.getSegment(s).setOption(SEG_OPTION_ON, true, s);
strip.getSegment(s).setOption(SEG_OPTION_FREEZE, true, s);
}
}
}
// if strip is off (bri==0) and not already in RTM
if (briT == 0 && !realtimeMode && !realtimeOverride) {
strip.setBrightness(scaledBri(briLast), true);
}
if (realtimeTimeout != UINT32_MAX) {
if (timeoutMs == 255001 || timeoutMs == 65000) realtimeTimeout = UINT32_MAX;
else realtimeTimeout = millis() + timeoutMs;
}
// if strip is off (bri==0) and not already in RTM
if (briT == 0 && !realtimeMode) {
strip.setBrightness(scaledBri(briLast), true);
realtimeTimeout = (timeoutMs == 255001 || timeoutMs == 65000) ? UINT32_MAX : millis() + timeoutMs;
}
realtimeMode = md;
if (arlsForceMaxBri && !realtimeOverride) strip.setBrightness(scaledBri(255), true);
if (realtimeOverride) return;
if (arlsForceMaxBri) strip.setBrightness(scaledBri(255), true);
if (briT > 0 && md == REALTIME_MODE_GENERIC) strip.show();
}
void exitRealtime() {
if (!realtimeMode) return;
if (realtimeOverride == REALTIME_OVERRIDE_ONCE) realtimeOverride = REALTIME_OVERRIDE_NONE;
strip.setBrightness(scaledBri(bri));
realtimeTimeout = 0; // cancel realtime mode immediately
realtimeMode = REALTIME_MODE_INACTIVE; // inform UI immediately
realtimeIP[0] = 0;
if (useMainSegmentOnly) { // unfreeze live segment again
strip.getMainSegment().setOption(SEG_OPTION_FREEZE, false, strip.getMainSegmentId());
}
}
#define TMP2NET_OUT_PORT 65442
@ -203,13 +214,7 @@ void handleNotifications()
}
//unlock strip when realtime UDP times out
if (realtimeMode && millis() > realtimeTimeout)
{
if (realtimeOverride == REALTIME_OVERRIDE_ONCE) realtimeOverride = REALTIME_OVERRIDE_NONE;
strip.setBrightness(scaledBri(bri));
realtimeMode = REALTIME_MODE_INACTIVE;
realtimeIP[0] = 0;
}
if (realtimeMode && millis() > realtimeTimeout) exitRealtime();
//receive UDP notifications
if (!udpConnected) return;