Added PIR sensor night time presets.
Added PIR sensor Disable/Enable button. UI refinements. Added colorUpdated() on HTTP API in IR JSON.
This commit is contained in:
parent
9092549f07
commit
dc9d48850f
@ -72,6 +72,9 @@ private:
|
||||
// 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)
|
||||
@ -88,6 +91,8 @@ private:
|
||||
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[];
|
||||
@ -97,24 +102,23 @@ private:
|
||||
* 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 && sunset) {
|
||||
if (hour(sunrise)<hr && hour(sunset)>hr) {
|
||||
isDayTime = true;
|
||||
return true;
|
||||
} else {
|
||||
if (hour(sunrise)==hr && minute(sunrise)<mi) {
|
||||
isDayTime = true;
|
||||
return true;
|
||||
}
|
||||
if (hour(sunset)==hr && minute(sunset)>mi) {
|
||||
isDayTime = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return isDayTime;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -124,17 +128,33 @@ private:
|
||||
{
|
||||
if (m_offOnly && bri && (switchOn || (!PIRtriggered && !switchOn))) return;
|
||||
PIRtriggered = switchOn;
|
||||
if (switchOn && m_onPreset) {
|
||||
applyPreset(m_onPreset);
|
||||
} else if (!switchOn && m_offPreset) {
|
||||
applyPreset(m_offPreset);
|
||||
} else if (switchOn && bri == 0) {
|
||||
bri = briLast;
|
||||
colorUpdated(NotifyUpdateMode);
|
||||
} else if (!switchOn && bri != 0) {
|
||||
briLast = bri;
|
||||
bri = 0;
|
||||
colorUpdated(NotifyUpdateMode);
|
||||
if (switchOn) {
|
||||
if (m_onNighttime && !isDayTime()) {
|
||||
applyPreset(m_onNighttime);
|
||||
return;
|
||||
} else if (m_onPreset) {
|
||||
applyPreset(m_onPreset);
|
||||
return;
|
||||
}
|
||||
// preset not assigned
|
||||
if (bri == 0) {
|
||||
bri = briLast;
|
||||
colorUpdated(NotifyUpdateMode);
|
||||
}
|
||||
} else {
|
||||
if (m_offNighttime && !isDayTime()) {
|
||||
applyPreset(m_offNighttime);
|
||||
return;
|
||||
} else if (m_offPreset) {
|
||||
applyPreset(m_offPreset);
|
||||
return;
|
||||
}
|
||||
// preset not assigned
|
||||
if (bri != 0) {
|
||||
briLast = bri;
|
||||
bri = 0;
|
||||
colorUpdated(NotifyUpdateMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -248,11 +268,21 @@ public:
|
||||
JsonObject user = root["u"];
|
||||
if (user.isNull()) user = root.createNestedObject("u");
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
// off timer
|
||||
String uiDomString = F("PIR <i class=\"icons\"></i>");
|
||||
JsonArray infoArr = user.createNestedArray(uiDomString); // timer value
|
||||
String uiDomString = F("<button class=\"btn\" onclick=\"requestJson({");
|
||||
uiDomString += FPSTR(_name);
|
||||
uiDomString += F(":{");
|
||||
uiDomString += FPSTR(_enabled);
|
||||
if (enabled) {
|
||||
uiDomString += F(":false}});loadInfo();\">");
|
||||
uiDomString += F("PIR <i class=\"icons\"></i>");
|
||||
} else {
|
||||
uiDomString += F(":true}});loadInfo();\">");
|
||||
uiDomString += F("PIR <i class=\"icons\"></i>");
|
||||
}
|
||||
uiDomString += F("</button>");
|
||||
JsonArray infoArr = user.createNestedArray(uiDomString); // timer value
|
||||
|
||||
if (enabled) {
|
||||
if (m_offTimerStart > 0)
|
||||
{
|
||||
uiDomString = "";
|
||||
@ -282,8 +312,6 @@ public:
|
||||
infoArr.add(sensorPinState ? F("sensor on") : F("inactive"));
|
||||
}
|
||||
} else {
|
||||
String uiDomString = F("PIR sensor");
|
||||
JsonArray infoArr = user.createNestedArray(uiDomString);
|
||||
infoArr.add(F("disabled"));
|
||||
}
|
||||
}
|
||||
@ -302,11 +330,18 @@ public:
|
||||
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
/*
|
||||
|
||||
void readFromJsonState(JsonObject &root)
|
||||
{
|
||||
if (!initDone) return; // prevent crash on boot applyPreset()
|
||||
JsonObject usermod = root[FPSTR(_name)];
|
||||
if (!usermod.isNull()) {
|
||||
if (usermod[FPSTR(_enabled)].is<bool>()) {
|
||||
enabled = usermod[FPSTR(_enabled)].as<bool>();
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* provide the changeable values
|
||||
@ -314,14 +349,16 @@ public:
|
||||
void addToConfig(JsonObject &root)
|
||||
{
|
||||
JsonObject top = root.createNestedObject(FPSTR(_name));
|
||||
top[FPSTR(_enabled)] = enabled;
|
||||
top[FPSTR(_enabled)] = enabled;
|
||||
top[FPSTR(_switchOffDelay)] = m_switchOffDelay / 1000;
|
||||
top["pin"] = PIRsensorPin;
|
||||
top[FPSTR(_onPreset)] = m_onPreset;
|
||||
top[FPSTR(_offPreset)] = m_offPreset;
|
||||
top[FPSTR(_nightTime)] = m_nightTimeOnly;
|
||||
top[FPSTR(_mqttOnly)] = m_mqttOnly;
|
||||
top[FPSTR(_offOnly)] = m_offOnly;
|
||||
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;
|
||||
DEBUG_PRINTLN(F("PIR config saved."));
|
||||
}
|
||||
|
||||
@ -336,9 +373,9 @@ public:
|
||||
bool oldEnabled = enabled;
|
||||
int8_t oldPin = PIRsensorPin;
|
||||
|
||||
DEBUG_PRINT(FPSTR(_name));
|
||||
JsonObject top = root[FPSTR(_name)];
|
||||
if (top.isNull()) {
|
||||
DEBUG_PRINT(FPSTR(_name));
|
||||
DEBUG_PRINTLN(F(": No config found. (Using defaults.)"));
|
||||
return false;
|
||||
}
|
||||
@ -351,15 +388,18 @@ public:
|
||||
|
||||
m_onPreset = top[FPSTR(_onPreset)] | m_onPreset;
|
||||
m_onPreset = max(0,min(250,(int)m_onPreset));
|
||||
|
||||
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;
|
||||
|
||||
DEBUG_PRINT(FPSTR(_name));
|
||||
if (!initDone) {
|
||||
// reading config prior to setup()
|
||||
DEBUG_PRINTLN(F(" config loaded."));
|
||||
@ -385,7 +425,7 @@ public:
|
||||
DEBUG_PRINTLN(F(" config (re)loaded."));
|
||||
}
|
||||
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features
|
||||
return !top[FPSTR(_offOnly)].isNull();
|
||||
return !top[FPSTR(_onNighttime)].isNull();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -404,6 +444,8 @@ 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";
|
||||
|
@ -128,11 +128,6 @@ button {
|
||||
font-size: 42px;
|
||||
}
|
||||
|
||||
.infot {
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.segt, .plentry TABLE {
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
@ -455,14 +450,24 @@ button {
|
||||
}
|
||||
|
||||
#kv, #kn {
|
||||
max-width: 490px;
|
||||
/*max-width: 490px;*/
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#kv td {
|
||||
#info table, #nodes table {
|
||||
table-layout: fixed;
|
||||
width: 490px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
#info td, #nodes td {
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
#info .btn, #nodes .btn {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#lv {
|
||||
max-width: 600px;
|
||||
display: inline-block;
|
||||
@ -1130,14 +1135,17 @@ input[type="text"].fnd:hover {
|
||||
|
||||
@media all and (max-width: 335px) {
|
||||
.sliderbubble {
|
||||
display: none;
|
||||
}
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 550px) and (min-width: 374px) {
|
||||
.infobtn {
|
||||
#info .btn, #nodes .btn {
|
||||
width: 155px;
|
||||
}
|
||||
#info table, #nodes table {
|
||||
width: 320px;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 540px) {
|
||||
|
@ -201,18 +201,28 @@
|
||||
<img class="wi" alt="" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAFCAYAAAC5Fuf5AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABbSURBVChTlY9bDoAwDMNW7n9nwCipytQN4Z8tbrTHmDmF4oPzyldwRqp1SSdnV/NuZuzqerAByxXznBw3igkeFEfXyUuhK/yFM0CxJfyqXZEOc6/Sr9/bf7uIC5Nwd7orMvAPAAAAAElFTkSuQmCC" />
|
||||
</div><br>
|
||||
<div id="kv">Loading...</div><br>
|
||||
<button class="btn infobtn" onclick="loadInfo()">Refresh</button>
|
||||
<button class="btn infobtn" onclick="toggleInfo()">Close Info</button><br>
|
||||
<button class="btn infobtn" onclick="toggleNodes()">Instance List</button>
|
||||
<button class="btn infobtn" id="resetbtn" onclick="cnfReset()">Reboot WLED</button><br>
|
||||
<table>
|
||||
<tr>
|
||||
<td class="keytd"><button class="btn" onclick="loadInfo()">Refresh</button></td>
|
||||
<td class="valtd"><button class="btn" onclick="toggleInfo()">Close Info</button></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="keytd"><button class="btn" onclick="toggleNodes()">Instance List</button></td>
|
||||
<td class="valtd"><button class="btn" id="resetbtn" onclick="cnfReset()">Reboot WLED</button></td>
|
||||
</tr>
|
||||
</table><br>
|
||||
<span class="h">Made with <span id="heart">❤︎</span> by Aircoookie and the WLED community</span>
|
||||
</div>
|
||||
|
||||
<div id="nodes" class="modal">
|
||||
<div id="ndlt">WLED instances</div>
|
||||
<div id="kn">Loading...</div><br>
|
||||
<button class="btn infobtn" onclick="loadNodes()">Refresh</button>
|
||||
<button class="btn infobtn" onclick="toggleNodes()">Close list</button><br>
|
||||
<table>
|
||||
<tr>
|
||||
<td class="keytd"><button class="btn infobtn" onclick="loadNodes()">Refresh</button></td>
|
||||
<td class="valtd"><button class="btn infobtn" onclick="toggleNodes()">Close list</button></td>
|
||||
</tr>
|
||||
</table><br>
|
||||
</div>
|
||||
|
||||
<div id="rover" class="modal">
|
||||
|
@ -629,7 +629,7 @@ function populateInfo(i)
|
||||
if (i.ver.includes("-bl")) vcn = "Ryujin";
|
||||
if (i.cn) vcn = i.cn;
|
||||
|
||||
cn += `v${i.ver} "${vcn}"<br><br><table class="infot">
|
||||
cn += `v${i.ver} "${vcn}"<br><br><table>
|
||||
${urows}
|
||||
${inforow("Build",i.vid)}
|
||||
${inforow("Signal strength",i.wifi.signal +"% ("+ i.wifi.rssi, " dBm)")}
|
||||
@ -760,7 +760,7 @@ function populateNodes(i,n)
|
||||
for (var x=0;x<n.nodes.length;x++) {
|
||||
var o = n.nodes[x];
|
||||
if (o.name) {
|
||||
var url = `<button class="btn infobtn" title="${o.ip}" onclick="location.assign('http://${o.ip}');">${bname(o)}</button>`;
|
||||
var url = `<button class="btn" title="${o.ip}" onclick="location.assign('http://${o.ip}');">${bname(o)}</button>`;
|
||||
urows += inforow(url,`${btype(o.type)}<br><i>${o.vid==0?"N/A":o.vid}</i>`);
|
||||
nnodes++;
|
||||
}
|
||||
@ -768,9 +768,9 @@ function populateNodes(i,n)
|
||||
}
|
||||
if (i.ndc < 0) cn += `Instance List is disabled.`;
|
||||
else if (nnodes == 0) cn += `No other instances found.`;
|
||||
cn += `<table class="infot">
|
||||
${urows}
|
||||
cn += `<table>
|
||||
${inforow("Current instance:",i.name)}
|
||||
${urows}
|
||||
</table>`;
|
||||
gId('kn').innerHTML = cn;
|
||||
}
|
||||
|
4347
wled00/html_ui.h
4347
wled00/html_ui.h
File diff suppressed because it is too large
Load Diff
@ -625,6 +625,7 @@ void decodeIRJson(uint32_t code)
|
||||
cmdStr = "win&" + cmdStr;
|
||||
}
|
||||
handleSet(nullptr, cmdStr, false);
|
||||
colorUpdated(CALL_MODE_BUTTON);
|
||||
}
|
||||
} else if (!jsonCmdObj.isNull()) {
|
||||
// command is JSON object
|
||||
|
@ -713,12 +713,10 @@ void WLED::initInterfaces()
|
||||
|
||||
// Set up mDNS responder:
|
||||
if (strlen(cmDNS) > 0) {
|
||||
#ifndef WLED_DISABLE_OTA
|
||||
if (!aOtaEnabled) //ArduinoOTA begins mDNS for us if enabled
|
||||
MDNS.begin(cmDNS);
|
||||
#else
|
||||
// "end" must be called before "begin" is called a 2nd time
|
||||
// see https://github.com/esp8266/Arduino/issues/7213
|
||||
MDNS.end();
|
||||
MDNS.begin(cmDNS);
|
||||
#endif
|
||||
|
||||
DEBUG_PRINTLN(F("mDNS started"));
|
||||
MDNS.addService("http", "tcp", 80);
|
||||
|
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
// version code in format yymmddb (b = daily build)
|
||||
#define VERSION 2109261
|
||||
#define VERSION 2109281
|
||||
|
||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||
//#define WLED_USE_MY_CONFIG
|
||||
@ -87,6 +87,7 @@
|
||||
#include <WiFiUdp.h>
|
||||
#include <DNSServer.h>
|
||||
#ifndef WLED_DISABLE_OTA
|
||||
#define NO_OTA_PORT
|
||||
#include <ArduinoOTA.h>
|
||||
#endif
|
||||
#include <SPIFFSEditor.h>
|
||||
|
Loading…
Reference in New Issue
Block a user