#pragma once #include #include #include #include #include "esp_err.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "freertos/task.h" #include "nvs.h" namespace gateway { enum class GatewayCachePriorityMode : uint8_t { kOutsideBusFirst = 0, kLocalGatewayFirst = 1, }; struct GatewayCacheConfig { std::string storage_namespace{"gateway_rt"}; uint32_t flush_interval_ms{5000}; uint32_t task_stack_size{4096}; UBaseType_t task_priority{3}; GatewayCachePriorityMode default_priority_mode{GatewayCachePriorityMode::kOutsideBusFirst}; }; struct GatewayCacheChannelFlags { bool need_update_group{false}; bool need_update_scene{false}; bool need_update_settings{false}; }; class GatewayCache { public: struct SceneEntry { 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 GroupEntry { bool enabled{false}; uint8_t target_type{2}; uint8_t target_value{0}; std::string name; }; using SceneStore = std::array; using GroupStore = std::array; explicit GatewayCache(GatewayCacheConfig config = {}); ~GatewayCache(); esp_err_t start(); void preloadChannel(uint8_t gateway_id); SceneStore scenes(uint8_t gateway_id); GroupStore groups(uint8_t gateway_id); SceneEntry scene(uint8_t gateway_id, uint8_t scene_id); GroupEntry 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 sceneMask(uint8_t gateway_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 groupMask(uint8_t gateway_id); GatewayCacheChannelFlags channelFlags(uint8_t gateway_id); void markGroupUpdateNeeded(uint8_t gateway_id, bool needed = true); void markSceneUpdateNeeded(uint8_t gateway_id, bool needed = true); void markSettingsUpdateNeeded(uint8_t gateway_id, bool needed = true); GatewayCachePriorityMode priorityMode(); void setPriorityMode(GatewayCachePriorityMode mode); private: static void TaskEntry(void* arg); void taskLoop(); bool flushDirty(); bool openStorageLocked(); void closeStorageLocked(); SceneStore& ensureSceneStoreLocked(uint8_t gateway_id); GroupStore& ensureGroupStoreLocked(uint8_t gateway_id); void loadSceneStoreLocked(uint8_t gateway_id, SceneStore& scenes); void loadGroupStoreLocked(uint8_t gateway_id, GroupStore& groups); std::string readStringLocked(std::string_view key); bool writeStringLocked(std::string_view key, std::string_view value); bool eraseKeyLocked(std::string_view key); GatewayCacheConfig config_; GatewayCachePriorityMode priority_mode_; TaskHandle_t task_handle_{nullptr}; SemaphoreHandle_t lock_{nullptr}; nvs_handle_t storage_{0}; std::map scenes_; std::map groups_; std::map channel_flags_; bool dirty_{false}; }; } // namespace gateway