feat(gateway): enhance KNX support with DALI integration and configuration updates
Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
@@ -57,6 +57,10 @@ constexpr uint32_t kBacnetMaxObjectInstance = 4194303;
|
||||
constexpr uint32_t kBacnetReliabilityNoFaultDetected = 0;
|
||||
constexpr uint32_t kBacnetReliabilityCommunicationFailure = 12;
|
||||
constexpr const char* kModbusManagementPrefix = "@DALIGW";
|
||||
constexpr uint8_t kDaliGroupRawMin = 0x80;
|
||||
constexpr uint8_t kDaliGroupRawMax = 0x9F;
|
||||
constexpr uint8_t kDaliCmdOff = 0x00;
|
||||
constexpr uint8_t kDaliCmdRecallMax = 0x05;
|
||||
|
||||
struct GatewayBridgeStoredConfig {
|
||||
BridgeRuntimeConfig bridge;
|
||||
@@ -71,6 +75,11 @@ struct BridgeDiscoveryEntry {
|
||||
DaliDomainSnapshot discovery;
|
||||
};
|
||||
|
||||
struct DaliKnxStatusUpdate {
|
||||
GatewayKnxDaliTarget target;
|
||||
uint8_t actual_level{0};
|
||||
};
|
||||
|
||||
using BridgeDiscoveryInventory = std::map<int, BridgeDiscoveryEntry>;
|
||||
|
||||
class LockGuard {
|
||||
@@ -220,6 +229,51 @@ bool ValidDaliAddress(int address) {
|
||||
return address >= 0 && address <= 127;
|
||||
}
|
||||
|
||||
std::optional<GatewayKnxDaliTarget> DecodeKnxDaliTarget(uint8_t raw_addr) {
|
||||
if (raw_addr <= 0x7F) {
|
||||
return GatewayKnxDaliTarget{GatewayKnxDaliTargetKind::kShortAddress,
|
||||
static_cast<int>(raw_addr >> 1)};
|
||||
}
|
||||
if (raw_addr >= kDaliGroupRawMin && raw_addr <= kDaliGroupRawMax) {
|
||||
return GatewayKnxDaliTarget{GatewayKnxDaliTargetKind::kGroup,
|
||||
static_cast<int>((raw_addr - kDaliGroupRawMin) >> 1)};
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<DaliKnxStatusUpdate> DecodeDaliKnxStatusUpdate(const DaliRawFrame& frame) {
|
||||
if (frame.data.size() != 2 && frame.data.size() != 3) {
|
||||
return std::nullopt;
|
||||
}
|
||||
uint8_t raw_addr = 0;
|
||||
uint8_t command = 0;
|
||||
if (frame.data.size() == 2) {
|
||||
raw_addr = frame.data[0];
|
||||
command = frame.data[1];
|
||||
if (raw_addr == 0xBE) {
|
||||
return std::nullopt;
|
||||
}
|
||||
} else {
|
||||
raw_addr = frame.data[1];
|
||||
command = frame.data[2];
|
||||
}
|
||||
auto target = DecodeKnxDaliTarget(raw_addr);
|
||||
if (!target.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
if ((raw_addr & 0x01U) == 0) {
|
||||
if (command > 254) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return DaliKnxStatusUpdate{*target, command};
|
||||
}
|
||||
if (command == kDaliCmdOff || command == kDaliCmdRecallMax) {
|
||||
return DaliKnxStatusUpdate{*target,
|
||||
static_cast<uint8_t>(command == kDaliCmdOff ? 0 : 254)};
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool ValidShortAddress(int address) {
|
||||
return address >= 0 && address <= kMaxDaliShortAddress;
|
||||
}
|
||||
@@ -3652,6 +3706,9 @@ esp_err_t GatewayBridgeService::start() {
|
||||
runtimes_.push_back(std::move(runtime));
|
||||
}
|
||||
|
||||
dali_domain_.addRawFrameSink(
|
||||
[this](const DaliRawFrame& frame) { handleDaliRawFrame(frame); });
|
||||
|
||||
std::set<int> used_serial_uarts;
|
||||
if (config_.modbus_enabled && config_.modbus_startup_enabled) {
|
||||
std::set<uint16_t> used_modbus_ports;
|
||||
@@ -3708,6 +3765,22 @@ const GatewayBridgeService::ChannelRuntime* GatewayBridgeService::findRuntime(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void GatewayBridgeService::handleDaliRawFrame(const DaliRawFrame& frame) {
|
||||
const auto update = DecodeDaliKnxStatusUpdate(frame);
|
||||
if (!update.has_value()) {
|
||||
return;
|
||||
}
|
||||
auto* runtime = findRuntime(frame.gateway_id);
|
||||
if (runtime == nullptr) {
|
||||
return;
|
||||
}
|
||||
LockGuard guard(runtime->lock);
|
||||
if (!runtime->knx_started || runtime->knx_router == nullptr) {
|
||||
return;
|
||||
}
|
||||
runtime->knx_router->publishDaliStatus(update->target, update->actual_level);
|
||||
}
|
||||
|
||||
void GatewayBridgeService::collectUsedRuntimeResources(
|
||||
uint8_t except_gateway_id,
|
||||
std::set<uint16_t>* modbus_tcp_ports,
|
||||
|
||||
Reference in New Issue
Block a user