feat(gateway): add cloud integration for KNX and DALI with configurable transport options
Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
@@ -1010,6 +1010,57 @@ config GATEWAY_START_CLOUD_BRIDGE_ENABLED
|
|||||||
help
|
help
|
||||||
Starts configured MQTT cloud bridges at boot when broker URI and device id are present.
|
Starts configured MQTT cloud bridges at boot when broker URI and device id are present.
|
||||||
|
|
||||||
|
config GATEWAY_CLOUD_TOPIC_PREFIX
|
||||||
|
string "Default MQTT cloud topic prefix"
|
||||||
|
depends on GATEWAY_CLOUD_BRIDGE_SUPPORTED
|
||||||
|
default "devices"
|
||||||
|
help
|
||||||
|
Topic namespace used for canonical MQTT cloud bridge traffic.
|
||||||
|
|
||||||
|
choice GATEWAY_CLOUD_CEMI_TRANSPORT
|
||||||
|
prompt "Default KNX cEMI cloud transport"
|
||||||
|
depends on GATEWAY_CLOUD_BRIDGE_SUPPORTED
|
||||||
|
default GATEWAY_CLOUD_CEMI_TRANSPORT_MQTT
|
||||||
|
help
|
||||||
|
Selects the default transport for cloud KNX cEMI proxy envelopes.
|
||||||
|
|
||||||
|
config GATEWAY_CLOUD_CEMI_TRANSPORT_MQTT
|
||||||
|
bool "MQTT topics only"
|
||||||
|
|
||||||
|
config GATEWAY_CLOUD_CEMI_TRANSPORT_LTE_UART
|
||||||
|
bool "LTE UART transparent bridge only"
|
||||||
|
|
||||||
|
config GATEWAY_CLOUD_CEMI_TRANSPORT_MQTT_AND_LTE_UART
|
||||||
|
bool "MQTT topics and LTE UART"
|
||||||
|
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config GATEWAY_CLOUD_LTE_UART_PORT
|
||||||
|
int "LTE UART port for cEMI transparent bridge"
|
||||||
|
depends on GATEWAY_CLOUD_BRIDGE_SUPPORTED
|
||||||
|
range -1 2
|
||||||
|
default -1
|
||||||
|
help
|
||||||
|
UART index used by a transparent 4G LTE module. Use -1 to leave it disabled.
|
||||||
|
|
||||||
|
config GATEWAY_CLOUD_LTE_UART_TX_PIN
|
||||||
|
int "LTE UART TX pin"
|
||||||
|
depends on GATEWAY_CLOUD_BRIDGE_SUPPORTED
|
||||||
|
range -1 48
|
||||||
|
default -1
|
||||||
|
|
||||||
|
config GATEWAY_CLOUD_LTE_UART_RX_PIN
|
||||||
|
int "LTE UART RX pin"
|
||||||
|
depends on GATEWAY_CLOUD_BRIDGE_SUPPORTED
|
||||||
|
range -1 48
|
||||||
|
default -1
|
||||||
|
|
||||||
|
config GATEWAY_CLOUD_LTE_UART_BAUDRATE
|
||||||
|
int "LTE UART baudrate"
|
||||||
|
depends on GATEWAY_CLOUD_BRIDGE_SUPPORTED
|
||||||
|
range 1200 921600
|
||||||
|
default 115200
|
||||||
|
|
||||||
config GATEWAY_BRIDGE_MODBUS_TASK_STACK_SIZE
|
config GATEWAY_BRIDGE_MODBUS_TASK_STACK_SIZE
|
||||||
int "Modbus bridge task stack bytes"
|
int "Modbus bridge task stack bytes"
|
||||||
depends on GATEWAY_MODBUS_BRIDGE_SUPPORTED
|
depends on GATEWAY_MODBUS_BRIDGE_SUPPORTED
|
||||||
|
|||||||
+19
-2
@@ -696,7 +696,7 @@ CONFIG_GATEWAY_KNX_INSTANCE_COUNT=1
|
|||||||
CONFIG_GATEWAY_KNX_BRIDGE_SUPPORTED=y
|
CONFIG_GATEWAY_KNX_BRIDGE_SUPPORTED=y
|
||||||
CONFIG_GATEWAY_START_KNX_BRIDGE_ENABLED=y
|
CONFIG_GATEWAY_START_KNX_BRIDGE_ENABLED=y
|
||||||
CONFIG_GATEWAY_KNX_DATA_SECURE_SUPPORTED=y
|
CONFIG_GATEWAY_KNX_DATA_SECURE_SUPPORTED=y
|
||||||
# CONFIG_GATEWAY_KNX_IP_SECURE_SUPPORTED is not set
|
CONFIG_GATEWAY_KNX_IP_SECURE_SUPPORTED=y
|
||||||
CONFIG_GATEWAY_KNX_SECURITY_DEV_ENDPOINTS=y
|
CONFIG_GATEWAY_KNX_SECURITY_DEV_ENDPOINTS=y
|
||||||
CONFIG_GATEWAY_KNX_SECURITY_PLAIN_NVS=y
|
CONFIG_GATEWAY_KNX_SECURITY_PLAIN_NVS=y
|
||||||
CONFIG_GATEWAY_KNX_OEM_MANUFACTURER_ID=0x01e5
|
CONFIG_GATEWAY_KNX_OEM_MANUFACTURER_ID=0x01e5
|
||||||
@@ -712,7 +712,16 @@ CONFIG_GATEWAY_KNX_UDP_PORT=3671
|
|||||||
CONFIG_GATEWAY_KNX_MULTICAST_ADDRESS="224.0.23.12"
|
CONFIG_GATEWAY_KNX_MULTICAST_ADDRESS="224.0.23.12"
|
||||||
CONFIG_GATEWAY_KNX_IP_INTERFACE_INDIVIDUAL_ADDRESS=65281
|
CONFIG_GATEWAY_KNX_IP_INTERFACE_INDIVIDUAL_ADDRESS=65281
|
||||||
CONFIG_GATEWAY_KNX_INDIVIDUAL_ADDRESS=65534
|
CONFIG_GATEWAY_KNX_INDIVIDUAL_ADDRESS=65534
|
||||||
# CONFIG_GATEWAY_KNX_OAM_ROUTER_SUPPORTED is not set
|
CONFIG_GATEWAY_KNX_OAM_ROUTER_SUPPORTED=y
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_ROUTER_ENABLED=y
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_ROUTER_OEM_MANUFACTURER_ID=0x00FA
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_ROUTER_HARDWARE_ID=0x0001
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_ROUTER_APPLICATION_NUMBER=0xA11F
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_ROUTER_APPLICATION_VERSION=0x07
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_ROUTER_INDIVIDUAL_ADDRESS=65282
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_ROUTER_TUNNEL_ADDRESS_BASE=65296
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_PROGRAMMING_BUTTON_GPIO=-1
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_PROGRAMMING_LED_GPIO=-1
|
||||||
CONFIG_GATEWAY_KNX_PROGRAMMING_BUTTON_GPIO=0
|
CONFIG_GATEWAY_KNX_PROGRAMMING_BUTTON_GPIO=0
|
||||||
CONFIG_GATEWAY_KNX_PROGRAMMING_BUTTON_ACTIVE_LOW=y
|
CONFIG_GATEWAY_KNX_PROGRAMMING_BUTTON_ACTIVE_LOW=y
|
||||||
CONFIG_GATEWAY_KNX_PROGRAMMING_LED_GPIO=10
|
CONFIG_GATEWAY_KNX_PROGRAMMING_LED_GPIO=10
|
||||||
@@ -730,6 +739,14 @@ CONFIG_GATEWAY_BRIDGE_KNX_TASK_PRIORITY=5
|
|||||||
|
|
||||||
CONFIG_GATEWAY_CLOUD_BRIDGE_SUPPORTED=y
|
CONFIG_GATEWAY_CLOUD_BRIDGE_SUPPORTED=y
|
||||||
# CONFIG_GATEWAY_START_CLOUD_BRIDGE_ENABLED is not set
|
# CONFIG_GATEWAY_START_CLOUD_BRIDGE_ENABLED is not set
|
||||||
|
CONFIG_GATEWAY_CLOUD_TOPIC_PREFIX="devices"
|
||||||
|
CONFIG_GATEWAY_CLOUD_CEMI_TRANSPORT_MQTT=y
|
||||||
|
# CONFIG_GATEWAY_CLOUD_CEMI_TRANSPORT_LTE_UART is not set
|
||||||
|
# CONFIG_GATEWAY_CLOUD_CEMI_TRANSPORT_MQTT_AND_LTE_UART is not set
|
||||||
|
CONFIG_GATEWAY_CLOUD_LTE_UART_PORT=-1
|
||||||
|
CONFIG_GATEWAY_CLOUD_LTE_UART_TX_PIN=-1
|
||||||
|
CONFIG_GATEWAY_CLOUD_LTE_UART_RX_PIN=-1
|
||||||
|
CONFIG_GATEWAY_CLOUD_LTE_UART_BAUDRATE=115200
|
||||||
CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_STACK_SIZE=6144
|
CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_STACK_SIZE=6144
|
||||||
CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_PRIORITY=4
|
CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_PRIORITY=4
|
||||||
CONFIG_GATEWAY_BRIDGE_BACNET_TASK_STACK_SIZE=8192
|
CONFIG_GATEWAY_BRIDGE_BACNET_TASK_STACK_SIZE=8192
|
||||||
|
|||||||
@@ -596,7 +596,11 @@ CONFIG_PARTITION_TABLE_MD5=y
|
|||||||
#
|
#
|
||||||
# Gateway App
|
# Gateway App
|
||||||
#
|
#
|
||||||
CONFIG_GATEWAY_CHANNEL_COUNT=1
|
|
||||||
|
#
|
||||||
|
# DALI Settings
|
||||||
|
#
|
||||||
|
CONFIG_GATEWAY_CHANNEL_COUNT=2
|
||||||
|
|
||||||
#
|
#
|
||||||
# Gateway Channel 1
|
# Gateway Channel 1
|
||||||
@@ -615,6 +619,15 @@ CONFIG_GATEWAY_CHANNEL1_NATIVE_BAUDRATE=1200
|
|||||||
#
|
#
|
||||||
# Gateway Channel 2
|
# Gateway Channel 2
|
||||||
#
|
#
|
||||||
|
CONFIG_GATEWAY_CHANNEL2_GW_ID=4
|
||||||
|
# CONFIG_GATEWAY_CHANNEL2_PHY_DISABLED is not set
|
||||||
|
CONFIG_GATEWAY_CHANNEL2_PHY_NATIVE=y
|
||||||
|
# CONFIG_GATEWAY_CHANNEL2_PHY_UART1 is not set
|
||||||
|
# CONFIG_GATEWAY_CHANNEL2_PHY_UART2 is not set
|
||||||
|
CONFIG_GATEWAY_CHANNEL2_NATIVE_BUS_ID=1
|
||||||
|
CONFIG_GATEWAY_CHANNEL2_NATIVE_TX_PIN=4
|
||||||
|
CONFIG_GATEWAY_CHANNEL2_NATIVE_RX_PIN=3
|
||||||
|
CONFIG_GATEWAY_CHANNEL2_NATIVE_BAUDRATE=1200
|
||||||
# end of Gateway Channel 2
|
# end of Gateway Channel 2
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -624,13 +637,14 @@ CONFIG_GATEWAY_CACHE_SUPPORTED=y
|
|||||||
CONFIG_GATEWAY_CACHE_START_ENABLED=y
|
CONFIG_GATEWAY_CACHE_START_ENABLED=y
|
||||||
CONFIG_GATEWAY_CACHE_RECONCILIATION_ENABLED=y
|
CONFIG_GATEWAY_CACHE_RECONCILIATION_ENABLED=y
|
||||||
CONFIG_GATEWAY_CACHE_FULL_STATE_MIRROR=y
|
CONFIG_GATEWAY_CACHE_FULL_STATE_MIRROR=y
|
||||||
CONFIG_GATEWAY_CACHE_FLUSH_INTERVAL_MS=10000
|
CONFIG_GATEWAY_CACHE_FLUSH_INTERVAL_MS=600000
|
||||||
CONFIG_GATEWAY_CACHE_REFRESH_INTERVAL_MS=120000
|
CONFIG_GATEWAY_CACHE_REFRESH_INTERVAL_MS=120000
|
||||||
CONFIG_GATEWAY_CACHE_OUTSIDE_BUS_FIRST=y
|
CONFIG_GATEWAY_CACHE_OUTSIDE_BUS_FIRST=y
|
||||||
# CONFIG_GATEWAY_CACHE_LOCAL_GATEWAY_FIRST is not set
|
# CONFIG_GATEWAY_CACHE_LOCAL_GATEWAY_FIRST is not set
|
||||||
# end of Gateway Cache
|
# end of Gateway Cache
|
||||||
|
|
||||||
# CONFIG_GATEWAY_ENABLE_DALI_BUS is not set
|
# CONFIG_GATEWAY_ENABLE_DALI_BUS is not set
|
||||||
|
# end of DALI Settings
|
||||||
|
|
||||||
#
|
#
|
||||||
# Gateway Startup Services
|
# Gateway Startup Services
|
||||||
@@ -674,6 +688,11 @@ CONFIG_GATEWAY_MODBUS_TCP_PORT=1502
|
|||||||
CONFIG_GATEWAY_MODBUS_UNIT_ID=1
|
CONFIG_GATEWAY_MODBUS_UNIT_ID=1
|
||||||
CONFIG_GATEWAY_BACNET_BRIDGE_SUPPORTED=y
|
CONFIG_GATEWAY_BACNET_BRIDGE_SUPPORTED=y
|
||||||
# CONFIG_GATEWAY_START_BACNET_BRIDGE_ENABLED is not set
|
# CONFIG_GATEWAY_START_BACNET_BRIDGE_ENABLED is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# KNX Settings
|
||||||
|
#
|
||||||
|
CONFIG_GATEWAY_KNX_INSTANCE_COUNT=1
|
||||||
CONFIG_GATEWAY_KNX_BRIDGE_SUPPORTED=y
|
CONFIG_GATEWAY_KNX_BRIDGE_SUPPORTED=y
|
||||||
CONFIG_GATEWAY_START_KNX_BRIDGE_ENABLED=y
|
CONFIG_GATEWAY_START_KNX_BRIDGE_ENABLED=y
|
||||||
CONFIG_GATEWAY_KNX_DATA_SECURE_SUPPORTED=y
|
CONFIG_GATEWAY_KNX_DATA_SECURE_SUPPORTED=y
|
||||||
@@ -707,8 +726,18 @@ CONFIG_GATEWAY_KNX_TP_UART_9BIT_MODE=y
|
|||||||
CONFIG_GATEWAY_KNX_TP_FULL_IP_FORWARD=y
|
CONFIG_GATEWAY_KNX_TP_FULL_IP_FORWARD=y
|
||||||
CONFIG_GATEWAY_BRIDGE_KNX_TASK_STACK_SIZE=12288
|
CONFIG_GATEWAY_BRIDGE_KNX_TASK_STACK_SIZE=12288
|
||||||
CONFIG_GATEWAY_BRIDGE_KNX_TASK_PRIORITY=5
|
CONFIG_GATEWAY_BRIDGE_KNX_TASK_PRIORITY=5
|
||||||
|
# end of KNX Settings
|
||||||
|
|
||||||
CONFIG_GATEWAY_CLOUD_BRIDGE_SUPPORTED=y
|
CONFIG_GATEWAY_CLOUD_BRIDGE_SUPPORTED=y
|
||||||
# CONFIG_GATEWAY_START_CLOUD_BRIDGE_ENABLED is not set
|
# CONFIG_GATEWAY_START_CLOUD_BRIDGE_ENABLED is not set
|
||||||
|
CONFIG_GATEWAY_CLOUD_TOPIC_PREFIX="devices"
|
||||||
|
CONFIG_GATEWAY_CLOUD_CEMI_TRANSPORT_MQTT=y
|
||||||
|
# CONFIG_GATEWAY_CLOUD_CEMI_TRANSPORT_LTE_UART is not set
|
||||||
|
# CONFIG_GATEWAY_CLOUD_CEMI_TRANSPORT_MQTT_AND_LTE_UART is not set
|
||||||
|
CONFIG_GATEWAY_CLOUD_LTE_UART_PORT=-1
|
||||||
|
CONFIG_GATEWAY_CLOUD_LTE_UART_TX_PIN=-1
|
||||||
|
CONFIG_GATEWAY_CLOUD_LTE_UART_RX_PIN=-1
|
||||||
|
CONFIG_GATEWAY_CLOUD_LTE_UART_BAUDRATE=115200
|
||||||
CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_STACK_SIZE=6144
|
CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_STACK_SIZE=6144
|
||||||
CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_PRIORITY=4
|
CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_PRIORITY=4
|
||||||
CONFIG_GATEWAY_BRIDGE_BACNET_TASK_STACK_SIZE=8192
|
CONFIG_GATEWAY_BRIDGE_BACNET_TASK_STACK_SIZE=8192
|
||||||
@@ -1652,7 +1681,7 @@ CONFIG_ESP_NETIF_TCPIP_LWIP=y
|
|||||||
# CONFIG_ESP_NETIF_LOOPBACK is not set
|
# CONFIG_ESP_NETIF_LOOPBACK is not set
|
||||||
CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y
|
CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y
|
||||||
CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y
|
CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y
|
||||||
# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set
|
CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS=y
|
||||||
# CONFIG_ESP_NETIF_L2_TAP is not set
|
# CONFIG_ESP_NETIF_L2_TAP is not set
|
||||||
# CONFIG_ESP_NETIF_BRIDGE_EN is not set
|
# CONFIG_ESP_NETIF_BRIDGE_EN is not set
|
||||||
# CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set
|
# CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set
|
||||||
|
|||||||
@@ -1226,6 +1226,28 @@ std::optional<GatewayBridgeStoredConfig> GatewayBridgeStoredConfigFromJson(std::
|
|||||||
|
|
||||||
GatewayCloudConfig GatewayCloudConfigFromJson(cJSON* root) {
|
GatewayCloudConfig GatewayCloudConfigFromJson(cJSON* root) {
|
||||||
GatewayCloudConfig config;
|
GatewayCloudConfig config;
|
||||||
|
#if defined(CONFIG_GATEWAY_CLOUD_TOPIC_PREFIX)
|
||||||
|
config.topicPrefix = CONFIG_GATEWAY_CLOUD_TOPIC_PREFIX;
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_GATEWAY_CLOUD_CEMI_TRANSPORT_LTE_UART)
|
||||||
|
config.cemiTransport = "lte_uart";
|
||||||
|
config.lteUartEnabled = true;
|
||||||
|
#elif defined(CONFIG_GATEWAY_CLOUD_CEMI_TRANSPORT_MQTT_AND_LTE_UART)
|
||||||
|
config.cemiTransport = "mqtt_lte_uart";
|
||||||
|
config.lteUartEnabled = true;
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_GATEWAY_CLOUD_LTE_UART_PORT)
|
||||||
|
config.lteUartPort = CONFIG_GATEWAY_CLOUD_LTE_UART_PORT;
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_GATEWAY_CLOUD_LTE_UART_TX_PIN)
|
||||||
|
config.lteTxPin = CONFIG_GATEWAY_CLOUD_LTE_UART_TX_PIN;
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_GATEWAY_CLOUD_LTE_UART_RX_PIN)
|
||||||
|
config.lteRxPin = CONFIG_GATEWAY_CLOUD_LTE_UART_RX_PIN;
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_GATEWAY_CLOUD_LTE_UART_BAUDRATE)
|
||||||
|
config.lteBaudrate = CONFIG_GATEWAY_CLOUD_LTE_UART_BAUDRATE;
|
||||||
|
#endif
|
||||||
if (const char* value = JsonString(root, "brokerURI")) {
|
if (const char* value = JsonString(root, "brokerURI")) {
|
||||||
config.brokerURI = value;
|
config.brokerURI = value;
|
||||||
}
|
}
|
||||||
@@ -1241,6 +1263,28 @@ GatewayCloudConfig GatewayCloudConfigFromJson(cJSON* root) {
|
|||||||
if (const char* value = JsonString(root, "topicPrefix")) {
|
if (const char* value = JsonString(root, "topicPrefix")) {
|
||||||
config.topicPrefix = value;
|
config.topicPrefix = value;
|
||||||
}
|
}
|
||||||
|
if (const char* value = JsonString(root, "cemiTransport")) {
|
||||||
|
config.cemiTransport = value;
|
||||||
|
}
|
||||||
|
config.lteUartEnabled = JsonBool(root, "lteUartEnabled", config.lteUartEnabled);
|
||||||
|
if (const auto value = JsonInt(root, "lteUartPort")) {
|
||||||
|
config.lteUartPort = value.value();
|
||||||
|
}
|
||||||
|
if (const auto value = JsonInt(root, "lteTxPin")) {
|
||||||
|
config.lteTxPin = value.value();
|
||||||
|
}
|
||||||
|
if (const auto value = JsonInt(root, "lteRxPin")) {
|
||||||
|
config.lteRxPin = value.value();
|
||||||
|
}
|
||||||
|
if (const auto value = JsonInt(root, "lteBaudrate")) {
|
||||||
|
config.lteBaudrate = value.value();
|
||||||
|
}
|
||||||
|
if (const auto value = JsonInt(root, "lteRxBufferSize")) {
|
||||||
|
config.lteRxBufferSize = value.value();
|
||||||
|
}
|
||||||
|
if (const auto value = JsonInt(root, "lteTxBufferSize")) {
|
||||||
|
config.lteTxBufferSize = value.value();
|
||||||
|
}
|
||||||
if (const auto qos = JsonInt(root, "qos")) {
|
if (const auto qos = JsonInt(root, "qos")) {
|
||||||
config.qos = qos.value();
|
config.qos = qos.value();
|
||||||
}
|
}
|
||||||
@@ -1257,6 +1301,14 @@ cJSON* GatewayCloudConfigToCjson(const GatewayCloudConfig& config) {
|
|||||||
cJSON_AddStringToObject(root, "username", config.username.c_str());
|
cJSON_AddStringToObject(root, "username", config.username.c_str());
|
||||||
cJSON_AddStringToObject(root, "password", config.password.c_str());
|
cJSON_AddStringToObject(root, "password", config.password.c_str());
|
||||||
cJSON_AddStringToObject(root, "topicPrefix", config.topicPrefix.c_str());
|
cJSON_AddStringToObject(root, "topicPrefix", config.topicPrefix.c_str());
|
||||||
|
cJSON_AddStringToObject(root, "cemiTransport", config.cemiTransport.c_str());
|
||||||
|
cJSON_AddBoolToObject(root, "lteUartEnabled", config.lteUartEnabled);
|
||||||
|
cJSON_AddNumberToObject(root, "lteUartPort", config.lteUartPort);
|
||||||
|
cJSON_AddNumberToObject(root, "lteTxPin", config.lteTxPin);
|
||||||
|
cJSON_AddNumberToObject(root, "lteRxPin", config.lteRxPin);
|
||||||
|
cJSON_AddNumberToObject(root, "lteBaudrate", config.lteBaudrate);
|
||||||
|
cJSON_AddNumberToObject(root, "lteRxBufferSize", config.lteRxBufferSize);
|
||||||
|
cJSON_AddNumberToObject(root, "lteTxBufferSize", config.lteTxBufferSize);
|
||||||
cJSON_AddNumberToObject(root, "qos", config.qos);
|
cJSON_AddNumberToObject(root, "qos", config.qos);
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
@@ -1832,6 +1884,22 @@ struct GatewayBridgeService::ChannelRuntime {
|
|||||||
for (const auto& model : bridge_config.models) {
|
for (const auto& model : bridge_config.models) {
|
||||||
cloud->bridge().upsertModel(model);
|
cloud->bridge().upsertModel(model);
|
||||||
}
|
}
|
||||||
|
wireCloudCemiProxyLocked();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wireCloudCemiProxyLocked() {
|
||||||
|
if (knx_router != nullptr) {
|
||||||
|
knx_router->setCloudCemiPublisher([this](const uint8_t* data, size_t len) {
|
||||||
|
if (cloud_started && cloud != nullptr) {
|
||||||
|
cloud->publishCemiFrame(data, len);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (cloud != nullptr) {
|
||||||
|
cloud->setCemiDownlinkHandler([this](const uint8_t* data, size_t len) {
|
||||||
|
return knx_router != nullptr && knx_router->injectCloudCemiFrame(data, len);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t saveBridgeConfig(std::string_view json) {
|
esp_err_t saveBridgeConfig(std::string_view json) {
|
||||||
@@ -2454,8 +2522,12 @@ struct GatewayBridgeService::ChannelRuntime {
|
|||||||
cJSON* cloud_remote_json = cJSON_CreateObject();
|
cJSON* cloud_remote_json = cJSON_CreateObject();
|
||||||
if (cloud_remote_json != nullptr) {
|
if (cloud_remote_json != nullptr) {
|
||||||
const auto& cloud_remote = effective_knx->oam_router.cloud_remote;
|
const auto& cloud_remote = effective_knx->oam_router.cloud_remote;
|
||||||
|
const auto cloud_stats = knx_router == nullptr
|
||||||
|
? GatewayKnxTpIpRouter::CloudCemiStats{}
|
||||||
|
: knx_router->cloudCemiStats();
|
||||||
cJSON_AddBoolToObject(cloud_remote_json, "prepared", true);
|
cJSON_AddBoolToObject(cloud_remote_json, "prepared", true);
|
||||||
cJSON_AddBoolToObject(cloud_remote_json, "enabled", cloud_remote.enabled);
|
cJSON_AddBoolToObject(cloud_remote_json, "enabled", cloud_remote.enabled);
|
||||||
|
cJSON_AddBoolToObject(cloud_remote_json, "running", cloud_stats.enabled);
|
||||||
cJSON_AddStringToObject(cloud_remote_json, "mode", cloud_remote.mode.c_str());
|
cJSON_AddStringToObject(cloud_remote_json, "mode", cloud_remote.mode.c_str());
|
||||||
cJSON_AddBoolToObject(cloud_remote_json, "requireSecureTunnel",
|
cJSON_AddBoolToObject(cloud_remote_json, "requireSecureTunnel",
|
||||||
cloud_remote.require_secure_tunnel);
|
cloud_remote.require_secure_tunnel);
|
||||||
@@ -2467,6 +2539,10 @@ struct GatewayBridgeService::ChannelRuntime {
|
|||||||
!cloud_remote.mqtt_topic_prefix.empty());
|
!cloud_remote.mqtt_topic_prefix.empty());
|
||||||
cJSON_AddBoolToObject(cloud_remote_json, "authTokenRefConfigured",
|
cJSON_AddBoolToObject(cloud_remote_json, "authTokenRefConfigured",
|
||||||
!cloud_remote.auth_token_ref.empty());
|
!cloud_remote.auth_token_ref.empty());
|
||||||
|
cJSON_AddNumberToObject(cloud_remote_json, "uplinkFrames",
|
||||||
|
static_cast<double>(cloud_stats.uplink_frames));
|
||||||
|
cJSON_AddNumberToObject(cloud_remote_json, "downlinkFrames",
|
||||||
|
static_cast<double>(cloud_stats.downlink_frames));
|
||||||
cJSON_AddItemToObject(knx_json, "cloudKnxRemoteAccess", cloud_remote_json);
|
cJSON_AddItemToObject(knx_json, "cloudKnxRemoteAccess", cloud_remote_json);
|
||||||
}
|
}
|
||||||
cJSON* serial_json = cJSON_CreateObject();
|
cJSON* serial_json = cJSON_CreateObject();
|
||||||
@@ -2564,9 +2640,16 @@ struct GatewayBridgeService::ChannelRuntime {
|
|||||||
cJSON_AddBoolToObject(cloud_json, "configured", cloud_config_loaded);
|
cJSON_AddBoolToObject(cloud_json, "configured", cloud_config_loaded);
|
||||||
cJSON_AddBoolToObject(cloud_json, "started", cloud_started);
|
cJSON_AddBoolToObject(cloud_json, "started", cloud_started);
|
||||||
cJSON_AddBoolToObject(cloud_json, "connected", cloud != nullptr && cloud->isConnected());
|
cJSON_AddBoolToObject(cloud_json, "connected", cloud != nullptr && cloud->isConnected());
|
||||||
|
cJSON_AddBoolToObject(cloud_json, "lteUartActive",
|
||||||
|
cloud != nullptr && cloud->lteUartActive());
|
||||||
if (cloud_config.has_value()) {
|
if (cloud_config.has_value()) {
|
||||||
cJSON_AddStringToObject(cloud_json, "deviceID", cloud_config->deviceID.c_str());
|
cJSON_AddStringToObject(cloud_json, "deviceID", cloud_config->deviceID.c_str());
|
||||||
cJSON_AddStringToObject(cloud_json, "topicPrefix", cloud_config->topicPrefix.c_str());
|
cJSON_AddStringToObject(cloud_json, "topicPrefix", cloud_config->topicPrefix.c_str());
|
||||||
|
cJSON_AddStringToObject(cloud_json, "cemiTransport",
|
||||||
|
cloud_config->cemiTransport.c_str());
|
||||||
|
cJSON_AddBoolToObject(cloud_json, "lteUartEnabled",
|
||||||
|
cloud_config->lteUartEnabled);
|
||||||
|
cJSON_AddNumberToObject(cloud_json, "lteUartPort", cloud_config->lteUartPort);
|
||||||
}
|
}
|
||||||
cJSON_AddItemToObject(root, "cloud", cloud_json);
|
cJSON_AddItemToObject(root, "cloud", cloud_json);
|
||||||
}
|
}
|
||||||
@@ -2968,6 +3051,7 @@ struct GatewayBridgeService::ChannelRuntime {
|
|||||||
cJSON_AddBoolToObject(root, "configured", cloud_config_loaded);
|
cJSON_AddBoolToObject(root, "configured", cloud_config_loaded);
|
||||||
cJSON_AddBoolToObject(root, "started", cloud_started);
|
cJSON_AddBoolToObject(root, "started", cloud_started);
|
||||||
cJSON_AddBoolToObject(root, "connected", cloud != nullptr && cloud->isConnected());
|
cJSON_AddBoolToObject(root, "connected", cloud != nullptr && cloud->isConnected());
|
||||||
|
cJSON_AddBoolToObject(root, "lteUartActive", cloud != nullptr && cloud->lteUartActive());
|
||||||
if (cloud_config.has_value()) {
|
if (cloud_config.has_value()) {
|
||||||
cJSON_AddItemToObject(root, "config", GatewayCloudConfigToCjson(cloud_config.value()));
|
cJSON_AddItemToObject(root, "config", GatewayCloudConfigToCjson(cloud_config.value()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -268,6 +268,13 @@ class GatewayKnxTpIpRouter {
|
|||||||
const uint8_t* data,
|
const uint8_t* data,
|
||||||
size_t len)>;
|
size_t len)>;
|
||||||
using RoutingSequenceStoreHandler = std::function<void(uint64_t sequence)>;
|
using RoutingSequenceStoreHandler = std::function<void(uint64_t sequence)>;
|
||||||
|
using CloudCemiPublisher = std::function<void(const uint8_t* data, size_t len)>;
|
||||||
|
|
||||||
|
struct CloudCemiStats {
|
||||||
|
bool enabled{false};
|
||||||
|
uint64_t uplink_frames{0};
|
||||||
|
uint64_t downlink_frames{0};
|
||||||
|
};
|
||||||
|
|
||||||
GatewayKnxTpIpRouter(GatewayKnxBridge& bridge,
|
GatewayKnxTpIpRouter(GatewayKnxBridge& bridge,
|
||||||
std::string openknx_namespace = "openknx");
|
std::string openknx_namespace = "openknx");
|
||||||
@@ -279,7 +286,10 @@ class GatewayKnxTpIpRouter {
|
|||||||
void setGroupObjectWriteHandler(GroupObjectWriteHandler handler);
|
void setGroupObjectWriteHandler(GroupObjectWriteHandler handler);
|
||||||
void setOamIpSecureCredentials(const GatewayKnxIpSecureCredentialMaterial& credentials);
|
void setOamIpSecureCredentials(const GatewayKnxIpSecureCredentialMaterial& credentials);
|
||||||
void setOamIpSecureRoutingSequenceStoreHandler(RoutingSequenceStoreHandler handler);
|
void setOamIpSecureRoutingSequenceStoreHandler(RoutingSequenceStoreHandler handler);
|
||||||
|
void setCloudCemiPublisher(CloudCemiPublisher publisher);
|
||||||
const GatewayKnxConfig& config() const;
|
const GatewayKnxConfig& config() const;
|
||||||
|
bool injectCloudCemiFrame(const uint8_t* data, size_t len);
|
||||||
|
CloudCemiStats cloudCemiStats() const;
|
||||||
bool tpUartOnline() const;
|
bool tpUartOnline() const;
|
||||||
bool programmingMode();
|
bool programmingMode();
|
||||||
esp_err_t setProgrammingMode(bool enabled);
|
esp_err_t setProgrammingMode(bool enabled);
|
||||||
@@ -458,6 +468,7 @@ class GatewayKnxTpIpRouter {
|
|||||||
size_t suppress_routing_echo_len = 0);
|
size_t suppress_routing_echo_len = 0);
|
||||||
bool handleOpenKnxBusFrame(const uint8_t* data, size_t len);
|
bool handleOpenKnxBusFrame(const uint8_t* data, size_t len);
|
||||||
bool transmitOpenKnxTpFrame(const uint8_t* data, size_t len);
|
bool transmitOpenKnxTpFrame(const uint8_t* data, size_t len);
|
||||||
|
void publishCloudCemiFrame(const uint8_t* data, size_t len);
|
||||||
void selectOpenKnxNetworkInterface(const ::sockaddr_in& remote);
|
void selectOpenKnxNetworkInterface(const ::sockaddr_in& remote);
|
||||||
bool routeOpenKnxGroupWrite(const uint8_t* data, size_t len, const char* context);
|
bool routeOpenKnxGroupWrite(const uint8_t* data, size_t len, const char* context);
|
||||||
bool emitOpenKnxGroupValue(uint16_t group_object_number, const uint8_t* data, size_t len);
|
bool emitOpenKnxGroupValue(uint16_t group_object_number, const uint8_t* data, size_t len);
|
||||||
@@ -476,6 +487,7 @@ class GatewayKnxTpIpRouter {
|
|||||||
GroupWriteHandler group_write_handler_;
|
GroupWriteHandler group_write_handler_;
|
||||||
GroupObjectWriteHandler group_object_write_handler_;
|
GroupObjectWriteHandler group_object_write_handler_;
|
||||||
RoutingSequenceStoreHandler routing_sequence_store_handler_;
|
RoutingSequenceStoreHandler routing_sequence_store_handler_;
|
||||||
|
CloudCemiPublisher cloud_cemi_publisher_;
|
||||||
std::string openknx_namespace_;
|
std::string openknx_namespace_;
|
||||||
GatewayKnxConfig config_;
|
GatewayKnxConfig config_;
|
||||||
std::unique_ptr<openknx::EtsDeviceRuntime> ets_device_;
|
std::unique_ptr<openknx::EtsDeviceRuntime> ets_device_;
|
||||||
@@ -505,6 +517,8 @@ class GatewayKnxTpIpRouter {
|
|||||||
bool tp_uart_online_{false};
|
bool tp_uart_online_{false};
|
||||||
bool commissioning_only_{false};
|
bool commissioning_only_{false};
|
||||||
std::atomic_bool openknx_configured_{false};
|
std::atomic_bool openknx_configured_{false};
|
||||||
|
std::atomic<uint64_t> cloud_cemi_uplink_frames_{0};
|
||||||
|
std::atomic<uint64_t> cloud_cemi_downlink_frames_{0};
|
||||||
bool programming_button_last_pressed_{false};
|
bool programming_button_last_pressed_{false};
|
||||||
bool programming_led_state_{false};
|
bool programming_led_state_{false};
|
||||||
TickType_t programming_button_last_toggle_tick_{0};
|
TickType_t programming_button_last_toggle_tick_{0};
|
||||||
|
|||||||
@@ -46,8 +46,27 @@ void GatewayKnxTpIpRouter::setOamIpSecureRoutingSequenceStoreHandler(
|
|||||||
routing_sequence_store_handler_ = std::move(handler);
|
routing_sequence_store_handler_ = std::move(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GatewayKnxTpIpRouter::setCloudCemiPublisher(CloudCemiPublisher publisher) {
|
||||||
|
cloud_cemi_publisher_ = std::move(publisher);
|
||||||
|
}
|
||||||
|
|
||||||
const GatewayKnxConfig& GatewayKnxTpIpRouter::config() const { return config_; }
|
const GatewayKnxConfig& GatewayKnxTpIpRouter::config() const { return config_; }
|
||||||
|
|
||||||
|
bool GatewayKnxTpIpRouter::injectCloudCemiFrame(const uint8_t* data, size_t len) {
|
||||||
|
if (data == nullptr || len == 0 || !config_.oam_router.cloud_remote.enabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cloud_cemi_downlink_frames_.fetch_add(1, std::memory_order_relaxed);
|
||||||
|
return handleOpenKnxTunnelFrame(data, len, nullptr, kServiceTunnellingRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
GatewayKnxTpIpRouter::CloudCemiStats GatewayKnxTpIpRouter::cloudCemiStats() const {
|
||||||
|
return CloudCemiStats{
|
||||||
|
config_.oam_router.cloud_remote.enabled,
|
||||||
|
cloud_cemi_uplink_frames_.load(std::memory_order_relaxed),
|
||||||
|
cloud_cemi_downlink_frames_.load(std::memory_order_relaxed)};
|
||||||
|
}
|
||||||
|
|
||||||
bool GatewayKnxTpIpRouter::tpUartOnline() const { return tp_uart_online_; }
|
bool GatewayKnxTpIpRouter::tpUartOnline() const { return tp_uart_online_; }
|
||||||
|
|
||||||
bool GatewayKnxTpIpRouter::programmingMode() {
|
bool GatewayKnxTpIpRouter::programmingMode() {
|
||||||
@@ -328,6 +347,7 @@ esp_err_t GatewayKnxTpIpRouter::initializeRuntime() {
|
|||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
ets_device_->setBusFrameSender([this](const uint8_t* data, size_t len) {
|
ets_device_->setBusFrameSender([this](const uint8_t* data, size_t len) {
|
||||||
|
publishCloudCemiFrame(data, len);
|
||||||
sendTunnelIndication(data, len);
|
sendTunnelIndication(data, len);
|
||||||
sendRoutingIndication(data, len);
|
sendRoutingIndication(data, len);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ bool GatewayKnxTpIpRouter::handleOpenKnxTunnelFrame(const uint8_t* data, size_t
|
|||||||
if (response == nullptr || response_len == 0) {
|
if (response == nullptr || response_len == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
publishCloudCemiFrame(response, response_len);
|
||||||
const bool routing_context =
|
const bool routing_context =
|
||||||
response_client == nullptr && response_service == kServiceRoutingIndication;
|
response_client == nullptr && response_service == kServiceRoutingIndication;
|
||||||
const auto message_code = CemiMessageCode(response, response_len);
|
const auto message_code = CemiMessageCode(response, response_len);
|
||||||
@@ -128,6 +129,7 @@ bool GatewayKnxTpIpRouter::handleOamRouterTunnelFrame(const uint8_t* data, size_
|
|||||||
if (response == nullptr || response_len == 0) {
|
if (response == nullptr || response_len == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
publishCloudCemiFrame(response, response_len);
|
||||||
const bool routing_context =
|
const bool routing_context =
|
||||||
response_client == nullptr && response_service == kServiceRoutingIndication;
|
response_client == nullptr && response_service == kServiceRoutingIndication;
|
||||||
const auto message_code = CemiMessageCode(response, response_len);
|
const auto message_code = CemiMessageCode(response, response_len);
|
||||||
@@ -191,15 +193,30 @@ bool GatewayKnxTpIpRouter::transmitOpenKnxTpFrame(const uint8_t* data, size_t le
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool GatewayKnxTpIpRouter::handleOpenKnxBusFrame(const uint8_t* data, size_t len) {
|
bool GatewayKnxTpIpRouter::handleOpenKnxBusFrame(const uint8_t* data, size_t len) {
|
||||||
SemaphoreGuard guard(openknx_lock_);
|
bool consumed = false;
|
||||||
if (ets_device_ == nullptr) {
|
{
|
||||||
return false;
|
SemaphoreGuard guard(openknx_lock_);
|
||||||
|
if (ets_device_ == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
consumed = ets_device_->handleBusFrame(data, len);
|
||||||
|
syncOpenKnxConfigFromDevice();
|
||||||
|
}
|
||||||
|
if (consumed) {
|
||||||
|
publishCloudCemiFrame(data, len);
|
||||||
}
|
}
|
||||||
const bool consumed = ets_device_->handleBusFrame(data, len);
|
|
||||||
syncOpenKnxConfigFromDevice();
|
|
||||||
return consumed;
|
return consumed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GatewayKnxTpIpRouter::publishCloudCemiFrame(const uint8_t* data, size_t len) {
|
||||||
|
if (data == nullptr || len == 0 || !config_.oam_router.cloud_remote.enabled ||
|
||||||
|
!cloud_cemi_publisher_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cloud_cemi_uplink_frames_.fetch_add(1, std::memory_order_relaxed);
|
||||||
|
cloud_cemi_publisher_(data, len);
|
||||||
|
}
|
||||||
|
|
||||||
bool GatewayKnxTpIpRouter::routeOpenKnxGroupWrite(const uint8_t* data, size_t len,
|
bool GatewayKnxTpIpRouter::routeOpenKnxGroupWrite(const uint8_t* data, size_t len,
|
||||||
const char* context) {
|
const char* context) {
|
||||||
const auto decoded = DecodeOpenKnxGroupWrite(data, len);
|
const auto decoded = DecodeOpenKnxGroupWrite(data, len);
|
||||||
|
|||||||
Reference in New Issue
Block a user