Merge pull request #2863 from Aircoookie/staircase-fix

Staircase fix
This commit is contained in:
Blaž Kristan 2022-11-04 22:45:04 +01:00 committed by GitHub
commit edd487c1f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

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