feat(gateway): enhance DALI command handling with mirroring and new target types
This commit is contained in:
@@ -14,6 +14,15 @@ namespace {
|
||||
|
||||
constexpr const char* kTag = "gateway_cache";
|
||||
constexpr size_t kMaxNameBytes = 32;
|
||||
constexpr uint8_t kDaliRawBroadcastArc = 0xFE;
|
||||
constexpr uint8_t kDaliRawBroadcastCommand = 0xFF;
|
||||
constexpr uint8_t kDaliGroupRawMin = 0x80;
|
||||
constexpr uint8_t kDaliGroupRawMax = 0x9F;
|
||||
constexpr uint8_t kDaliCmdOff = 0x00;
|
||||
constexpr uint8_t kDaliCmdRecallMax = 0x05;
|
||||
constexpr uint8_t kDaliCmdRecallMin = 0x06;
|
||||
constexpr uint8_t kDaliCmdGoToSceneMin = 0x10;
|
||||
constexpr uint8_t kDaliCmdGoToSceneMax = 0x1F;
|
||||
constexpr uint8_t kDaliCmdReset = 0x20;
|
||||
constexpr uint8_t kDaliCmdStoreDtrAsMaxLevel = 0x2A;
|
||||
constexpr uint8_t kDaliCmdStoreDtrAsMinLevel = 0x2B;
|
||||
@@ -104,9 +113,17 @@ bool AnyFlagSet(const GatewayCacheChannelFlags& flags) {
|
||||
return flags.need_update_group || flags.need_update_scene || flags.need_update_settings;
|
||||
}
|
||||
|
||||
std::optional<uint8_t> DecodeShortAddress(uint8_t raw_addr) {
|
||||
if (raw_addr <= 0x7F && (raw_addr & 0x01) != 0) {
|
||||
return static_cast<uint8_t>(raw_addr >> 1);
|
||||
std::optional<GatewayCacheDaliTarget> DecodeDaliTarget(uint8_t raw_addr) {
|
||||
if (raw_addr <= 0x7F) {
|
||||
return GatewayCacheDaliTarget{GatewayCacheDaliTargetKind::kShortAddress,
|
||||
static_cast<uint8_t>(raw_addr >> 1)};
|
||||
}
|
||||
if (raw_addr >= kDaliGroupRawMin && raw_addr <= kDaliGroupRawMax) {
|
||||
return GatewayCacheDaliTarget{GatewayCacheDaliTargetKind::kGroup,
|
||||
static_cast<uint8_t>((raw_addr - kDaliGroupRawMin) >> 1)};
|
||||
}
|
||||
if (raw_addr == kDaliRawBroadcastArc || raw_addr == kDaliRawBroadcastCommand) {
|
||||
return GatewayCacheDaliTarget{GatewayCacheDaliTargetKind::kBroadcast, 0};
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
@@ -122,6 +139,7 @@ void ClearDaliState(GatewayCacheDaliAddressState& state) {
|
||||
state.group_mask = 0;
|
||||
state.scene_levels.fill(std::nullopt);
|
||||
state.settings = {};
|
||||
state.status = {};
|
||||
}
|
||||
|
||||
void ApplyObservedSettingsValue(GatewayCacheDaliSettingsSnapshot& settings, uint8_t command,
|
||||
@@ -577,6 +595,20 @@ GatewayCacheDaliAddressState GatewayCache::daliAddressState(uint8_t gateway_id,
|
||||
return ensureDaliAddressStateLocked(gateway_id, short_address);
|
||||
}
|
||||
|
||||
GatewayCacheDaliRuntimeStatus GatewayCache::daliGroupStatus(uint8_t gateway_id,
|
||||
uint8_t group_id) {
|
||||
LockGuard guard(lock_);
|
||||
if (group_id >= 16) {
|
||||
return {};
|
||||
}
|
||||
return ensureDaliGroupStatusLocked(gateway_id, group_id);
|
||||
}
|
||||
|
||||
GatewayCacheDaliRuntimeStatus GatewayCache::daliBroadcastStatus(uint8_t gateway_id) {
|
||||
LockGuard guard(lock_);
|
||||
return ensureDaliBroadcastStatusLocked(gateway_id);
|
||||
}
|
||||
|
||||
bool GatewayCache::setDaliGroupMask(uint8_t gateway_id, uint8_t short_address,
|
||||
std::optional<uint16_t> group_mask) {
|
||||
LockGuard guard(lock_);
|
||||
@@ -587,6 +619,7 @@ bool GatewayCache::setDaliGroupMask(uint8_t gateway_id, uint8_t short_address,
|
||||
auto& state = ensureDaliAddressStateLocked(gateway_id, short_address);
|
||||
state.group_mask_known = group_mask.has_value();
|
||||
state.group_mask = group_mask.value_or(0);
|
||||
refreshDaliAddressAggregateStatusLocked(gateway_id, state);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -664,62 +697,31 @@ bool GatewayCache::fullStateMirrorEnabled() const {
|
||||
return reconciliationEnabled() && config_.full_state_mirror_enabled;
|
||||
}
|
||||
|
||||
bool GatewayCache::mirrorDaliCommand(uint8_t gateway_id, uint8_t raw_addr, uint8_t command) {
|
||||
LockGuard guard(lock_);
|
||||
if (!config_.cache_enabled) {
|
||||
return false;
|
||||
}
|
||||
return mirrorDaliCommandLocked(gateway_id, raw_addr, command);
|
||||
}
|
||||
|
||||
bool GatewayCache::observeDaliCommand(uint8_t gateway_id, uint8_t raw_addr, uint8_t command,
|
||||
GatewayCacheRawFrameOrigin origin) {
|
||||
LockGuard guard(lock_);
|
||||
if (!shouldTrackUpdateFlagsLocked()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto& dtr_state = dtr_states_[gateway_id];
|
||||
if (raw_addr == kDaliCmdSetDtr0) {
|
||||
dtr_state.dtr0 = command;
|
||||
return false;
|
||||
}
|
||||
if (raw_addr == kDaliCmdSetDtr1) {
|
||||
dtr_state.dtr1 = command;
|
||||
return false;
|
||||
}
|
||||
if (raw_addr == kDaliCmdSetDtr2) {
|
||||
dtr_state.dtr2 = command;
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto detected = ClassifyDaliMutation(raw_addr, command);
|
||||
if (!AnyFlagSet(detected)) {
|
||||
if (!config_.cache_enabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ShouldMirrorObservedMutation(origin, priority_mode_)) {
|
||||
if (command == kDaliCmdReset) {
|
||||
if (const auto short_address = DecodeShortAddress(raw_addr); short_address.has_value()) {
|
||||
ClearDaliState(ensureDaliAddressStateLocked(gateway_id, *short_address));
|
||||
} else if (auto states = dali_states_.find(gateway_id); states != dali_states_.end()) {
|
||||
for (auto& state : states->second) {
|
||||
ClearDaliState(state);
|
||||
}
|
||||
}
|
||||
} else if (const auto short_address = DecodeShortAddress(raw_addr); short_address.has_value()) {
|
||||
auto& state = ensureDaliAddressStateLocked(gateway_id, *short_address);
|
||||
mirrorDaliCommandLocked(gateway_id, raw_addr, command);
|
||||
}
|
||||
|
||||
if (command >= kDaliCmdAddToGroupMin && command <= kDaliCmdRemoveFromGroupMax &&
|
||||
state.group_mask_known) {
|
||||
const uint16_t bit = static_cast<uint16_t>(1U << (command & 0x0F));
|
||||
if (command < (kDaliCmdAddToGroupMin + 16)) {
|
||||
state.group_mask |= bit;
|
||||
} else {
|
||||
state.group_mask &= static_cast<uint16_t>(~bit);
|
||||
}
|
||||
} else if (command >= kDaliCmdSetSceneMin && command < (kDaliCmdSetSceneMin + 16) &&
|
||||
dtr_state.dtr0.has_value()) {
|
||||
state.scene_levels[command - kDaliCmdSetSceneMin] = *dtr_state.dtr0;
|
||||
} else if (command >= (kDaliCmdSetSceneMin + 16) && command <= kDaliCmdRemoveSceneMax) {
|
||||
state.scene_levels[command - (kDaliCmdSetSceneMin + 16)] = 255U;
|
||||
} else if (command >= kDaliCmdStoreDtrAsMaxLevel && command <= kDaliCmdStoreDtrAsFadeRate &&
|
||||
dtr_state.dtr0.has_value()) {
|
||||
ApplyObservedSettingsValue(state.settings, command, *dtr_state.dtr0);
|
||||
}
|
||||
}
|
||||
if (!shouldTrackUpdateFlagsLocked()) {
|
||||
return false;
|
||||
}
|
||||
const auto detected = ClassifyDaliMutation(raw_addr, command);
|
||||
if (!AnyFlagSet(detected)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (origin != GatewayCacheRawFrameOrigin::kOutsideBus) {
|
||||
@@ -752,6 +754,394 @@ void GatewayCache::setPriorityMode(GatewayCachePriorityMode mode) {
|
||||
priority_mode_ = mode;
|
||||
}
|
||||
|
||||
uint32_t GatewayCache::nextDaliRuntimeRevisionLocked() {
|
||||
++dali_runtime_revision_;
|
||||
if (dali_runtime_revision_ == 0) {
|
||||
++dali_runtime_revision_;
|
||||
}
|
||||
return dali_runtime_revision_;
|
||||
}
|
||||
|
||||
bool GatewayCache::mirrorDaliCommandLocked(uint8_t gateway_id, uint8_t raw_addr,
|
||||
uint8_t command) {
|
||||
auto& dtr_state = dtr_states_[gateway_id];
|
||||
if (raw_addr == kDaliCmdSetDtr0) {
|
||||
dtr_state.dtr0 = command;
|
||||
return false;
|
||||
}
|
||||
if (raw_addr == kDaliCmdSetDtr1) {
|
||||
dtr_state.dtr1 = command;
|
||||
return false;
|
||||
}
|
||||
if (raw_addr == kDaliCmdSetDtr2) {
|
||||
dtr_state.dtr2 = command;
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto target = DecodeDaliTarget(raw_addr);
|
||||
if (!target.has_value()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool arc_power_frame = (raw_addr & 0x01) == 0;
|
||||
if (arc_power_frame) {
|
||||
if (command > 254) {
|
||||
return false;
|
||||
}
|
||||
GatewayCacheDaliRuntimeStatus status;
|
||||
status.actual_level = command;
|
||||
status.revision = nextDaliRuntimeRevisionLocked();
|
||||
applyDaliTargetRuntimeStatusLocked(gateway_id, *target, status);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (command == kDaliCmdReset) {
|
||||
clearDaliTargetStateLocked(gateway_id, *target, nextDaliRuntimeRevisionLocked());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (command == kDaliCmdOff || command == kDaliCmdRecallMax) {
|
||||
GatewayCacheDaliRuntimeStatus status;
|
||||
status.actual_level = command == kDaliCmdOff ? 0 : 254;
|
||||
status.revision = nextDaliRuntimeRevisionLocked();
|
||||
applyDaliTargetRuntimeStatusLocked(gateway_id, *target, status);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (command == kDaliCmdRecallMin) {
|
||||
GatewayCacheDaliRuntimeStatus status;
|
||||
status.use_min_level = true;
|
||||
status.revision = nextDaliRuntimeRevisionLocked();
|
||||
applyDaliTargetRuntimeStatusLocked(gateway_id, *target, status);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (command >= kDaliCmdGoToSceneMin && command <= kDaliCmdGoToSceneMax) {
|
||||
GatewayCacheDaliRuntimeStatus status;
|
||||
status.scene_id = static_cast<uint8_t>(command - kDaliCmdGoToSceneMin);
|
||||
status.revision = nextDaliRuntimeRevisionLocked();
|
||||
applyDaliTargetRuntimeStatusLocked(gateway_id, *target, status);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (command >= kDaliCmdAddToGroupMin && command <= kDaliCmdRemoveFromGroupMax) {
|
||||
applyDaliTargetGroupMutationLocked(gateway_id, *target,
|
||||
static_cast<uint8_t>(command & 0x0F),
|
||||
command < (kDaliCmdAddToGroupMin + 16));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (command >= kDaliCmdSetSceneMin && command < (kDaliCmdSetSceneMin + 16) &&
|
||||
dtr_state.dtr0.has_value()) {
|
||||
applyDaliTargetSceneLevelLocked(gateway_id, *target,
|
||||
static_cast<uint8_t>(command - kDaliCmdSetSceneMin),
|
||||
*dtr_state.dtr0);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (command >= (kDaliCmdSetSceneMin + 16) && command <= kDaliCmdRemoveSceneMax) {
|
||||
applyDaliTargetSceneLevelLocked(
|
||||
gateway_id, *target, static_cast<uint8_t>(command - (kDaliCmdSetSceneMin + 16)),
|
||||
static_cast<uint8_t>(255U));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (command >= kDaliCmdStoreDtrAsMaxLevel && command <= kDaliCmdStoreDtrAsFadeRate &&
|
||||
dtr_state.dtr0.has_value()) {
|
||||
applyDaliTargetSettingsLocked(gateway_id, *target, command, *dtr_state.dtr0);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GatewayCache::clearDaliTargetStateLocked(uint8_t gateway_id,
|
||||
const GatewayCacheDaliTarget& target,
|
||||
uint32_t revision) {
|
||||
auto clear_state = [revision](GatewayCacheDaliAddressState& state) {
|
||||
ClearDaliState(state);
|
||||
state.status.revision = revision;
|
||||
};
|
||||
|
||||
switch (target.kind) {
|
||||
case GatewayCacheDaliTargetKind::kShortAddress:
|
||||
if (target.value < 64) {
|
||||
clear_state(ensureDaliAddressStateLocked(gateway_id, target.value));
|
||||
}
|
||||
break;
|
||||
case GatewayCacheDaliTargetKind::kGroup: {
|
||||
if (target.value >= 16) {
|
||||
break;
|
||||
}
|
||||
auto& group_status = ensureDaliGroupStatusLocked(gateway_id, target.value);
|
||||
group_status = {};
|
||||
group_status.revision = revision;
|
||||
const uint16_t bit = static_cast<uint16_t>(1U << target.value);
|
||||
if (auto states = dali_states_.find(gateway_id); states != dali_states_.end()) {
|
||||
for (auto& state : states->second) {
|
||||
if (state.group_mask_known && (state.group_mask & bit) != 0) {
|
||||
clear_state(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GatewayCacheDaliTargetKind::kBroadcast: {
|
||||
auto& broadcast_status = ensureDaliBroadcastStatusLocked(gateway_id);
|
||||
broadcast_status = {};
|
||||
broadcast_status.revision = revision;
|
||||
auto& group_statuses = dali_group_status_[gateway_id];
|
||||
for (auto& group_status : group_statuses) {
|
||||
group_status = {};
|
||||
group_status.revision = revision;
|
||||
}
|
||||
auto& states = dali_states_[gateway_id];
|
||||
for (auto& state : states) {
|
||||
clear_state(state);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GatewayCache::applyDaliTargetRuntimeStatusLocked(
|
||||
uint8_t gateway_id, const GatewayCacheDaliTarget& target,
|
||||
const GatewayCacheDaliRuntimeStatus& status) {
|
||||
if (!status.anyKnown()) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (target.kind) {
|
||||
case GatewayCacheDaliTargetKind::kShortAddress:
|
||||
if (target.value < 64) {
|
||||
applyDaliRuntimeStatusToAddressLocked(ensureDaliAddressStateLocked(gateway_id,
|
||||
target.value),
|
||||
status);
|
||||
}
|
||||
break;
|
||||
case GatewayCacheDaliTargetKind::kGroup: {
|
||||
if (target.value >= 16) {
|
||||
break;
|
||||
}
|
||||
ensureDaliGroupStatusLocked(gateway_id, target.value) = status;
|
||||
const uint16_t bit = static_cast<uint16_t>(1U << target.value);
|
||||
if (auto states = dali_states_.find(gateway_id); states != dali_states_.end()) {
|
||||
for (auto& state : states->second) {
|
||||
if (state.group_mask_known && (state.group_mask & bit) != 0) {
|
||||
applyDaliRuntimeStatusToAddressLocked(state, status);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GatewayCacheDaliTargetKind::kBroadcast: {
|
||||
ensureDaliBroadcastStatusLocked(gateway_id) = status;
|
||||
auto& states = dali_states_[gateway_id];
|
||||
for (auto& state : states) {
|
||||
applyDaliRuntimeStatusToAddressLocked(state, status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GatewayCache::applyDaliRuntimeStatusToAddressLocked(
|
||||
GatewayCacheDaliAddressState& state, const GatewayCacheDaliRuntimeStatus& status) {
|
||||
if (!status.anyKnown() || status.revision <= state.status.revision) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (status.scene_id.has_value()) {
|
||||
state.status.scene_id = status.scene_id;
|
||||
state.status.use_min_level = false;
|
||||
const uint8_t scene_id = *status.scene_id;
|
||||
if (scene_id < state.scene_levels.size()) {
|
||||
const auto scene_level = state.scene_levels[scene_id];
|
||||
if (scene_level.has_value() && *scene_level != 255U) {
|
||||
state.status.actual_level = *scene_level;
|
||||
} else if (status.actual_level.has_value()) {
|
||||
state.status.actual_level = status.actual_level;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
state.status.scene_id.reset();
|
||||
state.status.use_min_level = status.use_min_level;
|
||||
if (status.use_min_level) {
|
||||
state.status.actual_level = state.settings.min_level;
|
||||
} else {
|
||||
state.status.actual_level = status.actual_level;
|
||||
}
|
||||
}
|
||||
state.status.revision = status.revision;
|
||||
}
|
||||
|
||||
void GatewayCache::applyDaliTargetGroupMutationLocked(uint8_t gateway_id,
|
||||
const GatewayCacheDaliTarget& target,
|
||||
uint8_t group_id, bool add_to_group) {
|
||||
if (group_id >= 16) {
|
||||
return;
|
||||
}
|
||||
const uint16_t bit = static_cast<uint16_t>(1U << group_id);
|
||||
auto apply = [&](GatewayCacheDaliAddressState& state) {
|
||||
if (!state.group_mask_known) {
|
||||
return;
|
||||
}
|
||||
if (add_to_group) {
|
||||
state.group_mask |= bit;
|
||||
} else {
|
||||
state.group_mask &= static_cast<uint16_t>(~bit);
|
||||
}
|
||||
refreshDaliAddressAggregateStatusLocked(gateway_id, state);
|
||||
};
|
||||
|
||||
switch (target.kind) {
|
||||
case GatewayCacheDaliTargetKind::kShortAddress:
|
||||
if (target.value < 64) {
|
||||
apply(ensureDaliAddressStateLocked(gateway_id, target.value));
|
||||
}
|
||||
break;
|
||||
case GatewayCacheDaliTargetKind::kGroup: {
|
||||
if (target.value >= 16) {
|
||||
break;
|
||||
}
|
||||
const uint16_t target_bit = static_cast<uint16_t>(1U << target.value);
|
||||
if (auto states = dali_states_.find(gateway_id); states != dali_states_.end()) {
|
||||
for (auto& state : states->second) {
|
||||
if (state.group_mask_known && (state.group_mask & target_bit) != 0) {
|
||||
apply(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GatewayCacheDaliTargetKind::kBroadcast: {
|
||||
auto& states = dali_states_[gateway_id];
|
||||
for (auto& state : states) {
|
||||
apply(state);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GatewayCache::applyDaliTargetSceneLevelLocked(uint8_t gateway_id,
|
||||
const GatewayCacheDaliTarget& target,
|
||||
uint8_t scene_id,
|
||||
std::optional<uint8_t> level) {
|
||||
if (scene_id >= 16) {
|
||||
return;
|
||||
}
|
||||
auto apply = [scene_id, level](GatewayCacheDaliAddressState& state) {
|
||||
state.scene_levels[scene_id] = level;
|
||||
if (state.status.scene_id.has_value() && *state.status.scene_id == scene_id &&
|
||||
level.has_value() && *level != 255U) {
|
||||
state.status.actual_level = *level;
|
||||
}
|
||||
};
|
||||
|
||||
switch (target.kind) {
|
||||
case GatewayCacheDaliTargetKind::kShortAddress:
|
||||
if (target.value < 64) {
|
||||
apply(ensureDaliAddressStateLocked(gateway_id, target.value));
|
||||
}
|
||||
break;
|
||||
case GatewayCacheDaliTargetKind::kGroup: {
|
||||
if (target.value >= 16) {
|
||||
break;
|
||||
}
|
||||
const uint16_t bit = static_cast<uint16_t>(1U << target.value);
|
||||
if (auto states = dali_states_.find(gateway_id); states != dali_states_.end()) {
|
||||
for (auto& state : states->second) {
|
||||
if (state.group_mask_known && (state.group_mask & bit) != 0) {
|
||||
apply(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GatewayCacheDaliTargetKind::kBroadcast: {
|
||||
auto& states = dali_states_[gateway_id];
|
||||
for (auto& state : states) {
|
||||
apply(state);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GatewayCache::applyDaliTargetSettingsLocked(uint8_t gateway_id,
|
||||
const GatewayCacheDaliTarget& target,
|
||||
uint8_t command, uint8_t value) {
|
||||
auto apply = [command, value](GatewayCacheDaliAddressState& state) {
|
||||
ApplyObservedSettingsValue(state.settings, command, value);
|
||||
if (command == kDaliCmdStoreDtrAsMinLevel && state.status.use_min_level) {
|
||||
state.status.actual_level = value;
|
||||
}
|
||||
};
|
||||
|
||||
switch (target.kind) {
|
||||
case GatewayCacheDaliTargetKind::kShortAddress:
|
||||
if (target.value < 64) {
|
||||
apply(ensureDaliAddressStateLocked(gateway_id, target.value));
|
||||
}
|
||||
break;
|
||||
case GatewayCacheDaliTargetKind::kGroup: {
|
||||
if (target.value >= 16) {
|
||||
break;
|
||||
}
|
||||
const uint16_t bit = static_cast<uint16_t>(1U << target.value);
|
||||
if (auto states = dali_states_.find(gateway_id); states != dali_states_.end()) {
|
||||
for (auto& state : states->second) {
|
||||
if (state.group_mask_known && (state.group_mask & bit) != 0) {
|
||||
apply(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GatewayCacheDaliTargetKind::kBroadcast: {
|
||||
auto& states = dali_states_[gateway_id];
|
||||
for (auto& state : states) {
|
||||
apply(state);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GatewayCache::refreshDaliAddressAggregateStatusLocked(uint8_t gateway_id,
|
||||
GatewayCacheDaliAddressState& state) {
|
||||
if (!state.group_mask_known) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (const auto broadcast = dali_broadcast_status_.find(gateway_id);
|
||||
broadcast != dali_broadcast_status_.end()) {
|
||||
applyDaliRuntimeStatusToAddressLocked(state, broadcast->second);
|
||||
}
|
||||
|
||||
const auto groups = dali_group_status_.find(gateway_id);
|
||||
if (groups == dali_group_status_.end()) {
|
||||
return;
|
||||
}
|
||||
for (uint8_t group_id = 0; group_id < groups->second.size(); ++group_id) {
|
||||
const uint16_t bit = static_cast<uint16_t>(1U << group_id);
|
||||
if ((state.group_mask & bit) != 0) {
|
||||
applyDaliRuntimeStatusToAddressLocked(state, groups->second[group_id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GatewayCache::TaskEntry(void* arg) {
|
||||
static_cast<GatewayCache*>(arg)->taskLoop();
|
||||
}
|
||||
@@ -921,6 +1311,17 @@ GatewayCacheDaliAddressState& GatewayCache::ensureDaliAddressStateLocked(uint8_t
|
||||
return it->second[short_address];
|
||||
}
|
||||
|
||||
GatewayCacheDaliRuntimeStatus& GatewayCache::ensureDaliGroupStatusLocked(uint8_t gateway_id,
|
||||
uint8_t group_id) {
|
||||
auto [it, inserted] = dali_group_status_.try_emplace(gateway_id);
|
||||
(void)inserted;
|
||||
return it->second[group_id];
|
||||
}
|
||||
|
||||
GatewayCacheDaliRuntimeStatus& GatewayCache::ensureDaliBroadcastStatusLocked(uint8_t gateway_id) {
|
||||
return dali_broadcast_status_[gateway_id];
|
||||
}
|
||||
|
||||
GatewayCache::SceneStore& GatewayCache::ensureSceneStoreLocked(uint8_t gateway_id) {
|
||||
auto [it, inserted] = scenes_.try_emplace(gateway_id);
|
||||
if (inserted) {
|
||||
|
||||
Reference in New Issue
Block a user