SensESP 3.0.1
Universal Signal K sensor toolkit ESP32
Loading...
Searching...
No Matches
config_item.h
Go to the documentation of this file.
1#ifndef SENSESP_SRC_SENSESP_NET_WEB_CONFIG_ITEM_H_
2#define SENSESP_SRC_SENSESP_NET_WEB_CONFIG_ITEM_H_
3
4#include <map>
5#include <memory>
6#include <vector>
7#include <cstddef>
8
9#include "Arduino.h"
10#include "ArduinoJson.h"
12
13namespace sensesp {
14
19// an unknown type may not be rendered in Json editor
20template <class T>
21const char* get_schema_type_string(const T dummy) {
22 return "unknown";
23}
24template <>
25const char* get_schema_type_string(const int dummy);
26
27template <>
28const char* get_schema_type_string(const float dummy);
29
30template <>
31const char* get_schema_type_string(const String& dummy);
32
33template <>
34const char* get_schema_type_string(const bool dummy);
35
47inline const String ConfigSchema(const std::nullptr_t& obj) {
48 return "null";
49}
50
51template <typename T>
52bool ConfigRequiresRestart(const T& obj) {
53 return false;
54}
55
56template <typename T>
57bool ConfigRequiresRestart(const std::shared_ptr<T>& obj) {
58 return ConfigRequiresRestart(*obj);
59}
60
61// Forward declarations
62
63template <typename T>
64class ConfigItemT;
65
66template <typename T>
67std::shared_ptr<ConfigItemT<T>> ConfigItem(std::shared_ptr<T>);
68
69
71 : virtual public std::enable_shared_from_this<ConfigItemBase> {
72 public:
73 const String& get_title() const { return title_; }
74 ConfigItemBase* set_title(const String& title) {
75 title_ = title;
76 return this;
77 }
78
83 const String& get_description() const { return description_; }
84
88 ConfigItemBase* set_description(const String& description) {
89 description_ = description;
90 return this;
91 }
92
100 virtual const String get_config_schema() const {
101 if (config_schema_ != "") {
102 return config_schema_;
103 }
105 }
106
107 int get_sort_order() const { return sort_order_; }
108
110 sort_order_ = sort_order;
111 return this;
112 }
113
118 bool requires_restart() const { return requires_restart_; }
119
129
135 static std::shared_ptr<ConfigItemBase> get_config_item(const String key) {
136 auto it = ConfigItemBase::config_items_.find(key);
137 if (it != ConfigItemBase::config_items_.end()) {
138 return it->second;
139 }
140 return nullptr;
141 }
142
147 static std::unique_ptr<std::vector<std::shared_ptr<ConfigItemBase>>>
149 std::unique_ptr<std::vector<std::shared_ptr<ConfigItemBase>>>
150 sorted_config_items(new std::vector<std::shared_ptr<ConfigItemBase>>());
151
152 for (auto& it : ConfigItemBase::config_items_) {
153 sorted_config_items->push_back(it.second);
154 }
155 std::sort(sorted_config_items->begin(), sorted_config_items->end(),
156 [](std::shared_ptr<ConfigItemBase> a,
157 std::shared_ptr<ConfigItemBase> b) {
158 return a->get_sort_order() < b->get_sort_order();
159 });
160
161 return sorted_config_items;
162 }
163
164 virtual bool load() = 0;
165 virtual bool refresh() = 0;
166 virtual bool save() = 0;
167 virtual bool to_json(JsonObject& config) const = 0;
168 virtual bool from_json(const JsonObject& config) const = 0;
169 virtual const String& get_config_path() const = 0;
170
171 protected:
172 static std::map<String, std::shared_ptr<ConfigItemBase>> config_items_;
173
175 String config_path_ = "";
178 String config_schema_ = "";
180 String title_ = "";
182 String description_ = "";
184 int sort_order_ = 1000;
187 bool requires_restart_ = false;
188
189 virtual const String get_default_config_schema() const = 0;
190
191 template <typename T>
192 friend std::shared_ptr<ConfigItemT<T>> ConfigItem(std::shared_ptr<T>);
193};
194
200template <typename T>
202 // Template classes must inherit from Serializable and Saveable.
203 static_assert(std::is_base_of<Serializable, T>::value,
204 "T must inherit from Serializable");
205 static_assert(std::is_base_of<Saveable, T>::value,
206 "T must inherit from Saveable");
207
208 public:
209 ConfigItemT(std::shared_ptr<T> config_object)
210 : ConfigItemBase(), config_object_{config_object} {}
211
212 virtual bool to_json(JsonObject& config) const override {
213 return config_object_->to_json(config);
214 }
215
216 virtual bool from_json(const JsonObject& config) const override {
217 return config_object_->from_json(config);
218 }
219
220 virtual bool load() override { return config_object_->load(); }
221 virtual bool refresh() override { return config_object_->refresh(); }
222 virtual bool save() override { return config_object_->save(); }
223
224 virtual const String& get_config_path() const override {
225 return config_object_->get_config_path();
226 }
227
228 ConfigItemT<T>* set_title(const String& title) {
230 return this;
231 }
232
233 ConfigItemT<T>* set_description(const String& description) {
235 return this;
236 }
237
240 return this;
241 }
242
247
248 ConfigItemT<T>* set_config_schema(const String& config_schema) {
249 config_schema_ = config_schema;
250 return this;
251 }
252
259
260 protected:
261 // The object that this ConfigItemT is managing.
262 std::shared_ptr<T> config_object_;
268 const String get_default_config_schema() const {
269 String schema = ConfigSchema(*config_object_);
270 return schema;
271 }
272};
273
288template <typename T>
289std::shared_ptr<ConfigItemT<T>> ConfigItem(std::shared_ptr<T> config_object) {
290 ESP_LOGD(__FILENAME__, "Registering ConfigItemT with path %s",
291 config_object->get_config_path().c_str());
292 auto config_item = std::make_shared<ConfigItemT<T>>(config_object);
293 auto base_sptr = std::static_pointer_cast<ConfigItemBase>(config_item);
294 ConfigItemBase::config_items_[config_object->get_config_path()] = base_sptr;
295 return config_item;
296}
297
298// Unsafe: We don't know whether other shared_ptrs to the same object exist!
299template <typename T>
300std::shared_ptr<ConfigItemT<T>> ConfigItem(T* config_object) {
301 auto config_object_sptr = std::shared_ptr<T>(config_object);
302 return ConfigItem(config_object_sptr);
303}
304
305} // namespace sensesp
306
307#endif // SENSESP_SRC_SENSESP_NET_WEB_CONFIG_ITEM_H_
String description_
Description of the ConfigItemT to be displayed on the web UI.
virtual bool save()=0
ConfigItemBase * set_description(const String &description)
Set the description of the ConfigItemT.
Definition config_item.h:88
virtual const String get_config_schema() const
ConfigItemBase * set_sort_order(int sort_order)
ConfigItemBase * set_requires_restart(bool requires_restart)
Set the requires_restart flag.
virtual bool load()=0
virtual const String get_default_config_schema() const =0
virtual bool refresh()=0
friend std::shared_ptr< ConfigItemT< T > > ConfigItem(std::shared_ptr< T >)
Register a ConfigItemT with the ConfigItemBase.
String config_path_
The path of the ConfigItemT. This is used to identify the ConfigItemT.
virtual bool from_json(const JsonObject &config) const =0
virtual const String & get_config_path() const =0
bool requires_restart() const
Return true if the ConfigItemT requires restart after saving for the changes to take effect.
String title_
Title of the ConfigItemT to be displayed on the web UI.
static std::map< String, std::shared_ptr< ConfigItemBase > > config_items_
const String & get_description() const
Definition config_item.h:83
const String & get_title() const
Definition config_item.h:73
virtual bool to_json(JsonObject &config) const =0
int sort_order_
The sort order of ConfigItemT. Lower numbers have precedence.
static std::shared_ptr< ConfigItemBase > get_config_item(const String key)
Get a single ConfigItemT by key.
ConfigItemBase * set_title(const String &title)
Definition config_item.h:74
static std::unique_ptr< std::vector< std::shared_ptr< ConfigItemBase > > > get_config_items()
Get all config items as a vector.
Class providing sufficient data for rendering a config card in the frontend.
virtual bool from_json(const JsonObject &config) const override
virtual bool refresh() override
T * get_config_object()
Get the object that this ConfigItemT is managing.
virtual bool save() override
ConfigItemT< T > * set_description(const String &description)
virtual bool to_json(JsonObject &config) const override
ConfigItemT(std::shared_ptr< T > config_object)
ConfigItemT< T > * set_config_schema(const String &config_schema)
ConfigItemT< T > * set_requires_restart(bool requires_restart)
virtual bool load() override
std::shared_ptr< T > config_object_
virtual const String & get_config_path() const override
ConfigItemT< T > * set_title(const String &title)
ConfigItemT< T > * set_sort_order(int sort_order)
const String get_default_config_schema() const
Get the default configuration schema.
const String ConfigSchema(const SmartSwitchController &obj)
const char * get_schema_type_string(const int)
bool ConfigRequiresRestart(const HTTPServer &obj)
std::shared_ptr< ConfigItemT< T > > ConfigItem(std::shared_ptr< T >)
Register a ConfigItemT with the ConfigItemBase.