Skip to content

Commit 7255e0f

Browse files
committed
Cleanup notifications and on/off logic
1 parent 902e8be commit 7255e0f

5 files changed

Lines changed: 44 additions & 48 deletions

File tree

wled00/button.cpp

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ void shortPressAction(uint8_t b)
2020
if (!buttons[b].macroButton) {
2121
switch (b) {
2222
case 0: toggleOnOff(); stateUpdated(CALL_MODE_BUTTON); break;
23-
case 1: ++effectCurrent %= strip.getModeCount(); stateChanged = true; colorUpdated(CALL_MODE_BUTTON); break;
23+
case 1: ++effectCurrent %= strip.getModeCount(); colorUpdated(CALL_MODE_BUTTON); break;
2424
}
2525
} else {
2626
applyPreset(buttons[b].macroButton, CALL_MODE_BUTTON_PRESET);
@@ -361,20 +361,21 @@ void handleButton()
361361
void handleOnOff()
362362
{
363363
unsigned long now = millis();
364-
if (rlyStartTime && now - rlyStartTime < rlyDelay*10) return; // don't do anything if we are waiting for relay delay
364+
if (rlyStartTime) {
365+
if (now - rlyStartTime < rlyDelay*10) return; // don't do anything if we are waiting for relay delay
366+
else {
367+
// relay delay has passed start actual transition
368+
transitionActive = true;
369+
transitionStartTime = now; // start counting transition from the moment when relay delay finished
370+
rlyStartTime = 0; // reset relay status
371+
}
372+
}
365373

366374
// perform fade global brightness transition
367375
if (transitionActive) {
368-
// we need to start segment transitions after relay delay passed
369-
if (rlyStartTime) {
370-
strip.setTransitionMode(true); // force all segments to transition mode
371-
rlyStartTime = 0; // reset relay status
372-
transitionStartTime = now; // start counting transition from the moment when relay delay finished
373-
}
374376
int ti = now - transitionStartTime;
375377
int tr = strip.getTransition() + 1; // ensure non-zero just in case
376378
if (ti/tr > 0) {
377-
strip.setTransitionMode(false); // stop all transitions
378379
// restore (global) transition time if not called from UDP notifier or single/temporary transition from JSON (also playlist)
379380
if (jsonTransitionOnce) strip.setTransition(transitionDelay);
380381
transitionActive = false;
@@ -383,9 +384,6 @@ void handleOnOff()
383384
} else {
384385
byte briTO = briT;
385386
int deltaBri = (int)bri - (int)briOld;
386-
// if we have non-fade transition set final brightness immediately
387-
//if (transitionStyle != TRANSITION_FADE) briT = bri;
388-
//else
389387
briT = briOld + (deltaBri * ti / tr);
390388
if (briTO != briT) applyBri();
391389
}

wled00/ir.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ static void decodeIRJson(uint32_t code)
598598
}
599599
} else {
600600
// HTTP API command
601-
String apireq = "win"; apireq += '&'; // reduce flash string usage
601+
String apireq = "win"; apireq += '&'; // reduce RAM string usage
602602
if (cmdStr.indexOf("~") > 0 || fdo["rpt"]) lastValidCode = code; // repeatable action
603603
if (!cmdStr.startsWith(apireq)) cmdStr = apireq + cmdStr; // if no "win&" prefix
604604
if (!irApplyToAllSelected && cmdStr.indexOf(F("SS="))<0) {
@@ -607,8 +607,8 @@ static void decodeIRJson(uint32_t code)
607607
cmdStr += tmp;
608608
}
609609
fdo.clear(); // clear JSON buffer (it is no longer needed)
610-
handleSet(nullptr, cmdStr, false); // no stateUpdated() call here
611-
stateUpdated(CALL_MODE_BUTTON_PRESET);
610+
handleSet(nullptr, cmdStr, false); // stateUpdated(CALL_MODE_NO_NOTIFY) called here
611+
notify(CALL_MODE_BUTTON_PRESET); // since notifications are not sent in handleSet()
612612
}
613613
} else {
614614
// command is JSON object
@@ -619,7 +619,6 @@ static void decodeIRJson(uint32_t code)
619619
jsonCmdObj["seg"] = seg; // replace array with object
620620
}
621621
deserializeState(jsonCmdObj, CALL_MODE_BUTTON_PRESET); // **will call stateUpdated() with correct CALL_MODE**
622-
stateUpdated(CALL_MODE_BUTTON_PRESET);
623622
} else {
624623
uint8_t psave = jsonCmdObj[F("psave")].as<int>();
625624
char pname[33];

wled00/json.cpp

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -399,17 +399,13 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
399399
netDebugEnabled = root[F("debug")] | netDebugEnabled;
400400
#endif
401401

402+
// on/off & brightness logic : brightness always overrides "on" switch; i.e. if both are set, ignore "on"
402403
bool onBefore = bri;
403-
getVal(root["bri"], bri);
404-
if (bri != briOld) stateChanged = true;
405-
406-
bool on = root["on"] | (bri > 0);
407-
if (!on != !bri) toggleOnOff();
408-
409-
if (root["on"].is<const char*>() && tolower(root["on"].as<const char*>()[0]) == 't') {
410-
if (onBefore || !bri) toggleOnOff(); // do not toggle off again if just turned on by bri (makes e.g. "{"on":"t","bri":32}" work)
404+
if (getVal(root["bri"], bri)) {
405+
if (onBefore ^ (bri > 0)) toggleOnOff(); // XOR logic (will also fire toggleRelay() if necessary and set stateChanged)
406+
} else {
407+
if (onBefore ^ getBoolVal(root["on"], onBefore)) toggleOnOff(); // XOR logic (will also fire toggleRelay() if necessary and set stateChanged)
411408
}
412-
if (!onBefore && on) toggleRelay(on); // must toggle relay manually
413409

414410
if (bri && !onBefore) { // unfreeze all segments when turning on
415411
for (size_t s=0; s < strip.getSegmentsNum(); s++) {
@@ -531,9 +527,9 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
531527
// HTTP API commands (must be handled before "ps")
532528
const char* httpwin = root["win"];
533529
if (httpwin) {
534-
String apireq = "win"; apireq += '&'; // reduce flash string usage
530+
String apireq = "win"; apireq += '&'; // reduce RAM string usage
535531
apireq += httpwin;
536-
handleSet(nullptr, apireq, false); // may set stateChanged
532+
handleSet(nullptr, apireq, false); // calls stateUpdated(CALL_MODE_NO_NOTIFY)
537533
}
538534

539535
// Applying preset from JSON API has 2 cases: a) "pd" AKA "preset direct" and b) "ps" AKA "preset select"

wled00/led.cpp

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,12 @@ void stateUpdated(byte callMode) {
8484
// 6: fx changed 7: hue 8: preset cycle 9: blynk 10: alexa 11: ws send only 12: button preset
8585
setValuesFromFirstSelectedSeg(); // a much better approach would be to use main segment: setValuesFromMainSeg()
8686

87-
if (bri != briOld || stateChanged) {
87+
// notifications
88+
if (bri != briOld || stateChanged) { // bri != briOld must be checked since changing brightness does not always set stateChanged
8889
if (stateChanged) currentPreset = 0; //something changed, so we are no longer in the preset
8990

9091
if (callMode != CALL_MODE_NOTIFICATION && callMode != CALL_MODE_NO_NOTIFY) notify(callMode);
91-
if (bri != briOld && nodeBroadcastEnabled) sendSysInfoUDP(); // update on state
92+
if (bri != briOld && nodeBroadcastEnabled) sendSysInfoUDP(); // update "on" state
9293

9394
//set flag to update ws and mqtt
9495
interfaceUpdateCallMode = callMode;
@@ -99,21 +100,25 @@ void stateUpdated(byte callMode) {
99100
}
100101
}
101102

103+
// nightlight
102104
unsigned long now = millis();
103-
if (callMode != CALL_MODE_NO_NOTIFY && nightlightActive && (nightlightMode == NL_MODE_FADE || nightlightMode == NL_MODE_COLORFADE)) {
104-
briNlT = bri;
105-
nightlightDelayMs -= (now - nightlightStartTime);
106-
nightlightStartTime = now;
105+
if (nightlightActive && callMode != CALL_MODE_NO_NOTIFY) {
106+
if (nightlightMode == NL_MODE_FADE || nightlightMode == NL_MODE_COLORFADE) {
107+
briNlT = bri;
108+
nightlightDelayMs -= (now - nightlightStartTime);
109+
nightlightStartTime = now;
110+
}
111+
//deactivate nightlight if target brightness is reached
112+
if (bri == nightlightTargetBri && nightlightMode != NL_MODE_SUN) nightlightActive = false;
107113
}
114+
115+
// off
108116
if (briT == 0) {
109117
if (callMode != CALL_MODE_NOTIFICATION) strip.resetTimebase(); //effect start from beginning
110118
}
111119

112120
if (bri > 0) briLast = bri;
113121

114-
//deactivate nightlight if target brightness is reached
115-
if (bri == nightlightTargetBri && callMode != CALL_MODE_NO_NOTIFY && nightlightMode != NL_MODE_SUN) nightlightActive = false;
116-
117122
// notify usermods of state change
118123
UsermodManager::onStateChange(callMode);
119124

@@ -128,11 +133,11 @@ void stateUpdated(byte callMode) {
128133
} else {
129134
if (transitionActive) {
130135
// already active, just update briOld to reflect current state (no further notifications sent during on/off fade)
131-
briOld = briT;
132-
} else {
133-
// since not all effects are updated each frame we will need to force all segments into transtiton mode
134-
// but we will do that after relay delay has passed
135-
if (!rlyStartTime && (bri != briOld || stateChanged)) strip.setTransitionMode(true); // force all segments to transition mode
136+
briOld = briT; // briT is updated in handleOnOff()
137+
} else if (!rlyStartTime && (bri != briOld)) {
138+
// if relay is in idle state (!rlyStartTime) then we have change in brightness; start global brightness transition (may be to "off")
139+
// if relay is not in idle state (rlyStartTime>0) then we have an global "off" to "on" transition and LEDs start
140+
// with a delay (this delay is handled in handleOnOff())
136141
transitionActive = true;
137142
transitionStartTime = now;
138143
}
@@ -165,6 +170,7 @@ void updateInterfaces(uint8_t callMode) {
165170
// legacy method, applies values from col, effectCurrent, ... to selected segments
166171
void colorUpdated(byte callMode) {
167172
applyValuesToSelectedSegs();
173+
if (callMode != CALL_MODE_NO_NOTIFY && callMode != CALL_MODE_INIT) stateChanged = true;
168174
stateUpdated(callMode);
169175
}
170176

wled00/presets.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -189,19 +189,18 @@ void handlePresets()
189189
//HTTP API commands
190190
const char* httpwin = fdo["win"];
191191
if (httpwin) {
192-
String apireq = "win"; // reduce flash string usage
193-
apireq += F("&IN&"); // internal call
192+
String apireq = "win"; apireq += '&'; // reduce RAM string usage
194193
apireq += httpwin;
195-
handleSet(nullptr, apireq, false); // may call applyPreset() via PL=
196-
setValuesFromFirstSelectedSeg(); // fills legacy values
197-
changePreset = true;
194+
handleSet(nullptr, apireq, false); // may call applyPreset() via PL=
195+
setValuesFromFirstSelectedSeg(); // fills legacy values
198196
} else {
199197
if (!fdo["seg"].isNull() || !fdo["on"].isNull() || !fdo["bri"].isNull() || !fdo["nl"].isNull() || !fdo["ps"].isNull() || !fdo[F("playlist")].isNull()) changePreset = true;
200198
if (!(tmpMode == CALL_MODE_BUTTON_PRESET && fdo["ps"].is<const char *>() && strchr(fdo["ps"].as<const char *>(),'~') != strrchr(fdo["ps"].as<const char *>(),'~')))
201199
fdo.remove("ps"); // remove load request for presets to prevent recursive crash (if not called by button and contains preset cycling string "1~5~")
202200
deserializeState(fdo, CALL_MODE_NO_NOTIFY, tmpPreset); // may change presetToApply by calling applyPreset()
203201
}
204202
if (!errorFlag && tmpPreset < 255 && changePreset) currentPreset = tmpPreset;
203+
if (tmpMode != CALL_MODE_NO_NOTIFY && tmpMode != CALL_MODE_NOTIFICATION) notify(tmpMode); // send actual notifications
205204

206205
#if defined(ARDUINO_ARCH_ESP32)
207206
//Aircoookie recommended not to delete buffer
@@ -212,8 +211,6 @@ void handlePresets()
212211
#endif
213212

214213
releaseJSONBufferLock();
215-
if (changePreset) notify(tmpMode); // force UDP notification
216-
stateUpdated(tmpMode); // was colorUpdated() if anything breaks (also schedules updateInterfaces())
217214
}
218215

219216
//called from handleSet(PS=) [network callback (sObj is empty)], IR (irrational) [loop context] and deserializeState() [network callback]

0 commit comments

Comments
 (0)