From 49d706f54c0b681d46a8bcf3587efd003111854c Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Thu, 31 Oct 2024 17:01:36 +0100
Subject: [PATCH] Add DALI command `DaliGroupSliders 0..16` to show GUI group
sliders with feedback disabling `DaliLight`
---
CHANGELOG.md | 16 +-
RELEASENOTES.md | 3 +-
tasmota/include/tasmota_types.h | 16 +-
tasmota/include/tasmota_version.h | 2 +-
tasmota/tasmota_support/settings.ino | 3 +
.../xdrv_01_9_webserver.ino | 8 +-
tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino | 259 +++++++++++++-----
7 files changed, 225 insertions(+), 82 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0a901e3b6..0cd6b0ae4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,12 +3,22 @@ All notable changes to this project will be documented in this file.
## [Unreleased] - Development
-## [14.3.0.3]
+## [14.3.0.4]
### Added
-- Support for I2C over Serial, preliminary stub (#22388)
+- DALI command `DaliGroupSliders 0..16` to show GUI group sliders with feedback disabling `DaliLight`
### Breaking Changed
+### Changed
+
+### Fixed
+
+### Removed
+
+## [14.3.0.3] 20241031
+### Added
+- Support for I2C over Serial, preliminary stub (#22388)
+
### Changed
- ESP32 Platform from 2024.10.30 to 2024.11.30, Framework (Arduino Core) from v3.1.0.241023 to v3.1.0.241030 and IDF to 5.3.1.241024 (#22384)
- ESP32 LVGL library from v9.2.0 to v9.2.2 (#22385)
@@ -17,8 +27,6 @@ All notable changes to this project will be documented in this file.
### Fixed
- ESP32 Arduino Core IPv6 zones used by Matter (#22378)
-### Removed
-
## [14.3.0.2] 20241030
### Added
- DALI command `DaliGear` to set max found gear to speed up scan response
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index b20c59033..a1c8e88f5 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -114,13 +114,14 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
[Complete list](BUILDS.md) of available feature and sensors.
-## Changelog v14.3.0.3
+## Changelog v14.3.0.4
### Added
- Command ``SetOption161 1`` to disable web page slider updates by commands
- DALI support for short addresses (gear) and groups
- DALI command `DaliGear` to set max found gear to speed up scan response
- DALI command `DaliGroup` to add gear to groups
- DALI command `DaliTarget` to set light control broadcast, group number or gear number
+- DALI command `DaliGroupSliders 0..16` to show GUI group sliders with feedback disabling `DaliLight`
- DALI inverted signal configuration using GPIO DALI RX_i/TX_i
- Support for I2C over Serial, preliminary stub [#22388](https://github.com/arendst/Tasmota/issues/22388)
- Support for Shelly DALI Dimmer Gen3
diff --git a/tasmota/include/tasmota_types.h b/tasmota/include/tasmota_types.h
index 41b3a03fb..8752a6ec8 100644
--- a/tasmota/include/tasmota_types.h
+++ b/tasmota/include/tasmota_types.h
@@ -195,7 +195,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
uint32_t mqtt_disable_modbus : 1; // bit 12 (v13.3.0.5) - SetOption158 - (MQTT) Disable publish ModbusReceived MQTT messages (1), you must use event trigger rules instead
uint32_t counter_both_edges : 1; // bit 13 (v13.3.0.5) - SetOption159 - (Counter) Enable counting on both rising and falling edge (1)
uint32_t ld2410_use_pin : 1; // bit 14 (v14.3.0.2) - SetOption160 - (LD2410) Disable generate moving event by sensor report - use LD2410 out pin for events (1)
- uint32_t disable_slider_updates : 1; // bit 15 (v14.3.0.2) - SetOption161 - (Light) Disable slider updates (1)
+ uint32_t disable_slider_updates : 1; // bit 15 (v14.3.0.2) - SetOption161 - (Light) Disable slider updates by commands (1)
uint32_t spare16 : 1; // bit 16
uint32_t spare17 : 1; // bit 17
uint32_t spare18 : 1; // bit 18
@@ -260,15 +260,11 @@ typedef union {
uint32_t spare16 : 1; // bit 16
uint32_t spare17 : 1; // bit 17
uint32_t spare18 : 1; // bit 18
- uint32_t spare19 : 1; // bit 19
- uint32_t spare20 : 1; // bit 20
- uint32_t spare21 : 1; // bit 21
- uint32_t spare22 : 1; // bit 22
- uint32_t spare23 : 1; // bit 23
- uint32_t FTP_Mode : 2; // bit 24, 25
- uint32_t tariff_forced : 2; // bit 26..27 (v12.4.0.2) - Energy forced tariff : 0=tariff change on time, 1|2=tariff forced
- uint32_t sunrise_dawn_angle : 2; // bits 28/29 (v12.1.1.4) -
- uint32_t temperature_set_res : 2; // bits 30/31 (v9.3.1.4) - (Tuya)
+ uint32_t dali_group_sliders : 5; // bit 19.23 (v14.3.0.3) - (DALI) Number of group sliders 0 to 16
+ uint32_t FTP_Mode : 2; // bit 24/25
+ uint32_t tariff_forced : 2; // bit 26/27 (v12.4.0.2) - Energy forced tariff : 0=tariff change on time, 1|2=tariff forced
+ uint32_t sunrise_dawn_angle : 2; // bit 28/29 (v12.1.1.4) -
+ uint32_t temperature_set_res : 2; // bit 30/31 (v9.3.1.4) - (Tuya)
};
} SysMBitfield2;
diff --git a/tasmota/include/tasmota_version.h b/tasmota/include/tasmota_version.h
index fe63d03c4..d49cbe725 100644
--- a/tasmota/include/tasmota_version.h
+++ b/tasmota/include/tasmota_version.h
@@ -22,6 +22,6 @@
#define TASMOTA_SHA_SHORT // Filled by Github sed
-const uint32_t TASMOTA_VERSION = 0x0E030003; // 14.3.0.3
+const uint32_t TASMOTA_VERSION = 0x0E030004; // 14.3.0.4
#endif // _TASMOTA_VERSION_H_
diff --git a/tasmota/tasmota_support/settings.ino b/tasmota/tasmota_support/settings.ino
index b74d7c663..c509f5cba 100644
--- a/tasmota/tasmota_support/settings.ino
+++ b/tasmota/tasmota_support/settings.ino
@@ -1838,6 +1838,9 @@ void SettingsDelta(void) {
if (Settings->version < 0x0E030002) { // 14.3.0.2
Settings->sbflag1.dali_light = 1;
}
+ if (Settings->version < 0x0E030004) { // 14.3.0.4
+ Settings->mbflag2.dali_group_sliders = 2;
+ }
Settings->version = TASMOTA_VERSION;
SettingsSave(1);
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino
index 0382e78a3..a452417ef 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino
@@ -271,6 +271,9 @@ const char HTTP_MSG_SLIDER_GRADIENT[] PROGMEM =
""
"";
+const char HTTP_MSG_SLIDER_UPDATE[] PROGMEM =
+ "
" D_DEVICE_WILL_RESTART "
";
@@ -1354,7 +1357,7 @@ void HandleRoot(void)
WSContentSpaceButton(BUTTON_FIRMWARE_UPGRADE);
#endif // ESP32
WSContentButton(BUTTON_CONSOLE);
-#else
+#else // Not FIRMWARE_MINIMAL
WSContentSpaceButton(BUTTON_CONFIGURATION);
WSContentButton(BUTTON_INFORMATION);
WSContentButton(BUTTON_FIRMWARE_UPGRADE);
@@ -1534,7 +1537,8 @@ bool HandleRootStatusRefresh(void)
if (current_value != Web.slider[i]) {
Web.slider[i] = current_value;
// https://stackoverflow.com/questions/4057236/how-to-add-onload-event-to-a-div-element
- WSContentSend_P(PSTR(""), i +1, current_value);
+ WSContentSend_P(HTTP_MSG_SLIDER_UPDATE); // ""), i +1, current_value);
}
}
}
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino
index 4fe44e7a1..7818b0362 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino
@@ -19,6 +19,8 @@
--------------------------------------------------------------------------------------------
Version yyyymmdd Action Description
--------------------------------------------------------------------------------------------
+ 1.1.0.0 20241031 update - Add GUI sliders with feedback when `DaliLight 0`
+ - Add command `DaliGroupSliders 0..16` to show GUI sliders
1.0.0.2 20241025 update - Fix GPIO detection
- Fix ESP32(C3) transmit stability by disabling interrupts
1.0.0.1 20241024 update - Change from signal invert defines to GPIO config DALI RX_i/DALI TX_i
@@ -264,6 +266,8 @@
// Address type - Send as first byte
#define DALI_BROADCAST_DP 0x00FE // 0b11111110 254 - Broadcast address
+#define DALI_MAX_STORED 17 // Store broadcast and group states
+
#define DALI_TOPIC "DALI"
#define D_PRFX_DALI "Dali"
@@ -272,14 +276,16 @@ const char kDALICommands[] PROGMEM = D_PRFX_DALI "|" // Prefix
#ifdef USE_LIGHT
"|Light"
#endif // USE_LIGHT
- "|Send|Query|Scan|Group|Gear";
+ "|Send|Query|Scan|Group"
+ "|GroupSliders|Gear";
void (* const DALICommand[])(void) PROGMEM = {
&CmndDali, &CmndDaliPower, &CmndDaliDimmer, &CmndDaliTarget,
#ifdef USE_LIGHT
&CmndDaliLight,
#endif // USE_LIGHT
- &CmndDaliSend, &CmndDaliQuery, &CmndDaliScan, &CmndDaliGroup, &CmndDaliGear };
+ &CmndDaliSend, &CmndDaliQuery, &CmndDaliScan, &CmndDaliGroup,
+ &CmndDaliGroupSliders, &CmndDaliGear };
struct DALI {
uint32_t bit_cycles;
@@ -290,9 +296,13 @@ struct DALI {
uint8_t max_short_address;
uint8_t address;
uint8_t command;
- uint8_t dimmer;
+ uint8_t last_dimmer;
+ uint8_t dimmer[DALI_MAX_STORED];
+ uint8_t web_dimmer[DALI_MAX_STORED];
uint8_t target;
- bool power;
+ bool last_power;
+ bool power[DALI_MAX_STORED];
+ bool web_power[DALI_MAX_STORED];
bool available;
bool response;
bool light_sync;
@@ -305,23 +315,23 @@ struct DALI {
* DALI low level
\*********************************************************************************************/
-uint32_t DaliTarget2Address(uint32_t target) {
+uint32_t DaliTarget2Address(void) {
// 1..64 = Short address
// 101..116 = Group address
// Others = Broadcast
- if ((target >= 1) && (target <= 64)) { // 1 .. 64
- target -= 1; // Short address
- target <<= 1;
+ if ((Dali->target >= 1) && (Dali->target <= 64)) { // 1 .. 64
+ Dali->target -= 1; // Short address
+ Dali->target <<= 1;
}
- else if ((target >= 101) && (target <= 116)) { // 101 .. 116
- target -= 101;
- target <<= 1;
- target |= 0x80; // Group address
+ else if ((Dali->target >= 101) && (Dali->target <= 116)) { // 101 .. 116
+ Dali->target -= 101;
+ Dali->target <<= 1;
+ Dali->target |= 0x80; // Group address
}
else { // Others
- target = DALI_BROADCAST_DP; // Broadcast address
+ Dali->target = DALI_BROADCAST_DP; // Broadcast address
}
- return target &0xFE; // Direct Arc Power Control command
+ return Dali->target &0xFE; // Direct Arc Power Control command
}
/*
@@ -336,6 +346,34 @@ uint32_t DaliAddress2Target(uint32_t adr) {
}
*/
+uint32_t DaliSaveState(uint32_t adr, uint32_t cmd) {
+ if (adr &0x01) { return 0; } // No address
+ int index = -1;
+ if (DALI_BROADCAST_DP == adr) { // Broadcast address
+ index = 0;
+ }
+ adr >>= 1;
+ if ((adr >= 0x40) && (adr <= 0x4F)) { // Group address 0 to 15
+ index = adr -0x3F;
+ }
+ if (index >= 0) {
+ Dali->last_power = Dali->power[index];
+ Dali->power[index] = (cmd); // State
+ if (Dali->power[index]) {
+ Dali->last_dimmer = Dali->dimmer[index];
+ Dali->dimmer[index] = cmd; // Value
+ }
+ if ((0 == index) && !Dali->power[0]) { // Only on Broadcast change to power Off
+ for (uint32_t i = 0; i < DALI_MAX_STORED; i++) {
+ Dali->power[i] = false; // Log all group power as Off when Broadcast is Off
+ }
+ }
+ } else {
+ index = 0; // Use broadcast
+ }
+ return index;
+}
+
void DaliEnableRxInterrupt(void) {
Dali->available = false;
attachInterrupt(Dali->pin_rx, DaliReceiveData, (Dali->invert_rx) ? RISING : FALLING);
@@ -508,13 +546,7 @@ void DaliSendData(uint32_t adr, uint32_t cmd) {
Dali->address = adr;
Dali->command = cmd;
- if (DaliTarget2Address(Dali->target) == adr) {
- repeat = true;
- Dali->power = (cmd); // State
- if (Dali->power) {
- Dali->dimmer = cmd; // Value
- }
- }
+ DaliSaveState(adr, cmd);
if (!repeat && (adr &0x01)) { // YAAAAAA1 Commands where user didn't set repeat
if ((adr >= 0xA1) && (adr <= 0xFD)) { // Special commands
@@ -751,25 +783,28 @@ uint32_t DaliCommission(uint8_t init_arg) {
#ifdef USE_LIGHT
DaliInitLight();
- uint32_t address = (Settings->sbflag1.dali_light) ? DaliTarget2Address(Dali->target) : DALI_BROADCAST_DP;
- DaliSendData(address, Dali->power); // Restore lights
+ uint32_t address = (Settings->sbflag1.dali_light) ? DaliTarget2Address() : DALI_BROADCAST_DP;
+ DaliSendData(address, Dali->power[0]); // Restore lights
#else
- DaliSendData(DALI_BROADCAST_DP, Dali->power); // Restore lights
+ DaliSendData(DALI_BROADCAST_DP, Dali->power[0]); // Restore lights
#endif // USE_LIGHT
return cnt;
}
/*********************************************************************************************/
-void ResponseAppendDali(void) {
- uint8_t dimmer = changeUIntScale(Dali->dimmer, 0, 254, 0, 100);
- ResponseAppend_P(PSTR("\"DALI\":{\"Power\":\"%s\",\"Dimmer\":%d,\"Address\":%d,\"Command\":%d}"),
- GetStateText(Dali->power), dimmer, Dali->address, Dali->command);
+void ResponseAppendDali(uint32_t index) {
+ char number[12];
+ uint8_t dimmer = changeUIntScale(Dali->dimmer[index], 0, 254, 0, 100);
+ ResponseAppend_P(PSTR("\"DALI\":{\"Power%s\":\"%s\",\"Dimmer%s\":%d,\"Address\":%d,\"Command\":%d}"),
+ (0==index)?"":itoa(index+100, number, 10), GetStateText(Dali->power[index]),
+ (0==index)?"":itoa(index+100, number, 10), dimmer,
+ Dali->address, Dali->command);
}
-void ResponseDali(void) {
+void ResponseDali(uint32_t index) {
Response_P(PSTR("{"));
- ResponseAppendDali();
+ ResponseAppendDali(index);
ResponseJsonEnd();
}
@@ -787,45 +822,32 @@ void DaliLoop(void) {
Dali->address = Dali->received_dali_data >> 8;
Dali->command = Dali->received_dali_data;
+ uint32_t index = DaliSaveState(Dali->address, Dali->command); // Update dimmer and power
-#ifdef USE_LIGHT
bool show_response = true;
- if (DaliTarget2Address(Dali->target) == Dali->address) {
- uint8_t dimmer_old = changeUIntScale(Dali->dimmer, 0, 254, 0, 100);
- uint8_t power_old = Dali->power;
- Dali->power = (Dali->command); // State
- if (Dali->power) {
- Dali->dimmer = Dali->command; // Value
- }
+#ifdef USE_LIGHT
+ if (DaliTarget2Address() == Dali->address) {
if (Settings->sbflag1.dali_light) { // DaliLight 1
- uint8_t dimmer_new = changeUIntScale(Dali->dimmer, 0, 254, 0, 100);
- if (power_old != Dali->power) {
+ uint8_t dim_old = changeUIntScale(Dali->last_dimmer, 0, 254, 0, 100);
+ uint8_t dim_new = changeUIntScale(Dali->dimmer[index], 0, 254, 0, 100);
+ if (Dali->last_power != Dali->power[index]) {
Dali->light_sync = true; // Block local loop
- ExecuteCommandPower(LightDevice(), Dali->power, SRC_SWITCH);
+ ExecuteCommandPower(LightDevice(), Dali->power[index], SRC_SWITCH);
}
- else if (dimmer_old != dimmer_new) {
+ else if (dim_old != dim_new) {
char scmnd[20];
- snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_DIMMER " %d"), dimmer_new);
+ snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_DIMMER " %d"), dim_new);
Dali->light_sync = true; // Block local loop
ExecuteCommand(scmnd, SRC_SWITCH);
}
show_response = false;
}
}
+#endif // USE_LIGHT
if (show_response) {
- ResponseDali();
+ ResponseDali(index);
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_PRFX_DALI));
}
-#else
- if (DaliTarget2Address(Dali->target) == Dali->address) {
- Dali->power = (Dali->command); // State
- if (Dali->power) {
- Dali->dimmer = Dali->command; // Value
- }
- }
- ResponseDali();
- MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_PRFX_DALI));
-#endif // USE_LIGHT
Dali->available = false;
}
@@ -850,7 +872,7 @@ bool DaliSetChannels(void) {
} else {
uint8_t value = ((uint8_t*)XdrvMailbox.data)[0];
if (255 == value) { value = 254; } // Max Dali value
- DaliSendData(DaliTarget2Address(Dali->target), value);
+ DaliSendData(DaliTarget2Address(), value);
}
}
return true;
@@ -900,7 +922,10 @@ bool DaliInit(void) {
#endif // DALI_DEBUG
Dali->max_short_address = 64;
- Dali->dimmer = DALI_INIT_STATE;
+ for (uint32_t i = 0; i < DALI_MAX_STORED; i++) {
+ Dali->dimmer[i] = DALI_INIT_STATE;
+ }
+
// Manchester twice 1200 bps = 2400 bps = 417 (protocol 416.76 +/- 10%) us
Dali->bit_cycles = ESP.getCpuFreqMHz() * 1000000 / 2400;
@@ -983,7 +1008,7 @@ void CmndDali(void) {
}
DaliJsonParse();
}
- ResponseDali();
+ ResponseDali(0);
}
/*-------------------------------------------------------------------------------------------*/
@@ -1010,15 +1035,19 @@ void CmndDaliPower(void) {
// DaliPower0 0..254 - Broadcast control (= DaliPower)
// DaliPower1 0..254 - Short address 0 control
// DaliPower3 0..254 - Short address 2 control
+ uint32_t index = 0; // Broadcast
+ if ((XdrvMailbox.index >= 101) && (XdrvMailbox.index <= 116)) {
+ index = XdrvMailbox.index - 100; // Group1 to 16
+ }
if (((XdrvMailbox.index >= 0) && (XdrvMailbox.index <= 64)) ||
((XdrvMailbox.index >= 101) && (XdrvMailbox.index <= 116))) {
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 254)) {
if (XdrvMailbox.payload <= 2) {
if (2 == XdrvMailbox.payload) {
- XdrvMailbox.payload = (Dali->power) ? 0 : 1;
+ XdrvMailbox.payload = (Dali->power[index]) ? 0 : 1;
}
if (1 == XdrvMailbox.payload) {
- XdrvMailbox.payload = Dali->dimmer;
+ XdrvMailbox.payload = Dali->dimmer[index];
}
}
uint32_t DALIaddr = DALI_BROADCAST_DP;
@@ -1031,7 +1060,7 @@ void CmndDaliPower(void) {
DaliSendData(DALIaddr, XdrvMailbox.payload);
}
}
- ResponseDali();
+ ResponseDali(index);
}
void CmndDaliDimmer(void) {
@@ -1039,6 +1068,10 @@ void CmndDaliDimmer(void) {
// DaliDimmer0 0..100 - Broadcast set power off or dimmer state
// DaliDimmer1 0..100 - Short address 0 set power off or dimmer state
// DaliDimmer3 0..100 - Short address 2 set power off or dimmer state
+ uint32_t index = 0; // Broadcast
+ if ((XdrvMailbox.index >= 101) && (XdrvMailbox.index <= 116)) {
+ index = XdrvMailbox.index - 100; // Group1 to 16
+ }
if (((XdrvMailbox.index >= 0) && (XdrvMailbox.index <= 64)) ||
((XdrvMailbox.index >= 101) && (XdrvMailbox.index <= 116))) {
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) {
@@ -1053,7 +1086,7 @@ void CmndDaliDimmer(void) {
DaliSendData(DALIaddr, dimmer);
}
}
- ResponseDali();
+ ResponseDali(index);
}
void CmndDaliGroup(void) {
@@ -1169,13 +1202,23 @@ void CmndDaliScan(void) {
}
}
+void CmndDaliGroupSliders(void) {
+ // DaliGroupSliders 0..16 - Disable light controls and add group sliders
+ if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 16)) {
+ Settings->sbflag1.dali_light = 0; // Disable DaliLight
+ Settings->mbflag2.dali_group_sliders = XdrvMailbox.payload;
+ TasmotaGlobal.restart_flag = 2; // Restart to update GUI
+ }
+ ResponseCmndNumber(Settings->mbflag2.dali_group_sliders);
+}
+
#ifdef USE_LIGHT
void CmndDaliLight(void) {
// DaliLight 0 - Disable light controls
// DaliLight 1 - Enable light controls
if (XdrvMailbox.data_len > 0) {
Settings->sbflag1.dali_light = XdrvMailbox.payload &1;
- TasmotaGlobal.restart_flag = 2;
+ TasmotaGlobal.restart_flag = 2; // Restart to update GUI
}
ResponseCmndStateText(Settings->sbflag1.dali_light);
}
@@ -1185,10 +1228,86 @@ void CmndDaliLight(void) {
* Presentation
\*********************************************************************************************/
+#ifdef USE_WEBSERVER
+const char HTTP_MSG_SLIDER_DALI[] PROGMEM =
+ ""
+ " | "
+ ""
+ " | "
+ "
";
+
+void DaliWebAddMainSlider(void) {
+ WSContentSend_P(HTTP_TABLE100);
+ char number[12];
+ uint32_t max_sliders = 1 + Settings->mbflag2.dali_group_sliders;
+ for (uint32_t i = 0; i < max_sliders; i++) {
+ Dali->web_dimmer[i] = Dali->dimmer[i];
+ Dali->web_power[i] = Dali->power[i];
+ WSContentSend_P(HTTP_MSG_SLIDER_DALI, // Brightness - Black to White
+ i, // k75
+ WebColor((Dali->web_power[i])?COL_BUTTON:COL_BACKGROUND),
+ i, // k75=
+ (0==i)?"B":"G", // B (Broadcast) or G1 to G16 (Group)
+ (0==i)?"":itoa(i, number, 10),
+ i, // i75
+ changeUIntScale(Dali->web_dimmer[i], 0, 254, 0, 100),
+ i // i75
+ );
+ }
+ WSContentSend_P(PSTR(""));
+}
+
+void DaliWebGetArg(void) {
+ char tmp[8]; // WebGetArg numbers only
+ char svalue[32]; // Command and number parameter
+ char webindex[8]; // WebGetArg name
+
+ uint32_t index;
+ uint32_t max_sliders = 1 + Settings->mbflag2.dali_group_sliders;
+ for (uint32_t i = 0; i < max_sliders; i++) {
+ snprintf_P(webindex, sizeof(webindex), PSTR("i75%d"), i);
+ WebGetArg(webindex, tmp, sizeof(tmp)); // 0 - 100 percent
+ if (strlen(tmp)) {
+ index = i;
+ if (index > 0) { index += 100; } // Group
+ snprintf_P(svalue, sizeof(svalue), PSTR("DaliDimmer%d %s"), index, tmp);
+ ExecuteWebCommand(svalue);
+ }
+ }
+ WebGetArg(PSTR("k75"), tmp, sizeof(tmp));
+ if (strlen(tmp)) {
+ index = atoi(tmp);
+ if (index > 0) { index += 100; } // Group
+ snprintf_P(svalue, sizeof(svalue), PSTR("DaliPower%d 2"), index);
+ ExecuteWebCommand(svalue);
+ }
+}
+#endif // USE_WEBSERVER
+
void DaliShow(bool json) {
if (json) {
ResponseAppend_P(PSTR(","));
- ResponseAppendDali();
+ ResponseAppendDali(0);
+#ifdef USE_WEBSERVER
+ } else {
+ uint32_t max_sliders = 1 + Settings->mbflag2.dali_group_sliders;
+ for (uint32_t i = 0; i < max_sliders; i++) {
+ if (Dali->power[i] != Dali->web_power[i]) {
+ Dali->web_power[i] = Dali->power[i];
+ WSContentSend_P(HTTP_MSG_SLIDER_UPDATE); // ""),
+ i, WebColor((Dali->web_power[i])?COL_BUTTON:COL_BACKGROUND));
+ WSContentSeparator(3); // Don't print separator on next WSContentSeparator(1)
+ }
+ if (Dali->dimmer[i] != Dali->web_dimmer[i]) {
+ Dali->web_dimmer[i] = Dali->dimmer[i];
+ WSContentSend_P(HTTP_MSG_SLIDER_UPDATE); // ""),
+ i, changeUIntScale(Dali->web_dimmer[i], 0, 254, 0, 100));
+ WSContentSeparator(3); // Don't print separator on next WSContentSeparator(1)
+ }
+ }
+#endif // USE_WEBSERVER
}
}
@@ -1220,7 +1339,19 @@ bool Xdrv75(uint32_t function) {
break;
#ifdef USE_WEBSERVER
case FUNC_WEB_SENSOR:
- DaliShow(false);
+ if (!Settings->sbflag1.dali_light) { // DaliLight 0
+ DaliShow(false);
+ }
+ break;
+ case FUNC_WEB_ADD_MAIN_BUTTON:
+ if (!Settings->sbflag1.dali_light) { // DaliLight 0
+ DaliWebAddMainSlider();
+ }
+ break;
+ case FUNC_WEB_GET_ARG:
+ if (!Settings->sbflag1.dali_light) { // DaliLight 0
+ DaliWebGetArg();
+ }
break;
#endif // USE_WEBSERVER
case FUNC_COMMAND: