From fa4acef881f556968acc3ca1716c49503fbd5aee Mon Sep 17 00:00:00 2001 From: Tony Date: Mon, 4 May 2026 02:25:39 +0800 Subject: [PATCH] Refactor DALI component: remove BACnet bridge support and update related documentation Co-authored-by: Copilot --- CMakeLists.txt | 1 - README.md | 9 ++-- examples/esp32s3_bridge/README.md | 5 +-- examples/esp32s3_bridge/main/main.cpp | 37 --------------- include/bacnet_bridge.hpp | 44 ------------------ include/bridge_provisioning.hpp | 3 -- include/dali.hpp | 1 - src/bacnet_bridge.cpp | 65 --------------------------- src/bridge_provisioning.cpp | 22 --------- 9 files changed, 6 insertions(+), 181 deletions(-) delete mode 100644 include/bacnet_bridge.hpp delete mode 100644 src/bacnet_bridge.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9512a23..1117ee4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,6 @@ idf_component_register( "src/bridge.cpp" "src/bridge_model.cpp" "src/bridge_provisioning.cpp" - "src/bacnet_bridge.cpp" "src/decode.cpp" "src/device.cpp" "src/dt1.cpp" diff --git a/README.md b/README.md index c8395c9..8442406 100644 --- a/README.md +++ b/README.md @@ -50,9 +50,8 @@ The component now includes a protocol-agnostic bridge layer for mapping external - `bridge_model.hpp` defines the strongly typed mapping model: protocol kind, external point, DALI target, default operation, and value transform. - `bridge.hpp` provides `DaliBridgeEngine`, which resolves models and dispatches requests into `DaliComm`, `DaliBase`, and `DaliDT8`. -- `bridge_provisioning.hpp` provides `BridgeProvisioningStore` for persisting bridge models and shared protocol config in ESP-IDF NVS. -- Modbus runtime support is owned by the native gateway project in `gateway/components/gateway_modbus`. -- `bacnet_bridge.hpp` provides a BACnet skeleton adapter keyed by object type, instance, and property bindings. +- `bridge_provisioning.hpp` provides `BridgeProvisioningStore` for persisting bridge models in ESP-IDF NVS. +- Modbus and BACnet runtime support are owned by the native gateway project in `gateway/components/gateway_modbus` and `gateway/components/gateway_bacnet`. ### Example Model Mapping @@ -107,7 +106,7 @@ Query-style operations return `data` when available and may include decoded flag ## Bridge Provisioning via NVS -Use `BridgeProvisioningStore` to persist bridge models and shared protocol-specific config such as BACnet: +Use `BridgeProvisioningStore` to persist bridge models: ```cpp BridgeRuntimeConfig runtime; @@ -224,4 +223,4 @@ idf.py set-target esp32s3 idf.py build ``` -The example persists its bridge config in NVS, starts a real Modbus TCP listener, registers Modbus and BACnet bridge models, and routes Modbus writes through the shared bridge engine. The DALI gateway callbacks are still placeholders where you should connect your UART or transport driver. +The example persists its bridge config in NVS, registers generic bridge models, and routes requests through the shared bridge engine. The DALI gateway callbacks are still placeholders where you should connect your UART or transport driver. Use `gateway/apps/gateway` to exercise the gateway-owned Modbus and BACnet runtimes. diff --git a/examples/esp32s3_bridge/README.md b/examples/esp32s3_bridge/README.md index beb88a9..abc8406 100644 --- a/examples/esp32s3_bridge/README.md +++ b/examples/esp32s3_bridge/README.md @@ -1,6 +1,6 @@ # ESP32-S3 Bridge Example -This ESP-IDF example wires `dali_cpp` into a standalone application and demonstrates how to register strongly typed bridge and BACnet models. Modbus runtime support now lives in the native gateway project. +This ESP-IDF example wires `dali_cpp` into a standalone application and demonstrates how to register strongly typed bridge models. Modbus and BACnet runtime support now live in the native gateway project. ## Environment @@ -21,9 +21,8 @@ idf.py build - `DaliBridgeEngine` resolving model bindings. - `BridgeProvisioningStore` loading and saving model/config state in NVS. -- `DaliBacnetBridge` mapping BACnet property writes to DALI brightness percentage updates. - Placeholder DALI gateway callbacks where you can connect your UART transport. ## Modbus Notes -The gateway implementation in `gateway/components/gateway_modbus` owns Modbus TCP, generated DALI point tables, and provisioned Modbus overrides. Use `gateway/apps/gateway` to exercise Modbus behavior. \ No newline at end of file +The gateway implementation in `gateway/components/gateway_modbus` owns Modbus TCP, generated DALI point tables, and provisioned Modbus overrides. `gateway/components/gateway_bacnet` owns BACnet/IP object publishing and present-value routing. Use `gateway/apps/gateway` to exercise protocol behavior. \ No newline at end of file diff --git a/examples/esp32s3_bridge/main/main.cpp b/examples/esp32s3_bridge/main/main.cpp index 9cc1304..d721a71 100644 --- a/examples/esp32s3_bridge/main/main.cpp +++ b/examples/esp32s3_bridge/main/main.cpp @@ -1,4 +1,3 @@ -#include "bacnet_bridge.hpp" #include "bridge.hpp" #include "bridge_model.hpp" #include "bridge_provisioning.hpp" @@ -56,32 +55,10 @@ BridgeModel makeStatusQueryModel() { return model; } -BridgeModel makeBacnetBrightnessModel() { - BridgeModel model; - model.id = "bacnet-zone-2"; - model.name = "BACnet zone 2 level"; - model.protocol = BridgeProtocolKind::bacnet; - model.external.network = "floor-2"; - model.external.device = "bacnet-controller"; - model.external.objectType = BridgeObjectType::analogOutput; - model.external.objectInstance = 2; - model.external.property = "presentValue"; - model.dali.shortAddress = 2; - model.operation = BridgeOperation::setBrightnessPercent; - model.valueEncoding = BridgeValueEncoding::percentage; - return model; -} - BridgeRuntimeConfig makeDefaultRuntimeConfig() { BridgeRuntimeConfig config; config.models.push_back(makeBrightnessModel()); config.models.push_back(makeStatusQueryModel()); - config.models.push_back(makeBacnetBrightnessModel()); - - BacnetBridgeConfig bacnet; - bacnet.deviceInstance = 1001; - bacnet.localAddress = "192.168.10.20"; - config.bacnet = bacnet; config.metadata["example"] = "esp32s3_bridge"; return config; @@ -115,26 +92,12 @@ extern "C" void app_main(void) { engine.upsertModel(model); } - static DaliBacnetBridge bacnet(engine); - BacnetBridgeConfig bacnet_config = runtime_config.bacnet.value_or(BacnetBridgeConfig{}); - bacnet.setConfig(bacnet_config); - - for (const auto& binding : bacnet.describeObjects()) { - ESP_LOGI(kTag, "bacnet binding model=%s object=%s:%d property=%s", - binding.modelID.c_str(), bridgeObjectTypeToString(binding.objectType), - binding.objectInstance, binding.property.c_str()); - } - DaliBridgeRequest brightness_request; brightness_request.sequence = "startup-brightness"; brightness_request.modelID = "line-1-brightness"; brightness_request.value = 180; logResult("bridge brightness", engine.execute(brightness_request)); - const DaliBridgeResult bacnet_result = - bacnet.handlePropertyWrite(BridgeObjectType::analogOutput, 2, "presentValue", 75.0); - logResult("bacnet write", bacnet_result); - DaliBridgeRequest status_request; status_request.sequence = "startup-status"; status_request.modelID = "line-1-status"; diff --git a/include/bacnet_bridge.hpp b/include/bacnet_bridge.hpp deleted file mode 100644 index ba491d9..0000000 --- a/include/bacnet_bridge.hpp +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include "bridge.hpp" - -#include -#include -#include -#include - -struct BacnetBridgeConfig { - uint32_t deviceInstance = 4194303; - std::string localAddress; - uint16_t udpPort = 47808; -}; - -struct BacnetObjectBinding { - std::string modelID; - BridgeObjectType objectType = BridgeObjectType::unknown; - int objectInstance = -1; - std::string property; - BridgeOperation operation = BridgeOperation::unknown; - BridgeDaliTarget target; -}; - -class DaliBacnetBridge { - public: - explicit DaliBacnetBridge(DaliBridgeEngine& engine); - - void setConfig(const BacnetBridgeConfig& config); - const BacnetBridgeConfig& config() const; - - DaliBridgeResult handlePropertyWrite(BridgeObjectType objectType, - int objectInstance, - const std::string& property, - const DaliValue& value) const; - std::optional findObject(BridgeObjectType objectType, - int objectInstance, - const std::string& property) const; - std::vector describeObjects() const; - - private: - DaliBridgeEngine& engine_; - BacnetBridgeConfig config_; -}; \ No newline at end of file diff --git a/include/bridge_provisioning.hpp b/include/bridge_provisioning.hpp index e674f9e..663b18c 100644 --- a/include/bridge_provisioning.hpp +++ b/include/bridge_provisioning.hpp @@ -1,9 +1,7 @@ #pragma once -#include "bacnet_bridge.hpp" #include "bridge_model.hpp" -#include #include #include @@ -17,7 +15,6 @@ using esp_err_t = int; struct BridgeRuntimeConfig { std::vector models; - std::optional bacnet; DaliValue::Object metadata; static BridgeRuntimeConfig fromJson(const DaliValue::Object& json); diff --git a/include/dali.hpp b/include/dali.hpp index 913b4a8..466be18 100644 --- a/include/dali.hpp +++ b/include/dali.hpp @@ -1,7 +1,6 @@ #pragma once #include "base.hpp" -#include "bacnet_bridge.hpp" #include "bridge.hpp" #include "bridge_model.hpp" #include "bridge_provisioning.hpp" diff --git a/src/bacnet_bridge.cpp b/src/bacnet_bridge.cpp deleted file mode 100644 index ed23dc4..0000000 --- a/src/bacnet_bridge.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "bacnet_bridge.hpp" - -#include - -DaliBacnetBridge::DaliBacnetBridge(DaliBridgeEngine& engine) : engine_(engine) {} - -void DaliBacnetBridge::setConfig(const BacnetBridgeConfig& config) { config_ = config; } - -const BacnetBridgeConfig& DaliBacnetBridge::config() const { return config_; } - -DaliBridgeResult DaliBacnetBridge::handlePropertyWrite(BridgeObjectType objectType, - int objectInstance, - const std::string& property, - const DaliValue& value) const { - const auto binding = findObject(objectType, objectInstance, property); - DaliBridgeRequest request; - request.sequence = "bacnet-" + std::to_string(objectInstance); - request.value = value; - - if (!binding.has_value()) { - DaliBridgeResult result; - result.sequence = request.sequence; - result.error = "unmapped bacnet object"; - return result; - } - - request.modelID = binding->modelID; - return engine_.execute(request); -} - -std::optional DaliBacnetBridge::findObject(BridgeObjectType objectType, - int objectInstance, - const std::string& property) const { - for (const auto& model : engine_.listModels()) { - if (model.protocol != BridgeProtocolKind::bacnet) { - continue; - } - if (model.external.objectType != objectType) { - continue; - } - if (model.external.objectInstance.value_or(-1) != objectInstance) { - continue; - } - if (!model.external.property.empty() && model.external.property != property) { - continue; - } - return BacnetObjectBinding{model.id, objectType, objectInstance, property, - model.operation, model.dali}; - } - return std::nullopt; -} - -std::vector DaliBacnetBridge::describeObjects() const { - std::vector bindings; - for (const auto& model : engine_.listModels()) { - if (model.protocol != BridgeProtocolKind::bacnet || !model.external.objectInstance.has_value()) { - continue; - } - bindings.push_back(BacnetObjectBinding{model.id, model.external.objectType, - model.external.objectInstance.value(), - model.external.property, model.operation, - model.dali}); - } - return bindings; -} \ No newline at end of file diff --git a/src/bridge_provisioning.cpp b/src/bridge_provisioning.cpp index bb20d18..140f0fe 100644 --- a/src/bridge_provisioning.cpp +++ b/src/bridge_provisioning.cpp @@ -101,26 +101,6 @@ esp_err_t readString(nvs_handle_t handle, const char* key, std::string* value) { return ESP_OK; } -std::optional bacnetFromJson(const DaliValue* value) { - if (value == nullptr || value->asObject() == nullptr) { - return std::nullopt; - } - const auto& json = *value->asObject(); - BacnetBridgeConfig config; - config.deviceInstance = static_cast(getObjectInt(json, "deviceInstance").value_or(4194303)); - config.localAddress = getObjectString(json, "localAddress").value_or(""); - config.udpPort = static_cast(getObjectInt(json, "udpPort").value_or(47808)); - return config; -} - -DaliValue bacnetToJson(const BacnetBridgeConfig& config) { - DaliValue::Object out; - out["deviceInstance"] = static_cast(config.deviceInstance); - out["localAddress"] = config.localAddress; - out["udpPort"] = static_cast(config.udpPort); - return DaliValue(std::move(out)); -} - esp_err_t saveJsonObject(const std::string& nvs_namespace, const char* key, const DaliValue::Object& object) { if (key == nullptr || key[0] == '\0') { @@ -227,7 +207,6 @@ BridgeRuntimeConfig BridgeRuntimeConfig::fromJson(const DaliValue::Object& json) } } } - config.bacnet = bacnetFromJson(getObjectValue(json, "bacnet")); if (const auto* metadata = getObjectValue(json, "meta")) { if (const auto* object = metadata->asObject()) { config.metadata = *object; @@ -244,7 +223,6 @@ DaliValue::Object BridgeRuntimeConfig::toJson() const { modelsValue.emplace_back(model.toJson()); } out["models"] = std::move(modelsValue); - if (bacnet.has_value()) out["bacnet"] = bacnetToJson(bacnet.value()); if (!metadata.empty()) out["meta"] = metadata; return out; }