feat(gateway_cache): enhance DALI state management and caching
- Increased flush interval to 10 seconds and added a refresh interval of 120 seconds in GatewayCacheConfig. - Introduced a new boolean `stale` in GatewayCacheDaliRuntimeStatus to track stale states. - Added methods for setting actual DALI levels and persisting DALI address states. - Implemented functions to build and apply DALI state payloads, including handling scene levels. - Enhanced the GatewayCache class to manage DALI states more effectively, including loading and persisting states. - Updated GatewayController to support cache refresh operations, including handling cache commands and reporting cache status. - Added mechanisms for periodic cache refresh based on idle time and configured intervals. Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
@@ -24,7 +24,8 @@ struct GatewayCacheConfig {
|
||||
bool cache_enabled{true};
|
||||
bool reconciliation_enabled{true};
|
||||
bool full_state_mirror_enabled{false};
|
||||
uint32_t flush_interval_ms{5000};
|
||||
uint32_t flush_interval_ms{10000};
|
||||
uint32_t refresh_interval_ms{120000};
|
||||
uint32_t task_stack_size{4096};
|
||||
UBaseType_t task_priority{3};
|
||||
GatewayCachePriorityMode default_priority_mode{GatewayCachePriorityMode::kOutsideBusFirst};
|
||||
@@ -71,6 +72,7 @@ struct GatewayCacheDaliRuntimeStatus {
|
||||
std::optional<uint8_t> actual_level;
|
||||
std::optional<uint8_t> scene_id;
|
||||
bool use_min_level{false};
|
||||
bool stale{false};
|
||||
uint32_t revision{0};
|
||||
|
||||
bool anyKnown() const {
|
||||
@@ -144,6 +146,8 @@ class GatewayCache {
|
||||
std::optional<uint8_t> level);
|
||||
bool setDaliSettings(uint8_t gateway_id, uint8_t short_address,
|
||||
std::optional<GatewayCacheDaliSettingsSnapshot> settings);
|
||||
bool setDaliActualLevel(uint8_t gateway_id, uint8_t short_address,
|
||||
std::optional<uint8_t> level);
|
||||
bool clearChannelFlagsIfMatched(uint8_t gateway_id, const GatewayCacheChannelFlags& flags);
|
||||
void markGroupUpdateNeeded(uint8_t gateway_id, bool needed = true);
|
||||
void markSceneUpdateNeeded(uint8_t gateway_id, bool needed = true);
|
||||
@@ -174,6 +178,8 @@ class GatewayCache {
|
||||
void closeStorageLocked();
|
||||
bool persistSceneLocked(uint8_t gateway_id, uint8_t scene_id, const SceneEntry& scene);
|
||||
bool persistGroupLocked(uint8_t gateway_id, uint8_t group_id, const GroupEntry& group);
|
||||
bool persistDaliAddressStateLocked(uint8_t gateway_id, uint8_t short_address,
|
||||
const GatewayCacheDaliAddressState& state);
|
||||
bool commitStorageLocked();
|
||||
bool shouldTrackUpdateFlagsLocked() const;
|
||||
uint32_t nextDaliRuntimeRevisionLocked();
|
||||
@@ -205,6 +211,8 @@ class GatewayCache {
|
||||
GroupStore& ensureGroupStoreLocked(uint8_t gateway_id);
|
||||
void loadSceneStoreLocked(uint8_t gateway_id, SceneStore& scenes);
|
||||
void loadGroupStoreLocked(uint8_t gateway_id, GroupStore& groups);
|
||||
void loadDaliStateStoreLocked(uint8_t gateway_id,
|
||||
std::array<GatewayCacheDaliAddressState, 64>& states);
|
||||
std::string readStringLocked(std::string_view key);
|
||||
bool writeStringLocked(std::string_view key, std::string_view value);
|
||||
bool eraseKeyLocked(std::string_view key);
|
||||
|
||||
@@ -43,6 +43,18 @@ constexpr uint8_t kDaliCmdDt8StoreDtrAsColorX = 0xE0;
|
||||
constexpr uint8_t kDaliCmdDt8StoreDtrAsColorY = 0xE1;
|
||||
constexpr uint8_t kDaliCmdDt8StorePrimaryMin = 0xF0;
|
||||
constexpr uint8_t kDaliCmdDt8StartAutoCalibration = 0xF6;
|
||||
constexpr int kDaliStatePayloadVersion = 1;
|
||||
constexpr uint32_t kDaliStateGroupMaskKnown = 1U << 0;
|
||||
constexpr uint32_t kDaliStateActualKnown = 1U << 1;
|
||||
constexpr uint32_t kDaliStateSceneKnown = 1U << 2;
|
||||
constexpr uint32_t kDaliStateUseMinLevel = 1U << 3;
|
||||
constexpr uint32_t kDaliStateStatusStale = 1U << 4;
|
||||
constexpr uint32_t kDaliStatePowerOnKnown = 1U << 5;
|
||||
constexpr uint32_t kDaliStateSystemFailureKnown = 1U << 6;
|
||||
constexpr uint32_t kDaliStateMinKnown = 1U << 7;
|
||||
constexpr uint32_t kDaliStateMaxKnown = 1U << 8;
|
||||
constexpr uint32_t kDaliStateFadeTimeKnown = 1U << 9;
|
||||
constexpr uint32_t kDaliStateFadeRateKnown = 1U << 10;
|
||||
|
||||
class LockGuard {
|
||||
public:
|
||||
@@ -134,6 +146,18 @@ bool ShouldMirrorObservedMutation(GatewayCacheRawFrameOrigin origin,
|
||||
priority_mode == GatewayCachePriorityMode::kOutsideBusFirst;
|
||||
}
|
||||
|
||||
bool ShouldAlwaysMirrorObservedStatus(uint8_t raw_addr, uint8_t command) {
|
||||
if (!DecodeDaliTarget(raw_addr).has_value()) {
|
||||
return false;
|
||||
}
|
||||
if ((raw_addr & 0x01) == 0) {
|
||||
return command <= 254;
|
||||
}
|
||||
return command == kDaliCmdOff || command == kDaliCmdRecallMax ||
|
||||
command == kDaliCmdRecallMin ||
|
||||
(command >= kDaliCmdGoToSceneMin && command <= kDaliCmdGoToSceneMax);
|
||||
}
|
||||
|
||||
void ClearDaliState(GatewayCacheDaliAddressState& state) {
|
||||
state.group_mask_known = false;
|
||||
state.group_mask = 0;
|
||||
@@ -215,6 +239,139 @@ std::string BuildGroupPayload(const GatewayCache::GroupEntry& group) {
|
||||
return std::string(payload);
|
||||
}
|
||||
|
||||
uint8_t ByteValue(int value) {
|
||||
return static_cast<uint8_t>(std::clamp(value, 0, 255));
|
||||
}
|
||||
|
||||
uint16_t WordValue(int value) {
|
||||
return static_cast<uint16_t>(std::clamp(value, 0, 0xffff));
|
||||
}
|
||||
|
||||
uint16_t SceneKnownMask(const GatewayCacheDaliAddressState& state) {
|
||||
uint16_t mask = 0;
|
||||
for (size_t index = 0; index < state.scene_levels.size(); ++index) {
|
||||
if (state.scene_levels[index].has_value()) {
|
||||
mask |= static_cast<uint16_t>(1U << index);
|
||||
}
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
bool IsDefaultDaliAddressState(const GatewayCacheDaliAddressState& state) {
|
||||
return !state.group_mask_known && state.group_mask == 0 && SceneKnownMask(state) == 0 &&
|
||||
!state.settings.anyKnown() && !state.status.anyKnown();
|
||||
}
|
||||
|
||||
uint32_t DaliStateFlags(const GatewayCacheDaliAddressState& state) {
|
||||
uint32_t flags = 0;
|
||||
if (state.group_mask_known) {
|
||||
flags |= kDaliStateGroupMaskKnown;
|
||||
}
|
||||
if (state.status.actual_level.has_value()) {
|
||||
flags |= kDaliStateActualKnown;
|
||||
}
|
||||
if (state.status.scene_id.has_value()) {
|
||||
flags |= kDaliStateSceneKnown;
|
||||
}
|
||||
if (state.status.use_min_level) {
|
||||
flags |= kDaliStateUseMinLevel;
|
||||
}
|
||||
if (state.status.stale) {
|
||||
flags |= kDaliStateStatusStale;
|
||||
}
|
||||
if (state.settings.power_on_level.has_value()) {
|
||||
flags |= kDaliStatePowerOnKnown;
|
||||
}
|
||||
if (state.settings.system_failure_level.has_value()) {
|
||||
flags |= kDaliStateSystemFailureKnown;
|
||||
}
|
||||
if (state.settings.min_level.has_value()) {
|
||||
flags |= kDaliStateMinKnown;
|
||||
}
|
||||
if (state.settings.max_level.has_value()) {
|
||||
flags |= kDaliStateMaxKnown;
|
||||
}
|
||||
if (state.settings.fade_time.has_value()) {
|
||||
flags |= kDaliStateFadeTimeKnown;
|
||||
}
|
||||
if (state.settings.fade_rate.has_value()) {
|
||||
flags |= kDaliStateFadeRateKnown;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
std::string BuildDaliStatePayload(const GatewayCacheDaliAddressState& state) {
|
||||
const uint16_t scene_known_mask = SceneKnownMask(state);
|
||||
std::string payload = std::to_string(kDaliStatePayloadVersion);
|
||||
payload += "," + std::to_string(DaliStateFlags(state));
|
||||
payload += "," + std::to_string(state.status.revision);
|
||||
payload += "," + std::to_string(state.group_mask);
|
||||
payload += "," + std::to_string(state.status.actual_level.value_or(0));
|
||||
payload += "," + std::to_string(state.status.scene_id.value_or(0));
|
||||
payload += "," + std::to_string(state.settings.power_on_level.value_or(0));
|
||||
payload += "," + std::to_string(state.settings.system_failure_level.value_or(0));
|
||||
payload += "," + std::to_string(state.settings.min_level.value_or(0));
|
||||
payload += "," + std::to_string(state.settings.max_level.value_or(0));
|
||||
payload += "," + std::to_string(state.settings.fade_time.value_or(0));
|
||||
payload += "," + std::to_string(state.settings.fade_rate.value_or(0));
|
||||
payload += "," + std::to_string(scene_known_mask);
|
||||
for (const auto& scene_level : state.scene_levels) {
|
||||
payload += "," + std::to_string(scene_level.value_or(255));
|
||||
}
|
||||
return payload;
|
||||
}
|
||||
|
||||
void ApplyDaliStatePayload(std::string_view raw, GatewayCacheDaliAddressState& state) {
|
||||
const auto values = ParseCsv(raw);
|
||||
if (values.size() < 13 || values[0] != kDaliStatePayloadVersion) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t flags = static_cast<uint32_t>(std::max(values[1], 0));
|
||||
state.group_mask_known = (flags & kDaliStateGroupMaskKnown) != 0;
|
||||
state.group_mask = state.group_mask_known ? WordValue(values[3]) : 0;
|
||||
|
||||
state.status = {};
|
||||
state.status.revision = static_cast<uint32_t>(std::max(values[2], 0));
|
||||
state.status.stale = (flags & kDaliStateStatusStale) != 0;
|
||||
state.status.use_min_level = (flags & kDaliStateUseMinLevel) != 0;
|
||||
if ((flags & kDaliStateActualKnown) != 0) {
|
||||
state.status.actual_level = ByteValue(values[4]);
|
||||
}
|
||||
if ((flags & kDaliStateSceneKnown) != 0) {
|
||||
state.status.scene_id = static_cast<uint8_t>(std::min<int>(ByteValue(values[5]), 15));
|
||||
}
|
||||
|
||||
state.settings = {};
|
||||
if ((flags & kDaliStatePowerOnKnown) != 0) {
|
||||
state.settings.power_on_level = ByteValue(values[6]);
|
||||
}
|
||||
if ((flags & kDaliStateSystemFailureKnown) != 0) {
|
||||
state.settings.system_failure_level = ByteValue(values[7]);
|
||||
}
|
||||
if ((flags & kDaliStateMinKnown) != 0) {
|
||||
state.settings.min_level = ByteValue(values[8]);
|
||||
}
|
||||
if ((flags & kDaliStateMaxKnown) != 0) {
|
||||
state.settings.max_level = ByteValue(values[9]);
|
||||
}
|
||||
if ((flags & kDaliStateFadeTimeKnown) != 0) {
|
||||
state.settings.fade_time = ByteValue(values[10]);
|
||||
}
|
||||
if ((flags & kDaliStateFadeRateKnown) != 0) {
|
||||
state.settings.fade_rate = ByteValue(values[11]);
|
||||
}
|
||||
|
||||
state.scene_levels.fill(std::nullopt);
|
||||
const uint16_t scene_known_mask = WordValue(values[12]);
|
||||
for (uint8_t scene_id = 0; scene_id < state.scene_levels.size(); ++scene_id) {
|
||||
const size_t value_index = 13 + scene_id;
|
||||
if ((scene_known_mask & (1U << scene_id)) != 0 && value_index < values.size()) {
|
||||
state.scene_levels[scene_id] = ByteValue(values[value_index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
GatewayCache::GatewayCache(GatewayCacheConfig config)
|
||||
@@ -269,8 +426,11 @@ esp_err_t GatewayCache::start() {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
ESP_LOGI(kTag, "cache started namespace=%s flush_interval_ms=%u reconciliation=%d full_mirror=%d",
|
||||
ESP_LOGI(kTag,
|
||||
"cache started namespace=%s flush_interval_ms=%u refresh_interval_ms=%u "
|
||||
"reconciliation=%d full_mirror=%d",
|
||||
config_.storage_namespace.c_str(), static_cast<unsigned>(config_.flush_interval_ms),
|
||||
static_cast<unsigned>(config_.refresh_interval_ms),
|
||||
config_.reconciliation_enabled, config_.full_state_mirror_enabled);
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -282,6 +442,10 @@ void GatewayCache::preloadChannel(uint8_t gateway_id) {
|
||||
}
|
||||
ensureSceneStoreLocked(gateway_id);
|
||||
ensureGroupStoreLocked(gateway_id);
|
||||
auto [it, inserted] = dali_states_.try_emplace(gateway_id);
|
||||
if (inserted) {
|
||||
loadDaliStateStoreLocked(gateway_id, it->second);
|
||||
}
|
||||
}
|
||||
|
||||
GatewayCache::SceneStore GatewayCache::scenes(uint8_t gateway_id) {
|
||||
@@ -620,6 +784,7 @@ bool GatewayCache::setDaliGroupMask(uint8_t gateway_id, uint8_t short_address,
|
||||
state.group_mask_known = group_mask.has_value();
|
||||
state.group_mask = group_mask.value_or(0);
|
||||
refreshDaliAddressAggregateStatusLocked(gateway_id, state);
|
||||
dirty_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -632,6 +797,7 @@ bool GatewayCache::setDaliSceneLevel(uint8_t gateway_id, uint8_t short_address,
|
||||
|
||||
auto& state = ensureDaliAddressStateLocked(gateway_id, short_address);
|
||||
state.scene_levels[scene_id] = level;
|
||||
dirty_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -644,6 +810,31 @@ bool GatewayCache::setDaliSettings(uint8_t gateway_id, uint8_t short_address,
|
||||
|
||||
auto& state = ensureDaliAddressStateLocked(gateway_id, short_address);
|
||||
state.settings = settings.value_or(GatewayCacheDaliSettingsSnapshot{});
|
||||
dirty_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GatewayCache::setDaliActualLevel(uint8_t gateway_id, uint8_t short_address,
|
||||
std::optional<uint8_t> level) {
|
||||
LockGuard guard(lock_);
|
||||
if (short_address >= 64) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GatewayCacheDaliRuntimeStatus status;
|
||||
status.actual_level = level;
|
||||
status.revision = nextDaliRuntimeRevisionLocked();
|
||||
status.stale = false;
|
||||
auto& state = ensureDaliAddressStateLocked(gateway_id, short_address);
|
||||
state.status.scene_id.reset();
|
||||
state.status.use_min_level = false;
|
||||
applyDaliRuntimeStatusToAddressLocked(state, status);
|
||||
if (!level.has_value()) {
|
||||
state.status.actual_level.reset();
|
||||
state.status.revision = status.revision;
|
||||
state.status.stale = false;
|
||||
}
|
||||
dirty_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -712,7 +903,8 @@ bool GatewayCache::observeDaliCommand(uint8_t gateway_id, uint8_t raw_addr, uint
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ShouldMirrorObservedMutation(origin, priority_mode_)) {
|
||||
if (ShouldAlwaysMirrorObservedStatus(raw_addr, command) ||
|
||||
ShouldMirrorObservedMutation(origin, priority_mode_)) {
|
||||
mirrorDaliCommandLocked(gateway_id, raw_addr, command);
|
||||
}
|
||||
|
||||
@@ -791,12 +983,15 @@ bool GatewayCache::mirrorDaliCommandLocked(uint8_t gateway_id, uint8_t raw_addr,
|
||||
GatewayCacheDaliRuntimeStatus status;
|
||||
status.actual_level = command;
|
||||
status.revision = nextDaliRuntimeRevisionLocked();
|
||||
status.stale = false;
|
||||
applyDaliTargetRuntimeStatusLocked(gateway_id, *target, status);
|
||||
dirty_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (command == kDaliCmdReset) {
|
||||
clearDaliTargetStateLocked(gateway_id, *target, nextDaliRuntimeRevisionLocked());
|
||||
dirty_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -804,7 +999,9 @@ bool GatewayCache::mirrorDaliCommandLocked(uint8_t gateway_id, uint8_t raw_addr,
|
||||
GatewayCacheDaliRuntimeStatus status;
|
||||
status.actual_level = command == kDaliCmdOff ? 0 : 254;
|
||||
status.revision = nextDaliRuntimeRevisionLocked();
|
||||
status.stale = false;
|
||||
applyDaliTargetRuntimeStatusLocked(gateway_id, *target, status);
|
||||
dirty_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -812,7 +1009,9 @@ bool GatewayCache::mirrorDaliCommandLocked(uint8_t gateway_id, uint8_t raw_addr,
|
||||
GatewayCacheDaliRuntimeStatus status;
|
||||
status.use_min_level = true;
|
||||
status.revision = nextDaliRuntimeRevisionLocked();
|
||||
status.stale = false;
|
||||
applyDaliTargetRuntimeStatusLocked(gateway_id, *target, status);
|
||||
dirty_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -820,7 +1019,9 @@ bool GatewayCache::mirrorDaliCommandLocked(uint8_t gateway_id, uint8_t raw_addr,
|
||||
GatewayCacheDaliRuntimeStatus status;
|
||||
status.scene_id = static_cast<uint8_t>(command - kDaliCmdGoToSceneMin);
|
||||
status.revision = nextDaliRuntimeRevisionLocked();
|
||||
status.stale = false;
|
||||
applyDaliTargetRuntimeStatusLocked(gateway_id, *target, status);
|
||||
dirty_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -828,6 +1029,7 @@ bool GatewayCache::mirrorDaliCommandLocked(uint8_t gateway_id, uint8_t raw_addr,
|
||||
applyDaliTargetGroupMutationLocked(gateway_id, *target,
|
||||
static_cast<uint8_t>(command & 0x0F),
|
||||
command < (kDaliCmdAddToGroupMin + 16));
|
||||
dirty_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -836,6 +1038,7 @@ bool GatewayCache::mirrorDaliCommandLocked(uint8_t gateway_id, uint8_t raw_addr,
|
||||
applyDaliTargetSceneLevelLocked(gateway_id, *target,
|
||||
static_cast<uint8_t>(command - kDaliCmdSetSceneMin),
|
||||
*dtr_state.dtr0);
|
||||
dirty_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -843,12 +1046,14 @@ bool GatewayCache::mirrorDaliCommandLocked(uint8_t gateway_id, uint8_t raw_addr,
|
||||
applyDaliTargetSceneLevelLocked(
|
||||
gateway_id, *target, static_cast<uint8_t>(command - (kDaliCmdSetSceneMin + 16)),
|
||||
static_cast<uint8_t>(255U));
|
||||
dirty_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (command >= kDaliCmdStoreDtrAsMaxLevel && command <= kDaliCmdStoreDtrAsFadeRate &&
|
||||
dtr_state.dtr0.has_value()) {
|
||||
applyDaliTargetSettingsLocked(gateway_id, *target, command, *dtr_state.dtr0);
|
||||
dirty_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -977,6 +1182,7 @@ void GatewayCache::applyDaliRuntimeStatusToAddressLocked(
|
||||
}
|
||||
}
|
||||
state.status.revision = status.revision;
|
||||
state.status.stale = status.stale;
|
||||
}
|
||||
|
||||
void GatewayCache::applyDaliTargetGroupMutationLocked(uint8_t gateway_id,
|
||||
@@ -1127,7 +1333,9 @@ void GatewayCache::refreshDaliAddressAggregateStatusLocked(uint8_t gateway_id,
|
||||
|
||||
if (const auto broadcast = dali_broadcast_status_.find(gateway_id);
|
||||
broadcast != dali_broadcast_status_.end()) {
|
||||
applyDaliRuntimeStatusToAddressLocked(state, broadcast->second);
|
||||
if (!broadcast->second.stale) {
|
||||
applyDaliRuntimeStatusToAddressLocked(state, broadcast->second);
|
||||
}
|
||||
}
|
||||
|
||||
const auto groups = dali_group_status_.find(gateway_id);
|
||||
@@ -1137,6 +1345,9 @@ void GatewayCache::refreshDaliAddressAggregateStatusLocked(uint8_t gateway_id,
|
||||
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) {
|
||||
if (groups->second[group_id].stale) {
|
||||
continue;
|
||||
}
|
||||
applyDaliRuntimeStatusToAddressLocked(state, groups->second[group_id]);
|
||||
}
|
||||
}
|
||||
@@ -1209,6 +1420,14 @@ bool GatewayCache::flushDirty() {
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& [gateway_id, states] : dali_states_) {
|
||||
for (uint8_t short_address = 0; short_address < states.size(); ++short_address) {
|
||||
if (!persistDaliAddressStateLocked(gateway_id, short_address, states[short_address])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const esp_err_t commit_err = nvs_commit(storage_);
|
||||
if (commit_err != ESP_OK) {
|
||||
ESP_LOGE(kTag, "cache commit failed: %s", esp_err_to_name(commit_err));
|
||||
@@ -1288,6 +1507,18 @@ bool GatewayCache::persistGroupLocked(uint8_t gateway_id, uint8_t group_id,
|
||||
return commitStorageLocked();
|
||||
}
|
||||
|
||||
bool GatewayCache::persistDaliAddressStateLocked(
|
||||
uint8_t gateway_id, uint8_t short_address, const GatewayCacheDaliAddressState& state) {
|
||||
if (short_address >= 64) {
|
||||
return false;
|
||||
}
|
||||
if (!IsDefaultDaliAddressState(state)) {
|
||||
return writeStringLocked(ShortKey("ds", gateway_id, short_address),
|
||||
BuildDaliStatePayload(state));
|
||||
}
|
||||
return eraseKeyLocked(ShortKey("ds", gateway_id, short_address));
|
||||
}
|
||||
|
||||
bool GatewayCache::commitStorageLocked() {
|
||||
if (storage_ == 0) {
|
||||
return false;
|
||||
@@ -1307,7 +1538,9 @@ bool GatewayCache::shouldTrackUpdateFlagsLocked() const {
|
||||
GatewayCacheDaliAddressState& GatewayCache::ensureDaliAddressStateLocked(uint8_t gateway_id,
|
||||
uint8_t short_address) {
|
||||
auto [it, inserted] = dali_states_.try_emplace(gateway_id);
|
||||
(void)inserted;
|
||||
if (inserted) {
|
||||
loadDaliStateStoreLocked(gateway_id, it->second);
|
||||
}
|
||||
return it->second[short_address];
|
||||
}
|
||||
|
||||
@@ -1377,6 +1610,23 @@ void GatewayCache::loadGroupStoreLocked(uint8_t gateway_id, GroupStore& groups)
|
||||
}
|
||||
}
|
||||
|
||||
void GatewayCache::loadDaliStateStoreLocked(
|
||||
uint8_t gateway_id, std::array<GatewayCacheDaliAddressState, 64>& states) {
|
||||
for (uint8_t short_address = 0; short_address < states.size(); ++short_address) {
|
||||
ClearDaliState(states[short_address]);
|
||||
const auto raw = readStringLocked(ShortKey("ds", gateway_id, short_address));
|
||||
if (!raw.empty()) {
|
||||
ApplyDaliStatePayload(raw, states[short_address]);
|
||||
if (states[short_address].status.anyKnown()) {
|
||||
states[short_address].status.stale = true;
|
||||
}
|
||||
if (states[short_address].status.revision > dali_runtime_revision_) {
|
||||
dali_runtime_revision_ = states[short_address].status.revision;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string GatewayCache::readStringLocked(std::string_view key) {
|
||||
if (!openStorageLocked()) {
|
||||
return {};
|
||||
|
||||
Reference in New Issue
Block a user