SensESP 2.7.2
Universal Signal K sensor toolkit ESP32
Loading...
Searching...
No Matches
signalk_delta_queue.cpp
Go to the documentation of this file.
2
3#include "Arduino.h"
4#include "ArduinoJson.h"
5#include "sensesp.h"
6#include "sensesp_app.h"
7#include "signalk_emitter.h"
8
9namespace sensesp {
10
11SKDeltaQueue::SKDeltaQueue(unsigned int max_buffer_size)
12 : Startable{0}, max_buffer_size{max_buffer_size}, meta_sent_{false} {
13 semaphore_ = xSemaphoreCreateRecursiveMutex();
14 }
15
17
19 if (timeout_ms == 0) {
20 return xSemaphoreTakeRecursive(semaphore_, portMAX_DELAY) == pdTRUE;
21 } else {
22 return xSemaphoreTakeRecursive(semaphore_, timeout_ms) == pdTRUE;
23 }
24}
25
27
30 if (get_buffer_size() >= max_buffer_size) {
31 buffer.pop_back();
32 }
33 buffer.push_front(val);
35}
36
38 for (auto const& sk_source : SKEmitter::get_sources()) {
39 if (sk_source->get_sk_path() != "") {
41 [sk_source, this]() { this->append(sk_source->as_signalk()); });
42 }
43 }
44}
45
48 bool available = buffer.size() > 0;
50 return available;
51}
52
53unsigned int SKDeltaQueue::get_doc_size_estimate() {
55 int buf_size = get_buffer_size();
56 int estimate =
57 2 * JSON_OBJECT_SIZE(1) + // source and one update
58 JSON_ARRAY_SIZE(1) + // one update
59 JSON_ARRAY_SIZE(buf_size) + // buf_size values in the update
60 buf_size * JSON_OBJECT_SIZE(2) + // two key-value pairs in each object
61 200; // some extra headroom to hide embarrassing bugs
62
63 for (auto item : buffer) {
64 // also reserve space for the pre-rendered strings
65 estimate += item.length() + 1;
66 }
68 return estimate;
69}
70
71unsigned int SKDeltaQueue::get_metadata_size_estimate() {
72 int num_metadata = SKEmitter::get_sources().size();
73 int estimate = JSON_ARRAY_SIZE(num_metadata);
74
75 int num_fields;
76 auto update_estimate = [&](String& field) {
77 if (!field.isEmpty()) {
78 num_fields++;
79 estimate += field.length() + 1;
80 }
81 };
82
83 for (auto const& source : SKEmitter::get_sources()) {
84 num_fields = 0;
85 auto metadata = source->get_metadata();
86 if (metadata == NULL) {
87 continue;
88 }
89 update_estimate(metadata->units_);
90 update_estimate(metadata->display_name_);
91 update_estimate(metadata->description_);
92 update_estimate(metadata->short_name_);
93
94 estimate += JSON_OBJECT_SIZE(num_fields);
95 }
96 return estimate;
97}
98
100 // estimate the size of the serialized json string
101
102 unsigned int doc_size_estimate = get_doc_size_estimate();
103
104 if (!meta_sent_) {
105 doc_size_estimate += JSON_OBJECT_SIZE(1) + get_metadata_size_estimate();
106 }
107
109
110 // JsonObject delta = jsonDoc.as<JsonObject>();
111 JsonArray updates = jsonDoc.createNestedArray("updates");
112
113 if (!meta_sent_) {
114 this->add_metadata(updates);
115 }
116
117 JsonObject current = updates.createNestedObject();
118 JsonObject source = current.createNestedObject("source");
120 JsonArray values = current.createNestedArray("values");
121
123 while (!buffer.empty()) {
124 values.add(serialized(buffer.back()));
125 buffer.pop_back();
126 }
128
129 serializeJson(jsonDoc, output);
130
131 debugD("delta: %s", output.c_str());
132}
133
134void SKDeltaQueue::add_metadata(JsonArray updates) {
135 JsonObject new_entry = updates.createNestedObject();
136 JsonArray meta = new_entry.createNestedArray("meta");
137 for (auto const& sk_source : SKEmitter::get_sources()) {
138 sk_source->add_metadata(meta);
139 }
140 meta_sent_ = true;
141}
142
143} // namespace sensesp
Construct a new transform based on a single function.
void attach(std::function< void()> observer)
SKDeltaQueue(unsigned int max_buffer_size=20)
void get_delta(String &output)
virtual void start() override
bool take_semaphore(unsigned long int timeout_ms=0)
void append(const String val)
A class that produces Signal K output to be forwarded to the Signal K server (if the system is connec...
static const std::vector< SKEmitter * > & get_sources()
static String get_hostname()
Get the current hostname.
Automatic calling of the start() method at startup.
Definition startable.h:20
#define debugD(fmt,...)
Definition local_debug.h:47