REDAC HybridController
Firmware for LUCIDAC/REDAC Teensy
Loading...
Searching...
No Matches
base.cpp
Go to the documentation of this file.
1#include "proto/main.pb.h"
2
3#include <cstring>
4#include <entity/base.h>
5#include <entity/visitor.h>
6#include <utils/mac.h> // toString(eui64)
7
8std::string entities::EntityClassifier::to_string() const {
9 return "(class = " + std::to_string(class_) + ", type = " + std::to_string(type) +
10 ", version = " + version.to_string() + ", variant = " + std::to_string(variant) + ")";
11}
12
13bool entities::EntityClassifier::operator==(const EntityClassifier &rhs) const {
14 return class_ == rhs.class_ && class_enum == rhs.class_enum && type == rhs.type && version == rhs.version &&
15 variant == rhs.variant;
16}
17
18bool entities::EntityClassifier::operator!=(const EntityClassifier &rhs) const {
19 return !(rhs == *this);
20}
21
22void entities::Entity::set_entity_classifier(EntityClassifier classifier) {
23 this->classifier = classifier;
24}
25
26
27const entities::EntityClassifier &entities::Entity::get_entity_classifier() const { return classifier; }
28
29entities::EntityClass entities::Entity::get_entity_class() const { return classifier.class_enum; }
30
31uint8_t entities::Entity::get_entity_type() const { return classifier.type; }
32
33entities::Version entities::Entity::get_entity_version() const { return classifier.version; }
34
35uint8_t entities::Entity::get_entity_variant() const { return classifier.variant; }
36
37
38entities::Entity *entities::Entity::resolve_child_entity(const Path& path) {
39 auto resolved_entity = this;
40 for (auto& segment : path) {
41 resolved_entity = resolved_entity->get_child_entity(segment);
42 if (!resolved_entity)
43 return nullptr;
44 }
45
46 return resolved_entity;
47}
48
49
50void entities::Entity::encode_classifier(pb_Entity &out) {
51 out.id[0] = '/';
52 auto it = get_entity_id().copy(out.id + 1, std::size(out.id) - 2);
53 out.id[it + 1] = 0;
54
55 auto classifier = get_entity_classifier();
56 out.class_ = static_cast<pb_Entity_Class>(classifier.class_);
57 out.type = classifier.type;
58 out.variant = classifier.variant;
59 out.has_version = true;
60 classifier.version.to_pb(out.version);
61
62 it = utils::toString(get_entity_eui()).copy(out.eui, sizeof(out.eui));
63 out.eui[it] = 0;
64
65 auto children = get_child_entities();
66 auto& idx = out.children_count = 0;
67
68 if (children.empty()) {
69 out.children = nullptr;
70 return;
71 }
72
73 auto children_classifiers = new pb_Entity[children.size()];
74 out.children = children_classifiers;
75
76 for (auto &child_ptr : children) {
77 if (!child_ptr) continue;
78 child_ptr->encode_classifier(children_classifiers[idx++]);
79 }
80}
81
82
83UnitResult entities::Entity::setup(Entity* entity, const pb_ConfigCommand& cmd, pb_ConfigResponse &response) {
84#ifdef ANABRID_DEBUG_COMMS
85 Serial.println(__PRETTY_FUNCTION__);
86#endif
87 if (cmd.reset_before) {
88 entity->reset(ResetAction::CIRCUIT_RESET | ResetAction::OVERLOAD_RESET);
89 (void)entity->write_to_hardware();
90 }
91
92 if (!cmd.has_module)
93 return UnitResult::err("Expected bundle inside Config commandCommand");
94
95 Setup setup_helper;
96 setup_helper.set(cmd.module);
97 setup_helper.apply(entity);
98 return UnitResult::ok();
99}
100
101
102UnitResult entities::Entity::extract(Entity* entity, const pb_ExtractCommand& cmd, pb_ExtractResponse &response) {
103#ifdef ANABRID_DEBUG_COMMS
104 Serial.println(__PRETTY_FUNCTION__);
105#endif
106 if (cmd.has_entity) {
107 Path path;
108 path.push(cmd.entity.path);
109 entity = entity->resolve_child_entity(path);
110 }
111
112 Setup setup;
113 ExtractSettings settings{ cmd.recursive, cmd.specification, cmd.calibration, cmd.calibration};
114 setup.extract(entity, settings);
115 setup.get(response.module);
116 response.has_module = true;
117
118 // Save entity path back into response
119 return UnitResult::ok();
120}
121
122UnitResult entities::Entity::reset(Entity *entity, const pb_ResetCommand &msg_in, pb_ResetResponse &msg_out) {
123 entities::ResetAction reset_request(0);
124
125 // msg_in["foo"] | default_value
126 // is a short way to write
127 // msg_in.contains("foo") ? msg_in["foo"].as<bool>() : default_value
128
129 msg_out.has_entity = false;
130
131 bool keep_calibration = msg_in.keep_calibration | true;
132
133 if (!keep_calibration)
134 reset_request.val |= entities::ResetAction::CALIBRATION_RESET;
135
136 bool overload_reset = msg_in.overload_reset | true;
137
138 if (overload_reset)
139 reset_request.val |= entities::ResetAction::OVERLOAD_RESET;
140 // attention: Overload request always immediately writes to hardware
141
142 bool circuit_reset = msg_in.circuit_reset | true;
143
144 if (circuit_reset)
145 reset_request.val |= entities::ResetAction::CIRCUIT_RESET;
146
147 entity->reset(reset_request);
148
149 if (msg_in.sync | true) {
150 TRY(entity->write_to_hardware());
151 }
152 return UnitResult::ok();
153}
void setup()