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
+15 -1
View File
@@ -91,6 +91,11 @@ enum class Dt8SceneStoreColorMode {
rgbcw, rgbcw,
}; };
enum class Dt8PreferredColorType {
xy,
rgbwaf,
};
class DaliDT8 { class DaliDT8 {
public: public:
explicit DaliDT8(DaliBase& base); explicit DaliDT8(DaliBase& base);
@@ -139,6 +144,10 @@ class DaliDT8 {
std::optional<int> getColourRaw(int a, int type); std::optional<int> getColourRaw(int a, int type);
std::vector<double> getColour(int a); std::vector<double> getColour(int a);
bool setColourRGB(int addr, int r, int g, int b); bool setColourRGB(int addr, int r, int g, int b);
bool setTemporaryColourRGBPreferred(int addr, int r, int g, int b,
Dt8PreferredColorType preferredColorType = Dt8PreferredColorType::xy);
bool setColourRGBPreferred(int addr, int r, int g, int b,
Dt8PreferredColorType preferredColorType = Dt8PreferredColorType::xy);
bool setColourRGBW(int addr, int r, int g, int b, int w); 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 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, bool setColourRGBWAF(int addr, int r, int g, int b, int w, int amber, int freecolour,
@@ -203,11 +212,15 @@ class DaliDT8 {
bool storeSceneSnapshot(int address, int scene, int brightness, bool storeSceneSnapshot(int address, int scene, int brightness,
Dt8SceneStoreColorMode colorMode = Dt8SceneStoreColorMode::disabled, Dt8SceneStoreColorMode colorMode = Dt8SceneStoreColorMode::disabled,
int colorTemperature = 0, int red = 0, int green = 0, int blue = 0, int colorTemperature = 0, int red = 0, int green = 0, int blue = 0,
int white = 0, int amber = 0, int freecolour = 255, int white = 0, int amber = 0, int freecolour = 254,
int rgbwafControl = -1, int rgbwafControl = -1,
int gateway = -1); int gateway = -1);
bool storePowerOnLevelSnapshot(int address, int level); bool storePowerOnLevelSnapshot(int address, int level);
bool storePowerOnLevelColorSnapshot(int address, int level, int r, int g, int b,
Dt8PreferredColorType preferredColorType = Dt8PreferredColorType::xy);
bool storeSystemFailureLevelSnapshot(int address, int level); bool storeSystemFailureLevelSnapshot(int address, int level);
bool storeSystemFailureLevelColorSnapshot(int address, int level, int r, int g, int b,
Dt8PreferredColorType preferredColorType = Dt8PreferredColorType::xy);
std::optional<Dt8LevelColorReport> getPowerOnLevelColorReport(int a); std::optional<Dt8LevelColorReport> getPowerOnLevelColorReport(int a);
std::optional<Dt8LevelColorReport> getSystemFailureLevelColorReport(int a); std::optional<Dt8LevelColorReport> getSystemFailureLevelColorReport(int a);
bool storeColourTempLimitRaw(int a, int limitType, int mirek); bool storeColourTempLimitRaw(int a, int limitType, int mirek);
@@ -223,6 +236,7 @@ class DaliDT8 {
std::optional<int> getExtendedVersion(int a); std::optional<int> getExtendedVersion(int a);
private: private:
Dt8PreferredColorType resolvePreferredColorType(int address, Dt8PreferredColorType preferredColorType);
std::optional<Dt8LevelColorReport> buildLevelColorReport(int a, std::optional<int> level); std::optional<Dt8LevelColorReport> buildLevelColorReport(int a, std::optional<int> level);
std::vector<int> getReportRGBWAF(int a); std::vector<int> getReportRGBWAF(int a);
+69 -11
View File
@@ -6,6 +6,7 @@
#include <cmath> #include <cmath>
namespace { namespace {
constexpr int kRgbControl = 0x07;
constexpr int kRgbWControl = 0x0F; constexpr int kRgbWControl = 0x0F;
constexpr int kRgbCwControl = 0x1F; constexpr int kRgbCwControl = 0x1F;
constexpr int kRgbWafControl = 0x3F; constexpr int kRgbWafControl = 0x3F;
@@ -33,6 +34,25 @@ std::optional<int> kelvinFromMirek(std::optional<int> mirek) {
DaliDT8::DaliDT8(DaliBase& base) : base_(base) {} 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); } bool DaliDT8::enableDT8() { return base_.dtSelect(8); }
std::optional<ColorTypeFeature> DaliDT8::getColorTypeFeature(int a) { 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) { bool DaliDT8::setTemporaryRGBDimLevels(int a, int r, int g, int b) {
const int R = std::clamp(r, 0, 255); const int R = std::clamp(r, 0, 254);
const int G = std::clamp(g, 0, 255); const int G = std::clamp(g, 0, 254);
const int B = std::clamp(b, 0, 255); const int B = std::clamp(b, 0, 254);
const int addr = a * 2 + 1; const int addr = a * 2 + 1;
return base_.setDTR(R) && base_.setDTR1(G) && base_.setDTR2(B) && return base_.setDTR(R) && base_.setDTR1(G) && base_.setDTR2(B) &&
base_.dtSelect(8) && base_.sendExtCmd(addr, DALI_CMD_DT8_SET_TEMPORARY_RGB_DIM_LEVELS); 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) { bool DaliDT8::setTemporaryWAFDimLevels(int a, int w, int amber, int freecolour) {
const int W = std::clamp(w, 0, 255); const int W = std::clamp(w, 0, 254);
const int A = std::clamp(amber, 0, 255); const int A = std::clamp(amber, 0, 254);
const int F = std::clamp(freecolour, 0, 255); const int F = std::clamp(freecolour, 0, 254);
const int addr = a * 2 + 1; const int addr = a * 2 + 1;
return base_.setDTR(W) && base_.setDTR1(A) && base_.setDTR2(F) && return base_.setDTR(W) && base_.setDTR1(A) && base_.setDTR2(F) &&
base_.dtSelect(8) && base_.sendExtCmd(addr, DALI_CMD_DT8_SET_TEMPORARY_WAF_DIM_LEVELS); base_.dtSelect(8) && base_.sendExtCmd(addr, DALI_CMD_DT8_SET_TEMPORARY_WAF_DIM_LEVELS);
} }
bool DaliDT8::setTemporaryRGBWAFControl(int a, int control) { bool DaliDT8::setTemporaryRGBWAFControl(int a, int control) {
const int storedControl = std::clamp(control, 0, 254);
const int addr = a * 2 + 1; 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); 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) { 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)) { if (base_.setDTR(0xFF) && base_.setDTR1(0xFF) && base_.dtSelect(8) && base_.setDTRAsColourTemp(a)) {
return true; return true;
} }
@@ -345,12 +365,38 @@ bool DaliDT8::setColourRGB(int addr, int r, int g, int b) {
return setColour(addr, xy[0], xy[1]); 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) { 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) { 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, 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: { case Dt8SceneStoreColorMode::rgbw: {
const int control = rgbwafControl < 0 ? kRgbWControl : rgbwafControl; 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; break;
} }
case Dt8SceneStoreColorMode::rgbcw: { case Dt8SceneStoreColorMode::rgbcw: {
@@ -416,6 +462,12 @@ bool DaliDT8::storePowerOnLevelSnapshot(int address, int level) {
return base_.setDTR(storedLevel) && base_.dtSelect(8) && base_.storeDTRAsPoweredBright(address); 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) { bool DaliDT8::storeSystemFailureLevelSnapshot(int address, int level) {
const int storedLevel = std::clamp(level, 0, 254); const int storedLevel = std::clamp(level, 0, 254);
// DT SELECT is one-shot and SET DTR consumes any earlier selection. // 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); 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); } bool DaliDT8::activateTemporaryColour(int a) { return base_.dtSelect(8) && base_.activate(a); }
std::optional<int> DaliDT8::getPrimaryDimLevel(int a, int n) { std::optional<int> DaliDT8::getPrimaryDimLevel(int a, int n) {