diff --git a/usermods/Animated_Staircase/Animated_Staircase.h b/usermods/Animated_Staircase/Animated_Staircase.h index 427348d8..1ef2c959 100644 --- a/usermods/Animated_Staircase/Animated_Staircase.h +++ b/usermods/Animated_Staircase/Animated_Staircase.h @@ -65,7 +65,7 @@ class Animated_Staircase : public Usermod { // The maximum number of configured segments. // Dynamically updated based on user configuration. byte maxSegmentId = 1; - byte mainSegmentId = 0; + byte minSegmentId = 0; // These values are used by the API to read the // last sensor state, or trigger a sensor @@ -91,8 +91,7 @@ class Animated_Staircase : public Usermod { static const char _topEchoCm[]; static const char _bottomEchoCm[]; - void publishMqtt(bool bottom, const char* state) - { + void publishMqtt(bool bottom, const char* state) { //Check if MQTT Connected, otherwise it will crash the 8266 if (WLED_MQTT_CONNECTED){ char subuf[64]; @@ -102,16 +101,11 @@ class Animated_Staircase : public Usermod { } void updateSegments() { - mainSegmentId = strip.getMainSegmentId(); - for (int i = 0; i < strip.getSegmentsNum(); i++) { + for (int i = minSegmentId; i < maxSegmentId; i++) { Segment &seg = strip.getSegment(i); - if (!seg.isActive()) { - maxSegmentId = i - 1; - break; - } + if (!seg.isActive()) continue; // skip gaps if (i >= onIndex && i < offIndex) { seg.setOption(SEG_OPTION_ON, true); - // We may need to copy mode and colors from segment 0 to make sure // changes are propagated even when the config is changed during a wipe // seg.setMode(mainsegment.mode); @@ -120,8 +114,10 @@ class Animated_Staircase : public Usermod { seg.setOption(SEG_OPTION_ON, false); } // Always mark segments as "transitional", we are animating the staircase - seg.setOption(SEG_OPTION_TRANSITIONAL, true); + //seg.setOption(SEG_OPTION_TRANSITIONAL, true); // not needed anymore as setOption() does it } + strip.trigger(); // force strip refresh + stateChanged = true; // inform external devices/UI of change colorUpdated(CALL_MODE_DIRECT_CHANGE); } @@ -207,9 +203,9 @@ class Animated_Staircase : public Usermod { if (onIndex == offIndex) { // Position the indices for a correct on-swipe if (swipe == SWIPE_UP) { - onIndex = mainSegmentId; + onIndex = minSegmentId; } else { - onIndex = maxSegmentId+1; + onIndex = maxSegmentId; } offIndex = onIndex; } @@ -221,7 +217,7 @@ class Animated_Staircase : public Usermod { } void autoPowerOff() { - if (on && ((millis() - lastSwitchTime) > on_time_ms)) { + if ((millis() - lastSwitchTime) > on_time_ms) { // if sensors are still on, do nothing if (bottomSensorState || topSensorState) return; @@ -238,10 +234,12 @@ class Animated_Staircase : public Usermod { if ((millis() - lastTime) > segment_delay_ms) { lastTime = millis(); + byte oldOn = onIndex; + byte oldOff = offIndex; if (on) { // Turn on all segments - onIndex = MAX(mainSegmentId, onIndex - 1); - offIndex = MIN(maxSegmentId + 1, offIndex + 1); + onIndex = MAX(minSegmentId, onIndex - 1); + offIndex = MIN(maxSegmentId, offIndex + 1); } else { if (swipe == SWIPE_UP) { onIndex = MIN(offIndex, onIndex + 1); @@ -249,7 +247,7 @@ class Animated_Staircase : public Usermod { offIndex = MAX(onIndex, offIndex - 1); } } - updateSegments(); + if (oldOn != onIndex || oldOff != offIndex) updateSegments(); // reduce the number of updates to necessary ones } } @@ -287,16 +285,22 @@ class Animated_Staircase : public Usermod { pinMode(topPIRorTriggerPin, OUTPUT); pinMode(topEchoPin, INPUT); } + onIndex = minSegmentId = strip.getMainSegmentId(); // it may not be the best idea to start with main segment as it may not be the first one + offIndex = maxSegmentId = strip.getLastActiveSegmentId() + 1; + + // shorten the strip transition time to be equal or shorter than segment delay + transitionDelayTemp = transitionDelay = segment_delay_ms; + strip.setTransition(segment_delay_ms/100); + strip.trigger(); } else { // Restore segment options - for (int i = 0; i < strip.getSegmentsNum(); i++) { + for (int i = 0; i <= strip.getLastActiveSegmentId(); i++) { Segment &seg = strip.getSegment(i); - if (!seg.isActive()) { - maxSegmentId = i - 1; - break; - } + if (!seg.isActive()) continue; // skip vector gaps seg.setOption(SEG_OPTION_ON, true); } + strip.trigger(); // force strip update + stateChanged = true; // inform external dvices/UI of change colorUpdated(CALL_MODE_DIRECT_CHANGE); DEBUG_PRINTLN(F("Animated Staircase disabled.")); } @@ -332,8 +336,10 @@ class Animated_Staircase : public Usermod { void loop() { if (!enabled || strip.isUpdating()) return; + minSegmentId = strip.getMainSegmentId(); // it may not be the best idea to start with main segment as it may not be the first one + maxSegmentId = strip.getLastActiveSegmentId() + 1; checkSensors(); - autoPowerOff(); + if (on) autoPowerOff(); updateSwipe(); } @@ -392,14 +398,16 @@ class Animated_Staircase : public Usermod { */ void readFromJsonState(JsonObject& root) { if (!initDone) return; // prevent crash on boot applyPreset() + bool en = enabled; JsonObject staircase = root[FPSTR(_name)]; if (!staircase.isNull()) { if (staircase[FPSTR(_enabled)].is()) { - enabled = staircase[FPSTR(_enabled)].as(); + en = staircase[FPSTR(_enabled)].as(); } else { String str = staircase[FPSTR(_enabled)]; // checkbox -> off or on - enabled = (bool)(str!="off"); // off is guaranteed to be present + en = (bool)(str!="off"); // off is guaranteed to be present } + if (en != enabled) enable(en); readSensorsFromJson(staircase); DEBUG_PRINTLN(F("Staircase sensor state read from API.")); }