Added option to preserve old state in PIR usermod

This commit is contained in:
Blaz Kristan 2021-10-04 20:24:33 +02:00
parent 9c295d1884
commit 7b21c1bcbe

View File

@ -55,44 +55,35 @@ public:
bool PIRsensorEnabled() { return enabled; } bool PIRsensorEnabled() { return enabled; }
private: 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; 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) // strings to reduce flash memory usage (used more than twice)
static const char _name[]; static const char _name[];
static const char _switchOffDelay[]; static const char _switchOffDelay[];
static const char _enabled[]; static const char _enabled[];
static const char _onPreset[]; static const char _onPreset[];
static const char _offPreset[]; static const char _offPreset[];
static const char _onNighttime[];
static const char _offNighttime[];
static const char _nightTime[]; static const char _nightTime[];
static const char _mqttOnly[]; static const char _mqttOnly[];
static const char _offOnly[]; static const char _offOnly[];
@ -129,10 +120,15 @@ private:
if (m_offOnly && bri && (switchOn || (!PIRtriggered && !switchOn))) return; if (m_offOnly && bri && (switchOn || (!PIRtriggered && !switchOn))) return;
PIRtriggered = switchOn; PIRtriggered = switchOn;
if (switchOn) { if (switchOn) {
if (m_onNighttime && !isDayTime()) { if (m_onPreset) {
applyPreset(m_onNighttime); if (currentPlaylist>0) prevPlaylist = currentPlaylist;
return; else if (currentPreset>0) prevPreset = currentPreset;
} else if (m_onPreset) { else {
saveTemporaryPreset();
savedState = true;
prevPlaylist = 0;
prevPreset = 0;
}
applyPreset(m_onPreset); applyPreset(m_onPreset);
return; return;
} }
@ -142,12 +138,21 @@ private:
colorUpdated(NotifyUpdateMode); colorUpdated(NotifyUpdateMode);
} }
} else { } else {
if (m_offNighttime && !isDayTime()) { if (m_offPreset) {
applyPreset(m_offNighttime);
return;
} else if (m_offPreset) {
applyPreset(m_offPreset); applyPreset(m_offPreset);
return; 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 // preset not assigned
if (bri != 0) { if (bri != 0) {
@ -180,12 +185,12 @@ private:
sensorPinState = pinState; // change previous state sensorPinState = pinState; // change previous state
if (sensorPinState == HIGH) { if (sensorPinState == HIGH) {
m_offTimerStart = 0; offTimerStart = 0;
if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()))) switchStrip(true); if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()))) switchStrip(true);
publishMqtt("on"); publishMqtt("on");
} else /*if (bri != 0)*/ { } else /*if (bri != 0)*/ {
// start switch off timer // start switch off timer
m_offTimerStart = millis(); offTimerStart = millis();
} }
return true; return true;
} }
@ -197,14 +202,14 @@ private:
*/ */
bool handleOffTimer() bool handleOffTimer()
{ {
if (m_offTimerStart > 0 && millis() - m_offTimerStart > m_switchOffDelay) if (offTimerStart > 0 && millis() - offTimerStart > m_switchOffDelay)
{ {
if (enabled == true) if (enabled == true)
{ {
if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()))) switchStrip(false); if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()))) switchStrip(false);
publishMqtt("off"); publishMqtt("off");
} }
m_offTimerStart = 0; offTimerStart = 0;
return true; return true;
} }
return false; return false;
@ -283,10 +288,10 @@ public:
JsonArray infoArr = user.createNestedArray(uiDomString); // timer value JsonArray infoArr = user.createNestedArray(uiDomString); // timer value
if (enabled) { if (enabled) {
if (m_offTimerStart > 0) if (offTimerStart > 0)
{ {
uiDomString = ""; uiDomString = "";
unsigned int offSeconds = (m_switchOffDelay - (millis() - m_offTimerStart)) / 1000; unsigned int offSeconds = (m_switchOffDelay - (millis() - offTimerStart)) / 1000;
if (offSeconds >= 3600) if (offSeconds >= 3600)
{ {
uiDomString += (offSeconds / 3600); uiDomString += (offSeconds / 3600);
@ -354,8 +359,6 @@ public:
top["pin"] = PIRsensorPin; top["pin"] = PIRsensorPin;
top[FPSTR(_onPreset)] = m_onPreset; top[FPSTR(_onPreset)] = m_onPreset;
top[FPSTR(_offPreset)] = m_offPreset; top[FPSTR(_offPreset)] = m_offPreset;
top[FPSTR(_onNighttime)] = m_onNighttime;
top[FPSTR(_offNighttime)] = m_offNighttime;
top[FPSTR(_nightTime)] = m_nightTimeOnly; top[FPSTR(_nightTime)] = m_nightTimeOnly;
top[FPSTR(_mqttOnly)] = m_mqttOnly; top[FPSTR(_mqttOnly)] = m_mqttOnly;
top[FPSTR(_offOnly)] = m_offOnly; top[FPSTR(_offOnly)] = m_offOnly;
@ -391,11 +394,6 @@ public:
m_offPreset = top[FPSTR(_offPreset)] | m_offPreset; m_offPreset = top[FPSTR(_offPreset)] | m_offPreset;
m_offPreset = max(0,min(250,(int)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_nightTimeOnly = top[FPSTR(_nightTime)] | m_nightTimeOnly;
m_mqttOnly = top[FPSTR(_mqttOnly)] | m_mqttOnly; m_mqttOnly = top[FPSTR(_mqttOnly)] | m_mqttOnly;
m_offOnly = top[FPSTR(_offOnly)] | m_offOnly; m_offOnly = top[FPSTR(_offOnly)] | m_offOnly;
@ -425,7 +423,7 @@ public:
DEBUG_PRINTLN(F(" config (re)loaded.")); DEBUG_PRINTLN(F(" config (re)loaded."));
} }
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features // 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::_switchOffDelay[] PROGMEM = "PIRoffSec";
const char PIRsensorSwitch::_onPreset[] PROGMEM = "on-preset"; const char PIRsensorSwitch::_onPreset[] PROGMEM = "on-preset";
const char PIRsensorSwitch::_offPreset[] PROGMEM = "off-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::_nightTime[] PROGMEM = "nighttime-only";
const char PIRsensorSwitch::_mqttOnly[] PROGMEM = "mqtt-only"; const char PIRsensorSwitch::_mqttOnly[] PROGMEM = "mqtt-only";
const char PIRsensorSwitch::_offOnly[] PROGMEM = "off-only"; const char PIRsensorSwitch::_offOnly[] PROGMEM = "off-only";