feat(gateway): implement GatewayController and enhance GatewayRuntime
- Added GatewayController class to manage gateway operations, including command handling, scene and group management, and BLE state management. - Introduced methods for scene and group storage, including loading, saving, and deleting scenes/groups. - Enhanced GatewayRuntime with BLE management capabilities, including methods to check and set BLE state, and to generate BLE gateway names. - Implemented utility functions for string normalization and CSV parsing. - Added notification sinks for various events in the GatewayController. Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "nvs.h"
|
||||
|
||||
namespace gateway {
|
||||
|
||||
class DaliDomainService;
|
||||
class GatewayRuntime;
|
||||
|
||||
struct GatewayControllerConfig {
|
||||
uint32_t task_stack_size{6144};
|
||||
UBaseType_t task_priority{5};
|
||||
int color_temperature_min{2000};
|
||||
int color_temperature_max{6500};
|
||||
bool setup_supported{true};
|
||||
bool ble_supported{false};
|
||||
bool wifi_supported{true};
|
||||
bool ip_router_supported{true};
|
||||
bool internal_scene_supported{true};
|
||||
bool internal_group_supported{true};
|
||||
};
|
||||
|
||||
class GatewayController {
|
||||
public:
|
||||
using NotificationSink = std::function<void(const std::vector<uint8_t>& frame)>;
|
||||
using BleStateSink = std::function<void(bool enabled)>;
|
||||
using GatewayNameSink = std::function<void(uint8_t gateway_id)>;
|
||||
|
||||
GatewayController(GatewayRuntime& runtime, DaliDomainService& dali_domain,
|
||||
GatewayControllerConfig config = {});
|
||||
~GatewayController();
|
||||
|
||||
esp_err_t start();
|
||||
bool enqueueCommandFrame(const std::vector<uint8_t>& frame);
|
||||
void addNotificationSink(NotificationSink sink);
|
||||
void addBleStateSink(BleStateSink sink);
|
||||
void addGatewayNameSink(GatewayNameSink sink);
|
||||
|
||||
bool setupMode() const;
|
||||
bool bleEnabled() const;
|
||||
bool wifiEnabled() const;
|
||||
bool ipRouterEnabled() const;
|
||||
|
||||
private:
|
||||
struct InternalScene {
|
||||
bool enabled{false};
|
||||
uint8_t brightness{254};
|
||||
uint8_t color_mode{2};
|
||||
uint8_t data1{0};
|
||||
uint8_t data2{0};
|
||||
uint8_t data3{0};
|
||||
std::string name;
|
||||
};
|
||||
|
||||
struct InternalGroup {
|
||||
bool enabled{false};
|
||||
uint8_t target_type{2};
|
||||
uint8_t target_value{0};
|
||||
std::string name;
|
||||
};
|
||||
|
||||
using SceneStore = std::array<InternalScene, 16>;
|
||||
using GroupStore = std::array<InternalGroup, 16>;
|
||||
|
||||
static void TaskEntry(void* arg);
|
||||
void taskLoop();
|
||||
void dispatchCommand(const std::vector<uint8_t>& command);
|
||||
|
||||
bool hasGateway(uint8_t gateway_id) const;
|
||||
std::vector<uint8_t> gatewayIds() const;
|
||||
std::string gatewayName(uint8_t gateway_id) const;
|
||||
void refreshRuntimeGatewayNames();
|
||||
void publishPayload(uint8_t gateway_id, const std::vector<uint8_t>& payload);
|
||||
void publishFrame(const std::vector<uint8_t>& frame);
|
||||
|
||||
uint8_t resolveInternalGroupRawAddress(uint8_t gateway_id, uint8_t raw_addr);
|
||||
static uint8_t normalizeGroupTargetType(uint8_t target_type);
|
||||
static uint8_t normalizeGroupTargetValue(uint8_t target_type, uint8_t target_value);
|
||||
static uint8_t internalGroupRawTargetAddress(uint8_t target_type, uint8_t target_value,
|
||||
uint8_t raw_addr);
|
||||
static int internalGroupDecTargetAddress(uint8_t target_type, uint8_t target_value);
|
||||
static int shortAddressFromRaw(uint8_t raw_addr);
|
||||
static int reverseInRange(int value, int min_value, int max_value);
|
||||
|
||||
SceneStore& sceneStore(uint8_t gateway_id);
|
||||
GroupStore& groupStore(uint8_t gateway_id);
|
||||
InternalScene* scene(uint8_t gateway_id, uint8_t scene_id);
|
||||
InternalGroup* group(uint8_t gateway_id, uint8_t group_id);
|
||||
|
||||
bool setSceneEnabled(uint8_t gateway_id, uint8_t scene_id, bool enabled);
|
||||
bool setSceneDetail(uint8_t gateway_id, uint8_t scene_id, uint8_t brightness,
|
||||
uint8_t color_mode, uint8_t data1, uint8_t data2, uint8_t data3);
|
||||
bool setSceneName(uint8_t gateway_id, uint8_t scene_id, std::string_view name);
|
||||
bool deleteScene(uint8_t gateway_id, uint8_t scene_id);
|
||||
std::pair<uint8_t, uint8_t> sceneMask(uint8_t gateway_id);
|
||||
bool executeScene(uint8_t gateway_id, int short_address, uint8_t scene_id);
|
||||
|
||||
bool setGroupEnabled(uint8_t gateway_id, uint8_t group_id, bool enabled);
|
||||
bool setGroupDetail(uint8_t gateway_id, uint8_t group_id, uint8_t target_type,
|
||||
uint8_t target_value);
|
||||
bool setGroupName(uint8_t gateway_id, uint8_t group_id, std::string_view name);
|
||||
bool deleteGroup(uint8_t gateway_id, uint8_t group_id);
|
||||
std::pair<uint8_t, uint8_t> groupMask(uint8_t gateway_id);
|
||||
bool executeGroup(uint8_t gateway_id, uint8_t group_id);
|
||||
|
||||
void handleGatewayNameCommand(uint8_t gateway_id, const std::vector<uint8_t>& command);
|
||||
void handleGatewayIdentityCommand(uint8_t gateway_id, uint8_t op);
|
||||
void handleAllocationCommand(uint8_t gateway_id, const std::vector<uint8_t>& command);
|
||||
void handleInternalSceneCommand(uint8_t gateway_id, const std::vector<uint8_t>& command);
|
||||
void handleInternalGroupCommand(uint8_t gateway_id, const std::vector<uint8_t>& command);
|
||||
|
||||
bool openStorage();
|
||||
void closeStorage();
|
||||
void loadSceneStore(uint8_t gateway_id, SceneStore& scenes);
|
||||
void loadGroupStore(uint8_t gateway_id, GroupStore& groups);
|
||||
bool saveScene(uint8_t gateway_id, uint8_t scene_id);
|
||||
bool deleteSceneStorage(uint8_t gateway_id, uint8_t scene_id);
|
||||
bool saveSceneName(uint8_t gateway_id, uint8_t scene_id, std::string_view name);
|
||||
bool deleteSceneNameStorage(uint8_t gateway_id, uint8_t scene_id);
|
||||
bool saveGroup(uint8_t gateway_id, uint8_t group_id);
|
||||
bool deleteGroupStorage(uint8_t gateway_id, uint8_t group_id);
|
||||
bool saveGroupName(uint8_t gateway_id, uint8_t group_id, std::string_view name);
|
||||
bool deleteGroupNameStorage(uint8_t gateway_id, uint8_t group_id);
|
||||
std::string readString(std::string_view key) const;
|
||||
bool writeString(std::string_view key, std::string_view value);
|
||||
bool eraseKey(std::string_view key);
|
||||
|
||||
GatewayRuntime& runtime_;
|
||||
DaliDomainService& dali_domain_;
|
||||
GatewayControllerConfig config_;
|
||||
TaskHandle_t task_handle_{nullptr};
|
||||
nvs_handle_t storage_{0};
|
||||
std::vector<NotificationSink> notification_sinks_;
|
||||
std::vector<BleStateSink> ble_state_sinks_;
|
||||
std::vector<GatewayNameSink> gateway_name_sinks_;
|
||||
std::map<uint8_t, SceneStore> scenes_;
|
||||
std::map<uint8_t, GroupStore> groups_;
|
||||
bool setup_mode_{false};
|
||||
bool ble_enabled_{false};
|
||||
bool wifi_enabled_{false};
|
||||
bool ip_router_enabled_{true};
|
||||
};
|
||||
|
||||
} // namespace gateway
|
||||
Reference in New Issue
Block a user