esp8266_web_settings beta
Accumulator.h
1/*
2 * Copyright (c) 2021, 2022 G. R. McDorman
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in all
12 * copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
23#pragma once
24
25#include <WString.h>
26#include <ArduinoJson.h>
27
28#include <algorithm>
29#include <numeric>
30#include <vector>
31
32namespace grmcdorman::device
33{
34
52 template<typename T, uint8_t N, int unset = 0, int zero = 0>
54 {
55 public:
56 static constexpr T unset_value = unset;
57 static constexpr T zero_value = zero;
58 static constexpr uint8_t average_points = N;
59 typedef T value_type;
60
71 {
72 return last_reading;
73 }
83 float get_current_average() const
84 {
85 uint8_t count = std::min(data_read_first, average_points);
86 return count == 0 ? unset_value : std::accumulate(&last_reading_set[0], &last_reading_set[count], zero_value) / static_cast<float>(count);
87 }
96 void new_reading(T new_value)
97 {
98 last_reading = new_value;
99 last_reading_set[current_index] = new_value;
100 current_index = (current_index + 1) % N;
101 if (data_read_first < N)
102 {
103 ++data_read_first;
104 }
105 last_sample_time = millis();
106 }
113 bool has_accumulation() const
114 {
115 return data_read_first > 0;
116 }
117
125 uint8_t get_sample_count() const
126 {
127 return data_read_first;
128 }
129
135 uint32_t get_last_sample_age() const
136 {
137 return millis() - last_sample_time;
138 }
139
145 DynamicJsonDocument as_json() const
146 {
147 static const char average_string[] PROGMEM = "average";
148 static const char last_string[] PROGMEM = "last";
149 static const char sample_count_string[] PROGMEM = "sample_count";
150 static const char sample_age_string[] PROGMEM = "sample_age_ms";
151
152 DynamicJsonDocument json(128);
153 json[FPSTR(average_string)] = get_current_average();
154 json[FPSTR(last_string)] = get_last_reading();
155 json[FPSTR(sample_count_string)] = get_sample_count();
156 json[FPSTR(sample_age_string)] = get_last_sample_age();
157 return json;
158 }
159
160 private:
161 T last_reading = unset_value;
162 T last_reading_set[N];
163 uint32_t current_index = 0;
164 uint8_t data_read_first = 0;
165 uint32_t last_sample_time = 0;
166 };
167}
A class to handle accumulating values.
Definition: Accumulator.h:54
void new_reading(T new_value)
Record a new reading.
Definition: Accumulator.h:96
bool has_accumulation() const
Return a value indicate whether data has been accumulated.
Definition: Accumulator.h:113
static constexpr uint8_t average_points
The number of readings for the rolling average.
Definition: Accumulator.h:58
uint8_t get_sample_count() const
Get the number of samples used for the average.
Definition: Accumulator.h:125
T get_last_reading() const
Get the current value.
Definition: Accumulator.h:70
float get_current_average() const
Get the current rolling average.
Definition: Accumulator.h:83
static constexpr T zero_value
The zero value.
Definition: Accumulator.h:57
static constexpr T unset_value
The unset value.
Definition: Accumulator.h:56
DynamicJsonDocument as_json() const
Get the values in standard JSON.
Definition: Accumulator.h:145
uint32_t get_last_sample_age() const
Get the last sample age, in milliseconds.
Definition: Accumulator.h:135
T value_type
The value type.
Definition: Accumulator.h:59