feat(gateway): enhance DALI host activity tracking and presence management

Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
Tony
2026-05-26 22:21:36 +08:00
parent f922993d2f
commit 865bf8425a
9 changed files with 441 additions and 39 deletions
@@ -759,6 +759,86 @@ GatewayCacheDaliAddressState GatewayCache::daliAddressState(uint8_t gateway_id,
return ensureDaliAddressStateLocked(gateway_id, short_address);
}
GatewayCacheDaliPresence GatewayCache::daliAddressPresence(uint8_t gateway_id,
uint8_t short_address) {
LockGuard guard(lock_);
if (short_address >= 64) {
return GatewayCacheDaliPresence::kUnknown;
}
if (const auto it = dali_presence_.find(gateway_id); it != dali_presence_.end()) {
return it->second[short_address];
}
return GatewayCacheDaliPresence::kUnknown;
}
void GatewayCache::markDaliAddressPresence(uint8_t gateway_id, uint8_t short_address,
GatewayCacheDaliPresence presence) {
LockGuard guard(lock_);
markDaliAddressPresenceLocked(gateway_id, short_address, presence);
}
std::optional<GatewayCacheDaliTarget> GatewayCache::decodeDaliTarget(uint8_t raw_addr) {
return DecodeDaliTarget(raw_addr);
}
std::vector<uint8_t> GatewayCache::reconciliationAddresses(
uint8_t gateway_id, std::optional<GatewayCacheDaliTarget> target) {
LockGuard guard(lock_);
std::vector<uint8_t> addresses;
auto presence = [&](uint8_t short_address) {
if (const auto it = dali_presence_.find(gateway_id); it != dali_presence_.end()) {
return it->second[short_address];
}
return GatewayCacheDaliPresence::kUnknown;
};
auto add_if_known_online = [&](uint8_t short_address) {
if (short_address < 64 && presence(short_address) == GatewayCacheDaliPresence::kOnline) {
addresses.push_back(short_address);
}
};
if (!target.has_value()) {
for (uint8_t short_address = 0; short_address < 64; ++short_address) {
add_if_known_online(short_address);
}
return addresses;
}
switch (target->kind) {
case GatewayCacheDaliTargetKind::kShortAddress:
if (target->value < 64 && presence(target->value) != GatewayCacheDaliPresence::kOffline) {
addresses.push_back(target->value);
}
break;
case GatewayCacheDaliTargetKind::kGroup: {
if (target->value >= 16) {
break;
}
const uint16_t bit = static_cast<uint16_t>(1U << target->value);
auto [states_it, inserted] = dali_states_.try_emplace(gateway_id);
if (inserted) {
loadDaliStateStoreLocked(gateway_id, states_it->second);
}
for (uint8_t short_address = 0; short_address < states_it->second.size(); ++short_address) {
const auto& state = states_it->second[short_address];
if (state.group_mask_known && (state.group_mask & bit) != 0) {
add_if_known_online(short_address);
}
}
break;
}
case GatewayCacheDaliTargetKind::kBroadcast:
for (uint8_t short_address = 0; short_address < 64; ++short_address) {
add_if_known_online(short_address);
}
break;
default:
break;
}
return addresses;
}
GatewayCacheDaliRuntimeStatus GatewayCache::daliGroupStatus(uint8_t gateway_id,
uint8_t group_id) {
LockGuard guard(lock_);
@@ -1535,6 +1615,20 @@ bool GatewayCache::shouldTrackUpdateFlagsLocked() const {
return config_.cache_enabled && config_.reconciliation_enabled;
}
void GatewayCache::markDaliAddressPresenceLocked(uint8_t gateway_id, uint8_t short_address,
GatewayCacheDaliPresence presence) {
if (short_address >= 64) {
return;
}
auto& states = dali_presence_[gateway_id];
const auto previous = states[short_address];
states[short_address] = presence;
if (previous != presence) {
ESP_LOGD(kTag, "presence gateway=%u short=%u state=%u", gateway_id, short_address,
static_cast<unsigned>(presence));
}
}
GatewayCacheDaliAddressState& GatewayCache::ensureDaliAddressStateLocked(uint8_t gateway_id,
uint8_t short_address) {
auto [it, inserted] = dali_states_.try_emplace(gateway_id);