From 84b3d29ed85ca36491cfda510499db01517af932 Mon Sep 17 00:00:00 2001 From: Tony Date: Wed, 29 Apr 2026 19:39:23 +0800 Subject: [PATCH] Add support for power-on and system failure level snapshots in DaliDT8 --- include/dt8.hpp | 17 +++++++++++++++++ src/dt8.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/include/dt8.hpp b/include/dt8.hpp index 60479aa..b55d7b8 100644 --- a/include/dt8.hpp +++ b/include/dt8.hpp @@ -66,6 +66,17 @@ struct SceneColorReport { bool hasColorTemperature() const { return colorTemperature.has_value(); } }; +struct Dt8LevelColorReport { + int level = 0; + int colorTypeValue = 0; + std::vector xy; + std::optional colorTemperature; + + ColorType colorType() const { return ColorType(colorTypeValue); } + bool hasXy() const { return xy.size() == 2; } + bool hasColorTemperature() const { return colorTemperature.has_value(); } +}; + enum class Dt8SceneStoreColorMode { disabled, colorTemperature, @@ -176,6 +187,10 @@ class DaliDT8 { 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 storePowerOnLevelSnapshot(int address, int level); + bool storeSystemFailureLevelSnapshot(int address, int level); + std::optional getPowerOnLevelColorReport(int a); + std::optional getSystemFailureLevelColorReport(int a); bool storeColourTempLimitRaw(int a, int limitType, int mirek); bool storeColourTempLimit(int a, int limitType, int kelvin); bool setGearAutoActivate(int a, bool enable); @@ -189,5 +204,7 @@ class DaliDT8 { std::optional getExtendedVersion(int a); private: + std::optional buildLevelColorReport(int a, std::optional level); + DaliBase& base_; }; diff --git a/src/dt8.cpp b/src/dt8.cpp index 110f47f..bb1a340 100644 --- a/src/dt8.cpp +++ b/src/dt8.cpp @@ -328,6 +328,19 @@ bool DaliDT8::storeSceneSnapshot(int address, int scene, int brightness, return base_.dtSelect(8) && base_.storeDTRAsSceneBright(address, sceneIndex); } +bool DaliDT8::storePowerOnLevelSnapshot(int address, int level) { + const int storedLevel = std::clamp(level, 0, 254); + // DT SELECT is one-shot and SET DTR consumes any earlier selection. + return base_.setDTR(storedLevel) && base_.dtSelect(8) && base_.storeDTRAsPoweredBright(address); +} + +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. + return base_.setDTR(storedLevel) && base_.dtSelect(8) && + base_.storeDTRAsSystemFailureLevel(address); +} + bool DaliDT8::activateTemporaryColour(int a) { return base_.dtSelect(8) && base_.activate(a); } std::optional DaliDT8::getPrimaryDimLevel(int a, int n) { @@ -452,6 +465,35 @@ std::vector DaliDT8::getSceneColor(int a, int sense) { return report->xy; } +std::optional DaliDT8::buildLevelColorReport(int a, std::optional level) { + if (!level.has_value() || level.value() == 255) return std::nullopt; + + Dt8LevelColorReport report; + report.level = level.value(); + report.colorTypeValue = getReportColourType(a).value_or(0); + + const ColorType colorType(report.colorTypeValue); + if (colorType.xy()) { + report.xy = getReportColour(a); + return report; + } + + if (colorType.ct()) { + report.colorTemperature = getReportColorTemperature(a); + return report; + } + + return report; +} + +std::optional DaliDT8::getPowerOnLevelColorReport(int a) { + return buildLevelColorReport(a, base_.getPowerOnLevel(a)); +} + +std::optional DaliDT8::getSystemFailureLevelColorReport(int a) { + return buildLevelColorReport(a, base_.getSystemFailureLevel(a)); +} + bool DaliDT8::storePrimaryTy(int a, int n, int ty) { int idx = std::clamp(n, 0, 5); int t = std::clamp(ty, 0, 65535);