From 4c20fc2ae39a3a32b32b92b46ee83ccd94f07185 Mon Sep 17 00:00:00 2001 From: Tony Date: Tue, 28 Apr 2026 19:08:55 +0800 Subject: [PATCH] Add support for scene snapshot storage with color mode handling in DaliDT8 --- include/dt8.hpp | 10 ++++++++++ src/dt8.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/include/dt8.hpp b/include/dt8.hpp index 376c50e..60479aa 100644 --- a/include/dt8.hpp +++ b/include/dt8.hpp @@ -66,6 +66,12 @@ struct SceneColorReport { bool hasColorTemperature() const { return colorTemperature.has_value(); } }; +enum class Dt8SceneStoreColorMode { + disabled, + colorTemperature, + rgb, +}; + class DaliDT8 { public: explicit DaliDT8(DaliBase& base); @@ -94,6 +100,7 @@ class DaliDT8 { bool setTemporaryRGBDimLevels(int a, int r, int g, int b); bool setTemporaryWAFDimLevels(int a, int w, int amber, int freecolour); bool setTemporaryRGBWAFControl(int a, int control); + bool setTemporaryColourMask(int a); bool copyReportToTemporary(int a); // Step commands @@ -166,6 +173,9 @@ class DaliDT8 { // Store / config bool storePrimaryTy(int a, int n, int ty); bool storePrimaryXY(int a, int n, double x, double y); + bool storeSceneSnapshot(int address, int scene, int brightness, + Dt8SceneStoreColorMode colorMode = Dt8SceneStoreColorMode::disabled, + int colorTemperature = 0, int red = 0, int green = 0, int blue = 0); bool storeColourTempLimitRaw(int a, int limitType, int mirek); bool storeColourTempLimit(int a, int limitType, int kelvin); bool setGearAutoActivate(int a, bool enable); diff --git a/src/dt8.cpp b/src/dt8.cpp index cf03707..110f47f 100644 --- a/src/dt8.cpp +++ b/src/dt8.cpp @@ -192,6 +192,15 @@ bool DaliDT8::setTemporaryRGBWAFControl(int a, int control) { base_.sendExtCmd(addr, DALI_CMD_DT8_SET_TEMPORARY_RGBWAF_CONTROL); } +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; + } + const int addr = DaliComm::toCmdAddr(a); + return setTemporaryColourXRaw(addr, 0xFFFF) && setTemporaryColourYRaw(addr, 0xFFFF); +} + bool DaliDT8::copyReportToTemporary(int a) { return base_.dtSelect(8) && base_.copyReportColourToTemp(a); } bool DaliDT8::stepXUp(int a) { @@ -287,6 +296,38 @@ std::vector DaliDT8::getColourRGB(int a) { return {rgb[0], rgb[1], rgb[2]}; } +bool DaliDT8::storeSceneSnapshot(int address, int scene, int brightness, + Dt8SceneStoreColorMode colorMode, int colorTemperature, int red, + int green, int blue) { + const int sceneBrightness = std::clamp(brightness, 0, 255); + const int sceneIndex = std::clamp(scene, 0, 15); + + if (sceneBrightness != 255) { + switch (colorMode) { + case Dt8SceneStoreColorMode::colorTemperature: + if (!setTemporaryColourTemperature(address, colorTemperature)) return false; + break; + case Dt8SceneStoreColorMode::rgb: { + const int r = std::clamp(red, 0, 255); + const int g = std::clamp(green, 0, 255); + const int b = std::clamp(blue, 0, 255); + const auto xy = DaliColor::rgb2xy(static_cast(r) / 255.0, + static_cast(g) / 255.0, + static_cast(b) / 255.0); + if (!setTemporaryColourXY(address, xy[0], xy[1])) return false; + break; + } + case Dt8SceneStoreColorMode::disabled: + if (!setTemporaryColourMask(address)) return false; + break; + } + } + + if (!base_.setDTR(sceneBrightness)) return false; + // DT SELECT is one-shot and SET DTR consumes any earlier selection. + return base_.dtSelect(8) && base_.storeDTRAsSceneBright(address, sceneIndex); +} + bool DaliDT8::activateTemporaryColour(int a) { return base_.dtSelect(8) && base_.activate(a); } std::optional DaliDT8::getPrimaryDimLevel(int a, int n) {