diff --git a/CHANGELOG.md b/CHANGELOG.md
index b1fc61941..ebdf907ce 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,10 +5,13 @@ All notable changes to this project will be documented in this file.
 
 ## [14.3.0.1]
 ### Added
+- BLE track devices with RPA (#22300)
+- DALI support for short addresses and groups
 
 ### Breaking Changed
 
 ### Changed
+- ESP32 platform update from 2024.09.30 to 2024.10.30 and Framework (Arduino Core) from v3.1.0.240926 to v3.1.0.241015 (#22299)
 
 ### Fixed
 
@@ -30,11 +33,11 @@ All notable changes to this project will be documented in this file.
 - Command ``DaliSend <address>|<address+256>,<command>`` to send command (address+256 is repeat) on DALI bus
 - Command ``DaliQuery <address>|<address+256>,<command>`` to send command (address+256 is repeat) on DALI bus and wait up to DALI_TIMEOUT ms for response
 - Berry Serial `config` to change parity on-the-fly for RS-485 (#22285)
-- Misubishi Electric HVAC Heat/Dry/Cool Auto operation mode (#22216)
-- Misubishi Electric HVAC Bridge to HomeBridge/Homekit locally (#22236)
-- Misubishi Electric HVAC Air Direction Control (#22241)
-- Misubishi Electric HVAC prohibit function (#22269)
-- Misubishi Electric HVAC compressor map and operation power and energy (#22290)
+- Mitsubishi Electric HVAC Heat/Dry/Cool Auto operation mode (#22216)
+- Mitsubishi Electric HVAC Bridge to HomeBridge/Homekit locally (#22236)
+- Mitsubishi Electric HVAC Air Direction Control (#22241)
+- Mitsubishi Electric HVAC prohibit function (#22269)
+- Mitsubishi Electric HVAC compressor map and operation power and energy (#22290)
 
 ### Changed
 - ESP32 platform update from 2024.09.10 to 2024.09.30 and Framework (Arduino Core) from v3.0.5 to v3.1.0.240926 (#22203)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 17026f8f5..61b6aab1a 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -116,10 +116,13 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
 
 ## Changelog v14.3.0.1
 ### Added
+- DALI support for short addresses and groups
+- BLE track devices with RPA [#22300](https://github.com/arendst/Tasmota/issues/22300)
 
 ### Breaking Changed
 
 ### Changed
+- ESP32 platform update from 2024.09.30 to 2024.10.30 and Framework (Arduino Core) from v3.1.0.240926 to v3.1.0.241015 [#22299](https://github.com/arendst/Tasmota/issues/22299)
 
 ### Fixed
 
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino
index c11938e3d..1253fc73e 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_75_dali.ino
@@ -19,6 +19,11 @@
   --------------------------------------------------------------------------------------------
   Version yyyymmdd  Action    Description
   --------------------------------------------------------------------------------------------
+  0.1.0.7 20241017  update    - Add command `DaliCommission 1|2` assigning short addresses
+                              - Add command `DaliTarget 0, 1..64, 101..116` to select light control address
+                              - Add command `DaliGroup1..16 +<devices>|-<devices>` to add/remove devices from group
+                              - Extend commands `DaliPower` and `DaliDimmer` with index to control short address or group
+                              - Remove non-functional MQTT interface
   0.1.0.6 20241014  update    - Fix received light command loop
                               - Add send collision detection
   0.1.0.5 20241014  update    - Add command `DaliSend [repeat]<address>,<command>`
@@ -43,6 +48,29 @@
 
 /*********************************************************************************************\
  * DALI support for Tasmota
+ * 
+ * Available commands:
+ *   <first byte> = 0..255 or 0x00..0xFF + 256/0x100 for optional repeat (send twice)
+ *   <second byte> = 0..255 or 0x00..0xFF        - Both decimal and hexadecimal is supported
+ *   <broadcast> = 0                             - DALI default
+ *   <device> = 1..64                            - DALI short address + 1
+ *   <group> = 101..116                          - DALI group + 101
+ * DaliSend <first byte>,<second byte>           - Execute DALI code and do not expect a DALI backward frame
+ * DaliQuery <first byte>,<second byte>          - Execute DALI code and report result (DALI backward frame)
+ * DaliCommission 1|2                            - Reset (0) or (1)/and commission device short addresses
+ * DaliGroup<1..16> [+]|-<device>,<device>...    - Add(+) or Remove(-) devices to/from group
+ * DaliPower<broadcast>|<device>|<group> 0..254  - Control power (0 = Off, 1 = Last dimmer, 2 = Toggle, 3..254 = absolute light brightness)
+ * DaliDimmer<broadcast>|<device>|<group> 0..100 - Control dimmer (0 = Off, 1..100 = precentage of brightness)
+ * DaliWeb 0|1                                   - Enable Tasmota light control for DaliTarget device
+ * DaliTarget <broadcast>|<device>|<group>       - Set Tasmota light control device (0, 1..64, 101..116)
+ * 
+ * Address type        Address byte
+ * ------------------  --------------------
+ * Broadcast address   1111111S
+ * 64 short address    0AAAAAAS
+ * 16 group address    100AAAAS
+ * Special command     101CCCC1 to 110CCCC1
+ * A = Address bit, S = 0 Direct Arc Power control, S = 1 Command, C = Special command
 \*********************************************************************************************/
 
 #define XDRV_75             75
@@ -71,18 +99,18 @@
 #define D_PRFX_DALI "Dali"
 
 const char kDALICommands[] PROGMEM = D_PRFX_DALI "|"  // Prefix
-  "|" D_CMND_POWER 
+  "|" D_CMND_POWER "|" D_CMND_DIMMER "|Target"
 #ifdef USE_LIGHT
   "|Web"
 #endif  // USE_LIGHT
-  "|" D_CMND_DIMMER "|Send|Query"  ;
+  "|Send|Query|Commission|Group";
 
 void (* const DALICommand[])(void) PROGMEM = {
-  &CmndDali, &CmndDaliPower,
+  &CmndDali, &CmndDaliPower, &CmndDaliDimmer, &CmndDaliTarget,
 #ifdef USE_LIGHT
   &CmndDaliWeb,
 #endif  // USE_LIGHT
-  &CmndDaliDimmer, &CmndDaliSend, &CmndDaliQuery };
+  &CmndDaliSend, &CmndDaliQuery, &CmndDaliCommission, &CmndDaliGroup };
 
 struct DALI {
   uint32_t bit_time;
@@ -92,6 +120,7 @@ struct DALI {
   uint8_t address;
   uint8_t command;
   uint8_t dimmer;
+  uint8_t target;
   bool power;
   bool available;
   bool response;
@@ -102,6 +131,35 @@ struct DALI {
  * DALI low level
 \*********************************************************************************************/
 
+uint32_t DaliTarget2Address(uint32_t target) {
+  // 1..64    = Short address
+  // 101..116 = Group address
+  // Others   = Broadcast
+  if ((target >= 1) && (target <= 64)) {       // 1 .. 64
+    target -= 1;                               // Short address
+    target <<= 1;
+  }
+  else if ((target >= 101) && (target <= 116)) {  // 101 .. 116
+    target -= 101;
+    target <<= 1;
+    target |= 0x80;                            // Group address
+  }
+  else {                                       // Others
+    target = DALI_BROADCAST_DP;                // Broadcast address
+  }
+  return target &0xFE;                         // Direct Arc Power Control command
+}
+/*
+uint32_t DaliAddress2Target(uint32_t adr) {
+  if (adr >= 254) {                            // 0b1111111S
+    return 0;                                  // Broadcast address (0)
+  }
+  else if ((adr >= 128) && (adr <= 159)) {     // 0b1000000S .. 0b1001111S
+    return (adr >> 1) +101;                    // Group address (101 .. 116)
+  }
+  return (adr >> 1) +1;                        // 0b0000000S .. 0b0111111S Short address (1 .. 64)
+}
+*/
 void DaliEnableRxInterrupt(void) {
   Dali->available = false;
   attachInterrupt(Dali->pin_rx, DaliReceiveData, FALLING);
@@ -243,7 +301,7 @@ void DaliSendData(uint32_t adr, uint32_t cmd) {
 
   Dali->address = adr;
   Dali->command = cmd;
-  if (DALI_BROADCAST_DP == adr) {
+  if (DaliTarget2Address(Dali->target) == adr) {
     repeat = true;
     Dali->power = (cmd);                       // State
     if (Dali->power) {
@@ -263,6 +321,10 @@ void DaliSendData(uint32_t adr, uint32_t cmd) {
     }
   }
 
+#ifdef DALI_DEBUG
+  AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: SendData Repeat %d, Adr 0x%02X, Cmd 0x%02x"), repeat, adr, cmd);
+#endif  // DALI_DEBUG
+
   uint16_t send_dali_data = adr << 8 | cmd;
 
   DaliDisableRxInterrupt();
@@ -289,13 +351,164 @@ int DaliSendWaitResponse(uint32_t adr, uint32_t cmd, uint32_t timeout) {
     result = Dali->received_dali_data;
   }
   Dali->response = false;
+
+#ifdef DALI_DEBUG
+  AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: SendWaitResponse result %d = 0x%04X"), result, result);
+#endif  // DALI_DEBUG
+
   return result;
 }
 
-void DaliPower(uint32_t val) {
-  DaliSendData(DALI_BROADCAST_DP, val);
+/*********************************************************************************************\
+ * DALI commissioning short addresses
+ * 
+ * Courtesy of https://github.com/qqqlab/DALI-Lighting-Interface
+\*********************************************************************************************/
+
+// Query commands - Send as second byte
+#define DALI_QUERY_STATUS          0x0090  // 144  - Returns "STATUS INFORMATION"
+
+// Special commands - Send as first byte
+#define DALI_TERMINATE             0x00A1  // 256  - Releases the INITIALISE state.
+#define DALI_INITIALISE            0x01A5  // 258 REPEAT - Sets the slave to the INITIALISE status for15 minutes. Commands 259 to 270 are enabled only for a slave in this status.
+#define DALI_RANDOMISE             0x01A7  // 259 REPEAT - Generates a random address.
+#define DALI_COMPARE               0x00A9  // 260  - Is the random address smaller or equal to the search address?
+#define DALI_WITHDRAW              0x00AB  // 261  - Excludes slaves for which the random address and search address match from the Compare process.
+#define DALI_SEARCHADDRH           0x00B1  // 264  - Specifies the higher 8 bits of the search address.
+#define DALI_SEARCHADDRM           0x00B3  // 265  - Specifies the middle 8 bits of the search address.
+#define DALI_SEARCHADDRL           0x00B5  // 266  - Specifies the lower 8 bits of the search address.
+#define DALI_PROGRAM_SHORT_ADDRESS 0x00B7  // 267  - The slave shall store the received 6-bit address (AAA AAA) as a short address if it is selected.
+
+void DaliSetSearchAddress(uint32_t adr) {
+  // Set search address
+  DaliSendData(DALI_SEARCHADDRH, adr>>16);
+  DaliSendData(DALI_SEARCHADDRM, adr>>8);
+  DaliSendData(DALI_SEARCHADDRL, adr);
 }
 
+void DaliSetSearchAddressDifference(uint32_t adr_new, uint32_t adr_current) {
+  // Set search address, but set only changed bytes (takes less time)
+  if ( (uint8_t)(adr_new>>16) !=  (uint8_t)(adr_current>>16) ) DaliSendData(DALI_SEARCHADDRH, adr_new>>16);
+  if ( (uint8_t)(adr_new>>8)  !=  (uint8_t)(adr_current>>8)  ) DaliSendData(DALI_SEARCHADDRM, adr_new>>8);
+  if ( (uint8_t)(adr_new)     !=  (uint8_t)(adr_current)     ) DaliSendData(DALI_SEARCHADDRL, adr_new);
+}
+
+bool DaliCompare() {
+  // Is the random address smaller or equal to the search address?
+  // As more than one device can reply, the reply gets garbled
+  uint8_t retry = 2;
+  while (retry > 0) {
+    // Compare is true if we received any activity on the bus as reply.
+    // Sometimes the reply is not registered... so only accept retry times 'no reply' as a real false compare
+    int rv = DaliSendWaitResponse(DALI_COMPARE, 0x00);
+    if (rv == 0xFF) return true;               // Yes reply
+    retry--;
+  }
+  return false;
+}
+
+uint32_t DaliFindAddress(void) {
+  // Find addr with binary search
+  uint32_t adr = 0x800000;
+  uint32_t addsub = 0x400000;
+  uint32_t adr_last = adr;
+  DaliSetSearchAddress(adr);
+  
+  while (addsub) {
+    DaliSetSearchAddressDifference(adr, adr_last);
+    adr_last = adr;
+    if (DaliCompare()) {                       // Returns true if searchadr > adr
+      adr -= addsub;
+    } else {
+      adr += addsub;
+    }
+    addsub >>= 1;
+  }
+  DaliSetSearchAddressDifference(adr, adr_last);
+  adr_last = adr;
+  if (!DaliCompare()) {
+    adr++;
+    DaliSetSearchAddressDifference(adr, adr_last);
+  }
+  return adr;
+}
+
+void DaliProgramShortAddress(uint8_t shortadr) {
+  // The slave shall store the received 6-bit address (AAAAAA) as a short address if it is selected.
+  DaliSendData(DALI_PROGRAM_SHORT_ADDRESS, (shortadr << 1) | 0x01);
+
+  AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Set short address %d"), shortadr +1);
+}
+
+uint32_t DaliCommission(uint8_t init_arg) {
+  // init_arg=11111111 : all without short address
+  // init_arg=00000000 : all 
+  // init_arg=0AAAAAA1 : only for this shortadr
+  // returns number of new short addresses assigned
+  DaliSendData(DALI_BROADCAST_DP, 0);          // Turn all OFF
+  delay(100);                                  // Need 100ms pause before starting commissioning
+
+  uint8_t arr[64];
+  uint32_t sa;
+  for (sa = 0; sa < 64; sa++) {
+    arr[sa] = 0;
+  }
+
+  // Start commissioning
+  DaliSendData(DALI_INITIALISE, init_arg);
+  DaliSendData(DALI_RANDOMISE, 0x00);
+  delay(100);                                  // Need 100ms pause after RANDOMISE
+
+  // Find used short addresses (run always, seems to work better than without...)
+  for (sa = 0; sa < 64; sa++) {
+    int rv = DaliSendWaitResponse(sa << 1 | 1, DALI_QUERY_STATUS);
+    if (rv >= 0) {
+      if (init_arg != 0b00000000) {
+        arr[sa] = 1;                           // Remove address from list if not in "all" mode
+      }
+    }
+  }
+
+  uint32_t cnt = 0;
+  while (true) {                               // Find random addresses and assign unused short addresses
+    uint32_t adr = DaliFindAddress();
+    if (adr > 0xffffff) { break; }             // No more random addresses found -> exit
+    for (sa = 0; sa < 64; sa++) {              // Find first unused short address
+      if (0 == arr[sa]) { break; }
+    }
+    if( sa >= 64) { break; }                   // All 64 short addresses assigned -> exit
+    arr[sa] = 1;                               // Mark short address as used
+    cnt++;
+ 
+    DaliProgramShortAddress(sa);               // Assign short address
+    DaliSendData(DALI_WITHDRAW, 0x00);         // Remove the device from the search
+
+    delay(1);
+    OsWatchLoop();
+  }
+
+  DaliSendData(DALI_TERMINATE, 0x00);          // Terminate the DALI_INITIALISE command
+
+  for (sa = 0; sa < cnt; sa++) {
+    AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Flash short address %d"), sa +1);
+
+    DaliSendData(sa << 1, 200);                // Flash assigned lights
+    delay(1000);
+    OsWatchLoop();
+    DaliSendData(sa << 1, 0);
+  }
+
+  return cnt;
+}
+
+/*********************************************************************************************\
+ * DALI group management
+\*********************************************************************************************/
+
+// Configuration commands - Send as second byte
+#define DALI_ADD_TO_GROUP0         0x0060  //  96  - Adds the slave to Group XXXX.
+#define DALI_REMOVE_FROM_GROUP0    0x0070  // 112  - Deletes the slave from Group XXXX.
+
 /***********************************************************/
 
 void ResponseAppendDali(void) {
@@ -318,7 +531,7 @@ void DaliInput(void) {
 
 #ifdef USE_LIGHT
   bool show_response = true;
-  if (DALI_BROADCAST_DP == Dali->address) {
+  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
@@ -345,7 +558,7 @@ void DaliInput(void) {
     MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_PRFX_DALI));
   }
 #else
-  if (DALI_BROADCAST_DP == Dali->address) {
+  if (DaliTarget2Address(Dali->target) == Dali->address) {
     Dali->power = (Dali->command);             // State
     if (Dali->power) {
       Dali->dimmer = Dali->command;            // Value
@@ -366,7 +579,7 @@ bool DaliSetChannels(void) {
     } else {
       uint8_t value = ((uint8_t*)XdrvMailbox.data)[0];
       if (255 == value) { value = 254; }       // Max Dali value
-      DaliPower(value);
+      DaliSendData(DaliTarget2Address(Dali->target), value);
     }
   }
   return true;
@@ -411,84 +624,6 @@ bool DaliInit(void) {
 #endif  // USE_LIGHT
 }
 
-/*********************************************************************************************\
- * Experimental - Not functioning
-\*********************************************************************************************/
-
-bool DaliMqtt(void) {
-/*
-  XdrvMailbox.topic = topic;
-  XdrvMailbox.index = strlen(topic);
-  XdrvMailbox.data = (char*)data;
-  XdrvMailbox.data_len = data_len;
-
-  This won't work as there is currently no subscribe done
-*/
-  char stopic[TOPSZ];
-  strncpy(stopic, XdrvMailbox.topic, TOPSZ);
-  XdrvMailbox.topic[TOPSZ - 1] = 0;
-
-  char *items[10];
-  char *p = stopic;
-  int cnt = 0;
-  do {
-    items[cnt] = strtok(p, "/");
-    cnt++;
-    p = nullptr;
-  } while (items[cnt - 1]);
-  cnt--; // represents the number of items
-
-  AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Cnt %d, Topic '%s', Payload '%s'"), cnt, XdrvMailbox.topic, XdrvMailbox.data);
-
-  if (cnt < 3) { // not for us?
-    AddLog(LOG_LEVEL_INFO, PSTR("DLI: Cnt %d < 3"), cnt);
-    return false;
-  }
-
-  int DALIindex = 0;
-  int ADRindex = 0;
-  int CMDindex = 0;
-  uint8_t DALIaddr = DALI_BROADCAST_DP;
-
-  if (strcasecmp_P(items[cnt - 3], PSTR(DALI_TOPIC)) != 0) {      // dali
-    // cmnd
-    if (strcasecmp_P(items[cnt - 2], PSTR(DALI_TOPIC)) != 0) {    // dali
-      // device
-      return false; // not for us
-    } else {
-      // cmnd/dali/percent
-      DALIindex = cnt - 2;
-      CMDindex = cnt - 1;
-    }
-  } else {
-    // dali/percent/2 20 
-    DALIindex = cnt - 3;
-    CMDindex = cnt - 2;
-    ADRindex = cnt - 1;
-    DALIaddr = ((int)CharToFloat(items[ADRindex]))  << 1;
-  }
-
-  uint8_t level;
-  uint8_t value = (uint8_t)CharToFloat(XdrvMailbox.data);
-  if (strcasecmp_P(items[CMDindex], PSTR("percent")) == 0) {
-    // dali/percent/
-    float percent = (float)(254 * value * 0.01);
-    level = (uint8_t)percent;
-  }
-  else if (strcasecmp_P(items[CMDindex], PSTR("level")) == 0) {
-    level = value;
-  }
-  else {
-    AddLog(LOG_LEVEL_INFO,PSTR("DLI: Command not recognized: %s"), items[CMDindex]);
-    return false; // not for us
-  }
-
-  AddLog(LOG_LEVEL_INFO,PSTR("DLI: Dali value %d on address %d"), value, DALIaddr);
-  DaliSendData(DALIaddr, level);
-
-  return true;
-}
-
 /*********************************************************************************************\
  * Commands
 \*********************************************************************************************/
@@ -548,37 +683,109 @@ void CmndDali(void) {
   ResponseDali();
 }
 
+void CmndDaliTarget(void) {
+  // DaliTarget          - Set transmit target
+  // DaliTarget 0        - Set target to broadcast address
+  // DaliTarget 1..64    - Set target to short address
+  // DaliTarget 101..116 - Set target to group address
+  if (((XdrvMailbox.payload >= 1) && (XdrvMailbox.payload <= 64)) ||
+      ((XdrvMailbox.payload >= 101) && (XdrvMailbox.payload <= 116)) ||
+      (XdrvMailbox.payload == 0)) {
+    Dali->target = XdrvMailbox.payload;
+  }
+  ResponseCmndNumber(Dali->target);
+}
+
 void CmndDaliPower(void) {
-  // DaliPower 0      - Power off
-  // DaliPower 1      - Power on to last dimmer state
-  // DaliPower 2      - Toggle power off or last dimmer state
-  // DaliPower 3..254 - Equals DaliDimmer command
-  if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 254)) {
-    if (XdrvMailbox.payload <= 2) {
-      if (2 == XdrvMailbox.payload) {
-        XdrvMailbox.payload = (Dali->power) ? 0 : 1;
+  // DaliPower 0       - Broadcast power off
+  // DaliPower 1       - Broadcast power on to last dimmer state
+  // DaliPower 2       - Broadcast toggle power off or last dimmer state
+  // DaliPower 3..254  - Broadcast equals DaliDimmer command
+  // DaliPower 0..254  - Broadcast control
+  // DaliPower0 0..254 - Broadcast control (= DaliPower)
+  // DaliPower1 0..254 - Short address 0 control
+  // DaliPower3 0..254 - Short address 2 control
+  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;
+        }
+        if (1 == XdrvMailbox.payload) {
+          XdrvMailbox.payload = Dali->dimmer;
+        }
       }
-      if (1 == XdrvMailbox.payload) {
-        XdrvMailbox.payload = Dali->dimmer;
+      uint32_t DALIaddr = DALI_BROADCAST_DP;
+      if (XdrvMailbox.index >= 101) {
+        DALIaddr = ((XdrvMailbox.index -101) << 1) | 0x80;  // Group address
       }
+      else if ((XdrvMailbox.index > 0) && XdrvMailbox.usridx) {
+        DALIaddr = (XdrvMailbox.index -1) << 1;  // Short address
+      }
+      DaliSendData(DALIaddr, XdrvMailbox.payload);
     }
-    DaliPower(XdrvMailbox.payload);
   }
   ResponseDali();
 }
 
 void CmndDaliDimmer(void) {
-  // DaliDimmer 0..100 - Set power off or dimmer state
-  if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) {
-    uint8_t dimmer = changeUIntScale(XdrvMailbox.payload, 0, 100, 0, 254);
-    DaliPower(dimmer);
+  // DaliDimmer 0..100  - Broadcast set power off or dimmer state
+  // 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
+  if (((XdrvMailbox.index >= 0) && (XdrvMailbox.index <= 64)) ||
+      ((XdrvMailbox.index >= 101) && (XdrvMailbox.index <= 116))) {
+    if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) {
+      uint8_t dimmer = changeUIntScale(XdrvMailbox.payload, 0, 100, 0, 254);
+      uint32_t DALIaddr = DALI_BROADCAST_DP;
+      if (XdrvMailbox.index >= 101) {
+        DALIaddr = ((XdrvMailbox.index -101) << 1) | 0x80;  // Group address
+      }
+      else if ((XdrvMailbox.index > 0) && XdrvMailbox.usridx) {
+        DALIaddr = (XdrvMailbox.index -1) << 1;  // Short address
+      }
+      DaliSendData(DALIaddr, dimmer);
+    }
   }
   ResponseDali();
 }
 
+void CmndDaliGroup(void) {
+  // DaliGroup1 1,2   - Add device 1 and 2 to group 1
+  // DaliGroup1 -1,2  - Remove device 1 and 2 to group 1
+  if ((XdrvMailbox.index >= 1) && (XdrvMailbox.index <= 16)) {
+    if (XdrvMailbox.data_len) {
+      uint32_t command = DALI_ADD_TO_GROUP0;
+      if ('+' == XdrvMailbox.data[0]) {        // Add devices
+        XdrvMailbox.data++;
+        XdrvMailbox.data_len--;
+      }
+      else if ('-' == XdrvMailbox.data[0]) {   // Remove devices
+        command = DALI_REMOVE_FROM_GROUP0;
+        XdrvMailbox.data++;
+        XdrvMailbox.data_len--;
+      }
+      uint32_t argc = ArgC();                  // Number of devices
+      if (argc) {
+        command |= (XdrvMailbox.index -1);
+        uint32_t sas[argc];
+        ParseParameters(argc, sas);
+        for (uint32_t arg = 0; arg < argc; arg++) {
+          uint32_t sa = sas[arg] -1;
+          if (sa <= 63) {
+            DaliSendData(sa << 1 | 0x01, command);
+          }
+        }
+        ResponseCmndDone();
+      }
+    }
+  }
+}
+
 void CmndDaliSend(void) {
   // Send command
-  // Setting bit 8 will repeat command twice
+  // Setting bit 8 will repeat command once
   // DaliSend 0x1a5,255  - DALI Initialise (send twice)
   uint32_t values[2] = { 0 };
   uint32_t params = ParseParameters(2, values);
@@ -590,7 +797,7 @@ void CmndDaliSend(void) {
 
 void CmndDaliQuery(void) {
   // Send command and return response or -1 (no response within DALI_TIMEOUT)
-  // Setting bit 8 will repeat command twice
+  // Setting bit 8 will repeat command once
   // DaliQuery 0xff,0x90  - DALI Query status
   // DaliQuery 0xff,144   - DALI Query status
   uint32_t values[2] = { 0 };
@@ -601,6 +808,20 @@ void CmndDaliQuery(void) {
   }
 }
 
+void CmndDaliCommission(void) {
+  // Commission short addresses
+  // DaliCommission 1     - Reset and commission short addresses
+  // DaliCommission 2     - Commission unassigned short addresses
+  if ((XdrvMailbox.payload >= 1) && (XdrvMailbox.payload <= 2)) {
+    uint32_t init_arg = 0x00;                  // Commission all
+    if (2 == XdrvMailbox.payload) {
+      init_arg = 0xFF;                         // Commission all without short addresses
+    }
+    int result = DaliCommission(init_arg);
+    ResponseCmndNumber(result);
+  }
+}
+
 #ifdef USE_LIGHT
 void CmndDaliWeb(void) {
   // DaliWeb 0  - Disable GUI light controls
@@ -639,9 +860,6 @@ bool Xdrv75(uint32_t function) {
       case FUNC_LOOP:
         DaliInput();
         break;
-      case FUNC_MQTT_DATA:
-        result = DaliMqtt();
-        break;
 #ifdef USE_LIGHT
       case FUNC_SET_CHANNELS:
         result = DaliSetChannels();