Add KNX DALI Gateway Module and Message Queue Implementation
- Introduced KnxDaliModule class for handling DALI message queuing, commissioning, and KNX group-object dispatch. - Implemented Message and MessageQueue classes for managing message operations. - Removed obsolete OpenKNX IDF component files and CMake configurations. - Updated submodule reference for KNX. Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
#pragma once
|
||||
|
||||
#include "esp_idf_platform.h"
|
||||
#include "ets_memory_loader.h"
|
||||
|
||||
#include "knx/bau07B0.h"
|
||||
#include "knx/cemi_frame.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace gateway::openknx {
|
||||
|
||||
class EtsDeviceRuntime {
|
||||
public:
|
||||
using CemiFrameSender = std::function<void(const uint8_t* data, size_t len)>;
|
||||
using GroupWriteHandler = std::function<void(uint16_t group_address, const uint8_t* data,
|
||||
size_t len)>;
|
||||
using FunctionPropertyHandler = std::function<bool(uint8_t object_index, uint8_t property_id,
|
||||
const uint8_t* data, size_t len,
|
||||
std::vector<uint8_t>* response)>;
|
||||
|
||||
EtsDeviceRuntime(std::string nvs_namespace,
|
||||
uint16_t fallback_individual_address,
|
||||
uint16_t tunnel_client_address = 0);
|
||||
~EtsDeviceRuntime();
|
||||
|
||||
uint16_t individualAddress() const;
|
||||
uint16_t tunnelClientAddress() const;
|
||||
bool configured() const;
|
||||
bool programmingMode() const;
|
||||
void setProgrammingMode(bool enabled);
|
||||
void toggleProgrammingMode();
|
||||
EtsMemorySnapshot snapshot() const;
|
||||
|
||||
void setFunctionPropertyHandlers(FunctionPropertyHandler command_handler,
|
||||
FunctionPropertyHandler state_handler);
|
||||
void setGroupWriteHandler(GroupWriteHandler handler);
|
||||
void setNetworkInterface(esp_netif_t* netif);
|
||||
|
||||
bool handleTunnelFrame(const uint8_t* data, size_t len, CemiFrameSender sender);
|
||||
bool handleBusFrame(const uint8_t* data, size_t len);
|
||||
bool emitGroupValue(uint16_t group_object_number, const uint8_t* data, size_t len,
|
||||
CemiFrameSender sender);
|
||||
void loop();
|
||||
|
||||
private:
|
||||
static bool HandleOutboundCemiFrame(CemiFrame& frame, void* context);
|
||||
static void EmitTunnelFrame(CemiFrame& frame, void* context);
|
||||
static void HandleSecureGroupWrite(uint16_t group_address, const uint8_t* data,
|
||||
uint8_t data_length, void* context);
|
||||
static bool HandleFunctionPropertyCommand(uint8_t object_index, uint8_t property_id,
|
||||
uint8_t length, uint8_t* data,
|
||||
uint8_t* result_data, uint8_t& result_length);
|
||||
static bool HandleFunctionPropertyState(uint8_t object_index, uint8_t property_id,
|
||||
uint8_t length, uint8_t* data,
|
||||
uint8_t* result_data, uint8_t& result_length);
|
||||
static uint16_t DefaultTunnelClientAddress(uint16_t individual_address);
|
||||
static bool DispatchFunctionProperty(FunctionPropertyHandler* handler, uint8_t object_index,
|
||||
uint8_t property_id, uint8_t length, uint8_t* data,
|
||||
uint8_t* result_data, uint8_t& result_length);
|
||||
bool shouldConsumeTunnelFrame(CemiFrame& frame) const;
|
||||
bool shouldConsumeBusFrame(CemiFrame& frame) const;
|
||||
|
||||
std::string nvs_namespace_;
|
||||
EspIdfPlatform platform_;
|
||||
Bau07B0 device_;
|
||||
CemiFrameSender sender_;
|
||||
GroupWriteHandler group_write_handler_;
|
||||
FunctionPropertyHandler command_handler_;
|
||||
FunctionPropertyHandler state_handler_;
|
||||
};
|
||||
|
||||
} // namespace gateway::openknx
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace gateway::openknx {
|
||||
|
||||
struct EtsAssociation {
|
||||
uint16_t group_address{0};
|
||||
uint16_t group_object_number{0};
|
||||
};
|
||||
|
||||
struct EtsMemorySnapshot {
|
||||
bool configured{false};
|
||||
uint16_t individual_address{0};
|
||||
std::vector<EtsAssociation> associations;
|
||||
};
|
||||
|
||||
EtsMemorySnapshot LoadEtsMemorySnapshot(const std::string& nvs_namespace);
|
||||
|
||||
} // namespace gateway::openknx
|
||||
@@ -0,0 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
// Internal header shared between gateway_knx.cpp and gateway_knx_router.cpp.
|
||||
|
||||
#include "driver/uart.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "soc/uart_periph.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace gateway {
|
||||
namespace knx_internal {
|
||||
|
||||
constexpr const char* kTag = "gateway_knx";
|
||||
|
||||
// RAII semaphore guard.
|
||||
class SemaphoreGuard {
|
||||
public:
|
||||
explicit SemaphoreGuard(SemaphoreHandle_t semaphore) : semaphore_(semaphore) {
|
||||
if (semaphore_ != nullptr) {
|
||||
xSemaphoreTake(semaphore_, portMAX_DELAY);
|
||||
locked_ = true;
|
||||
}
|
||||
}
|
||||
~SemaphoreGuard() {
|
||||
if (locked_) {
|
||||
xSemaphoreGive(semaphore_);
|
||||
}
|
||||
}
|
||||
private:
|
||||
SemaphoreHandle_t semaphore_{nullptr};
|
||||
bool locked_{false};
|
||||
};
|
||||
|
||||
// Resolve a UART IO pin from config or SoC defaults.
|
||||
inline bool ResolveUartIoPin(uart_port_t uart_port, int configured_pin,
|
||||
uint32_t pin_index, int* resolved_pin) {
|
||||
if (resolved_pin == nullptr) return false;
|
||||
if (configured_pin >= 0) {
|
||||
*resolved_pin = configured_pin;
|
||||
return true;
|
||||
}
|
||||
if (uart_port < 0 || uart_port >= SOC_UART_NUM ||
|
||||
pin_index >= SOC_UART_PINS_COUNT) {
|
||||
*resolved_pin = UART_PIN_NO_CHANGE;
|
||||
return false;
|
||||
}
|
||||
const int default_pin =
|
||||
uart_periph_signal[uart_port].pins[pin_index].default_gpio;
|
||||
if (default_pin < 0) {
|
||||
*resolved_pin = UART_PIN_NO_CHANGE;
|
||||
return false;
|
||||
}
|
||||
*resolved_pin = default_pin;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace knx_internal
|
||||
} // namespace gateway
|
||||
Reference in New Issue
Block a user