initial commit
This commit is contained in:
226
src/dt1.cpp
Normal file
226
src/dt1.cpp
Normal file
@@ -0,0 +1,226 @@
|
||||
#include "dt1.hpp"
|
||||
|
||||
#include "dali_define.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
DaliDT1::DaliDT1(DaliBase& base) : base_(base) {}
|
||||
|
||||
bool DaliDT1::enable() { return base_.dtSelect(1); }
|
||||
|
||||
int DaliDT1::addrOf(int a) { return a * 2 + 1; }
|
||||
|
||||
bool DaliDT1::send(int a, int code) { return 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));
|
||||
if (!v.has_value() || v.value() == 0xFF) return std::nullopt;
|
||||
return v;
|
||||
}
|
||||
|
||||
bool DaliDT1::enableDT1() { return enable(); }
|
||||
|
||||
bool DaliDT1::startDT1Test(int a, int t) {
|
||||
if (t != 1) return false;
|
||||
return send(a, DALI_CMD_DT1_START_FUNCTION_TEST);
|
||||
}
|
||||
|
||||
std::optional<int> DaliDT1::getDT1EmergencyMode(int a) { return query(a, DALI_CMD_DT1_QUERY_EMERGENCY_MODE); }
|
||||
|
||||
std::optional<int> DaliDT1::getDT1Feature(int a) { return query(a, DALI_CMD_DT1_QUERY_FEATURE); }
|
||||
|
||||
std::optional<int> DaliDT1::getDT1FailureStatus(int a) {
|
||||
return query(a, DALI_CMD_DT1_QUERY_FAILURE_STATUS);
|
||||
}
|
||||
|
||||
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);
|
||||
if (!ret.has_value()) return std::nullopt;
|
||||
const bool inProgress = (ret.value() & 0x01) != 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);
|
||||
|
||||
if (!result.failureStatus.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;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DaliDT1::performDT1Test(int a, int timeout) {
|
||||
if (!startDT1Test(a)) return false;
|
||||
for (int i = 0; i < timeout; i++) {
|
||||
const auto ret = getDT1SelfTestStatus(a);
|
||||
if (!ret.has_value()) return false;
|
||||
if (ret.value() == 0) return true;
|
||||
if (ret.value() != 1) return false;
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DaliDT1::rest(int a) { return send(a, DALI_CMD_DT1_REST); }
|
||||
|
||||
bool DaliDT1::inhibit(int a) { return send(a, DALI_CMD_DT1_INHIBIT); }
|
||||
|
||||
bool DaliDT1::reLightOrResetInhibit(int a) { return send(a, DALI_CMD_DT1_RE_LIGHT_RESET_INHIBIT); }
|
||||
|
||||
bool DaliDT1::startFunctionTestCmd(int a) { return send(a, DALI_CMD_DT1_START_FUNCTION_TEST); }
|
||||
|
||||
bool DaliDT1::startDurationTestCmd(int a) { return send(a, DALI_CMD_DT1_START_DURATION_TEST); }
|
||||
|
||||
bool DaliDT1::stopTest(int a) { return send(a, DALI_CMD_DT1_STOP_TEST); }
|
||||
|
||||
bool DaliDT1::resetFunctionTestDoneFlag(int a) {
|
||||
return send(a, DALI_CMD_DT1_RESET_FUNCTION_TEST_DONE_FLAG);
|
||||
}
|
||||
|
||||
bool DaliDT1::resetDurationTestDoneFlag(int a) {
|
||||
return send(a, DALI_CMD_DT1_RESET_DURATION_TEST_DONE_FLAG);
|
||||
}
|
||||
|
||||
bool DaliDT1::resetLampTime(int a) { return send(a, DALI_CMD_DT1_RESET_LAMP_TIME); }
|
||||
|
||||
bool DaliDT1::resetStatusFlags(int a) { return resetFunctionTestDoneFlag(a); }
|
||||
|
||||
bool DaliDT1::resetLampOperationTime(int a) { return resetDurationTestDoneFlag(a); }
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
bool DaliDT1::storeFunctionTestIntervalDays(int a, int days) {
|
||||
return storeTestDelayTimeHighByte(a, days);
|
||||
}
|
||||
|
||||
bool DaliDT1::storeDurationTestIntervalWeeks(int a, int weeks) {
|
||||
return storeTestDelayTimeLowByte(a, weeks);
|
||||
}
|
||||
|
||||
bool DaliDT1::storeTestDelayTime16(int a, int quartersOfHour) {
|
||||
const int v = std::clamp(quartersOfHour, 0, 0xFFFF);
|
||||
const int hi = (v >> 8) & 0xFF;
|
||||
const int lo = v & 0xFF;
|
||||
return storeTestDelayTimeHighByte(a, hi) && storeTestDelayTimeLowByte(a, lo);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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::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::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::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;
|
||||
return base_.sendExtCmd(addrOf(a), DALI_CMD_DT1_PERFORM_DTR_SELECTED_FUNCTION);
|
||||
}
|
||||
|
||||
std::optional<int> DaliDT1::getExtendedVersionDT1(int a) {
|
||||
return query(a, DALI_CMD_DT1_QUERY_EXTENDED_VERSION);
|
||||
}
|
||||
|
||||
std::optional<int> DaliDT1::getEmergencyLevel(int a) { return query(a, DALI_CMD_DT1_QUERY_EMERGENCY_LEVEL); }
|
||||
|
||||
std::optional<int> DaliDT1::getEmergencyMinLevel(int a) {
|
||||
return query(a, DALI_CMD_DT1_QUERY_EMERGENCY_MIN_LEVEL);
|
||||
}
|
||||
|
||||
std::optional<int> DaliDT1::getEmergencyMaxLevel(int a) {
|
||||
return query(a, DALI_CMD_DT1_QUERY_EMERGENCY_MAX_LEVEL);
|
||||
}
|
||||
|
||||
std::optional<int> DaliDT1::getProlongTimeMinutes(int a) {
|
||||
return query(a, DALI_CMD_DT1_QUERY_PROLONG_TIME);
|
||||
}
|
||||
|
||||
std::optional<int> DaliDT1::getFunctionTestIntervalDays(int a) {
|
||||
return query(a, DALI_CMD_DT1_QUERY_FUNCTION_TEST_INTERVAL);
|
||||
}
|
||||
|
||||
std::optional<int> DaliDT1::getDurationTestIntervalWeeks(int a) {
|
||||
return query(a, DALI_CMD_DT1_QUERY_DURATION_TEST_INTERVAL);
|
||||
}
|
||||
|
||||
std::optional<int> DaliDT1::getDurationTestResult(int a) {
|
||||
return query(a, DALI_CMD_DT1_QUERY_DURATION_TEST_RESULT);
|
||||
}
|
||||
|
||||
std::optional<int> DaliDT1::getLampEmergencyTimeMinutes(int a) {
|
||||
return query(a, DALI_CMD_DT1_QUERY_LAMP_EMERGENCY_TIME);
|
||||
}
|
||||
|
||||
std::optional<int> DaliDT1::getRatedDurationMinutes(int a) {
|
||||
return query(a, DALI_CMD_DT1_QUERY_RATED_DURATION);
|
||||
}
|
||||
|
||||
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);
|
||||
if (!raw.has_value()) return std::nullopt;
|
||||
return DaliDT1DeviceStatus(raw.value());
|
||||
}
|
||||
|
||||
std::optional<DaliDT1EmergencyStatus> DaliDT1::getEmergencyStatusDecoded(int a) {
|
||||
const auto v = getDT1Status(a);
|
||||
if (!v.has_value()) return std::nullopt;
|
||||
return DaliDT1EmergencyStatus(v.value());
|
||||
}
|
||||
Reference in New Issue
Block a user