From 7b21c1bcbe1ae38031f3f9fb4b749f60ec0c5a5b Mon Sep 17 00:00:00 2001 From: Blaz Kristan Date: Mon, 4 Oct 2021 20:24:33 +0200 Subject: [PATCH] Added option to preserve old state in PIR usermod --- .../usermod_PIR_sensor_switch.h | 102 +++++++++--------- 1 file changed, 49 insertions(+), 53 deletions(-) diff --git a/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h b/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h index 03839d8d..457f4300 100644 --- a/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h +++ b/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h @@ -55,44 +55,35 @@ public: bool PIRsensorEnabled() { return enabled; } private: - // PIR sensor pin - int8_t PIRsensorPin = PIR_SENSOR_PIN; - // notification mode for colorUpdated() - const byte NotifyUpdateMode = CALL_MODE_NO_NOTIFY; // CALL_MODE_DIRECT_CHANGE - // delay before switch off after the sensor state goes LOW - uint32_t m_switchOffDelay = 600000; // 10min - // off timer start time - uint32_t m_offTimerStart = 0; - // current PIR sensor pin state - byte sensorPinState = LOW; - // PIR sensor enabled - bool enabled = true; - // status of initialisation - bool initDone = false; - // on and off presets - uint8_t m_onPreset = 0; - uint8_t m_offPreset = 0; - // nighttime presets (optional) - uint8_t m_onNighttime = 0; - uint8_t m_offNighttime = 0; - // flag to indicate that PIR sensor should activate WLED during nighttime only - bool m_nightTimeOnly = false; - // flag to send MQTT message only (assuming it is enabled) - bool m_mqttOnly = false; - // flag to enable triggering only if WLED is initially off (LEDs are not on, preventing running effect being overwritten by PIR) - bool m_offOnly = false; - bool PIRtriggered = false; + byte prevPreset = 0; + byte prevPlaylist = 0; + bool savedState = false; + + uint32_t offTimerStart = 0; // off timer start time + const byte NotifyUpdateMode = CALL_MODE_NO_NOTIFY; // notification mode for colorUpdated() CALL_MODE_DIRECT_CHANGE + byte sensorPinState = LOW; // current PIR sensor pin state + bool initDone = false; // status of initialization + bool PIRtriggered = false; unsigned long lastLoop = 0; + // configurable parameters + bool enabled = true; // PIR sensor enabled + int8_t PIRsensorPin = PIR_SENSOR_PIN; // PIR sensor pin + uint32_t m_switchOffDelay = 600000; // delay before switch off after the sensor state goes LOW (10min) + uint8_t m_onPreset = 0; // on preset + uint8_t m_offPreset = 0; // off preset + bool m_nightTimeOnly = false; // flag to indicate that PIR sensor should activate WLED during nighttime only + bool m_mqttOnly = false; // flag to send MQTT message only (assuming it is enabled) + // flag to enable triggering only if WLED is initially off (LEDs are not on, preventing running effect being overwritten by PIR) + bool m_offOnly = false; + // strings to reduce flash memory usage (used more than twice) static const char _name[]; static const char _switchOffDelay[]; static const char _enabled[]; static const char _onPreset[]; static const char _offPreset[]; - static const char _onNighttime[]; - static const char _offNighttime[]; static const char _nightTime[]; static const char _mqttOnly[]; static const char _offOnly[]; @@ -129,10 +120,15 @@ private: if (m_offOnly && bri && (switchOn || (!PIRtriggered && !switchOn))) return; PIRtriggered = switchOn; if (switchOn) { - if (m_onNighttime && !isDayTime()) { - applyPreset(m_onNighttime); - return; - } else if (m_onPreset) { + if (m_onPreset) { + if (currentPlaylist>0) prevPlaylist = currentPlaylist; + else if (currentPreset>0) prevPreset = currentPreset; + else { + saveTemporaryPreset(); + savedState = true; + prevPlaylist = 0; + prevPreset = 0; + } applyPreset(m_onPreset); return; } @@ -142,12 +138,21 @@ private: colorUpdated(NotifyUpdateMode); } } else { - if (m_offNighttime && !isDayTime()) { - applyPreset(m_offNighttime); - return; - } else if (m_offPreset) { + if (m_offPreset) { applyPreset(m_offPreset); return; + } else if (prevPlaylist) { + applyPreset(prevPlaylist); + prevPlaylist = 0; + return; + } else if (prevPreset) { + applyPreset(prevPreset); + prevPreset = 0; + return; + } else if (savedState) { + applyTemporaryPreset(); + savedState = false; + return; } // preset not assigned if (bri != 0) { @@ -180,12 +185,12 @@ private: sensorPinState = pinState; // change previous state if (sensorPinState == HIGH) { - m_offTimerStart = 0; + offTimerStart = 0; if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()))) switchStrip(true); publishMqtt("on"); } else /*if (bri != 0)*/ { // start switch off timer - m_offTimerStart = millis(); + offTimerStart = millis(); } return true; } @@ -197,14 +202,14 @@ private: */ bool handleOffTimer() { - if (m_offTimerStart > 0 && millis() - m_offTimerStart > m_switchOffDelay) + if (offTimerStart > 0 && millis() - offTimerStart > m_switchOffDelay) { if (enabled == true) { if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()))) switchStrip(false); publishMqtt("off"); } - m_offTimerStart = 0; + offTimerStart = 0; return true; } return false; @@ -283,10 +288,10 @@ public: JsonArray infoArr = user.createNestedArray(uiDomString); // timer value if (enabled) { - if (m_offTimerStart > 0) + if (offTimerStart > 0) { uiDomString = ""; - unsigned int offSeconds = (m_switchOffDelay - (millis() - m_offTimerStart)) / 1000; + unsigned int offSeconds = (m_switchOffDelay - (millis() - offTimerStart)) / 1000; if (offSeconds >= 3600) { uiDomString += (offSeconds / 3600); @@ -354,8 +359,6 @@ public: top["pin"] = PIRsensorPin; top[FPSTR(_onPreset)] = m_onPreset; top[FPSTR(_offPreset)] = m_offPreset; - top[FPSTR(_onNighttime)] = m_onNighttime; - top[FPSTR(_offNighttime)] = m_offNighttime; top[FPSTR(_nightTime)] = m_nightTimeOnly; top[FPSTR(_mqttOnly)] = m_mqttOnly; top[FPSTR(_offOnly)] = m_offOnly; @@ -391,11 +394,6 @@ public: m_offPreset = top[FPSTR(_offPreset)] | m_offPreset; m_offPreset = max(0,min(250,(int)m_offPreset)); - m_onNighttime = top[FPSTR(_onNighttime)] | m_onNighttime; - m_onNighttime = max(0,min(250,(int)m_onNighttime)); - m_offNighttime = top[FPSTR(_offNighttime)] | m_offNighttime; - m_offNighttime = max(0,min(250,(int)m_offNighttime)); - m_nightTimeOnly = top[FPSTR(_nightTime)] | m_nightTimeOnly; m_mqttOnly = top[FPSTR(_mqttOnly)] | m_mqttOnly; m_offOnly = top[FPSTR(_offOnly)] | m_offOnly; @@ -425,7 +423,7 @@ public: DEBUG_PRINTLN(F(" config (re)loaded.")); } // use "return !top["newestParameter"].isNull();" when updating Usermod with new features - return !top[FPSTR(_onNighttime)].isNull(); + return !top[FPSTR(_offOnly)].isNull(); } /** @@ -444,8 +442,6 @@ const char PIRsensorSwitch::_enabled[] PROGMEM = "PIRenabled"; const char PIRsensorSwitch::_switchOffDelay[] PROGMEM = "PIRoffSec"; const char PIRsensorSwitch::_onPreset[] PROGMEM = "on-preset"; const char PIRsensorSwitch::_offPreset[] PROGMEM = "off-preset"; -const char PIRsensorSwitch::_onNighttime[] PROGMEM = "on-nighttime"; -const char PIRsensorSwitch::_offNighttime[] PROGMEM = "off-nighttime"; const char PIRsensorSwitch::_nightTime[] PROGMEM = "nighttime-only"; const char PIRsensorSwitch::_mqttOnly[] PROGMEM = "mqtt-only"; const char PIRsensorSwitch::_offOnly[] PROGMEM = "off-only";