feat(gateway): add DALI bus ID configuration and enhance group object write handling
Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
@@ -1438,6 +1438,10 @@ struct GatewayBridgeService::ChannelRuntime {
|
||||
[this](uint16_t group_address, const uint8_t* data, size_t len) {
|
||||
return service.routeKnxGroupWrite(group_address, data, len);
|
||||
});
|
||||
knx_router->setGroupObjectWriteHandler(
|
||||
[this](uint16_t group_object_number, const uint8_t* data, size_t len) {
|
||||
return service.routeKnxGroupObjectWrite(group_object_number, data, len);
|
||||
});
|
||||
if (const auto active_knx = activeKnxConfigLocked(); active_knx.has_value()) {
|
||||
knx->setConfig(active_knx.value());
|
||||
knx_router->setConfig(active_knx.value());
|
||||
@@ -2058,12 +2062,13 @@ struct GatewayBridgeService::ChannelRuntime {
|
||||
const bool commissioning_only = !knx_config.has_value();
|
||||
ESP_LOGI(kTag,
|
||||
"gateway=%u KNX/IP start config namespace=%s storedConfig=%d udp=%u tunnel=%d "
|
||||
"multicast=%d multicastGroup=%s mainGroup=%u tpUart=%d tx=%d rx=%d nineBit=%d "
|
||||
"multicast=%d multicastGroup=%s mainGroup=%u daliBus=%u tpUart=%d tx=%d rx=%d nineBit=%d "
|
||||
"individual=0x%04x",
|
||||
channel.gateway_id, openKnxNamespace().c_str(), !commissioning_only,
|
||||
static_cast<unsigned>(runtime_config.udp_port), runtime_config.tunnel_enabled,
|
||||
runtime_config.multicast_enabled, runtime_config.multicast_address.c_str(),
|
||||
static_cast<unsigned>(runtime_config.main_group), runtime_config.tp_uart.uart_port,
|
||||
static_cast<unsigned>(runtime_config.main_group),
|
||||
static_cast<unsigned>(runtime_config.dali_bus_id), runtime_config.tp_uart.uart_port,
|
||||
runtime_config.tp_uart.tx_pin, runtime_config.tp_uart.rx_pin,
|
||||
runtime_config.tp_uart.nine_bit_mode,
|
||||
runtime_config.individual_address);
|
||||
@@ -3205,13 +3210,6 @@ struct GatewayBridgeService::ChannelRuntime {
|
||||
return std::nullopt;
|
||||
}
|
||||
GatewayKnxConfig config = service_config.default_knx_config.value();
|
||||
const uint8_t channel_index = channel.channel_index;
|
||||
config.main_group = static_cast<uint8_t>(std::min<int>(31, config.main_group + channel_index));
|
||||
const uint16_t device = config.ip_interface_individual_address & 0x00ff;
|
||||
if (device > 0 && device + channel_index <= 0x00ff) {
|
||||
config.ip_interface_individual_address = static_cast<uint16_t>(
|
||||
(config.ip_interface_individual_address & 0xff00) | (device + channel_index));
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -3945,7 +3943,9 @@ GatewayBridgeService::ChannelRuntime* GatewayBridgeService::selectKnxEndpointRun
|
||||
}
|
||||
LockGuard guard(runtime->lock);
|
||||
const auto config = runtime->activeKnxConfigLocked();
|
||||
return config.has_value() && config->ip_router_enabled;
|
||||
return config.has_value() && config->ip_router_enabled &&
|
||||
runtime->channel.native_bus_id.has_value() &&
|
||||
runtime->channel.native_bus_id.value() == config->dali_bus_id;
|
||||
};
|
||||
|
||||
if (eligible(knx_endpoint_runtime_)) {
|
||||
@@ -3963,7 +3963,13 @@ GatewayBridgeService::ChannelRuntime* GatewayBridgeService::selectKnxEndpointRun
|
||||
}
|
||||
knx_endpoint_runtime_ = selected;
|
||||
if (selected != nullptr) {
|
||||
ESP_LOGI(kTag, "gateway=%u owns shared KNXnet/IP endpoint", selected->channel.gateway_id);
|
||||
LockGuard guard(selected->lock);
|
||||
const auto config = selected->activeKnxConfigLocked();
|
||||
ESP_LOGI(kTag, "gateway=%u owns shared KNXnet/IP endpoint daliBus=%u",
|
||||
selected->channel.gateway_id,
|
||||
config.has_value() ? static_cast<unsigned>(config->dali_bus_id) : 0U);
|
||||
} else {
|
||||
ESP_LOGW(kTag, "no native DALI channel matches the configured KNX DALI bus id");
|
||||
}
|
||||
return selected;
|
||||
}
|
||||
@@ -4026,37 +4032,45 @@ esp_err_t GatewayBridgeService::stopKnxEndpoint(ChannelRuntime* requested_runtim
|
||||
|
||||
DaliBridgeResult GatewayBridgeService::routeKnxGroupWrite(uint16_t group_address,
|
||||
const uint8_t* data, size_t len) {
|
||||
std::vector<ChannelRuntime*> matches;
|
||||
for (const auto& runtime : runtimes_) {
|
||||
LockGuard guard(runtime->lock);
|
||||
if (runtime->knx != nullptr && runtime->knx->matchesGroupAddress(group_address)) {
|
||||
matches.push_back(runtime.get());
|
||||
}
|
||||
}
|
||||
if (matches.empty()) {
|
||||
ChannelRuntime* runtime = knx_endpoint_runtime_ != nullptr ? knx_endpoint_runtime_
|
||||
: selectKnxEndpointRuntime();
|
||||
if (runtime == nullptr) {
|
||||
DaliBridgeResult result;
|
||||
result.error = "No DALI bridge mapping matched KNX group " +
|
||||
result.error = "No DALI channel is selected for KNX group " +
|
||||
GatewayKnxGroupAddressString(group_address);
|
||||
return result;
|
||||
}
|
||||
if (matches.size() > 1) {
|
||||
DaliBridgeResult result;
|
||||
result.error = "KNX group " + GatewayKnxGroupAddressString(group_address) +
|
||||
" matched multiple DALI bridge channels";
|
||||
ESP_LOGW(kTag, "%s", result.error.c_str());
|
||||
return result;
|
||||
}
|
||||
|
||||
ChannelRuntime* runtime = matches.front();
|
||||
LockGuard guard(runtime->lock);
|
||||
if (runtime->knx == nullptr || !runtime->knx->matchesGroupAddress(group_address)) {
|
||||
DaliBridgeResult result;
|
||||
result.error = "DALI bridge mapping changed before KNX group dispatch";
|
||||
result.error = "Selected DALI bus does not map KNX group " +
|
||||
GatewayKnxGroupAddressString(group_address);
|
||||
return result;
|
||||
}
|
||||
return runtime->knx->handleGroupWrite(group_address, data, len);
|
||||
}
|
||||
|
||||
DaliBridgeResult GatewayBridgeService::routeKnxGroupObjectWrite(uint16_t group_object_number,
|
||||
const uint8_t* data, size_t len) {
|
||||
ChannelRuntime* runtime = knx_endpoint_runtime_ != nullptr ? knx_endpoint_runtime_
|
||||
: selectKnxEndpointRuntime();
|
||||
if (runtime == nullptr) {
|
||||
DaliBridgeResult result;
|
||||
result.error = "No DALI channel is selected for KNX group object " +
|
||||
std::to_string(group_object_number);
|
||||
return result;
|
||||
}
|
||||
LockGuard guard(runtime->lock);
|
||||
if (runtime->knx == nullptr) {
|
||||
DaliBridgeResult result;
|
||||
result.error = "Selected DALI bus has no KNX bridge for group object " +
|
||||
std::to_string(group_object_number);
|
||||
return result;
|
||||
}
|
||||
return runtime->knx->handleGroupObjectWrite(group_object_number, data, len);
|
||||
}
|
||||
|
||||
void GatewayBridgeService::handleDaliRawFrame(const DaliRawFrame& frame) {
|
||||
const auto update = DecodeDaliKnxStatusUpdate(frame);
|
||||
if (!update.has_value()) {
|
||||
|
||||
Reference in New Issue
Block a user