Refactor DALI command handling: update DALI_DT1 and DALI_DT6 methods for improved command execution and status querying

This commit is contained in:
Tony
2026-05-01 04:39:17 +08:00
parent ba536768e4
commit 9f9628db39
5 changed files with 280 additions and 63 deletions
+168 -49
View File
@@ -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<int> DaliDT1::query(int a, int code) {
if (!enable()) return std::nullopt;
const auto v = base_.queryCmd(static_cast<uint8_t>(addrOf(a)), static_cast<uint8_t>(code));
@@ -21,6 +26,11 @@ std::optional<int> DaliDT1::query(int a, int code) {
return v;
}
std::optional<int> 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<int> DaliDT1::getDT1FailureStatus(int a) {
std::optional<int> DaliDT1::getDT1Status(int a) { return query(a, DALI_CMD_DT1_QUERY_STATUS); }
std::optional<int> 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<DT1TestStatusDetailed> 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<int>& dtr0,
const std::optional<int>& 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<int> DaliDT1::getExtendedVersionDT1(int a) {
return query(a, DALI_CMD_DT1_QUERY_EXTENDED_VERSION);
}
std::optional<int> DaliDT1::getBatteryChargeLevel(int a) {
return query(a, DALI_CMD_DT1_QUERY_BATTERY_CHARGE);
}
std::optional<int> DaliDT1::getTestTiming(int a, int selector) {
return queryTiming(a, selector);
}
std::optional<int> DaliDT1::getFunctionTestDelayHighByte(int a) { return queryTiming(a, 0x00); }
std::optional<int> DaliDT1::getFunctionTestDelayLowByte(int a) { return queryTiming(a, 0x01); }
std::optional<int> DaliDT1::getDurationTestDelayHighByte(int a) { return queryTiming(a, 0x02); }
std::optional<int> DaliDT1::getDurationTestDelayLowByte(int a) { return queryTiming(a, 0x03); }
std::optional<int> DaliDT1::getEmergencyLevel(int a) { return query(a, DALI_CMD_DT1_QUERY_EMERGENCY_LEVEL); }
std::optional<int> DaliDT1::getEmergencyMinLevel(int a) {
@@ -188,30 +255,64 @@ std::optional<int> DaliDT1::getEmergencyMaxLevel(int a) {
return query(a, DALI_CMD_DT1_QUERY_EMERGENCY_MAX_LEVEL);
}
std::optional<int> DaliDT1::getProlongTimeHalfMinutes(int a) { return queryTiming(a, 0x07); }
std::optional<int> 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<int> DaliDT1::getFunctionTestIntervalDays(int a) {
return query(a, DALI_CMD_DT1_QUERY_FUNCTION_TEST_INTERVAL);
return queryTiming(a, 0x04);
}
std::optional<int> DaliDT1::getDurationTestIntervalWeeks(int a) {
return query(a, DALI_CMD_DT1_QUERY_DURATION_TEST_INTERVAL);
return queryTiming(a, 0x05);
}
std::optional<int> DaliDT1::getDurationTestResult(int a) {
std::optional<int> DaliDT1::getTestExecutionTimeoutDays(int a) { return queryTiming(a, 0x06); }
std::optional<int> DaliDT1::getDurationTestResultRaw(int a) {
return query(a, DALI_CMD_DT1_QUERY_DURATION_TEST_RESULT);
}
std::optional<int> DaliDT1::getLampEmergencyTimeMinutes(int a) {
std::optional<int> DaliDT1::getDurationTestResult(int a) {
const auto raw = getDurationTestResultRaw(a);
if (!raw.has_value()) return std::nullopt;
return raw.value() * 2;
}
std::optional<int> DaliDT1::getLampEmergencyTimeHours(int a) {
return query(a, DALI_CMD_DT1_QUERY_LAMP_EMERGENCY_TIME);
}
std::optional<int> DaliDT1::getRatedDurationMinutes(int a) {
std::optional<int> DaliDT1::getLampEmergencyTimeMinutes(int a) {
const auto hours = getLampEmergencyTimeHours(a);
if (!hours.has_value()) return std::nullopt;
return hours.value() * 60;
}
std::optional<int> DaliDT1::getLampTotalOperationTime4HourUnits(int a) {
return query(a, DALI_CMD_DT1_QUERY_LAMP_TOTAL_OPERATION_TIME);
}
std::optional<int> DaliDT1::getLampTotalOperationTimeHours(int a) {
const auto raw = getLampTotalOperationTime4HourUnits(a);
if (!raw.has_value()) return std::nullopt;
return raw.value() * 4;
}
std::optional<int> DaliDT1::getRatedDurationRaw(int a) {
return query(a, DALI_CMD_DT1_QUERY_RATED_DURATION);
}
std::optional<int> DaliDT1::getRatedDurationMinutes(int a) {
const auto raw = getRatedDurationRaw(a);
if (!raw.has_value()) return std::nullopt;
return raw.value() * 2;
}
std::optional<DaliDT1DeviceStatus> DaliDT1::getDeviceStatus(int a) {
if (!enable()) return std::nullopt;
const auto raw = base_.queryCmd(static_cast<uint8_t>(addrOf(a)), DALI_CMD_QUERY_STATUS);
@@ -224,3 +325,21 @@ std::optional<DaliDT1EmergencyStatus> DaliDT1::getEmergencyStatusDecoded(int a)
if (!v.has_value()) return std::nullopt;
return DaliDT1EmergencyStatus(v.value());
}
std::optional<DaliDT1FailureStatus> DaliDT1::getFailureStatusDecoded(int a) {
const auto v = getDT1FailureStatus(a);
if (!v.has_value()) return std::nullopt;
return DaliDT1FailureStatus(v.value());
}
std::optional<DaliDT1EmergencyMode> DaliDT1::getEmergencyModeDecoded(int a) {
const auto v = getDT1EmergencyMode(a);
if (!v.has_value()) return std::nullopt;
return DaliDT1EmergencyMode(v.value());
}
std::optional<DaliDT1Features> DaliDT1::getFeatureDecoded(int a) {
const auto v = getDT1Feature(a);
if (!v.has_value()) return std::nullopt;
return DaliDT1Features(v.value());
}
+1 -1
View File
@@ -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);
}
+1 -1
View File
@@ -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);
}