REDAC HybridController
Firmware for LUCIDAC/REDAC Teensy
Loading...
Searching...
No Matches
base.h
Go to the documentation of this file.
1// Copyright (c) 2024 anabrid GmbH
2// Contact: https://www.anabrid.com/licensing/
3//
4// SPDX-License-Identifier: MIT OR GPL-2.0-or-later
5
6#pragma once
7
8#include <string>
9#include <utility>
10#include <vector>
11
12#include <Arduino.h>
13#include <ArduinoJson.h>
14
15#include "utils/error.h"
16#include "version.h"
17
18namespace metadata {
19
20using eui_t = std::array<uint8_t, 8>;
21
22}
23
24namespace entities {
25
26enum class EntityClass : uint8_t {
27 UNKNOWN = 0,
28 CARRIER = 1,
29 CLUSTER = 2,
30 M_BLOCK = 3,
31 U_BLOCK = 4,
32 C_BLOCK = 5,
33 I_BLOCK = 6,
34 SH_BLOCK = 7,
35 FRONT_PANEL = 8,
36 CTRL_BLOCK = 9,
37 T_BLOCK = 10,
38 BACK_PANEL = 11
39};
40
41struct __attribute__((packed)) EntityClassifier {
42 union {
43 uint8_t class_;
44 EntityClass class_enum;
45 };
46
47 uint8_t type;
48 Version version;
49 uint8_t variant;
50
51 static constexpr uint8_t UNKNOWN = 0;
52 static constexpr uint8_t DEFAULT_ = 1;
53 static constexpr Version UNKNOWN_VERSION_{0, 0, 0};
54 static constexpr Version DEFAULT_VERSION_{1, 0, 0};
55
56 EntityClassifier() : class_(UNKNOWN), type(UNKNOWN), version(UNKNOWN_VERSION_), variant(DEFAULT_) {}
57
58 EntityClassifier(const EntityClass class_, const uint8_t type_, const Version version_,
59 const uint8_t variant_ = DEFAULT_)
60 : class_enum(class_), type(type_), version(version_), variant(variant_) {}
61
62 EntityClassifier(const uint8_t class_, const uint8_t type_, const Version version_,
63 const uint8_t variant_ = DEFAULT_)
64 : class_(class_), type(type_), version(version_), variant(variant_) {}
65
66 EntityClassifier(const EntityClass class_, const uint8_t type_, const uint8_t version_major_,
67 const uint8_t version_minor_, const uint8_t version_patch_,
68 const uint8_t variant_ = DEFAULT_)
69 : class_enum(class_), type(type_), version(version_major_, version_minor_, version_patch_),
70 variant(variant_) {}
71
72 EntityClassifier(const uint8_t class_, const uint8_t type_, const uint8_t version_major_,
73 const uint8_t version_minor_, const uint8_t version_patch_,
74 const uint8_t variant_ = DEFAULT_)
75 : class_(class_), type(type_), version(version_major_, version_minor_, version_patch_),
76 variant(variant_) {}
77
78 template <class EntityType_> EntityType_ type_as() const { return static_cast<EntityType_>(type); }
79
80 template <class EntityVariant_> EntityVariant_ variant_as() const {
81 return static_cast<EntityVariant_>(variant);
82 }
83
84 template <class Version_> Version_ version_as() const { return static_cast<Version_>(version); }
85
86 std::string to_string() const;
87
88 explicit operator bool() const {
89 // All fields of a valid EntityClassifier must not be all-zero or all-ones.
90 return class_ ^ 0xFF and type ^ 0xFF and version and variant ^ 0xFF;
91 }
92
93 bool operator==(const EntityClassifier &rhs) const;
94 bool operator!=(const EntityClassifier &rhs) const;
95
96 // EntityClassifier operator=(const EntityClassifier &other);
97};
98
99static_assert(sizeof(EntityClassifier) == 6, "EntityClassifier has unexpected number of bytes.");
100
102 constexpr static uint8_t CIRCUIT_RESET = 1 << 1;
103 constexpr static uint8_t CALIBRATION_RESET = 1 << 2;
104 constexpr static uint8_t OVERLOAD_RESET = 1 << 3;
105 constexpr static uint8_t EVERYTHING = 0xFF;
106
107 uint8_t val;
108
109 ResetAction(uint8_t val) : val(val) {}
110
111 inline bool has(uint8_t other) { return other & val; }
112};
113
114class Entity {
115protected:
116 std::string entity_id;
117
118public:
119 Entity() = default;
120
121 explicit Entity(std::string entityId) : entity_id(std::move(entityId)) {}
122
123 const std::string &get_entity_id() const { return entity_id; }
124
125 void rename_entity(const std::string entityId) { entity_id = entityId; }
126
127 EntityClassifier get_entity_classifier() const;
129 uint8_t get_entity_type() const;
130 Version get_entity_version() const;
131 uint8_t get_entity_variant() const;
132
133 virtual metadata::eui_t get_entity_eui() const = 0;
134
135 bool is_entity_class(EntityClass class_) const { return get_entity_class() == class_; }
136
137 bool is_entity_type(uint8_t type_) const { return get_entity_type() == type_; }
138
139 bool is_entity_version(Version version_) const { return get_entity_version() == version_; }
140
141 bool is_entity_variant(uint8_t variant_) const { return get_entity_variant() == variant_; }
142
143 virtual std::vector<Entity *> get_child_entities() = 0;
144
145 virtual Entity *get_child_entity(const std::string &child_id) = 0;
146
147 Entity *resolve_child_entity(std::string paths[], size_t len);
148 Entity *resolve_child_entity(JsonArrayConstIterator begin, JsonArrayConstIterator end);
149
150 Entity *resolve_child_entity(JsonArrayConst path) { return resolve_child_entity(path.begin(), path.end()); }
151
153 virtual bool init() { return true; }
154
155 virtual void reset(ResetAction action) {}
156
158 [[nodiscard]] virtual utils::status write_to_hardware() { return utils::status::success(); }
159
164 utils::status config_from_json(JsonObjectConst cfg);
165
170 void config_to_json(JsonObject &cfg, bool recursive = true) {
172 if (recursive)
174 }
175
178 utils::status user_set_config(JsonObjectConst msg_in, JsonObject &msg_out);
179 utils::status user_get_config(JsonObjectConst msg_in, JsonObject &msg_out);
180 utils::status user_reset_config(JsonObjectConst msg_in, JsonObject &msg_out);
182
184 void classifier_to_json(JsonObject &out);
185
186protected:
192 virtual utils::status config_self_from_json(JsonObjectConst cfg) = 0;
193
199 utils::status config_children_from_json(JsonObjectConst &cfg);
200
205 virtual void config_self_to_json(JsonObject &cfg) {
206#ifdef ANABRID_DEBUG_ENTITY_CONFIG
207 Serial.println(__PRETTY_FUNCTION__);
208#endif
209 }
210
215 void config_children_to_json(JsonObject &cfg);
216
217 EntityClassifier classifier;
218};
219
220} // namespace entities
221
222namespace ArduinoJson {
223
224template <> struct Converter<entities::EntityClassifier> {
225 static bool toJson(const entities::EntityClassifier &src, JsonVariant dst);
226 static entities::EntityClassifier fromJson(JsonVariantConst src);
227 static bool checkJson(JsonVariantConst src);
228};
229
230} // namespace ArduinoJson
231
232// As this uses static variables, we only allow using this in test cases
233
234#ifdef PIO_UNIT_TESTING
235
236#include <ostream>
237
238inline std::ostream &operator<<(std::ostream &os, entities::Entity &entity) {
239 static StaticJsonDocument<2048> doc;
240 doc.clear();
241 static JsonObject cfg = doc.to<JsonObject>();
242 cfg.clear();
243
244 entity.config_to_json(cfg, true);
245
246 os << cfg;
247
248 return os;
249}
250
251#endif
EntityClassifier classifier
Definition base.h:217
utils::status config_children_from_json(JsonObjectConst &cfg)
Deserialize a new configuration for all child entities from a JsonObject.
Definition base.cpp:72
Version get_entity_version() const
Definition base.cpp:25
virtual metadata::eui_t get_entity_eui() const =0
EntityClassifier get_entity_classifier() const
Definition base.cpp:19
std::string entity_id
Definition base.h:116
void classifier_to_json(JsonObject &out)
Provide recursive entity information in a tree.
Definition base.cpp:125
void config_children_to_json(JsonObject &cfg)
Serialize the configuration of the child entities of this entity to a JsonObject.
Definition base.cpp:89
virtual void reset(ResetAction action)
Definition base.h:155
uint8_t get_entity_variant() const
Definition base.cpp:27
virtual utils::status write_to_hardware()
returns true in case of success
Definition base.h:158
bool is_entity_version(Version version_) const
Definition base.h:139
void config_to_json(JsonObject &cfg, bool recursive=true)
Serialize the configuration for this entity to a JsonObject.
Definition base.h:170
void rename_entity(const std::string entityId)
Definition base.h:125
virtual std::vector< Entity * > get_child_entities()=0
const std::string & get_entity_id() const
Definition base.h:123
virtual bool init()
returns true in case of success
Definition base.h:153
virtual Entity * get_child_entity(const std::string &child_id)=0
Entity * resolve_child_entity(std::string paths[], size_t len)
Definition base.cpp:30
bool is_entity_variant(uint8_t variant_) const
Definition base.h:141
Entity()=default
uint8_t get_entity_type() const
Definition base.cpp:23
utils::status config_from_json(JsonObjectConst cfg)
Deserialize a new configuration for this entity and all its children from a JsonObject.
Definition base.cpp:56
Entity * resolve_child_entity(JsonArrayConst path)
Definition base.h:150
EntityClass get_entity_class() const
Definition base.cpp:21
bool is_entity_type(uint8_t type_) const
Definition base.h:137
virtual void config_self_to_json(JsonObject &cfg)
Serialize the configuration of this entity to a JsonObject.
Definition base.h:205
Entity(std::string entityId)
Definition base.h:121
virtual utils::status config_self_from_json(JsonObjectConst cfg)=0
Deserialize a new configuration for this entity from a JsonObject.
bool is_entity_class(EntityClass class_) const
Definition base.h:135
A recoverable error, inspired from https://abseil.io/docs/cpp/guides/status and https://github....
Definition error.h:35
static status success()
Syntactic sugar for success.
Definition error.h:104
uint32_t src
Definition flasher.cpp:63
utils::status user_reset_config(JsonObjectConst msg_in, JsonObject &msg_out)
Definition base.cpp:220
utils::status user_set_config(JsonObjectConst msg_in, JsonObject &msg_out)
Definition base.cpp:136
utils::status user_get_config(JsonObjectConst msg_in, JsonObject &msg_out)
Definition base.cpp:181
std::ostream & operator<<(std::ostream &os, const std::array< T, size > &arr)
Definition logging.h:143
EntityClass
Definition base.h:26
struct __attribute__((packed)) EntityClassifier
Definition base.h:41
std::array< uint8_t, 8 > eui_t
Definition base.h:20
STL namespace.
static bool checkJson(JsonVariantConst src)
static constexpr uint8_t OVERLOAD_RESET
Definition base.h:104
static constexpr uint8_t CALIBRATION_RESET
Definition base.h:103
ResetAction(uint8_t val)
Definition base.h:109
static constexpr uint8_t EVERYTHING
Definition base.h:105
bool has(uint8_t other)
Definition base.h:111
static constexpr uint8_t CIRCUIT_RESET
Definition base.h:102