Enhance DaliDT8: add support for color temperature handling and RGBWAF control adjustments

Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
Tony
2026-06-15 21:36:49 +08:00
parent 34d77aa9fe
commit 82e9c18b26
2 changed files with 73 additions and 15 deletions
+10 -2
View File
@@ -96,6 +96,11 @@ enum class Dt8PreferredColorType {
rgbwaf,
};
enum class Dt8ColorTemperatureWriteType {
colorTemperature,
rgbwaf,
};
enum class Dt8RgbwafControlMode {
channelControl = 0,
colorControl = 1,
@@ -162,9 +167,11 @@ class DaliDT8 {
bool setColourRGBPreferred(int addr, int r, int g, int b,
Dt8PreferredColorType preferredColorType = Dt8PreferredColorType::xy);
bool setTemporaryColourRGBWAPreferred(int addr, int r, int g, int b, int w, int amber,
Dt8PreferredColorType preferredColorType = Dt8PreferredColorType::rgbwaf);
Dt8PreferredColorType preferredColorType = Dt8PreferredColorType::rgbwaf,
int freecolour = 254);
bool setColourRGBWAPreferred(int addr, int r, int g, int b, int w, int amber,
Dt8PreferredColorType preferredColorType = Dt8PreferredColorType::rgbwaf);
Dt8PreferredColorType preferredColorType = Dt8PreferredColorType::rgbwaf,
int freecolour = 254);
bool setColourRGBW(int addr, int r, int g, int b, int w);
bool setColourRGBCW(int addr, int r, int g, int b, int coolWhite, int warmWhite);
bool setColourRGBWAF(int addr, int r, int g, int b, int w, int amber, int freecolour,
@@ -255,6 +262,7 @@ class DaliDT8 {
private:
Dt8PreferredColorType resolvePreferredColorType(int address, Dt8PreferredColorType preferredColorType);
Dt8ColorTemperatureWriteType resolveColorTemperatureWriteType(int address);
std::optional<Dt8LevelColorReport> buildLevelColorReport(int a, std::optional<int> level);
std::vector<int> getReportRGBWAF(int a);
+63 -13
View File
@@ -11,6 +11,8 @@ constexpr int kRgbWControl = 0x0F;
constexpr int kRgbWaControl = 0x1F;
constexpr int kRgbCwControl = 0x1F;
constexpr int kRgbWafControl = 0x3F;
constexpr int kCtFallbackWarmKelvin = 2700;
constexpr int kCtFallbackCoolKelvin = 6500;
int colourTempLimitQuerySelector(int limitType) {
switch (limitType & 0xFF) {
@@ -31,6 +33,15 @@ std::optional<int> kelvinFromMirek(std::optional<int> mirek) {
if (!mirek.has_value() || mirek.value() == 0) return std::nullopt;
return static_cast<int>(std::floor(1000000.0 / static_cast<double>(mirek.value())));
}
std::vector<int> rgbwafForColorTemperature(int kelvin) {
const int clamped = std::clamp(kelvin, kCtFallbackWarmKelvin, kCtFallbackCoolKelvin);
const double ratio = static_cast<double>(clamped - kCtFallbackWarmKelvin) /
static_cast<double>(kCtFallbackCoolKelvin - kCtFallbackWarmKelvin);
const int coolWhite = std::clamp(static_cast<int>(std::round(ratio * 254.0)), 0, 254);
const int warmWhite = std::clamp(254 - coolWhite, 0, 254);
return {0, 0, 0, coolWhite, warmWhite, 0};
}
} // namespace
DaliDT8::DaliDT8(DaliBase& base) : base_(base) {}
@@ -61,6 +72,22 @@ Dt8PreferredColorType DaliDT8::resolvePreferredColorType(
return preferredColorType;
}
Dt8ColorTemperatureWriteType DaliDT8::resolveColorTemperatureWriteType(int address) {
if (address < 0 || address > 63) return Dt8ColorTemperatureWriteType::colorTemperature;
const auto discovery = base_.discoverDeviceTypes(address);
if (!discovery.has_value()) return Dt8ColorTemperatureWriteType::colorTemperature;
if (std::find(discovery->types.begin(), discovery->types.end(), 8) ==
discovery->types.end()) {
return Dt8ColorTemperatureWriteType::colorTemperature;
}
const auto features = getColorTypeFeature(address);
if (!features.has_value()) return Dt8ColorTemperatureWriteType::colorTemperature;
if (features->ctCapable()) return Dt8ColorTemperatureWriteType::colorTemperature;
if (features->rgbwafCapable()) return Dt8ColorTemperatureWriteType::rgbwaf;
return Dt8ColorTemperatureWriteType::colorTemperature;
}
bool DaliDT8::enableDT8() { return base_.dtSelect(8); }
std::optional<ColorTypeFeature> DaliDT8::getColorTypeFeature(int a) {
@@ -122,9 +149,20 @@ bool DaliDT8::setColTempRaw(int a, int value) {
}
bool DaliDT8::setColorTemperature(int addr, int kelvin) {
int v = kelvin == 0 ? 1 : kelvin;
const int mirek = static_cast<int>(std::floor(1000000.0 / static_cast<double>(v)));
return setColTempRaw(addr, mirek);
const int k = kelvin <= 0 ? 1 : kelvin;
switch (resolveColorTemperatureWriteType(addr)) {
case Dt8ColorTemperatureWriteType::colorTemperature: {
const int mirek = static_cast<int>(std::floor(1000000.0 / static_cast<double>(k)));
return setColTempRaw(addr, mirek);
}
case Dt8ColorTemperatureWriteType::rgbwaf: {
const auto rgbwaf = rgbwafForColorTemperature(k);
return setTemporaryRGBWAFDimLevels(addr, rgbwaf[0], rgbwaf[1], rgbwaf[2], rgbwaf[3],
rgbwaf[4], rgbwaf[5], kRgbWafControl) &&
activateTemporaryColour(addr);
}
}
return false;
}
std::optional<int> DaliDT8::getColorTemperature(int a) {
@@ -210,12 +248,23 @@ bool DaliDT8::setTemporaryColourXY(int a, double x, double y) {
bool DaliDT8::setTemporaryColourTemperature(int a, int kelvin) {
int k = kelvin <= 0 ? 1 : kelvin;
const int mirek = static_cast<int>(std::floor(1000000.0 / static_cast<double>(k)));
const int addr = a * 2 + 1;
const int dtr = mirek & 0xFF;
const int dtr1 = (mirek >> 8) & 0xFF;
const int dec = addr / 2;
return base_.setDTR(dtr) && base_.setDTR1(dtr1) && base_.dtSelect(8) && base_.setDTRAsColourTemp(dec);
switch (resolveColorTemperatureWriteType(a)) {
case Dt8ColorTemperatureWriteType::colorTemperature: {
const int mirek = static_cast<int>(std::floor(1000000.0 / static_cast<double>(k)));
const int addr = a * 2 + 1;
const int dtr = mirek & 0xFF;
const int dtr1 = (mirek >> 8) & 0xFF;
const int dec = addr / 2;
return base_.setDTR(dtr) && base_.setDTR1(dtr1) && base_.dtSelect(8) &&
base_.setDTRAsColourTemp(dec);
}
case Dt8ColorTemperatureWriteType::rgbwaf: {
const auto rgbwaf = rgbwafForColorTemperature(k);
return setTemporaryRGBWAFDimLevels(a, rgbwaf[0], rgbwaf[1], rgbwaf[2], rgbwaf[3],
rgbwaf[4], rgbwaf[5], kRgbWafControl);
}
}
return false;
}
bool DaliDT8::setTemporaryPrimaryDimLevel(int a, int n, double level) {
@@ -419,17 +468,18 @@ bool DaliDT8::setColourRGBPreferred(int addr, int r, int g, int b,
}
bool DaliDT8::setTemporaryColourRGBWAPreferred(int addr, int r, int g, int b, int w, int amber,
Dt8PreferredColorType preferredColorType) {
Dt8PreferredColorType preferredColorType, int freecolour) {
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 W = std::clamp(w, 0, 255);
const int A = std::clamp(amber, 0, 255);
const int F = std::clamp(freecolour, 0, 255);
const auto resolved = resolvePreferredColorType(addr, preferredColorType);
switch (resolved) {
case Dt8PreferredColorType::rgbwaf:
return setTemporaryRGBWAFDimLevels(addr, R, G, B, W, A, 254, kRgbWaControl);
return setTemporaryRGBWAFDimLevels(addr, R, G, B, W, A, F, kRgbWaControl);
case Dt8PreferredColorType::xy: {
const auto xy = DaliColor::rgb2xy(static_cast<double>(R) / 255.0,
static_cast<double>(G) / 255.0,
@@ -441,8 +491,8 @@ bool DaliDT8::setTemporaryColourRGBWAPreferred(int addr, int r, int g, int b, in
}
bool DaliDT8::setColourRGBWAPreferred(int addr, int r, int g, int b, int w, int amber,
Dt8PreferredColorType preferredColorType) {
return setTemporaryColourRGBWAPreferred(addr, r, g, b, w, amber, preferredColorType) &&
Dt8PreferredColorType preferredColorType, int freecolour) {
return setTemporaryColourRGBWAPreferred(addr, r, g, b, w, amber, preferredColorType, freecolour) &&
activateTemporaryColour(addr);
}