Fix DALI Tasmota light control using non-broadcast address
This commit is contained in:
parent
01dfb76d36
commit
88c62f3c09
@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
### Changed
|
||||
- ESP32 Platform from 2025.10.30 to 2025.11.30, Framework (Arduino Core) from v3.1.4 to v3.1.5 and IDF from v5.3.4.250826 to v5.3.4.251110 (#24118)
|
||||
- JPEGDEC library from v1.8.3 to v1.8.4 (#24120)
|
||||
|
||||
### Fixed
|
||||
|
||||
|
||||
@ -130,6 +130,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
|
||||
### Changed
|
||||
- ESP32 Platform from 2025.10.30 to 2025.11.30, Framework (Arduino Core) from v3.1.4 to v3.1.5 and IDF from v5.3.4.250826 to v5.3.4.251110 [#24118](https://github.com/arendst/Tasmota/issues/24118)
|
||||
- LVGL library from v9.3.0 to v9.4.0 [#24028](https://github.com/arendst/Tasmota/issues/24028)
|
||||
- JPEGDEC library from v1.8.3 to v1.8.4 [#24120](https://github.com/arendst/Tasmota/issues/24120)
|
||||
- GPIOViewer from v1.6.3 to v1.7.0
|
||||
- Refactored library UDisplay [#24007](https://github.com/arendst/Tasmota/issues/24007)
|
||||
- Increased filesystem file name size from 48 to 50 characters
|
||||
|
||||
@ -58,6 +58,7 @@
|
||||
--------------------------------------------------------------------------------------------
|
||||
Version yyyymmdd Action Description
|
||||
--------------------------------------------------------------------------------------------
|
||||
1.1.0.4 20251115 fix - Tasmota light control using non-broadcast address
|
||||
1.1.0.3 20251112 remove - Remove optional repeat for commands `DaliSend` and `DaliQuery`
|
||||
Send twice is now based on DALI defined commands type
|
||||
1.1.0.2 20251109 update - Add optional extended commands prefix for commands `DaliSend` and `DaliQuery`
|
||||
@ -111,6 +112,8 @@
|
||||
#define DALI_TIMEOUT 50 // DALI backward frame receive timeout (ms)
|
||||
#endif
|
||||
|
||||
//#define DALI_LIGHT_COLOR_SUPPORT
|
||||
|
||||
//#define DALI_DEBUG
|
||||
#ifndef DALI_DEBUG_PIN
|
||||
#define DALI_DEBUG_PIN 4 // Debug GPIO
|
||||
@ -154,6 +157,7 @@ struct DALI {
|
||||
uint8_t dimmer[DALI_MAX_STORED];
|
||||
uint8_t web_dimmer[DALI_MAX_STORED];
|
||||
uint8_t target;
|
||||
uint8_t target_rgbwaf;
|
||||
uint8_t device_type;
|
||||
bool allow_light;
|
||||
bool last_power;
|
||||
@ -192,23 +196,17 @@ uint32_t DaliMirekToKelvin(uint32_t mirek) {
|
||||
|
||||
/*-------------------------------------------------------------------------------------------*/
|
||||
|
||||
uint32_t DaliTarget2Address(void) {
|
||||
uint32_t DaliTarget2Address(uint32_t target) {
|
||||
// 1..64 = Short address
|
||||
// 101..116 = Group address
|
||||
// Others = Broadcast
|
||||
if ((Dali->target >= 1) && (Dali->target <= 64)) { // 1 .. 64
|
||||
Dali->target -= 1; // Short address
|
||||
Dali->target <<= 1;
|
||||
if ((target >= 1) && (target <= 64)) { // 1 .. 64
|
||||
return (target -1) << 1; // Short address: 0b00000000 .. 0b01111110
|
||||
}
|
||||
else if ((Dali->target >= 101) && (Dali->target <= 116)) { // 101 .. 116
|
||||
Dali->target -= 101;
|
||||
Dali->target <<= 1;
|
||||
Dali->target |= 0x80; // Group address
|
||||
else if ((target >= 101) && (target <= 116)) { // 101 .. 116
|
||||
return ((target -101) << 1) | 0x80; // Group address: 0b10000000 .. 0b10011110
|
||||
}
|
||||
else { // Others
|
||||
Dali->target = DALI_BROADCAST_DP; // Broadcast address
|
||||
}
|
||||
return Dali->target &0xFE; // Direct Arc Power Control command
|
||||
return DALI_BROADCAST_DP; // Broadcast address: 0b11111110
|
||||
}
|
||||
|
||||
/*
|
||||
@ -544,6 +542,25 @@ bool DaliSetPowerOnLevel(uint32_t adr, uint32_t v) {
|
||||
return DaliSetValue(adr, DALI_102_QUERY_POWER_ON_LEVEL, DALI_102_SET_POWER_ON_LEVEL, v);
|
||||
}
|
||||
|
||||
int DaliQueryExtendedVersionNumber(uint32_t adr, uint32_t device_type) {
|
||||
DaliSendData(DALI_102_ENABLE_DEVICE_TYPE_X, device_type); // Enable Extended command
|
||||
return DaliSendWaitResponse(adr, 255); // DALI_xxx_QUERY_EXTENDED_VERSION_NUMBER
|
||||
}
|
||||
|
||||
#ifdef DALI_LIGHT_COLOR_SUPPORT
|
||||
uint32_t DaliQueryRGBWAF(uint32_t adr) {
|
||||
uint32_t rgbwaf_channels = 0;
|
||||
if (DaliQueryExtendedVersionNumber(adr, 8) >= 0) { // Colour device
|
||||
DaliSendData(DALI_102_ENABLE_DEVICE_TYPE_X, 8); // Enable Extended command
|
||||
int result = DaliSendWaitResponse(adr, DALI_209_QUERY_COLOUR_TYPE_FEATURES);
|
||||
if (result >= 0) {
|
||||
rgbwaf_channels = (result >> 5) & 0x07; // RGBWAF channels in bits 5..7
|
||||
}
|
||||
}
|
||||
return rgbwaf_channels;
|
||||
}
|
||||
#endif // DALI_LIGHT_COLOR_SUPPORT
|
||||
|
||||
/*-------------------------------------------------------------------------------------------*/
|
||||
|
||||
uint32_t DaliGearPresent(void) {
|
||||
@ -690,13 +707,14 @@ uint32_t DaliCommission(uint8_t init_arg) {
|
||||
delay(100);
|
||||
DaliSendData(DALI_102_TERMINATE, 0x00); // Terminate the DALI_102_INITIALISE command
|
||||
|
||||
uint32_t address = DALI_BROADCAST_DP;
|
||||
#ifdef USE_LIGHT
|
||||
DaliInitLight();
|
||||
uint32_t address = (Settings->sbflag1.dali_light) ? DaliTarget2Address() : DALI_BROADCAST_DP; // DaliLight 1
|
||||
DaliSendData(address, Dali->power[0]); // Restore lights
|
||||
#else
|
||||
DaliSendData(DALI_BROADCAST_DP, Dali->power[0]); // Restore lights
|
||||
if (Settings->sbflag1.dali_light) { // DaliLight 1
|
||||
address = DaliTarget2Address(Dali->target);
|
||||
}
|
||||
#endif // USE_LIGHT
|
||||
DaliSendData(address, Dali->power[0]); // Restore lights
|
||||
return cnt;
|
||||
}
|
||||
|
||||
@ -735,7 +753,7 @@ void DaliLoop(void) {
|
||||
|
||||
bool show_response = true;
|
||||
#ifdef USE_LIGHT
|
||||
if (Dali->allow_light && (DaliTarget2Address() == Dali->address)) {
|
||||
if (Dali->allow_light && (DaliTarget2Address(Dali->target) == Dali->address)) {
|
||||
if (Settings->sbflag1.dali_light) { // DaliLight 1
|
||||
uint8_t dim_old = changeUIntScale(Dali->last_dimmer, 0, 254, 0, 100);
|
||||
uint8_t dim_new = changeUIntScale(Dali->dimmer[index], 0, 254, 0, 100);
|
||||
@ -779,9 +797,40 @@ bool DaliSetChannels(void) {
|
||||
if (Dali->light_sync) { // Block local loop
|
||||
Dali->light_sync = false;
|
||||
} else {
|
||||
uint8_t value = ((uint8_t*)XdrvMailbox.data)[0];
|
||||
if (255 == value) { value = 254; } // Max Dali value
|
||||
DaliSendData(DaliTarget2Address(), value);
|
||||
uint8_t *cur_col = (uint8_t*)XdrvMailbox.data;
|
||||
// cur_col[0] = Red, cur_col[1] = Green, cur_col[2] = Blue, cur_col[3] = Warm = Amber, cur_col[4] = Cold = White
|
||||
for (uint32_t i = 0; i < 5; i++) {
|
||||
if (255 == cur_col[i]) { cur_col[1] = 254; } // Max Dali value
|
||||
}
|
||||
uint32_t adr = DaliTarget2Address(Dali->target);
|
||||
|
||||
#ifdef DALI_LIGHT_COLOR_SUPPORT
|
||||
if (Dali->target_rgbwaf > 0) { // Colour control
|
||||
if (!DaliSetDTR(0, adr, 0x7F)) { return true; } // Linked Channel control
|
||||
DaliSendData(DALI_102_ENABLE_DEVICE_TYPE_X, 8); // Enable Extended command
|
||||
DaliSendData(adr, DALI_209_SET_TEMPORARY_RGBWAF_CONTROL);
|
||||
|
||||
if (!DaliSetDTR(0, adr, cur_col[0])) { return true; } // DALI Red
|
||||
if (!DaliSetDTR(1, adr, cur_col[1])) { return true; } // DALI Green
|
||||
if (!DaliSetDTR(2, adr, cur_col[2])) { return true; } // DALI Blue
|
||||
DaliSendData(DALI_102_ENABLE_DEVICE_TYPE_X, 8); // Enable Extended command
|
||||
DaliSendData(adr, DALI_209_SET_TEMPORARY_RGB_DIMLEVEL);
|
||||
|
||||
if (Dali->target_rgbwaf > 3) {
|
||||
if (!DaliSetDTR(0, adr, cur_col[4])) { return true; } // DALI While
|
||||
if (!DaliSetDTR(1, adr, cur_col[3])) { return true; } // DALI Amber
|
||||
if (!DaliSetDTR(2, adr, 255)) { return true; } // DALI Freecolour - no change
|
||||
DaliSendData(DALI_102_ENABLE_DEVICE_TYPE_X, 8); // Enable Extended command
|
||||
DaliSendData(adr, DALI_209_SET_TEMPORARY_WAF_DIMLEVEL);
|
||||
}
|
||||
|
||||
DaliSendData(DALI_102_ENABLE_DEVICE_TYPE_X, 8); // Enable Extended command
|
||||
DaliSendData(adr, DALI_209_ACTIVATE);
|
||||
return true;
|
||||
}
|
||||
#endif // DALI_LIGHT_COLOR_SUPPORT
|
||||
|
||||
DaliSendData(adr, cur_col[0]); // DAPC command - dim level
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -854,6 +903,14 @@ bool DaliInit(uint32_t function) {
|
||||
Settings->light_correction = 0; // Use Dali light correction
|
||||
UpdateDevicesPresent(1);
|
||||
TasmotaGlobal.light_type = LT_SERIAL1; // Single channel
|
||||
|
||||
#ifdef DALI_LIGHT_COLOR_SUPPORT
|
||||
Dali->target_rgbwaf = DaliQueryRGBWAF(DaliTarget2Address(Dali->target));
|
||||
if (Dali->target_rgbwaf > 0) {
|
||||
TasmotaGlobal.light_type = LT_RGB; // RGB channel (TBD)
|
||||
}
|
||||
#endif // DALI_LIGHT_COLOR_SUPPORT
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
@ -939,6 +996,9 @@ void CmndDaliTarget(void) {
|
||||
(XdrvMailbox.payload == 0)) {
|
||||
Dali->target = XdrvMailbox.payload;
|
||||
}
|
||||
#ifdef DALI_LIGHT_COLOR_SUPPORT
|
||||
Dali->target_rgbwaf = DaliQueryRGBWAF(DaliTarget2Address(Dali->target));
|
||||
#endif // DALI_LIGHT_COLOR_SUPPORT
|
||||
ResponseCmndNumber(Dali->target);
|
||||
}
|
||||
|
||||
@ -968,14 +1028,7 @@ void CmndDaliPower(void) {
|
||||
XdrvMailbox.payload = Dali->dimmer[index];
|
||||
}
|
||||
}
|
||||
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);
|
||||
DaliSendData(DaliTarget2Address(XdrvMailbox.index), XdrvMailbox.payload);
|
||||
}
|
||||
}
|
||||
ResponseDali(index);
|
||||
@ -996,14 +1049,7 @@ void CmndDaliDimmer(void) {
|
||||
((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);
|
||||
DaliSendData(DaliTarget2Address(XdrvMailbox.index), dimmer);
|
||||
}
|
||||
}
|
||||
ResponseDali(index);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user