feat(gateway): implement reconciliation mechanism and command prioritization
- Introduced a reconciliation job structure to manage the reconciliation process for gateway channels. - Added methods to schedule and run reconciliation steps, including group, scene, and settings reconciliation. - Implemented a locking mechanism to ensure thread safety during reconciliation operations. - Enhanced command handling in GatewayRuntime to classify commands by priority (control, normal, maintenance). - Updated command enqueueing and processing to respect command priorities, ensuring maintenance commands are handled appropriately. - Added configuration options for enabling/disabling cache functionality in GatewayRuntime. - Improved logging to include cache status during runtime initialization. Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@@ -93,6 +94,21 @@ struct DaliDomainSnapshot {
|
||||
std::map<std::string, std::vector<double>> number_arrays;
|
||||
};
|
||||
|
||||
struct DaliAddressSettingsSnapshot {
|
||||
std::optional<uint8_t> power_on_level;
|
||||
std::optional<uint8_t> system_failure_level;
|
||||
std::optional<uint8_t> min_level;
|
||||
std::optional<uint8_t> max_level;
|
||||
std::optional<uint8_t> fade_time;
|
||||
std::optional<uint8_t> fade_rate;
|
||||
|
||||
bool anyKnown() const {
|
||||
return power_on_level.has_value() || system_failure_level.has_value() ||
|
||||
min_level.has_value() || max_level.has_value() || fade_time.has_value() ||
|
||||
fade_rate.has_value();
|
||||
}
|
||||
};
|
||||
|
||||
class DaliDomainService {
|
||||
public:
|
||||
DaliDomainService();
|
||||
@@ -141,6 +157,15 @@ class DaliDomainService {
|
||||
bool on(uint8_t gateway_id, int short_address) const;
|
||||
bool off(uint8_t gateway_id, int short_address) const;
|
||||
bool off(int short_address) const;
|
||||
std::optional<uint16_t> queryGroupMask(uint8_t gateway_id, int short_address) const;
|
||||
std::optional<uint8_t> querySceneLevel(uint8_t gateway_id, int short_address, int scene) const;
|
||||
std::optional<DaliAddressSettingsSnapshot> queryAddressSettings(uint8_t gateway_id,
|
||||
int short_address) const;
|
||||
bool applyGroupMask(uint8_t gateway_id, int short_address, uint16_t group_mask) const;
|
||||
bool applySceneLevel(uint8_t gateway_id, int short_address, int scene,
|
||||
std::optional<uint8_t> level) const;
|
||||
bool applyAddressSettings(uint8_t gateway_id, int short_address,
|
||||
const DaliAddressSettingsSnapshot& settings) const;
|
||||
bool updateChannelName(uint8_t gateway_id, std::string_view name);
|
||||
bool allocateAllAddr(uint8_t gateway_id, int start_address = 0) const;
|
||||
void stopAllocAddr(uint8_t gateway_id) const;
|
||||
|
||||
@@ -779,6 +779,125 @@ bool DaliDomainService::off(int short_address) const {
|
||||
return off(channels_.front()->config.gateway_id, short_address);
|
||||
}
|
||||
|
||||
std::optional<uint16_t> DaliDomainService::queryGroupMask(uint8_t gateway_id,
|
||||
int short_address) const {
|
||||
const auto* channel = findChannelByGateway(gateway_id);
|
||||
if (channel == nullptr || channel->dali == nullptr) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const auto group_mask = channel->dali->base.getGroup(short_address);
|
||||
if (!group_mask.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return static_cast<uint16_t>(*group_mask);
|
||||
}
|
||||
|
||||
std::optional<uint8_t> DaliDomainService::querySceneLevel(uint8_t gateway_id, int short_address,
|
||||
int scene) const {
|
||||
const auto* channel = findChannelByGateway(gateway_id);
|
||||
if (channel == nullptr || channel->dali == nullptr) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const auto level = channel->dali->base.getScene(short_address, scene);
|
||||
if (!level.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return static_cast<uint8_t>(*level);
|
||||
}
|
||||
|
||||
std::optional<DaliAddressSettingsSnapshot> DaliDomainService::queryAddressSettings(
|
||||
uint8_t gateway_id, int short_address) const {
|
||||
const auto* channel = findChannelByGateway(gateway_id);
|
||||
if (channel == nullptr || channel->dali == nullptr) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
DaliAddressSettingsSnapshot settings{};
|
||||
|
||||
if (const auto value = channel->dali->base.getPowerOnLevel(short_address); value.has_value()) {
|
||||
settings.power_on_level = static_cast<uint8_t>(*value);
|
||||
}
|
||||
if (const auto value = channel->dali->base.getSystemFailureLevel(short_address);
|
||||
value.has_value()) {
|
||||
settings.system_failure_level = static_cast<uint8_t>(*value);
|
||||
}
|
||||
if (const auto value = channel->dali->base.getMinLevel(short_address); value.has_value()) {
|
||||
settings.min_level = static_cast<uint8_t>(*value);
|
||||
}
|
||||
if (const auto value = channel->dali->base.getMaxLevel(short_address); value.has_value()) {
|
||||
settings.max_level = static_cast<uint8_t>(*value);
|
||||
}
|
||||
if (const auto value = channel->dali->base.getFadeTime(short_address); value.has_value()) {
|
||||
settings.fade_time = static_cast<uint8_t>(*value);
|
||||
}
|
||||
if (const auto value = channel->dali->base.getFadeRate(short_address); value.has_value()) {
|
||||
settings.fade_rate = static_cast<uint8_t>(*value);
|
||||
}
|
||||
|
||||
if (!settings.anyKnown()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
bool DaliDomainService::applyGroupMask(uint8_t gateway_id, int short_address,
|
||||
uint16_t group_mask) const {
|
||||
const auto* channel = findChannelByGateway(gateway_id);
|
||||
return channel != nullptr && channel->dali != nullptr &&
|
||||
channel->dali->base.setGroup(short_address, group_mask);
|
||||
}
|
||||
|
||||
bool DaliDomainService::applySceneLevel(uint8_t gateway_id, int short_address, int scene,
|
||||
std::optional<uint8_t> level) const {
|
||||
const auto* channel = findChannelByGateway(gateway_id);
|
||||
if (channel == nullptr || channel->dali == nullptr || !level.has_value()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*level == 255U) {
|
||||
return channel->dali->base.removeScene(short_address, scene);
|
||||
}
|
||||
|
||||
return channel->dali->base.setDTR(*level) &&
|
||||
channel->dali->base.storeDTRAsSceneBright(short_address, scene);
|
||||
}
|
||||
|
||||
bool DaliDomainService::applyAddressSettings(uint8_t gateway_id, int short_address,
|
||||
const DaliAddressSettingsSnapshot& settings) const {
|
||||
const auto* channel = findChannelByGateway(gateway_id);
|
||||
if (channel == nullptr || channel->dali == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ok = true;
|
||||
if (settings.power_on_level.has_value()) {
|
||||
ok = ok && channel->dali->base.setPowerOnLevel(short_address, *settings.power_on_level);
|
||||
}
|
||||
if (settings.system_failure_level.has_value()) {
|
||||
ok = ok &&
|
||||
channel->dali->base.setSystemFailureLevel(short_address, *settings.system_failure_level);
|
||||
}
|
||||
if (settings.min_level.has_value()) {
|
||||
ok = ok && channel->dali->base.setMinLevel(short_address, *settings.min_level);
|
||||
}
|
||||
if (settings.max_level.has_value()) {
|
||||
ok = ok && channel->dali->base.setMaxLevel(short_address, *settings.max_level);
|
||||
}
|
||||
if (settings.fade_time.has_value()) {
|
||||
ok = ok && channel->dali->base.setFadeTime(short_address, *settings.fade_time);
|
||||
}
|
||||
if (settings.fade_rate.has_value()) {
|
||||
ok = ok && channel->dali->base.setFadeRate(short_address, *settings.fade_rate);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool DaliDomainService::updateChannelName(uint8_t gateway_id, std::string_view name) {
|
||||
auto* channel = findChannelByGateway(gateway_id);
|
||||
if (channel == nullptr) {
|
||||
|
||||
Reference in New Issue
Block a user