feat(gateway): enhance DALI command handling with mirroring and new target types

This commit is contained in:
Tony
2026-05-02 03:19:02 +08:00
parent 639fdd860e
commit fa2eae87cf
4 changed files with 587 additions and 63 deletions
@@ -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,