6565 --------------------------------------------------------------------------------------------
6666 Version yyyymmdd Action Description
6767 --------------------------------------------------------------------------------------------
68+ 1.4.1.0 20251130 update - Add options to `DaliGear` and DaliGroup` to toggle specific outputs
69+ - Make max number of devices persistent to speed up scan response
6870 1.4.0.0 20251126 update - Change to TasmotaDali library
6971 1.3.0.4 20251123 update - Add send retry on collision detection
7072 - Prep DALI-2 24-bit transceive
@@ -154,12 +156,12 @@ typedef struct DliSettings_t {
154156 uint32_t crc32; // To detect file changes
155157 uint8_t target;
156158 uint8_t light_type;
159+ uint8_t max_gear;
157160} DliSettings_t;
158161
159162struct DALI {
160163 DliSettings_t Settings; // Persistent settings
161164 TasmotaDali *dali;
162- uint8_t max_short_address;
163165 uint8_t address;
164166 uint8_t command;
165167 uint8_t last_dimmer;
@@ -199,15 +201,17 @@ bool DaliLoadData(void) {
199201 Dali->Settings .crc32 = root.getUInt (PSTR (" Crc" ), Dali->Settings .crc32 );
200202 Dali->Settings .target = root.getUInt (PSTR (" Target" ), Dali->Settings .target );
201203 Dali->Settings .light_type = root.getUInt (PSTR (" LightType" ), Dali->Settings .light_type );
204+ Dali->Settings .max_gear = root.getUInt (PSTR (" MaxGear" ), Dali->Settings .max_gear );
202205
203206 return true ;
204207}
205208
206209bool DaliSaveData (void ) {
207- Response_P (PSTR (" {\" " XDRV_75_KEY " \" :{\" Crc\" :%u,\" Target\" :%u,\" LightType\" :%u}}" ),
210+ Response_P (PSTR (" {\" " XDRV_75_KEY " \" :{\" Crc\" :%u,\" Target\" :%u,\" LightType\" :%u, \" MaxGear \" :%u }}" ),
208211 Dali->Settings .crc32 ,
209212 Dali->Settings .target ,
210- Dali->Settings .light_type );
213+ Dali->Settings .light_type ,
214+ Dali->Settings .max_gear );
211215
212216 return UfsJsonSettingsWrite (ResponseData ());
213217}
@@ -227,6 +231,7 @@ void DaliSettingsLoad(bool erase) {
227231 // *** Start init default values in case key is not found ***
228232 memset (&Dali->Settings , 0x00 , sizeof (DliSettings_t));
229233 Dali->Settings .light_type = LT_RGB; // Default RGB channel
234+ Dali->Settings .max_gear = 64 ; // Default max supported short address
230235 // *** End Init default values ***
231236
232237#ifndef USE_UFILESYS
@@ -527,20 +532,6 @@ uint32_t DaliQueryRGBWAF(uint32_t adr) {
527532
528533/* -------------------------------------------------------------------------------------------*/
529534
530- uint32_t DaliGearPresent (void ) {
531- uint32_t count = 0 ;
532- for (uint32_t address = 0 ; address < Dali->max_short_address ; address++) { // Scanning 64 addresses takes about 2500 ms
533- uint32_t short_address = address << 1 ;
534- if (DaliSendWaitResponse (short_address | DALI_SELECTOR_BIT, DALI_102_QUERY_CONTROL_GEAR_PRESENT, 20 ) >= 0 ) {
535- count++;
536- AddLog (LOG_LEVEL_DEBUG, PSTR (" DLI: Device %d at %d, short address %d" ), count, address, short_address);
537- }
538- }
539- return count;
540- }
541-
542- /* -------------------------------------------------------------------------------------------*/
543-
544535void DaliInitLight (void ) {
545536 // Taken from Shelly Dali Dimmer ;-)
546537 uint32_t adr = DALI_BROADCAST_DP | DALI_SELECTOR_BIT;
@@ -686,6 +677,19 @@ uint32_t DaliCommission(uint32_t init_arg, uint32_t max_count) {
686677 return cnt;
687678}
688679
680+ /* -------------------------------------------------------------------------------------------*/
681+
682+ void DaliToggle (uint32_t adr, uint32_t *count) {
683+ static uint32_t interval = 0 ;
684+
685+ if (*count && TimeReached (interval)) {
686+ SetNextTimeInterval (interval, 600 );
687+ (*count)--;
688+ DaliSendData (adr, (*count &1 ) ? 128 : 0 ); // Power toggle
689+ }
690+ delay (1 );
691+ }
692+
689693/* ********************************************************************************************\
690694 * DALI Control Gear - Ballast or Sensor / Receiver
691695 *
@@ -933,7 +937,6 @@ bool DaliInit(uint32_t function) {
933937 if (!Dali) { return false ; }
934938 DaliSettingsLoad (0 );
935939
936- Dali->max_short_address = 64 ;
937940 for (uint32_t i = 0 ; i < DALI_MAX_STORED; i++) {
938941 Dali->dimmer [i] = DALI_INIT_STATE;
939942 }
@@ -1154,10 +1157,20 @@ void CmndDaliDimmer(void) {
11541157void CmndDaliGroup (void ) {
11551158 // DaliGroup1 1,2 - Add device 1 and 2 to group 1
11561159 // DaliGroup1 -1,2 - Remove device 1 and 2 to group 1
1160+ // DaliGroup1 b - Blink group devices twice
11571161 if ((XdrvMailbox.index >= 1 ) && (XdrvMailbox.index <= 16 )) {
11581162 uint32_t group = XdrvMailbox.index -1 ;
11591163 bool more = false ;
11601164 char temp[200 ] = { 0 };
1165+ uint32_t tcount = 0 ;
1166+ uint32_t adr = DaliTarget2Address (group + 101 );
1167+ if (XdrvMailbox.data_len ) {
1168+ if (' b' == XdrvMailbox.data [0 ]) { // Blink devices
1169+ tcount = 4 ;
1170+ XdrvMailbox.data ++;
1171+ XdrvMailbox.data_len --;
1172+ }
1173+ }
11611174 if (XdrvMailbox.data_len ) {
11621175 uint32_t command = DALI_102_ADD_TO_GROUP0;
11631176 temp[0 ] = ' +' ;
@@ -1184,6 +1197,7 @@ void CmndDaliGroup(void) {
11841197 DaliSendData ((sa << 1 ) | DALI_SELECTOR_BIT, command);
11851198 }
11861199 }
1200+ while (tcount) { DaliToggle (adr, &tcount); }
11871201 ResponseCmndIdxChar (temp);
11881202 }
11891203 } else {
@@ -1193,7 +1207,8 @@ void CmndDaliGroup(void) {
11931207 command = DALI_102_QUERY_GROUPS_8_15;
11941208 bitmask = 1 << group - 8 ;
11951209 }
1196- for (uint32_t sa = 0 ; sa < Dali->max_short_address ; sa++) { // Scanning 64 addresses takes about 2500 ms
1210+ for (uint32_t sa = 0 ; sa < Dali->Settings .max_gear ; sa++) { // Scanning 64 addresses takes about 2500 ms
1211+ if (tcount) { DaliToggle (adr, &tcount); }
11971212 int result = DaliSendWaitResponse ((sa << 1 ) | DALI_SELECTOR_BIT, command, 20 );
11981213 if ((result >= 0 ) && (result & bitmask)) {
11991214 snprintf_P (temp, sizeof (temp), PSTR (" %s%s%d" ), temp, (more)?" ," :" " , sa +1 );
@@ -1202,6 +1217,8 @@ void CmndDaliGroup(void) {
12021217 }
12031218 if (!strlen (temp)) {
12041219 snprintf_P (temp, sizeof (temp), PSTR (" None" ));
1220+ } else {
1221+ while (tcount) { DaliToggle (adr, &tcount); }
12051222 }
12061223 ResponseCmndIdxChar (temp);
12071224 }
@@ -1211,12 +1228,42 @@ void CmndDaliGroup(void) {
12111228/* -------------------------------------------------------------------------------------------*/
12121229
12131230void CmndDaliGear (void ) {
1214- if ((XdrvMailbox.payload >= 1 ) && (XdrvMailbox.payload <= 64 )) {
1215- Dali->max_short_address = XdrvMailbox.payload ;
1231+ // DaliGear[2] [<max_address>|<address>] - Scan bus for up to <max_address> devices and toggle output twice
1232+ // DaliGear - Scan bus for 64 devices taking around 2.5 sec
1233+ // DaliGear 15 - Scan bus for up to 15 devices
1234+ // DaliGear2 - Scan bus and toggle output twice
1235+ // DaliGear2 4 - Toggle output twice for device 4 only
1236+ uint32_t toggle_count = 0 ;
1237+ uint32_t start = 0 ;
1238+ uint32_t end = Dali->Settings .max_gear ;
1239+ uint32_t payload = ((XdrvMailbox.payload >= 1 ) && (XdrvMailbox.payload <= 64 )) ? XdrvMailbox.payload : 0 ;
1240+ if (1 == XdrvMailbox.index ) {
1241+ if (payload) {
1242+ end = payload;
1243+ Dali->Settings .max_gear = end;
1244+ }
1245+ }
1246+ else if (2 == XdrvMailbox.index ) {
1247+ toggle_count = 4 ;
1248+ if (payload) {
1249+ start = payload -1 ;
1250+ end = payload;
1251+ }
1252+ }
1253+ char temp[200 ] = { 0 };
1254+ uint32_t count = 0 ;
1255+ for (uint32_t address = start; address < end; address++) { // Scanning 64 addresses takes about 2500 ms
1256+ uint32_t adr = address << 1 ;
1257+ uint32_t tcount = toggle_count;
1258+ if (DaliSendWaitResponse (adr | DALI_SELECTOR_BIT, DALI_102_QUERY_CONTROL_GEAR_PRESENT, 20 ) >= 0 ) {
1259+ snprintf_P (temp, sizeof (temp), PSTR (" %s%s%d" ), temp, (count)?" ," :" " , address +1 );
1260+ count++;
1261+ AddLog (LOG_LEVEL_DEBUG, PSTR (" DLI: Device %d at %d, short address %d" ), count, address, adr);
1262+ while (tcount) { DaliToggle (adr, &tcount); }
1263+ }
12161264 }
1217- uint32_t count = DaliGearPresent ();
12181265 ResponseCmnd ();
1219- ResponseAppend_P (PSTR (" %d,\" Present\" :%d}" ), Dali->max_short_address , count);
1266+ ResponseAppend_P (PSTR (" %d,\" Present\" :%d, \" Address \" :[%s] }" ), Dali->Settings . max_gear , count, temp );
12201267}
12211268
12221269/* -------------------------------------------------------------------------------------------*/
0 commit comments