diff --git a/include/dali_define.hpp b/include/dali_define.hpp index 8dd86a2..e39736a 100644 --- a/include/dali_define.hpp +++ b/include/dali_define.hpp @@ -194,19 +194,19 @@ #define DALI_CMD_DT1_STORE_DTR_AS_EMERGENCY_LEVEL 0xE9 #define DALI_CMD_DT1_STORE_DTR_AS_DELAY_TIME_HIGH 0xEA #define DALI_CMD_DT1_STORE_DTR_AS_DELAY_TIME_LOW 0xEB -#define DALI_CMD_DT1_STORE_DTR_AS_PROLONG_TIME 0xEC -#define DALI_CMD_DT1_STORE_DTR_AS_RATED_DURATION 0xED -#define DALI_CMD_DT1_STORE_DTR_AS_EMERGENCY_MIN_LEVEL 0xEE -#define DALI_CMD_DT1_STORE_DTR_AS_EMERGENCY_MAX_LEVEL 0xEF +#define DALI_CMD_DT1_STORE_FUNCTION_TEST_INTERVAL 0xEC +#define DALI_CMD_DT1_STORE_DURATION_TEST_INTERVAL 0xED +#define DALI_CMD_DT1_STORE_TEST_EXECUTION_TIMEOUT 0xEE +#define DALI_CMD_DT1_STORE_PROLONG_TIME 0xEF #define DALI_CMD_DT1_START_IDENTIFICATION 0xF0 -#define DALI_CMD_DT1_QUERY_EMERGENCY_LEVEL 0xF1 -#define DALI_CMD_DT1_QUERY_EMERGENCY_MIN_LEVEL 0xF2 -#define DALI_CMD_DT1_QUERY_EMERGENCY_MAX_LEVEL 0xF3 -#define DALI_CMD_DT1_QUERY_PROLONG_TIME 0xF4 -#define DALI_CMD_DT1_QUERY_FUNCTION_TEST_INTERVAL 0xF5 -#define DALI_CMD_DT1_QUERY_DURATION_TEST_INTERVAL 0xF6 -#define DALI_CMD_DT1_QUERY_DURATION_TEST_RESULT 0xF7 -#define DALI_CMD_DT1_QUERY_LAMP_EMERGENCY_TIME 0xF8 +#define DALI_CMD_DT1_QUERY_BATTERY_CHARGE 0xF1 +#define DALI_CMD_DT1_QUERY_TEST_TIMING 0xF2 +#define DALI_CMD_DT1_QUERY_DURATION_TEST_RESULT 0xF3 +#define DALI_CMD_DT1_QUERY_LAMP_EMERGENCY_TIME 0xF4 +#define DALI_CMD_DT1_QUERY_LAMP_TOTAL_OPERATION_TIME 0xF5 +#define DALI_CMD_DT1_QUERY_EMERGENCY_LEVEL 0xF6 +#define DALI_CMD_DT1_QUERY_EMERGENCY_MIN_LEVEL 0xF7 +#define DALI_CMD_DT1_QUERY_EMERGENCY_MAX_LEVEL 0xF8 #define DALI_CMD_DT1_QUERY_RATED_DURATION 0xF9 #define DALI_CMD_DT1_QUERY_EMERGENCY_MODE 0xFA #define DALI_CMD_DT1_QUERY_FEATURE 0xFB diff --git a/include/dt1.hpp b/include/dt1.hpp index 5f30707..9d2f728 100644 --- a/include/dt1.hpp +++ b/include/dt1.hpp @@ -10,6 +10,7 @@ struct DT1TestStatusDetailed { std::optional emergencyStatus; std::optional emergencyMode; std::optional feature; + std::optional deviceStatus; bool testInProgress = false; bool lampFailure = false; bool batteryFailure = false; @@ -18,6 +19,26 @@ struct DT1TestStatusDetailed { bool testDone = false; bool identifyActive = false; bool physicalSelectionActive = false; + bool circuitFailure = false; + bool batteryDurationFailure = false; + bool emergencyLampFailure = false; + bool functionTestMaxDelayExceeded = false; + bool durationTestMaxDelayExceeded = false; + bool functionTestFailed = false; + bool durationTestFailed = false; + bool functionTestResultValid = false; + bool durationTestResultValid = false; + bool batteryFullyCharged = false; + bool functionTestPending = false; + bool durationTestPending = false; + bool restModeActive = false; + bool normalModeActive = false; + bool emergencyModeActive = false; + bool extendedEmergencyModeActive = false; + bool hardwiredInhibitActive = false; + bool hardwiredSwitchOn = false; + bool supportsAutoTest = false; + bool supportsAdjustableEmergencyLevel = false; }; class DaliDT1DeviceStatus { @@ -60,6 +81,63 @@ class DaliDT1EmergencyStatus { bool bit(int mask) const { return (raw_ & mask) != 0; } }; +class DaliDT1FailureStatus { + public: + explicit DaliDT1FailureStatus(int raw) : raw_(raw & 0xFF) {} + + int raw() const { return raw_; } + bool circuitFailure() const { return bit(0x01); } + bool batteryDurationFailure() const { return bit(0x02); } + bool batteryFailure() const { return bit(0x04); } + bool emergencyLampFailure() const { return bit(0x08); } + bool functionTestMaxDelayExceeded() const { return bit(0x10); } + bool durationTestMaxDelayExceeded() const { return bit(0x20); } + bool functionTestFailed() const { return bit(0x40); } + bool durationTestFailed() const { return bit(0x80); } + + private: + int raw_ = 0; + bool bit(int mask) const { return (raw_ & mask) != 0; } +}; + +class DaliDT1EmergencyMode { + public: + explicit DaliDT1EmergencyMode(int raw) : raw_(raw & 0xFF) {} + + int raw() const { return raw_; } + bool restModeActive() const { return bit(0x01); } + bool normalModeActive() const { return bit(0x02); } + bool emergencyModeActive() const { return bit(0x04); } + bool extendedEmergencyModeActive() const { return bit(0x08); } + bool functionTestInProgress() const { return bit(0x10); } + bool durationTestInProgress() const { return bit(0x20); } + bool hardwiredInhibitActive() const { return bit(0x40); } + bool hardwiredSwitchOn() const { return bit(0x80); } + + private: + int raw_ = 0; + bool bit(int mask) const { return (raw_ & mask) != 0; } +}; + +class DaliDT1Features { + public: + explicit DaliDT1Features(int raw) : raw_(raw & 0xFF) {} + + int raw() const { return raw_; } + bool integralEmergencyControlGear() const { return bit(0x01); } + bool maintainedControlGear() const { return bit(0x02); } + bool switchedMaintainedControlGear() const { return bit(0x04); } + bool autoTestCapability() const { return bit(0x08); } + bool adjustableEmergencyLevel() const { return bit(0x10); } + bool hardwiredInhibitSupported() const { return bit(0x20); } + bool physicalSelectionSupported() const { return bit(0x40); } + bool relightInRestModeSupported() const { return bit(0x80); } + + private: + int raw_ = 0; + bool bit(int mask) const { return (raw_ & mask) != 0; } +}; + class DaliDT1 { public: explicit DaliDT1(DaliBase& base); @@ -93,7 +171,9 @@ class DaliDT1 { bool storeTestDelayTimeLowByte(int a, int lowByte); bool storeFunctionTestIntervalDays(int a, int days); bool storeDurationTestIntervalWeeks(int a, int weeks); + bool storeTestExecutionTimeoutDays(int a, int days); bool storeTestDelayTime16(int a, int quartersOfHour); + bool storeProlongTimeHalfMinutes(int a, int halfMinutes); bool storeProlongTimeMinutes(int a, int minutes); bool storeRatedDurationMinutes(int a, int minutes); bool storeEmergencyMinLevel(int a, int level); @@ -105,18 +185,34 @@ class DaliDT1 { const std::optional& dtr1 = std::nullopt); std::optional getExtendedVersionDT1(int a); + std::optional getBatteryChargeLevel(int a); + std::optional getTestTiming(int a, int selector); + std::optional getFunctionTestDelayHighByte(int a); + std::optional getFunctionTestDelayLowByte(int a); + std::optional getDurationTestDelayHighByte(int a); + std::optional getDurationTestDelayLowByte(int a); std::optional getEmergencyLevel(int a); std::optional getEmergencyMinLevel(int a); std::optional getEmergencyMaxLevel(int a); + std::optional getProlongTimeHalfMinutes(int a); std::optional getProlongTimeMinutes(int a); std::optional getFunctionTestIntervalDays(int a); std::optional getDurationTestIntervalWeeks(int a); + std::optional getTestExecutionTimeoutDays(int a); + std::optional getDurationTestResultRaw(int a); std::optional getDurationTestResult(int a); + std::optional getLampEmergencyTimeHours(int a); std::optional getLampEmergencyTimeMinutes(int a); + std::optional getLampTotalOperationTime4HourUnits(int a); + std::optional getLampTotalOperationTimeHours(int a); + std::optional getRatedDurationRaw(int a); std::optional getRatedDurationMinutes(int a); std::optional getDeviceStatus(int a); std::optional getEmergencyStatusDecoded(int a); + std::optional getFailureStatusDecoded(int a); + std::optional getEmergencyModeDecoded(int a); + std::optional getFeatureDecoded(int a); private: DaliBase& base_; @@ -124,6 +220,8 @@ class DaliDT1 { bool enable(); static int addrOf(int a); bool send(int a, int code); + bool sendWithDTR(int a, int code, int value); std::optional query(int a, int code); + std::optional queryTiming(int a, int selector); }; diff --git a/src/dt1.cpp b/src/dt1.cpp index ce1bcb9..b3133d0 100644 --- a/src/dt1.cpp +++ b/src/dt1.cpp @@ -14,6 +14,11 @@ int DaliDT1::addrOf(int a) { return a * 2 + 1; } bool DaliDT1::send(int a, int code) { return enable() && base_.sendExtCmd(addrOf(a), code); } +bool DaliDT1::sendWithDTR(int a, int code, int value) { + return base_.setDTR(value & 0xFF) && enable() && + base_.sendExtCmd(addrOf(a), code); +} + std::optional DaliDT1::query(int a, int code) { if (!enable()) return std::nullopt; const auto v = base_.queryCmd(static_cast(addrOf(a)), static_cast(code)); @@ -21,6 +26,11 @@ std::optional DaliDT1::query(int a, int code) { return v; } +std::optional DaliDT1::queryTiming(int a, int selector) { + if (!base_.setDTR(selector & 0xFF)) return std::nullopt; + return query(a, DALI_CMD_DT1_QUERY_TEST_TIMING); +} + bool DaliDT1::enableDT1() { return enable(); } bool DaliDT1::startDT1Test(int a, int t) { @@ -39,30 +49,75 @@ std::optional DaliDT1::getDT1FailureStatus(int a) { std::optional DaliDT1::getDT1Status(int a) { return query(a, DALI_CMD_DT1_QUERY_STATUS); } std::optional DaliDT1::getDT1SelfTestStatus(int a) { - const auto ret = getDT1FailureStatus(a); + const auto ret = getDT1EmergencyMode(a); if (!ret.has_value()) return std::nullopt; - const bool inProgress = (ret.value() & 0x01) != 0; + const bool inProgress = (ret.value() & 0x10) != 0 || (ret.value() & 0x20) != 0; return inProgress ? 1 : 0; } std::optional DaliDT1::getDT1TestStatusDetailed(int a) { DT1TestStatusDetailed result; - result.failureStatus = getDT1FailureStatus(a); - result.emergencyStatus = getDT1Status(a); - result.emergencyMode = getDT1EmergencyMode(a); - result.feature = getDT1Feature(a); + const auto failure = getFailureStatusDecoded(a); + const auto emergencyStatus = getEmergencyStatusDecoded(a); + const auto emergencyMode = getEmergencyModeDecoded(a); + const auto feature = getFeatureDecoded(a); + const auto deviceStatus = getDeviceStatus(a); - if (!result.failureStatus.has_value()) return std::nullopt; + if (!failure.has_value()) return std::nullopt; - const int failure = result.failureStatus.value(); - result.testInProgress = (failure & 0x01) != 0; - result.lampFailure = (failure & 0x02) != 0; - result.batteryFailure = (failure & 0x04) != 0; - result.functionTestActive = (failure & 0x08) != 0; - result.durationTestActive = (failure & 0x10) != 0; - result.testDone = (failure & 0x20) != 0; - result.identifyActive = (failure & 0x40) != 0; - result.physicalSelectionActive = (failure & 0x80) != 0; + result.failureStatus = failure->raw(); + if (emergencyStatus.has_value()) result.emergencyStatus = emergencyStatus->raw(); + if (emergencyMode.has_value()) result.emergencyMode = emergencyMode->raw(); + if (feature.has_value()) result.feature = feature->raw(); + if (deviceStatus.has_value()) result.deviceStatus = deviceStatus->raw(); + + result.testInProgress = + emergencyMode.has_value() && + (emergencyMode->functionTestInProgress() || emergencyMode->durationTestInProgress()); + result.lampFailure = failure->emergencyLampFailure() || + (deviceStatus.has_value() && deviceStatus->lampFailure()); + result.batteryFailure = failure->batteryFailure() || failure->batteryDurationFailure(); + result.functionTestActive = + emergencyMode.has_value() && emergencyMode->functionTestInProgress(); + result.durationTestActive = + emergencyMode.has_value() && emergencyMode->durationTestInProgress(); + result.testDone = + (emergencyStatus.has_value() && emergencyStatus->functionTestResultValid()) || + (emergencyStatus.has_value() && emergencyStatus->durationTestResultValid()); + result.identifyActive = + emergencyStatus.has_value() && emergencyStatus->identificationActive(); + result.physicalSelectionActive = + emergencyStatus.has_value() && emergencyStatus->physicallySelected(); + result.circuitFailure = failure->circuitFailure(); + result.batteryDurationFailure = failure->batteryDurationFailure(); + result.emergencyLampFailure = failure->emergencyLampFailure(); + result.functionTestMaxDelayExceeded = failure->functionTestMaxDelayExceeded(); + result.durationTestMaxDelayExceeded = failure->durationTestMaxDelayExceeded(); + result.functionTestFailed = failure->functionTestFailed(); + result.durationTestFailed = failure->durationTestFailed(); + result.functionTestResultValid = + emergencyStatus.has_value() && emergencyStatus->functionTestResultValid(); + result.durationTestResultValid = + emergencyStatus.has_value() && emergencyStatus->durationTestResultValid(); + result.batteryFullyCharged = + emergencyStatus.has_value() && emergencyStatus->batteryFullyCharged(); + result.functionTestPending = + emergencyStatus.has_value() && emergencyStatus->functionTestRequestPending(); + result.durationTestPending = + emergencyStatus.has_value() && emergencyStatus->durationTestRequestPending(); + result.restModeActive = emergencyMode.has_value() && emergencyMode->restModeActive(); + result.normalModeActive = emergencyMode.has_value() && emergencyMode->normalModeActive(); + result.emergencyModeActive = + emergencyMode.has_value() && emergencyMode->emergencyModeActive(); + result.extendedEmergencyModeActive = + emergencyMode.has_value() && emergencyMode->extendedEmergencyModeActive(); + result.hardwiredInhibitActive = + emergencyMode.has_value() && emergencyMode->hardwiredInhibitActive(); + result.hardwiredSwitchOn = + emergencyMode.has_value() && emergencyMode->hardwiredSwitchOn(); + result.supportsAutoTest = feature.has_value() && feature->autoTestCapability(); + result.supportsAdjustableEmergencyLevel = + feature.has_value() && feature->adjustableEmergencyLevel(); return result; } @@ -108,28 +163,32 @@ bool DaliDT1::resetTestResults(int a) { return resetLampTime(a); } bool DaliDT1::storeEmergencyLevel(int a, int level) { const int v = std::clamp(level, 0, 254); - return enable() && base_.setDTR(v) && - base_.sendExtCmd(addrOf(a), DALI_CMD_DT1_STORE_DTR_AS_EMERGENCY_LEVEL); + return sendWithDTR(a, DALI_CMD_DT1_STORE_DTR_AS_EMERGENCY_LEVEL, v); } bool DaliDT1::storeTestDelayTimeHighByte(int a, int highByte) { const int v = std::clamp(highByte, 0, 255); - return enable() && base_.setDTR(v) && - base_.sendExtCmd(addrOf(a), DALI_CMD_DT1_STORE_DTR_AS_DELAY_TIME_HIGH); + return sendWithDTR(a, DALI_CMD_DT1_STORE_DTR_AS_DELAY_TIME_HIGH, v); } bool DaliDT1::storeTestDelayTimeLowByte(int a, int lowByte) { const int v = std::clamp(lowByte, 0, 255); - return enable() && base_.setDTR(v) && - base_.sendExtCmd(addrOf(a), DALI_CMD_DT1_STORE_DTR_AS_DELAY_TIME_LOW); + return sendWithDTR(a, DALI_CMD_DT1_STORE_DTR_AS_DELAY_TIME_LOW, v); } bool DaliDT1::storeFunctionTestIntervalDays(int a, int days) { - return storeTestDelayTimeHighByte(a, days); + const int v = std::clamp(days, 0, 255); + return sendWithDTR(a, DALI_CMD_DT1_STORE_FUNCTION_TEST_INTERVAL, v); } bool DaliDT1::storeDurationTestIntervalWeeks(int a, int weeks) { - return storeTestDelayTimeLowByte(a, weeks); + const int v = std::clamp(weeks, 0, 97); + return sendWithDTR(a, DALI_CMD_DT1_STORE_DURATION_TEST_INTERVAL, v); +} + +bool DaliDT1::storeTestExecutionTimeoutDays(int a, int days) { + const int v = std::clamp(days, 0, 255); + return sendWithDTR(a, DALI_CMD_DT1_STORE_TEST_EXECUTION_TIMEOUT, v); } bool DaliDT1::storeTestDelayTime16(int a, int quartersOfHour) { @@ -139,38 +198,30 @@ bool DaliDT1::storeTestDelayTime16(int a, int quartersOfHour) { return storeTestDelayTimeHighByte(a, hi) && storeTestDelayTimeLowByte(a, lo); } +bool DaliDT1::storeProlongTimeHalfMinutes(int a, int halfMinutes) { + const int v = std::clamp(halfMinutes, 0, 255); + return sendWithDTR(a, DALI_CMD_DT1_STORE_PROLONG_TIME, v); +} + bool DaliDT1::storeProlongTimeMinutes(int a, int minutes) { - const int v = std::clamp(minutes, 0, 255); - return enable() && base_.setDTR(v) && - base_.sendExtCmd(addrOf(a), DALI_CMD_DT1_STORE_DTR_AS_PROLONG_TIME); + const int v = std::clamp(minutes, 0, 127) * 2; + return storeProlongTimeHalfMinutes(a, v); } -bool DaliDT1::storeRatedDurationMinutes(int a, int minutes) { - const int v = std::clamp(minutes, 0, 255); - return enable() && base_.setDTR(v) && - base_.sendExtCmd(addrOf(a), DALI_CMD_DT1_STORE_DTR_AS_RATED_DURATION); -} +bool DaliDT1::storeRatedDurationMinutes(int a, int minutes) { return false; } -bool DaliDT1::storeEmergencyMinLevel(int a, int level) { - const int v = std::clamp(level, 0, 254); - return enable() && base_.setDTR(v) && - base_.sendExtCmd(addrOf(a), DALI_CMD_DT1_STORE_DTR_AS_EMERGENCY_MIN_LEVEL); -} +bool DaliDT1::storeEmergencyMinLevel(int a, int level) { return false; } -bool DaliDT1::storeEmergencyMaxLevel(int a, int level) { - const int v = std::clamp(level, 0, 254); - return enable() && base_.setDTR(v) && - base_.sendExtCmd(addrOf(a), DALI_CMD_DT1_STORE_DTR_AS_EMERGENCY_MAX_LEVEL); -} +bool DaliDT1::storeEmergencyMaxLevel(int a, int level) { return false; } bool DaliDT1::startIdentification(int a) { return send(a, DALI_CMD_DT1_START_IDENTIFICATION); } bool DaliDT1::performDTRSelectedFunction(int a, const std::optional& dtr0, const std::optional& dtr1) { - if (!enable()) return false; if (dtr0.has_value() && !base_.setDTR(dtr0.value() & 0xFF)) return false; if (dtr1.has_value() && !base_.setDTR1(dtr1.value() & 0xFF)) return false; + if (!enable()) return false; return base_.sendExtCmd(addrOf(a), DALI_CMD_DT1_PERFORM_DTR_SELECTED_FUNCTION); } @@ -178,6 +229,22 @@ std::optional DaliDT1::getExtendedVersionDT1(int a) { return query(a, DALI_CMD_DT1_QUERY_EXTENDED_VERSION); } +std::optional DaliDT1::getBatteryChargeLevel(int a) { + return query(a, DALI_CMD_DT1_QUERY_BATTERY_CHARGE); +} + +std::optional DaliDT1::getTestTiming(int a, int selector) { + return queryTiming(a, selector); +} + +std::optional DaliDT1::getFunctionTestDelayHighByte(int a) { return queryTiming(a, 0x00); } + +std::optional DaliDT1::getFunctionTestDelayLowByte(int a) { return queryTiming(a, 0x01); } + +std::optional DaliDT1::getDurationTestDelayHighByte(int a) { return queryTiming(a, 0x02); } + +std::optional DaliDT1::getDurationTestDelayLowByte(int a) { return queryTiming(a, 0x03); } + std::optional DaliDT1::getEmergencyLevel(int a) { return query(a, DALI_CMD_DT1_QUERY_EMERGENCY_LEVEL); } std::optional DaliDT1::getEmergencyMinLevel(int a) { @@ -188,30 +255,64 @@ std::optional DaliDT1::getEmergencyMaxLevel(int a) { return query(a, DALI_CMD_DT1_QUERY_EMERGENCY_MAX_LEVEL); } +std::optional DaliDT1::getProlongTimeHalfMinutes(int a) { return queryTiming(a, 0x07); } + std::optional DaliDT1::getProlongTimeMinutes(int a) { - return query(a, DALI_CMD_DT1_QUERY_PROLONG_TIME); + const auto raw = getProlongTimeHalfMinutes(a); + if (!raw.has_value()) return std::nullopt; + return (raw.value() + 1) / 2; } std::optional DaliDT1::getFunctionTestIntervalDays(int a) { - return query(a, DALI_CMD_DT1_QUERY_FUNCTION_TEST_INTERVAL); + return queryTiming(a, 0x04); } std::optional DaliDT1::getDurationTestIntervalWeeks(int a) { - return query(a, DALI_CMD_DT1_QUERY_DURATION_TEST_INTERVAL); + return queryTiming(a, 0x05); } -std::optional DaliDT1::getDurationTestResult(int a) { +std::optional DaliDT1::getTestExecutionTimeoutDays(int a) { return queryTiming(a, 0x06); } + +std::optional DaliDT1::getDurationTestResultRaw(int a) { return query(a, DALI_CMD_DT1_QUERY_DURATION_TEST_RESULT); } -std::optional DaliDT1::getLampEmergencyTimeMinutes(int a) { +std::optional DaliDT1::getDurationTestResult(int a) { + const auto raw = getDurationTestResultRaw(a); + if (!raw.has_value()) return std::nullopt; + return raw.value() * 2; +} + +std::optional DaliDT1::getLampEmergencyTimeHours(int a) { return query(a, DALI_CMD_DT1_QUERY_LAMP_EMERGENCY_TIME); } -std::optional DaliDT1::getRatedDurationMinutes(int a) { +std::optional DaliDT1::getLampEmergencyTimeMinutes(int a) { + const auto hours = getLampEmergencyTimeHours(a); + if (!hours.has_value()) return std::nullopt; + return hours.value() * 60; +} + +std::optional DaliDT1::getLampTotalOperationTime4HourUnits(int a) { + return query(a, DALI_CMD_DT1_QUERY_LAMP_TOTAL_OPERATION_TIME); +} + +std::optional DaliDT1::getLampTotalOperationTimeHours(int a) { + const auto raw = getLampTotalOperationTime4HourUnits(a); + if (!raw.has_value()) return std::nullopt; + return raw.value() * 4; +} + +std::optional DaliDT1::getRatedDurationRaw(int a) { return query(a, DALI_CMD_DT1_QUERY_RATED_DURATION); } +std::optional DaliDT1::getRatedDurationMinutes(int a) { + const auto raw = getRatedDurationRaw(a); + if (!raw.has_value()) return std::nullopt; + return raw.value() * 2; +} + std::optional DaliDT1::getDeviceStatus(int a) { if (!enable()) return std::nullopt; const auto raw = base_.queryCmd(static_cast(addrOf(a)), DALI_CMD_QUERY_STATUS); @@ -224,3 +325,21 @@ std::optional DaliDT1::getEmergencyStatusDecoded(int a) if (!v.has_value()) return std::nullopt; return DaliDT1EmergencyStatus(v.value()); } + +std::optional DaliDT1::getFailureStatusDecoded(int a) { + const auto v = getDT1FailureStatus(a); + if (!v.has_value()) return std::nullopt; + return DaliDT1FailureStatus(v.value()); +} + +std::optional DaliDT1::getEmergencyModeDecoded(int a) { + const auto v = getDT1EmergencyMode(a); + if (!v.has_value()) return std::nullopt; + return DaliDT1EmergencyMode(v.value()); +} + +std::optional DaliDT1::getFeatureDecoded(int a) { + const auto v = getDT1Feature(a); + if (!v.has_value()) return std::nullopt; + return DaliDT1Features(v.value()); +} diff --git a/src/dt5.cpp b/src/dt5.cpp index ce32171..436228f 100644 --- a/src/dt5.cpp +++ b/src/dt5.cpp @@ -42,7 +42,7 @@ bool DaliDT5::switchOffInternalPullUp(int a) { bool DaliDT5::storePhysicalMinimum(int a, int level) { const int value = std::clamp(level, 0, 254); - return enable() && base_.setDTR(value) && + return base_.setDTR(value) && enable() && base_.sendExtCmd(addrOf(a), DALI_CMD_DT5_STORE_DTR_AS_PHYSICAL_MINIMUM); } diff --git a/src/dt6.cpp b/src/dt6.cpp index ac881ca..de96136 100644 --- a/src/dt6.cpp +++ b/src/dt6.cpp @@ -49,7 +49,7 @@ bool DaliDT6::selectDimmingCurve(int a, int curve) { bool DaliDT6::storeFastFadeTime(int a, int value) { const int clamped = std::clamp(value, 0, 27); - return enable() && base_.setDTR(clamped) && + return base_.setDTR(clamped) && enable() && base_.sendExtCmd(addrOf(a), DALI_CMD_DT6_STORE_DTR_AS_FAST_FADE_TIME); }