Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 49 additions & 12 deletions usermods/Animated_Staircase/Animated_Staircase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class Animated_Staircase : public Usermod {
unsigned int topMaxDist = 50; // default maximum measured distance in cm, top
unsigned int bottomMaxDist = 50; // default maximum measured distance in cm, bottom
bool togglePower = false; // toggle power on/off with staircase on/off
bool enabledSentinel = false; // keep the first and last segment dimmed when on
unsigned int sentinelDimOpacity = 128; // opacity for dimmed sentinel segments (0-255)

/* runtime variables */
bool initDone = false;
Expand Down Expand Up @@ -91,6 +93,8 @@ class Animated_Staircase : public Usermod {
static const char _topEchoCm[];
static const char _bottomEchoCm[];
static const char _togglePower[];
static const char _enabledSentinel[];
static const char _sentinelDimOpacity[];

void publishMqtt(bool bottom, const char* state) {
#ifndef WLED_DISABLE_MQTT
Expand All @@ -104,15 +108,22 @@ class Animated_Staircase : public Usermod {
}

void updateSegments() {
byte firstSegId = minSegmentId;
byte lastSegId = (maxSegmentId > minSegmentId) ? maxSegmentId - 1 : minSegmentId;
for (int i = minSegmentId; i < maxSegmentId; i++) {
Segment &seg = strip.getSegment(i);
if (!seg.isActive()) continue; // skip gaps
if (i >= onIndex && i < offIndex) {
bool inSwipe = (i >= onIndex && i < offIndex);
bool isFirst = (i == firstSegId);
bool isLast = (i == lastSegId);
bool isSentinel = isFirst || isLast;

if (inSwipe) {
seg.setOption(SEG_OPTION_ON, true);
if (isSentinel) seg.setOpacity(255);
} else if (enabledSentinel && isSentinel && sentinelDimOpacity > 0) {
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);
// seg.setColor(0, mainsegment.colors[0]);
seg.setOpacity(sentinelDimOpacity);
} else {
seg.setOption(SEG_OPTION_ON, false);
}
Expand Down Expand Up @@ -194,9 +205,12 @@ class Animated_Staircase : public Usermod {
if (topSensorRead != bottomSensorRead) {
lastSwitchTime = millis();

if (on) {
lastSensor = topSensorRead;
} else {
// Record which sensor triggered last. Use bottomSensorRead so that
// lastSensor == true means the bottom sensor (swipe up) triggered,
// lastSensor == false means the top sensor (swipe down) triggered.
lastSensor = bottomSensorRead;

if (!on) {
if (togglePower && onIndex == offIndex && offMode) toggleOnOff(); // toggle power on if off
// If the bottom sensor triggered, we need to swipe up, ON
swipe = bottomSensorRead;
Expand Down Expand Up @@ -226,7 +240,7 @@ class Animated_Staircase : public Usermod {
if (bottomSensorState || topSensorState) return;

// Swipe OFF in the direction of the last sensor detection
swipe = lastSensor;
swipe = !lastSensor;
on = false;

DEBUG_PRINT(F("OFF -> Swipe "));
Expand Down Expand Up @@ -307,8 +321,18 @@ class Animated_Staircase : public Usermod {
if (!seg.isActive()) continue; // skip vector gaps
seg.setOption(SEG_OPTION_ON, true);
}
strip.trigger(); // force strip update
stateChanged = true; // inform external devices/UI of change
if (strip.getSegmentsNum() > 0) {
byte firstSegId = strip.getMainSegmentId();
byte lastSegId = strip.getLastActiveSegmentId();
Segment &firstSeg = strip.getSegment(firstSegId);
if (firstSeg.isActive()) firstSeg.setOpacity(255);
if (lastSegId != firstSegId) {
Segment &lastSeg = strip.getSegment(lastSegId);
if (lastSeg.isActive()) lastSeg.setOpacity(255);
}
}
strip.trigger(); // force strip update
stateChanged = true; // inform external devices/UI of change
colorUpdated(CALL_MODE_DIRECT_CHANGE);
DEBUG_PRINTLN(F("Animated Staircase disabled."));
}
Expand Down Expand Up @@ -451,6 +475,8 @@ class Animated_Staircase : public Usermod {
staircase[FPSTR(_topEchoCm)] = topMaxDist;
staircase[FPSTR(_bottomEchoCm)] = bottomMaxDist;
staircase[FPSTR(_togglePower)] = togglePower;
staircase[FPSTR(_enabledSentinel)] = enabledSentinel;
staircase[FPSTR(_sentinelDimOpacity)] = sentinelDimOpacity;
DEBUG_PRINTLN(F("Staircase config saved."));
}

Expand All @@ -466,6 +492,9 @@ class Animated_Staircase : public Usermod {
int8_t oldTopBPin = topEchoPin;
int8_t oldBottomAPin = bottomPIRorTriggerPin;
int8_t oldBottomBPin = bottomEchoPin;
bool oldEnabledSentinel = enabledSentinel;
unsigned int oldSentinelDimOpacity = sentinelDimOpacity;
bool changedSentinel = false;

JsonObject top = root[FPSTR(_name)];
if (top.isNull()) {
Expand Down Expand Up @@ -497,6 +526,11 @@ class Animated_Staircase : public Usermod {

togglePower = top[FPSTR(_togglePower)] | togglePower; // staircase toggles power on/off

enabledSentinel = top[FPSTR(_enabledSentinel)] | enabledSentinel;
sentinelDimOpacity = top[FPSTR(_sentinelDimOpacity)] | sentinelDimOpacity;
sentinelDimOpacity = min(255, max(0, (int)sentinelDimOpacity));
changedSentinel = (oldEnabledSentinel != enabledSentinel) || (oldSentinelDimOpacity != sentinelDimOpacity);

DEBUG_PRINT(FPSTR(_name));
if (!initDone) {
// first run: reading from cfg.json
Expand All @@ -518,9 +552,10 @@ class Animated_Staircase : public Usermod {
PinManager::deallocatePin(oldBottomBPin, PinOwner::UM_AnimatedStaircase);
}
if (changed) setup();
if (changedSentinel) updateSegments();
}
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features
return !top[FPSTR(_togglePower)].isNull();
return !top[FPSTR(_sentinelDimOpacity)].isNull();
}

/*
Expand Down Expand Up @@ -561,6 +596,8 @@ const char Animated_Staircase::_bottomEcho_pin[] PROGMEM = "bottomEch
const char Animated_Staircase::_topEchoCm[] PROGMEM = "top-dist-cm";
const char Animated_Staircase::_bottomEchoCm[] PROGMEM = "bottom-dist-cm";
const char Animated_Staircase::_togglePower[] PROGMEM = "toggle-on-off";
const char Animated_Staircase::_enabledSentinel[] PROGMEM = "enabled-sentinel";
const char Animated_Staircase::_sentinelDimOpacity[] PROGMEM = "sentinel-dim-opacity";


static Animated_Staircase animated_staircase;
Expand Down