diff --git a/tools/cdata.js b/tools/cdata.js
index 90619ba67..09816f959 100644
--- a/tools/cdata.js
+++ b/tools/cdata.js
@@ -219,36 +219,10 @@ function writeChunks(srcDir, specs, resultFile) {
}
writeHtmlGzipped("wled00/data/index.htm", "wled00/html_ui.h", 'index');
-writeHtmlGzipped("wled00/data/simple.htm", "wled00/html_simple.h", 'simple');
writeHtmlGzipped("wled00/data/pixart/pixart.htm", "wled00/html_pixart.h", 'pixart');
writeHtmlGzipped("wled00/data/cpal/cpal.htm", "wled00/html_cpal.h", 'cpal');
writeHtmlGzipped("wled00/data/pxmagic/pxmagic.htm", "wled00/html_pxmagic.h", 'pxmagic');
-/*
-writeChunks(
- "wled00/data",
- [
- {
- file: "simple.css",
- name: "PAGE_simpleCss",
- method: "gzip",
- filter: "css-minify",
- },
- {
- file: "simple.js",
- name: "PAGE_simpleJs",
- method: "gzip",
- filter: "js-minify",
- },
- {
- file: "simple.htm",
- name: "PAGE_simple",
- method: "gzip",
- filter: "html-minify-ui",
- }
- ],
- "wled00/html_simplex.h"
-);
-*/
+
writeChunks(
"wled00/data",
[
diff --git a/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h b/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h
index 8a4b9a608..62bf3d9df 100644
--- a/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h
+++ b/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h
@@ -70,6 +70,7 @@ private:
// Home Assistant
bool HomeAssistantDiscovery = false; // is HA discovery turned on
+ int16_t idx = -1; // Domoticz virtual switch idx
// strings to reduce flash memory usage (used more than twice)
static const char _name[];
@@ -83,6 +84,7 @@ private:
static const char _haDiscovery[];
static const char _notify[];
static const char _override[];
+ static const char _domoticzIDX[];
/**
* check if it is daytime
@@ -196,6 +198,7 @@ const char PIRsensorSwitch::_offOnly[] PROGMEM = "off-only";
const char PIRsensorSwitch::_haDiscovery[] PROGMEM = "HA-discovery";
const char PIRsensorSwitch::_notify[] PROGMEM = "notifications";
const char PIRsensorSwitch::_override[] PROGMEM = "override";
+const char PIRsensorSwitch::_domoticzIDX[] PROGMEM = "domoticz-idx";
bool PIRsensorSwitch::isDayTime() {
updateLocalTime();
@@ -271,9 +274,20 @@ void PIRsensorSwitch::publishMqtt(const char* state)
#ifndef WLED_DISABLE_MQTT
//Check if MQTT Connected, otherwise it will crash the 8266
if (WLED_MQTT_CONNECTED) {
- char buf[64];
+ char buf[128];
sprintf_P(buf, PSTR("%s/motion"), mqttDeviceTopic); //max length: 33 + 7 = 40
mqtt->publish(buf, 0, false, state);
+ // Domoticz formatted message
+ if (idx > 0) {
+ StaticJsonDocument <128> msg;
+ msg[F("idx")] = idx;
+ msg[F("RSSI")] = WiFi.RSSI();
+ msg[F("command")] = F("switchlight");
+ strcpy(buf, state); buf[0] = toupper(buf[0]);
+ msg[F("switchcmd")] = (const char *)buf;
+ serializeJson(msg, buf, 127);
+ mqtt->publish("domoticz/in", 0, false, buf);
+ }
}
#endif
}
@@ -482,6 +496,7 @@ void PIRsensorSwitch::addToConfig(JsonObject &root)
top[FPSTR(_offOnly)] = m_offOnly;
top[FPSTR(_override)] = m_override;
top[FPSTR(_haDiscovery)] = HomeAssistantDiscovery;
+ top[FPSTR(_domoticzIDX)] = idx;
top[FPSTR(_notify)] = (NotifyUpdateMode != CALL_MODE_NO_NOTIFY);
DEBUG_PRINTLN(F("PIR config saved."));
}
@@ -521,6 +536,7 @@ bool PIRsensorSwitch::readFromConfig(JsonObject &root)
m_offOnly = top[FPSTR(_offOnly)] | m_offOnly;
m_override = top[FPSTR(_override)] | m_override;
HomeAssistantDiscovery = top[FPSTR(_haDiscovery)] | HomeAssistantDiscovery;
+ idx = top[FPSTR(_domoticzIDX)] | idx;
NotifyUpdateMode = top[FPSTR(_notify)] ? CALL_MODE_DIRECT_CHANGE : CALL_MODE_NO_NOTIFY;
@@ -549,5 +565,5 @@ bool PIRsensorSwitch::readFromConfig(JsonObject &root)
DEBUG_PRINTLN(F(" config (re)loaded."));
}
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features
- return !top[FPSTR(_override)].isNull();
+ return !top[FPSTR(_domoticzIDX)].isNull();
}
diff --git a/usermods/Temperature/usermod_temperature.h b/usermods/Temperature/usermod_temperature.h
index a15baf878..0b9bbbda7 100644
--- a/usermods/Temperature/usermod_temperature.h
+++ b/usermods/Temperature/usermod_temperature.h
@@ -48,6 +48,7 @@ class UsermodTemperature : public Usermod {
bool enabled = true;
bool HApublished = false;
+ int16_t idx = -1; // Domoticz virtual sensor idx
// strings to reduce flash memory usage (used more than twice)
static const char _name[];
@@ -55,6 +56,7 @@ class UsermodTemperature : public Usermod {
static const char _readInterval[];
static const char _parasite[];
static const char _parasitePin[];
+ static const char _domoticzIDX[];
//Dallas sensor quick (& dirty) reading. Credit to - Author: Peter Scargill, August 17th, 2013
float readDallas();
@@ -264,7 +266,7 @@ void UsermodTemperature::loop() {
#ifndef WLED_DISABLE_MQTT
if (WLED_MQTT_CONNECTED) {
- char subuf[64];
+ char subuf[128];
strcpy(subuf, mqttDeviceTopic);
if (temperature > -100.0f) {
// dont publish super low temperature as the graph will get messed up
@@ -274,6 +276,16 @@ void UsermodTemperature::loop() {
mqtt->publish(subuf, 0, false, String(getTemperatureC()).c_str());
strcat_P(subuf, PSTR("_f"));
mqtt->publish(subuf, 0, false, String(getTemperatureF()).c_str());
+ if (idx > 0) {
+ StaticJsonDocument <128> msg;
+ msg[F("idx")] = idx;
+ msg[F("RSSI")] = WiFi.RSSI();
+ msg[F("nvalue")] = 0;
+ msg[F("svalue")] = String(getTemperatureC());
+ serializeJson(msg, subuf, 127);
+ DEBUG_PRINTLN(subuf);
+ mqtt->publish("domoticz/in", 0, false, subuf);
+ }
} else {
// publish something else to indicate status?
}
@@ -360,6 +372,7 @@ void UsermodTemperature::addToConfig(JsonObject &root) {
top[FPSTR(_readInterval)] = readingInterval / 1000;
top[FPSTR(_parasite)] = parasite;
top[FPSTR(_parasitePin)] = parasitePin;
+ top[FPSTR(_domoticzIDX)] = idx;
DEBUG_PRINTLN(F("Temperature config saved."));
}
@@ -386,6 +399,7 @@ bool UsermodTemperature::readFromConfig(JsonObject &root) {
readingInterval = min(120,max(10,(int)readingInterval)) * 1000; // convert to ms
parasite = top[FPSTR(_parasite)] | parasite;
parasitePin = top[FPSTR(_parasitePin)] | parasitePin;
+ idx = top[FPSTR(_domoticzIDX)] | idx;
if (!initDone) {
// first run: reading from cfg.json
@@ -406,7 +420,7 @@ bool UsermodTemperature::readFromConfig(JsonObject &root) {
}
}
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features
- return !top[FPSTR(_parasitePin)].isNull();
+ return !top[FPSTR(_domoticzIDX)].isNull();
}
void UsermodTemperature::appendConfigData() {
@@ -430,3 +444,4 @@ const char UsermodTemperature::_enabled[] PROGMEM = "enabled";
const char UsermodTemperature::_readInterval[] PROGMEM = "read-interval-s";
const char UsermodTemperature::_parasite[] PROGMEM = "parasite-pwr";
const char UsermodTemperature::_parasitePin[] PROGMEM = "parasite-pwr-pin";
+const char UsermodTemperature::_domoticzIDX[] PROGMEM = "domoticz-idx";
diff --git a/usermods/multi_relay/usermod_multi_relay.h b/usermods/multi_relay/usermod_multi_relay.h
index 0bf1871c7..7c8456f0e 100644
--- a/usermods/multi_relay/usermod_multi_relay.h
+++ b/usermods/multi_relay/usermod_multi_relay.h
@@ -803,13 +803,6 @@ bool MultiRelay::readFromConfig(JsonObject &root) {
_relay[i].external = top[parName][FPSTR(_external)] | _relay[i].external;
_relay[i].delay = top[parName][FPSTR(_delay_str)] | _relay[i].delay;
_relay[i].button = top[parName][FPSTR(_button)] | _relay[i].button;
- // begin backwards compatibility (beta) remove when 0.13 is released
- parName += '-';
- _relay[i].pin = top[parName+"pin"] | _relay[i].pin;
- _relay[i].invert = top[parName+FPSTR(_activeHigh)] | _relay[i].invert;
- _relay[i].external = top[parName+FPSTR(_external)] | _relay[i].external;
- _relay[i].delay = top[parName+FPSTR(_delay_str)] | _relay[i].delay;
- // end compatibility
_relay[i].delay = min(600,max(0,abs((int)_relay[i].delay))); // bounds checking max 10min
}
diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp
index 30218a4f0..42984a051 100644
--- a/wled00/FX_fcn.cpp
+++ b/wled00/FX_fcn.cpp
@@ -144,10 +144,13 @@ Segment& Segment::operator= (Segment &&orig) noexcept {
}
bool IRAM_ATTR Segment::allocateData(size_t len) {
- if (data && _dataLen == len) return true; //already allocated
+ if (data && _dataLen >= len) { // already allocated enough (reduce fragmentation)
+ if (call == 0) memset(data, 0, len); // erase buffer if called during effect initialisation
+ return true;
+ }
//DEBUG_PRINTF("-- Allocating data (%d): %p\n", len, this);
deallocateData();
- if (len == 0) return(false); // nothing to do
+ if (len == 0) return false; // nothing to do
if (Segment::getUsedSegmentData() + len > MAX_SEGMENT_DATA) {
// not enough memory
DEBUG_PRINT(F("!!! Effect RAM depleted: "));
@@ -156,7 +159,7 @@ bool IRAM_ATTR Segment::allocateData(size_t len) {
}
// do not use SPI RAM on ESP32 since it is slow
data = (byte*) malloc(len);
- if (!data) { DEBUG_PRINTLN(F("!!! Allocation failed. !!!")); return false; } //allocation failed
+ if (!data) { DEBUG_PRINTLN(F("!!! Allocation failed. !!!")); return false; } // allocation failed
Segment::addUsedSegmentData(len);
//DEBUG_PRINTF("--- Allocated data (%p): %d/%d -> %p\n", this, len, Segment::getUsedSegmentData(), data);
_dataLen = len;
diff --git a/wled00/button.cpp b/wled00/button.cpp
index fe414ca3f..f1487396a 100644
--- a/wled00/button.cpp
+++ b/wled00/button.cpp
@@ -99,7 +99,7 @@ bool isButtonPressed(uint8_t i)
case BTN_TYPE_TOUCH:
case BTN_TYPE_TOUCH_SWITCH:
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3)
- if (touchRead(pin) <= touchThreshold) return true;
+ if (digitalPinToTouchChannel(btnPin[i]) >= 0 && touchRead(pin) <= touchThreshold) return true;
#endif
break;
}
@@ -110,6 +110,7 @@ void handleSwitch(uint8_t b)
{
// isButtonPressed() handles inverted/noninverted logic
if (buttonPressedBefore[b] != isButtonPressed(b)) {
+ DEBUG_PRINT(F("Switch: State changed ")); DEBUG_PRINTLN(b);
buttonPressedTime[b] = millis();
buttonPressedBefore[b] = !buttonPressedBefore[b];
}
@@ -117,12 +118,15 @@ void handleSwitch(uint8_t b)
if (buttonLongPressed[b] == buttonPressedBefore[b]) return;
if (millis() - buttonPressedTime[b] > WLED_DEBOUNCE_THRESHOLD) { //fire edge event only after 50ms without change (debounce)
+ DEBUG_PRINT(F("Switch: Activating ")); DEBUG_PRINTLN(b);
if (!buttonPressedBefore[b]) { // on -> off
+ DEBUG_PRINT(F("Switch: On -> Off ")); DEBUG_PRINTLN(b);
if (macroButton[b]) applyPreset(macroButton[b], CALL_MODE_BUTTON_PRESET);
else { //turn on
if (!bri) {toggleOnOff(); stateUpdated(CALL_MODE_BUTTON);}
}
} else { // off -> on
+ DEBUG_PRINT(F("Switch: Off -> On ")); DEBUG_PRINTLN(b);
if (macroLongPress[b]) applyPreset(macroLongPress[b], CALL_MODE_BUTTON_PRESET);
else { //turn off
if (bri) {toggleOnOff(); stateUpdated(CALL_MODE_BUTTON);}
@@ -154,6 +158,8 @@ void handleAnalog(uint8_t b)
static float filteredReading[WLED_MAX_BUTTONS] = {0.0f};
uint16_t rawReading; // raw value from analogRead, scaled to 12bit
+ DEBUG_PRINT(F("Analog: Reading button ")); DEBUG_PRINTLN(b);
+
#ifdef ESP8266
rawReading = analogRead(A0) << 2; // convert 10bit read to 12bit
#else
@@ -162,6 +168,8 @@ void handleAnalog(uint8_t b)
#endif
yield(); // keep WiFi task running - analog read may take several millis on ESP8266
+ DEBUG_PRINT(F("Analog: Raw read = ")); DEBUG_PRINTLN(rawReading);
+
filteredReading[b] += POT_SMOOTHING * ((float(rawReading) / 16.0f) - filteredReading[b]); // filter raw input, and scale to [0..255]
uint16_t aRead = max(min(int(filteredReading[b]), 255), 0); // squash into 8bit
if(aRead <= POT_SENSITIVITY) aRead = 0; // make sure that 0 and 255 are used
@@ -172,6 +180,8 @@ void handleAnalog(uint8_t b)
// remove noise & reduce frequency of UI updates
if (abs(int(aRead) - int(oldRead[b])) <= POT_SENSITIVITY) return; // no significant change in reading
+ DEBUG_PRINT(F("Analog: Filtered read = ")); DEBUG_PRINTLN(aRead);
+
// Unomment the next lines if you still see flickering related to potentiometer
// This waits until strip finishes updating (why: strip was not updating at the start of handleButton() but may have started during analogRead()?)
//unsigned long wait_started = millis();
@@ -184,6 +194,7 @@ void handleAnalog(uint8_t b)
// if no macro for "short press" and "long press" is defined use brightness control
if (!macroButton[b] && !macroLongPress[b]) {
+ DEBUG_PRINT(F("Analog: Action = ")); DEBUG_PRINTLN(macroDoublePress[b]);
// if "double press" macro defines which option to change
if (macroDoublePress[b] >= 250) {
// global brightness
@@ -219,6 +230,7 @@ void handleAnalog(uint8_t b)
updateInterfaces(CALL_MODE_BUTTON);
}
} else {
+ DEBUG_PRINTLN(F("Analog: No action"));
//TODO:
// we can either trigger a preset depending on the level (between short and long entries)
// or use it for RGBW direct control
diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp
index fdb70099c..b036dc1d4 100644
--- a/wled00/cfg.cpp
+++ b/wled00/cfg.cpp
@@ -31,9 +31,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
getStringFromJson(cmDNS, id[F("mdns")], 33);
getStringFromJson(serverDescription, id[F("name")], 33);
getStringFromJson(alexaInvocationName, id[F("inv")], 33);
-#ifdef WLED_ENABLE_SIMPLE_UI
CJSON(simplifiedUI, id[F("sui")]);
-#endif
JsonObject nw = doc["nw"];
#ifndef WLED_DISABLE_ESPNOW
@@ -655,9 +653,7 @@ void serializeConfig() {
id[F("mdns")] = cmDNS;
id[F("name")] = serverDescription;
id[F("inv")] = alexaInvocationName;
-#ifdef WLED_ENABLE_SIMPLE_UI
id[F("sui")] = simplifiedUI;
-#endif
JsonObject nw = doc.createNestedObject("nw");
#ifndef WLED_DISABLE_ESPNOW
diff --git a/wled00/data/index.css b/wled00/data/index.css
index 7faaeb47e..0ffdf68d3 100644
--- a/wled00/data/index.css
+++ b/wled00/data/index.css
@@ -370,6 +370,16 @@ button {
padding: 5px 0 0;
}
+/* Quick load magin for simplified UI */
+.simplified #pql {
+ margin-bottom: 8px;
+}
+
+/* Button margin for simplified UI */
+.simplified #fx .btn, .simplified #palw .btn {
+ margin-top: 0;
+}
+
.smooth { transition: transform calc(var(--f, 1)*.5s) ease-out }
.tab-label {
@@ -413,6 +423,7 @@ button {
position: sticky;
bottom: 0;
max-width: 300px;
+ z-index: 2;
}
#sliders .labels {
@@ -754,13 +765,17 @@ input[type=range]::-moz-range-thumb {
}
#Colors .sliderwrap {
- margin: 4px 0 0;
+ margin: 2px 0 0;
}
-/* Dynamically hide brightness slider label */
+/* Dynamically hide labels */
.hd {
display: var(--bhd);
}
+/* Do not hide quick load label in simplified mode on small screen widths */
+.simplified #pql .hd {
+ display: var(--bhd) !important;
+}
#briwrap {
min-width: 300px;
@@ -1284,6 +1299,12 @@ TD .checkmark, TD .radiomark {
margin-top: 0;
}
+/* Simplify segments */
+.simplified #segcont .lstI {
+ margin-top: 4px;
+ min-height: unset;
+}
+
/* selected item/element */
.selected { /* has to be after .lstI since !important is not ok */
background: var(--c-4);
@@ -1324,6 +1345,19 @@ TD .checkmark, TD .radiomark {
top: calc(var(--sti) + 42px);
}
+dialog::backdrop {
+ backdrop-filter: blur(10px);
+ -webkit-backdrop-filter: blur(10px);
+}
+dialog {
+ max-height: 70%;
+ border: 0;
+ border-radius: 10px;
+ background: linear-gradient(rgba(0, 0, 0, 0.15), rgba(0, 0, 0, 0.1)), var(--c-3);
+ box-shadow: 4px 4px 10px 4px var(--c-1);
+ color: var(--c-f);
+}
+
#fxlist .lstI.sticky,
#pallist .lstI.sticky {
top: var(--sti);
diff --git a/wled00/data/index.htm b/wled00/data/index.htm
index 21aa28d6d..8dd26b7b7 100644
--- a/wled00/data/index.htm
+++ b/wled00/data/index.htm
@@ -168,7 +168,7 @@
-
diff --git a/wled00/data/index.js b/wled00/data/index.js
index 02bb07ff9..3fed6d20e 100644
--- a/wled00/data/index.js
+++ b/wled00/data/index.js
@@ -12,6 +12,7 @@ var currentPreset = -1;
var lastUpdate = 0;
var segCount = 0, ledCount = 0, lowestUnused = 0, maxSeg = 0, lSeg = 0;
var pcMode = false, pcModeA = false, lastw = 0, wW;
+var simplifiedUI = false;
var tr = 7;
var d = document;
var palettesData;
@@ -624,11 +625,12 @@ function parseInfo(i) {
if (name === "Dinnerbone") d.documentElement.style.transform = "rotate(180deg)"; // Minecraft easter egg
if (i.live) name = "(Live) " + name;
if (loc) name = "(L) " + name;
- d.title = name;
- ledCount = i.leds.count;
- //syncTglRecv = i.str;
- maxSeg = i.leds.maxseg;
- pmt = i.fs.pmt;
+ d.title = name;
+ simplifiedUI = i.simplifiedui;
+ ledCount = i.leds.count;
+ //syncTglRecv = i.str;
+ maxSeg = i.leds.maxseg;
+ pmt = i.fs.pmt;
gId('buttonNodes').style.display = lastinfo.ndc > 0 ? null:"none";
// do we have a matrix set-up
mw = i.leds.matrix ? i.leds.matrix.w : 0;
@@ -750,6 +752,7 @@ function populateSegments(s)
let rvXck = ``;
let miXck = ``;
let rvYck = "", miYck ="";
+ let smpl = simplifiedUI ? 'hide' : '';
if (isMSeg) {
rvYck = ``;
miYck = ``;
@@ -768,23 +771,23 @@ function populateSegments(s)
``+
`
`+
``;
- cn += ``+
- `