feat(gateway): enhance DALI command handling with mirroring and new target types
This commit is contained in:
@@ -18,6 +18,8 @@ constexpr const char* kTag = "gateway_controller";
|
||||
constexpr size_t kMaxNameBytes = 32;
|
||||
constexpr uint8_t kDaliShortAddressCount = 64;
|
||||
constexpr uint8_t kDaliSceneCount = 16;
|
||||
constexpr uint8_t kDaliCmdOff = 0x00;
|
||||
constexpr uint8_t kDaliCmdRecallMax = 0x05;
|
||||
constexpr TickType_t kMaintenancePollTicks = pdMS_TO_TICKS(20);
|
||||
|
||||
class LockGuard {
|
||||
@@ -558,7 +560,7 @@ void GatewayController::dispatchCommand(const std::vector<uint8_t>& command) {
|
||||
}
|
||||
case 0x07:
|
||||
case 0x08:
|
||||
dali_domain_.sendRaw(gateway_id, addr, data);
|
||||
sendRawAndMirror(gateway_id, addr, data);
|
||||
break;
|
||||
case 0x09: {
|
||||
const auto ids = gatewayIds();
|
||||
@@ -575,20 +577,20 @@ void GatewayController::dispatchCommand(const std::vector<uint8_t>& command) {
|
||||
break;
|
||||
case 0x10:
|
||||
case 0x11:
|
||||
dali_domain_.sendRaw(gateway_id, resolveInternalGroupRawAddress(gateway_id, addr), data);
|
||||
sendRawAndMirror(gateway_id, resolveInternalGroupRawAddress(gateway_id, addr), data);
|
||||
break;
|
||||
case 0x12:
|
||||
if (addr == 0xff && data >= 0x10 && data <= 0x1f) {
|
||||
const uint8_t scene_id = static_cast<uint8_t>(data - 0x10);
|
||||
if (!executeScene(gateway_id, shortAddressFromRaw(addr), scene_id)) {
|
||||
dali_domain_.sendRaw(gateway_id, addr, data);
|
||||
sendRawAndMirror(gateway_id, addr, data);
|
||||
}
|
||||
} else {
|
||||
dali_domain_.sendRaw(gateway_id, resolveInternalGroupRawAddress(gateway_id, addr), data);
|
||||
sendRawAndMirror(gateway_id, resolveInternalGroupRawAddress(gateway_id, addr), data);
|
||||
}
|
||||
break;
|
||||
case 0x13:
|
||||
dali_domain_.sendExtRaw(gateway_id, resolveInternalGroupRawAddress(gateway_id, addr), data);
|
||||
sendExtRawAndMirror(gateway_id, resolveInternalGroupRawAddress(gateway_id, addr), data);
|
||||
break;
|
||||
case 0x14: {
|
||||
const auto result = dali_domain_.queryRaw(gateway_id, resolveInternalGroupRawAddress(gateway_id, addr), data);
|
||||
@@ -645,7 +647,7 @@ void GatewayController::dispatchCommand(const std::vector<uint8_t>& command) {
|
||||
const uint8_t b = command[7];
|
||||
const int target = shortAddressFromRaw(resolveInternalGroupRawAddress(gateway_id, addr));
|
||||
if (r == 0 && g == 0 && b == 0) {
|
||||
dali_domain_.off(gateway_id, target);
|
||||
offAndMirror(gateway_id, target);
|
||||
} else {
|
||||
dali_domain_.setColourRGB(gateway_id, target, r, g, b);
|
||||
}
|
||||
@@ -755,6 +757,48 @@ void GatewayController::handleDaliRawFrame(const DaliRawFrame& frame) {
|
||||
publishPayload(frame.gateway_id, {0x01, frame.gateway_id, addr, data});
|
||||
}
|
||||
|
||||
bool GatewayController::sendRawAndMirror(uint8_t gateway_id, uint8_t raw_addr, uint8_t command) {
|
||||
const bool sent = dali_domain_.sendRaw(gateway_id, raw_addr, command);
|
||||
if (sent) {
|
||||
cache_.mirrorDaliCommand(gateway_id, raw_addr, command);
|
||||
}
|
||||
return sent;
|
||||
}
|
||||
|
||||
bool GatewayController::sendExtRawAndMirror(uint8_t gateway_id, uint8_t raw_addr,
|
||||
uint8_t command) {
|
||||
const bool sent = dali_domain_.sendExtRaw(gateway_id, raw_addr, command);
|
||||
if (sent) {
|
||||
cache_.mirrorDaliCommand(gateway_id, raw_addr, command);
|
||||
}
|
||||
return sent;
|
||||
}
|
||||
|
||||
bool GatewayController::setBrightAndMirror(uint8_t gateway_id, int dec_address, uint8_t level) {
|
||||
const bool sent = dali_domain_.setBright(gateway_id, dec_address, level);
|
||||
if (sent) {
|
||||
cache_.mirrorDaliCommand(gateway_id, rawArcAddressFromDec(dec_address), level);
|
||||
}
|
||||
return sent;
|
||||
}
|
||||
|
||||
bool GatewayController::offAndMirror(uint8_t gateway_id, int dec_address) {
|
||||
const bool sent = dali_domain_.off(gateway_id, dec_address);
|
||||
if (sent) {
|
||||
cache_.mirrorDaliCommand(gateway_id, rawCommandAddressFromDec(dec_address), kDaliCmdOff);
|
||||
}
|
||||
return sent;
|
||||
}
|
||||
|
||||
bool GatewayController::onAndMirror(uint8_t gateway_id, int dec_address) {
|
||||
const bool sent = dali_domain_.on(gateway_id, dec_address);
|
||||
if (sent) {
|
||||
cache_.mirrorDaliCommand(gateway_id, rawCommandAddressFromDec(dec_address),
|
||||
kDaliCmdRecallMax);
|
||||
}
|
||||
return sent;
|
||||
}
|
||||
|
||||
uint8_t GatewayController::resolveInternalGroupRawAddress(uint8_t gateway_id, uint8_t raw_addr) {
|
||||
if (raw_addr < 0x80 || raw_addr > 0x9f) {
|
||||
return raw_addr;
|
||||
@@ -808,6 +852,26 @@ int GatewayController::internalGroupDecTargetAddress(uint8_t target_type, uint8_
|
||||
return 127;
|
||||
}
|
||||
|
||||
uint8_t GatewayController::rawArcAddressFromDec(int dec_address) {
|
||||
if (dec_address >= 0 && dec_address < 64) {
|
||||
return static_cast<uint8_t>(dec_address * 2);
|
||||
}
|
||||
if (dec_address >= 64 && dec_address < 80) {
|
||||
return static_cast<uint8_t>(0x80 + (dec_address - 64) * 2);
|
||||
}
|
||||
return 0xfe;
|
||||
}
|
||||
|
||||
uint8_t GatewayController::rawCommandAddressFromDec(int dec_address) {
|
||||
if (dec_address >= 0 && dec_address < 64) {
|
||||
return static_cast<uint8_t>(dec_address * 2 + 1);
|
||||
}
|
||||
if (dec_address >= 64 && dec_address < 80) {
|
||||
return static_cast<uint8_t>(0x80 + (dec_address - 64) * 2 + 1);
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
int GatewayController::shortAddressFromRaw(uint8_t raw_addr) {
|
||||
return raw_addr / 2;
|
||||
}
|
||||
@@ -859,9 +923,9 @@ bool GatewayController::executeScene(uint8_t gateway_id, int short_address, uint
|
||||
return false;
|
||||
}
|
||||
if (scene_data.brightness <= 0) {
|
||||
dali_domain_.off(gateway_id, short_address);
|
||||
offAndMirror(gateway_id, short_address);
|
||||
} else {
|
||||
dali_domain_.setBright(gateway_id, short_address, scene_data.brightness);
|
||||
setBrightAndMirror(gateway_id, short_address, scene_data.brightness);
|
||||
}
|
||||
if (scene_data.color_mode == 0) {
|
||||
int kelvin = scene_data.data1 * 256 + scene_data.data2;
|
||||
@@ -877,7 +941,7 @@ bool GatewayController::executeScene(uint8_t gateway_id, int short_address, uint
|
||||
dali_domain_.setColourRGB(gateway_id, short_address, scene_data.data1, scene_data.data2,
|
||||
scene_data.data3);
|
||||
} else if (scene_data.brightness <= 0) {
|
||||
dali_domain_.off(gateway_id, short_address);
|
||||
offAndMirror(gateway_id, short_address);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -912,9 +976,9 @@ bool GatewayController::executeGroup(uint8_t gateway_id, uint8_t group_id) {
|
||||
if (!group_data.enabled) {
|
||||
return false;
|
||||
}
|
||||
return dali_domain_.on(gateway_id,
|
||||
internalGroupDecTargetAddress(group_data.target_type,
|
||||
group_data.target_value));
|
||||
return onAndMirror(gateway_id,
|
||||
internalGroupDecTargetAddress(group_data.target_type,
|
||||
group_data.target_value));
|
||||
}
|
||||
|
||||
void GatewayController::handleGatewayNameCommand(uint8_t gateway_id,
|
||||
|
||||
Reference in New Issue
Block a user