Added nigttime only and MQTT only options to PIR sensor switch usermod.

Clarified empty UM settings a bit.
This commit is contained in:
Blaz Kristan 2021-05-10 22:41:27 +02:00
parent 3e3dc3a6ab
commit e0c0f29fc6
4 changed files with 64 additions and 9 deletions

View File

@ -72,6 +72,10 @@ private:
// on and off presets
uint8_t m_onPreset = 0;
uint8_t m_offPreset = 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;
unsigned long lastLoop = 0;
@ -81,6 +85,8 @@ private:
static const char _enabled[];
static const char _onPreset[];
static const char _offPreset[];
static const char _nightTime[];
static const char _mqttOnly[];
/**
* return or change if new PIR sensor state is available
@ -92,6 +98,31 @@ private:
*/
static void IRAM_ATTR ISR_PIRstateChange();
/**
* check if it is daytime
* if sunrise/sunset is not defined (no NTP or lat/lon) default to nighttime
*/
bool isDayTime() {
bool isDayTime = false;
updateLocalTime();
uint8_t hr = hour(localTime);
uint8_t mi = minute(localTime);
if (sunrise==0 || sunset==0) return false;
if (hour(sunrise)>hr && hour(sunset)<hr) {
isDayTime = true;
} else {
if (hour(sunrise)==hr && minute(sunrise)<mi) {
isDayTime = true;
}
if (hour(sunset)==hr && minute(sunset)>mi) {
isDayTime = true;
}
}
return isDayTime;
}
/**
* switch strip on/off
*/
@ -133,7 +164,7 @@ private:
if (m_PIRsensorPinState == HIGH) {
m_offTimerStart = 0;
switchStrip(true);
if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()))) switchStrip(true);
publishMqtt("on");
} else /*if (bri != 0)*/ {
// start switch off timer
@ -154,7 +185,7 @@ private:
{
if (m_PIRenabled == true)
{
switchStrip(false);
if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()))) switchStrip(false);
publishMqtt("off");
}
m_offTimerStart = 0;
@ -288,11 +319,13 @@ public:
void addToConfig(JsonObject &root)
{
JsonObject top = root.createNestedObject(FPSTR(_name));
top[FPSTR(_enabled)] = m_PIRenabled;
top[FPSTR(_enabled)] = m_PIRenabled;
top[FPSTR(_switchOffDelay)] = m_switchOffDelay / 1000;
top["pin"] = PIRsensorPin;
top[FPSTR(_onPreset)] = m_onPreset;
top["pin"] = PIRsensorPin;
top[FPSTR(_onPreset)] = m_onPreset;
top[FPSTR(_offPreset)] = m_offPreset;
top[FPSTR(_nightTime)] = m_nightTimeOnly;
top[FPSTR(_mqttOnly)] = m_mqttOnly;
DEBUG_PRINTLN(F("PIR config saved."));
}
@ -334,6 +367,26 @@ public:
m_offPreset = max(0,min(250,top[FPSTR(_offPreset)].as<int>()));
}
if (top[FPSTR(_nightTime)] != nullptr) {
if (top[FPSTR(_nightTime)].is<bool>()) {
m_nightTimeOnly = top[FPSTR(_nightTime)].as<bool>(); // reading from cfg.json
} else {
// change from settings page
String str = top[FPSTR(_nightTime)]; // checkbox -> off or on
m_nightTimeOnly = (bool)(str!="off"); // off is guaranteed to be present
}
}
if (top[FPSTR(_mqttOnly)] != nullptr) {
if (top[FPSTR(_mqttOnly)].is<bool>()) {
m_mqttOnly = top[FPSTR(_mqttOnly)].as<bool>(); // reading from cfg.json
} else {
// change from settings page
String str = top[FPSTR(_mqttOnly)]; // checkbox -> off or on
m_mqttOnly = (bool)(str!="off"); // off is guaranteed to be present
}
}
if (!initDone) {
// reading config prior to setup()
DEBUG_PRINTLN(F("PIR config loaded."));
@ -396,3 +449,5 @@ 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::_nightTime[] PROGMEM = "nighttime-only";
const char PIRsensorSwitch::_mqttOnly[] PROGMEM = "mqtt-only";

View File

@ -100,9 +100,9 @@
addField(k,'unknown',o);
}
if (urows==="")
urows = "No Usermods configuration found.<br>Press <i>Save</i> to initialize defaults.";
urows = "No Usermods configuration found.<br>Press <i>Save</i> to initialize defaults if usermods were compiled in.";
} else {
urows = "Usermods configuration not found.<br>Most likely no Usermods exist.<br>Press <i>Save</i> to initialize defaults.";
urows = "Usermods configuration not found.<br>Most likely no Usermods exist.<br>Press <i>Save</i> to try to initialize defaults.";
}
gId("um").innerHTML = urows;
})

View File

@ -395,7 +395,7 @@ type="submit">Save & Reboot</button></form></body></html>)=====";
// Autogenerated from wled00/data/settings_um.htm, do not edit!!
const char PAGE_settings_um[] PROGMEM = R"=====(<!DOCTYPE html><html><head lang="en"><meta charset="utf-8"><meta
name="viewport" content="width=500"><title>UI Settings</title><script>
var owner,locip,urows,d=document,umCfg={},pins=[6,7,8,9,10,11],pinO=["reserved","reserved","reserved","reserved","reserved","reserved"],loc=!1;function gId(e){return d.getElementById(e)}function isO(e){return e&&"object"==typeof e&&!Array.isArray(e)}function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#usermod-settings")}function B(){window.open("/settings","_self")}function S(){"file:"==window.location.protocol&&(loc=!0,(locip=localStorage.getItem("locIp"))||(locip=prompt("File Mode. Please enter WLED IP!"),localStorage.setItem("locIp",locip))),ldS()}function check(e,o){var n=e.name.replace("[]","").substr(-3);if("number"==e.type&&"pin"==n.substr(0,3))for(var i=0;i<pins.length;i++)if(o!=pinO[i]){if(e.value==pins[i]||e.value<-1||e.value>39){e.style.color="red";break}e.style.color=e.value>33?"orange":"#fff"}}function getPins(e){if(isO(e))for(const[n,i]of Object.entries(e))if(isO(i))owner=n,getPins(i);else if("pin"==n.replace("[]","").substr(-3))if(Array.isArray(i))for(var o=0;o<i.length;o++)i[o]>=0&&(pins.push(i[o]),pinO.push(owner));else i>=0&&(pins.push(i),pinO.push(owner));else if(Array.isArray(i))for(o=0;o<i.length;o++)getPins(i[o])}function addField(e,o,n,i=!1){if(isO(n))for(const[o,i]of Object.entries(n))addField(e,o,i);else if(Array.isArray(n))for(var r=0;r<n.length;r++)addField(e,o,n[r],!0);else{var s,t;switch(typeof n){case"boolean":s="checkbox",t=n?'checked value="on"':"";break;case"number":s="number",t=`value="${parseInt(n,10)}"`;break;case"string":default:s="text",t=`value="${n}"`}"checkbox"==s&&(urows+=`<input type="hidden" name="${e}_${o}${i?"[]":""}" value="off">`),urows+=`${o}: <input type="${s}" name="${e}_${o}${i?"[]":""}" ${t} oninput="check(this,'${e}')"><br>`}}function ldS(){fetch((loc?"http://"+locip:"")+"/cfg.json",{method:"get"}).then(e=>(e.ok||(gId("lserr").style.display="inline"),e.json())).then(e=>{if(umCfg=e.um,getPins(e),urows="",isO(umCfg)){for(const[e,o]of Object.entries(umCfg))urows+=`<hr><h3>${e}</h3>`,addField(e,"unknown",o);""===urows&&(urows="No Usermods configuration found.<br>Press <i>Save</i> to initialize defaults.")}else urows="Usermods configuration not found.<br>Most likely no Usermods exist.<br>Press <i>Save</i> to initialize defaults.";gId("um").innerHTML=urows}).catch((function(e){gId("lserr").style.display="inline",console.log(e)}))}function svS(e){e.preventDefault(),console.log(d.Sf),d.Sf.checkValidity()&&d.Sf.submit()}function GetV(){}
var owner,locip,urows,d=document,umCfg={},pins=[6,7,8,9,10,11],pinO=["reserved","reserved","reserved","reserved","reserved","reserved"],loc=!1;function gId(e){return d.getElementById(e)}function isO(e){return e&&"object"==typeof e&&!Array.isArray(e)}function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#usermod-settings")}function B(){window.open("/settings","_self")}function S(){"file:"==window.location.protocol&&(loc=!0,(locip=localStorage.getItem("locIp"))||(locip=prompt("File Mode. Please enter WLED IP!"),localStorage.setItem("locIp",locip))),ldS()}function check(e,o){var i=e.name.replace("[]","").substr(-3);if("number"==e.type&&"pin"==i.substr(0,3))for(var n=0;n<pins.length;n++)if(o!=pinO[n]){if(e.value==pins[n]||e.value<-1||e.value>39){e.style.color="red";break}e.style.color=e.value>33?"orange":"#fff"}}function getPins(e){if(isO(e))for(const[i,n]of Object.entries(e))if(isO(n))owner=i,getPins(n);else if("pin"==i.replace("[]","").substr(-3))if(Array.isArray(n))for(var o=0;o<n.length;o++)n[o]>=0&&(pins.push(n[o]),pinO.push(owner));else n>=0&&(pins.push(n),pinO.push(owner));else if(Array.isArray(n))for(o=0;o<n.length;o++)getPins(n[o])}function addField(e,o,i,n=!1){if(isO(i))for(const[o,n]of Object.entries(i))addField(e,o,n);else if(Array.isArray(i))for(var r=0;r<i.length;r++)addField(e,o,i[r],!0);else{var s,t;switch(typeof i){case"boolean":s="checkbox",t=i?'checked value="on"':"";break;case"number":s="number",t=`value="${parseInt(i,10)}"`;break;case"string":default:s="text",t=`value="${i}"`}"checkbox"==s&&(urows+=`<input type="hidden" name="${e}_${o}${n?"[]":""}" value="off">`),urows+=`${o}: <input type="${s}" name="${e}_${o}${n?"[]":""}" ${t} oninput="check(this,'${e}')"><br>`}}function ldS(){fetch((loc?"http://"+locip:"")+"/cfg.json",{method:"get"}).then(e=>(e.ok||(gId("lserr").style.display="inline"),e.json())).then(e=>{if(umCfg=e.um,getPins(e),urows="",isO(umCfg)){for(const[e,o]of Object.entries(umCfg))urows+=`<hr><h3>${e}</h3>`,addField(e,"unknown",o);""===urows&&(urows="No Usermods configuration found.<br>Press <i>Save</i> to initialize defaults if usermods were compiled in.")}else urows="Usermods configuration not found.<br>Most likely no Usermods exist.<br>Press <i>Save</i> to try to initialize defaults.";gId("um").innerHTML=urows}).catch((function(e){gId("lserr").style.display="inline",console.log(e)}))}function svS(e){e.preventDefault(),console.log(d.Sf),d.Sf.checkValidity()&&d.Sf.submit()}function GetV(){}
</script>%CSS%%SCSS%</head><body onload="S()"><form
id="form_s" name="Sf" method="post" onsubmit="svS(event)"><div class="toprow">
<div class="helpB"><button type="button" onclick="H()">?</button></div><button

View File

@ -8,7 +8,7 @@
*/
// version code in format yymmddb (b = daily build)
#define VERSION 2105082
#define VERSION 2105101
//uncomment this if you have a "my_config.h" file you'd like to use
//#define WLED_USE_MY_CONFIG