1#include <entity/base.h>
4FLASHMEM std::string entities::EntityClassifier::to_string()
const {
5 return "(class = " + std::to_string(class_) +
", type = " + std::to_string(type) +
6 ", version = " + version.to_string() +
", variant = " + std::to_string(variant) +
")";
9bool entities::EntityClassifier::operator==(
const entities::EntityClassifier &rhs)
const {
10 return class_ == rhs.class_ && class_enum == rhs.class_enum && type == rhs.type && version == rhs.version &&
11 variant == rhs.variant;
14bool entities::EntityClassifier::operator!=(
const entities::EntityClassifier &rhs)
const {
15 return !(rhs == *
this);
19entities::EntityClassifier entities::Entity::get_entity_classifier()
const {
return classifier; }
21FLASHMEM entities::EntityClass entities::Entity::get_entity_class()
const {
return classifier.class_enum; }
23FLASHMEM uint8_t entities::Entity::get_entity_type()
const {
return classifier.type; }
25FLASHMEM entities::Version entities::Entity::get_entity_version()
const {
return classifier.version; }
27FLASHMEM uint8_t entities::Entity::get_entity_variant()
const {
return classifier.variant; }
30entities::Entity *entities::Entity::resolve_child_entity(std::string paths[],
size_t len) {
31 auto resolved_entity =
this;
32 for (
size_t path_depth = 0; path_depth < len; path_depth++) {
33 resolved_entity = resolved_entity->get_child_entity(paths[path_depth]);
34 if (!resolved_entity) {
38 return resolved_entity;
42entities::Entity *entities::Entity::resolve_child_entity(JsonArrayConstIterator begin,
43 JsonArrayConstIterator end) {
44 auto resolved_entity =
this;
45 for (
auto sub_path = begin; sub_path != end; ++sub_path) {
46 std::string child_entity_id = (*sub_path).as<
const char *>();
47 resolved_entity = resolved_entity->get_child_entity(child_entity_id);
48 if (!resolved_entity) {
52 return resolved_entity;
56utils::status entities::Entity::config_from_json(JsonObjectConst cfg) {
57#ifdef ANABRID_DEBUG_ENTITY_CONFIG
58 Serial.println(__PRETTY_FUNCTION__);
61 return utils::status(
"Configuration is Null at entity %s", get_entity_id().c_str());
62 auto res = config_self_from_json(cfg);
65 res = config_children_from_json(cfg);
68 return utils::status::success();
72utils::status entities::Entity::config_children_from_json(JsonObjectConst &cfg) {
73 for (JsonPairConst keyval : cfg) {
74 if (keyval.key().c_str()[0] ==
'/' and keyval.key().size() > 1) {
75 std::string child_id(keyval.key().c_str() + 1);
76 auto child_entity = get_child_entity(child_id);
78 return utils::status(
"Child entity '%s' does not exist at entity '%s'", child_id.c_str(),
79 get_entity_id().c_str());
80 auto res = child_entity->config_from_json(keyval.value());
85 return utils::status::success();
89void entities::Entity::config_children_to_json(JsonObject &cfg) {
90 for (
const auto &child : get_child_entities()) {
92 auto child_cfg = cfg.createNestedObject(std::string(
"/") + child->get_entity_id());
93 child->config_to_json(child_cfg,
true);
99bool ArduinoJson::Converter<entities::EntityClassifier>::toJson(
const entities::EntityClassifier &
src,
101 dst[
"class"] =
src.class_;
102 dst[
"type"] =
src.type;
103 dst[
"variant"] =
src.variant;
105 auto versions_arr = dst.createNestedArray(
"version");
106 versions_arr.add(
src.version.major);
107 versions_arr.add(
src.version.minor);
108 versions_arr.add(
src.version.patch);
113entities::EntityClassifier ArduinoJson::Converter<entities::EntityClassifier>::fromJson(JsonVariantConst
src) {
114 return {
src[
"class"].as<uint8_t>(),
src[
"type"],
src[
"version"][0],
115 src[
"version"][1],
src[
"version"][2],
src[
"variant"]};
119bool Converter<entities::EntityClassifier>::checkJson(JsonVariantConst
src) {
120 return src[
"class"].is<uint8_t>() and
src[
"type"].is<uint8_t>() and
src["variant"].is<uint8_t>() and
121 src["version"].is<JsonArrayConst>() and
src["version"].as<JsonArrayConst>().
size() == 3;
125void entities::Entity::classifier_to_json(JsonObject &out) {
126 auto jsonvar = out[
"/" + get_entity_id()] = get_entity_classifier();
127 auto jsonobj = jsonvar.as<JsonObject>();
128 jsonobj[
"eui"] = utils::toString(get_entity_eui());
130 for (
auto &child_ptr : get_child_entities()) {
132 child_ptr->classifier_to_json(jsonobj);
136FLASHMEM utils::status entities::Entity::user_set_config(JsonObjectConst msg_in, JsonObject &msg_out) {
137#ifdef ANABRID_DEBUG_COMMS
138 Serial.println(__PRETTY_FUNCTION__);
140 auto self_entity_id = get_entity_id();
141 if (!msg_in.containsKey(
"entity") or !msg_in.containsKey(
"config")) {
142 return utils::status(1,
"Malformed message.");
146 auto path_json = msg_in[
"entity"].as<JsonArrayConst>();
147 auto path_depth = path_json.size();
148 std::string
path[path_depth];
149 copyArray(path_json, path, path_depth);
153 return utils::status(2,
"Invalid entity path (depth)");
155 if (path[0] != self_entity_id) {
156 return utils::status(3,
"Message intended for another entity (%s but I am %s)", path[0].c_str(),
157 self_entity_id.c_str());
161 auto resolved_entity = resolve_child_entity(path + 1, path_depth - 1);
162 if (!resolved_entity) {
163 return utils::status(4,
"Could not resolve child entity in given path");
166 utils::status res = resolved_entity->config_from_json(msg_in[
"config"]);
173 utils::status hw_res = write_to_hardware();
178 return utils::status::success();
181FLASHMEM utils::status entities::Entity::user_get_config(JsonObjectConst msg_in, JsonObject &msg_out) {
182#ifdef ANABRID_DEBUG_COMMS
183 Serial.println(__PRETTY_FUNCTION__);
185 auto recursive =
true;
186 if (msg_in.containsKey(
"recursive"))
187 recursive = msg_in[
"recursive"].as<
bool>();
190 entities::Entity *entity =
nullptr;
191 if (!msg_in.containsKey(
"entity") or msg_in[
"entity"].isNull()) {
193 }
else if (msg_in[
"entity"].is<JsonArrayConst>()) {
194 auto path = msg_in[
"entity"].as<JsonArrayConst>();
197 }
else if (path[0].as<std::string>() != get_entity_id()) {
198 return utils::status(1,
"Requested entity %s but I am %s", path[0].as<const char *>(),
199 get_entity_id().c_str());
201 auto path_begin =
path.begin();
203 entity = resolve_child_entity(path_begin,
path.end());
205 return utils::status(2,
"Cannot resolve entity path");
209 return utils::status(3,
"Entity path is not a list");
213 msg_out[
"entity"] = msg_in[
"entity"];
215 auto cfg = msg_out.createNestedObject(
"config");
216 entity->config_to_json(cfg, recursive);
217 return utils::status::success();
220FLASHMEM utils::status entities::Entity::user_reset_config(JsonObjectConst msg_in, JsonObject &msg_out) {
221 entities::ResetAction reset_request(0);
227 bool keep_calibration = msg_in[
"keep_calibration"] |
true;
229 if (!keep_calibration)
230 reset_request.val |= entities::ResetAction::CALIBRATION_RESET;
232 bool overload_reset = msg_in[
"overload_reset"] |
true;
235 reset_request.val |= entities::ResetAction::OVERLOAD_RESET;
238 bool circuit_reset = msg_in[
"circuit_reset"] |
true;
241 reset_request.val |= entities::ResetAction::CIRCUIT_RESET;
243 reset(reset_request);
245 if (msg_in[
"sync"] |
true) {
246 auto status = write_to_hardware();
251 return utils::status::success();
255FLASHMEM
void entities::Entity::temperatures_to_json(JsonObject &cfg,
bool recursive) {
256 auto temperature = read_temperature();
257 if(temperature != temperature_inavailable)
258 cfg[
"temp_celsius"] = temperature;
260 if(recursive)
for (
const auto& child : get_child_entities()) {
262 auto child_cfg = cfg.createNestedObject(std::string(
"/") + child->get_entity_id());
263 child->temperatures_to_json(child_cfg,
true);