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: