Enhance DaliDT8: add support for preferred color type handling and temporary color operations

Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
Tony
2026-06-03 15:45:38 +08:00
parent d1cc27ae2a
commit 439a2078ba
2 changed files with 84 additions and 12 deletions
+69 -11
View File
@@ -6,6 +6,7 @@
#include <cmath>
namespace {
constexpr int kRgbControl = 0x07;
constexpr int kRgbWControl = 0x0F;
constexpr int kRgbCwControl = 0x1F;
constexpr int kRgbWafControl = 0x3F;
@@ -33,6 +34,25 @@ std::optional<int> kelvinFromMirek(std::optional<int> mirek) {
DaliDT8::DaliDT8(DaliBase& base) : base_(base) {}
Dt8PreferredColorType DaliDT8::resolvePreferredColorType(
int address, Dt8PreferredColorType preferredColorType) {
if (address < 0 || address > 63) return preferredColorType;
const auto features = getColorTypeFeature(address);
if (!features.has_value()) return preferredColorType;
switch (preferredColorType) {
case Dt8PreferredColorType::rgbwaf:
if (features->rgbwafCapable()) return Dt8PreferredColorType::rgbwaf;
if (features->xyCapable()) return Dt8PreferredColorType::xy;
break;
case Dt8PreferredColorType::xy:
if (features->xyCapable()) return Dt8PreferredColorType::xy;
if (features->rgbwafCapable()) return Dt8PreferredColorType::rgbwaf;
break;
}
return preferredColorType;
}
bool DaliDT8::enableDT8() { return base_.dtSelect(8); }
std::optional<ColorTypeFeature> DaliDT8::getColorTypeFeature(int a) {
@@ -203,26 +223,27 @@ bool DaliDT8::setTemporaryPrimaryDimLevel(int a, int n, double level) {
}
bool DaliDT8::setTemporaryRGBDimLevels(int a, int r, int g, int b) {
const int R = std::clamp(r, 0, 255);
const int G = std::clamp(g, 0, 255);
const int B = std::clamp(b, 0, 255);
const int R = std::clamp(r, 0, 254);
const int G = std::clamp(g, 0, 254);
const int B = std::clamp(b, 0, 254);
const int addr = a * 2 + 1;
return base_.setDTR(R) && base_.setDTR1(G) && base_.setDTR2(B) &&
base_.dtSelect(8) && base_.sendExtCmd(addr, DALI_CMD_DT8_SET_TEMPORARY_RGB_DIM_LEVELS);
}
bool DaliDT8::setTemporaryWAFDimLevels(int a, int w, int amber, int freecolour) {
const int W = std::clamp(w, 0, 255);
const int A = std::clamp(amber, 0, 255);
const int F = std::clamp(freecolour, 0, 255);
const int W = std::clamp(w, 0, 254);
const int A = std::clamp(amber, 0, 254);
const int F = std::clamp(freecolour, 0, 254);
const int addr = a * 2 + 1;
return base_.setDTR(W) && base_.setDTR1(A) && base_.setDTR2(F) &&
base_.dtSelect(8) && base_.sendExtCmd(addr, DALI_CMD_DT8_SET_TEMPORARY_WAF_DIM_LEVELS);
}
bool DaliDT8::setTemporaryRGBWAFControl(int a, int control) {
const int storedControl = std::clamp(control, 0, 254);
const int addr = a * 2 + 1;
return base_.setDTR(control & 0xFF) && base_.dtSelect(8) &&
return base_.setDTR(storedControl) && base_.dtSelect(8) &&
base_.sendExtCmd(addr, DALI_CMD_DT8_SET_TEMPORARY_RGBWAF_CONTROL);
}
@@ -233,7 +254,6 @@ bool DaliDT8::setTemporaryRGBWAFDimLevels(int a, int r, int g, int b, int w, int
}
bool DaliDT8::setTemporaryColourMask(int a) {
if (setTemporaryRGBDimLevels(a, 255, 255, 255)) return true;
if (base_.setDTR(0xFF) && base_.setDTR1(0xFF) && base_.dtSelect(8) && base_.setDTRAsColourTemp(a)) {
return true;
}
@@ -345,12 +365,38 @@ bool DaliDT8::setColourRGB(int addr, int r, int g, int b) {
return setColour(addr, xy[0], xy[1]);
}
bool DaliDT8::setTemporaryColourRGBPreferred(int addr, int r, int g, int b,
Dt8PreferredColorType preferredColorType) {
const int R = std::clamp(r, 0, 255);
const int G = std::clamp(g, 0, 255);
const int B = std::clamp(b, 0, 255);
const auto resolved = resolvePreferredColorType(addr, preferredColorType);
switch (resolved) {
case Dt8PreferredColorType::rgbwaf:
return setTemporaryRGBDimLevels(addr, R, G, B) && setTemporaryRGBWAFControl(addr, kRgbControl);
case Dt8PreferredColorType::xy: {
const auto xy = DaliColor::rgb2xy(static_cast<double>(R) / 255.0,
static_cast<double>(G) / 255.0,
static_cast<double>(B) / 255.0);
return setTemporaryColourXY(addr, xy[0], xy[1]);
}
}
return false;
}
bool DaliDT8::setColourRGBPreferred(int addr, int r, int g, int b,
Dt8PreferredColorType preferredColorType) {
return setTemporaryColourRGBPreferred(addr, r, g, b, preferredColorType) &&
activateTemporaryColour(addr);
}
bool DaliDT8::setColourRGBW(int addr, int r, int g, int b, int w) {
return setColourRGBWAF(addr, r, g, b, w, 255, 255, kRgbWControl);
return setColourRGBWAF(addr, r, g, b, w, 254, 254, kRgbWControl);
}
bool DaliDT8::setColourRGBCW(int addr, int r, int g, int b, int coolWhite, int warmWhite) {
return setColourRGBWAF(addr, r, g, b, coolWhite, warmWhite, 255, kRgbCwControl);
return setColourRGBWAF(addr, r, g, b, coolWhite, warmWhite, 254, kRgbCwControl);
}
bool DaliDT8::setColourRGBWAF(int addr, int r, int g, int b, int w, int amber, int freecolour,
@@ -391,7 +437,7 @@ bool DaliDT8::storeSceneSnapshot(int address, int scene, int brightness,
}
case Dt8SceneStoreColorMode::rgbw: {
const int control = rgbwafControl < 0 ? kRgbWControl : rgbwafControl;
if (!setTemporaryRGBWAFDimLevels(address, red, green, blue, white, 255, 255, control)) return false;
if (!setTemporaryRGBWAFDimLevels(address, red, green, blue, white, 254, 254, control)) return false;
break;
}
case Dt8SceneStoreColorMode::rgbcw: {
@@ -416,6 +462,12 @@ bool DaliDT8::storePowerOnLevelSnapshot(int address, int level) {
return base_.setDTR(storedLevel) && base_.dtSelect(8) && base_.storeDTRAsPoweredBright(address);
}
bool DaliDT8::storePowerOnLevelColorSnapshot(int address, int level, int r, int g, int b,
Dt8PreferredColorType preferredColorType) {
return setTemporaryColourRGBPreferred(address, r, g, b, preferredColorType) &&
storePowerOnLevelSnapshot(address, level);
}
bool DaliDT8::storeSystemFailureLevelSnapshot(int address, int level) {
const int storedLevel = std::clamp(level, 0, 254);
// DT SELECT is one-shot and SET DTR consumes any earlier selection.
@@ -423,6 +475,12 @@ bool DaliDT8::storeSystemFailureLevelSnapshot(int address, int level) {
base_.storeDTRAsSystemFailureLevel(address);
}
bool DaliDT8::storeSystemFailureLevelColorSnapshot(int address, int level, int r, int g, int b,
Dt8PreferredColorType preferredColorType) {
return setTemporaryColourRGBPreferred(address, r, g, b, preferredColorType) &&
storeSystemFailureLevelSnapshot(address, level);
}
bool DaliDT8::activateTemporaryColour(int a) { return base_.dtSelect(8) && base_.activate(a); }
std::optional<int> DaliDT8::getPrimaryDimLevel(int a, int n) {