3-phase PV router
Loading...
Searching...
No Matches
utils_relay.h
Go to the documentation of this file.
1
12#ifndef UTILS_RELAY_H
13#define UTILS_RELAY_H
14
15#include "types.h"
16#include "type_traits.hpp"
17#include "debug.h"
18
19#include "config_system.h"
20#include "movingAvg.h"
21#include "ewma_avg.hpp"
22#include "utils_pins.h"
23
30{
31public:
32 constexpr relayOutput() = delete;
33
39 explicit constexpr relayOutput(const uint8_t _relay_pin)
40 : relay_pin{ _relay_pin }
41 {
42 }
43
51 constexpr relayOutput(uint8_t _relay_pin, int16_t _surplusThreshold, int16_t _importThreshold)
52 : relay_pin{ _relay_pin }, surplusThreshold{ -abs(_surplusThreshold) }, importThreshold{ abs(_importThreshold) }
53 {
54 }
55
65 constexpr relayOutput(uint8_t _relay_pin, int16_t _surplusThreshold, int16_t _importThreshold, uint16_t _minON, uint16_t _minOFF)
66 : relay_pin{ _relay_pin }, surplusThreshold{ -abs(_surplusThreshold) }, importThreshold{ abs(_importThreshold) }, minON{ _minON * 60 }, minOFF{ _minOFF * 60 }
67 {
68 }
69
75 constexpr auto get_pin() const
76 {
77 return relay_pin;
78 }
79
85 constexpr auto get_surplusThreshold() const
86 {
87 return -surplusThreshold;
88 }
89
95 constexpr auto get_importThreshold() const
96 {
97 return importThreshold;
98 }
99
105 constexpr auto get_minON() const
106 {
107 return minON;
108 }
109
115 constexpr auto get_minOFF() const
116 {
117 return minOFF;
118 }
119
125 auto isRelayON() const
126 {
127 return relayIsON;
128 }
129
135 void inc_duration() const
136 {
137 if (duration < UINT16_MAX)
138 {
139 ++duration;
140 }
141 }
142
148 bool proceed_relay(const int32_t currentAvgPower) const
149 {
150 // To avoid changing sign, surplus is a negative value
151 if (currentAvgPower < surplusThreshold)
152 {
153 return try_turnON();
154 }
155 if (currentAvgPower > importThreshold)
156 {
157 return try_turnOFF();
158 }
159 return false;
160 }
161
166 void printRelayConfiguration(uint8_t idx) const
167 {
168 Serial.print(F("\tRelay configuration: #"));
169 Serial.println(idx + 1);
170
171 Serial.print(F("\t\tPin is "));
172 Serial.println(get_pin());
173
174 Serial.print(F("\t\tSurplus threshold: "));
175 Serial.println(get_surplusThreshold());
176
177 Serial.print(F("\t\tImport threshold: "));
178 Serial.println(get_importThreshold());
179
180 Serial.print(F("\t\tMinimum working time in minutes: "));
181 Serial.println(get_minON() / 60);
182
183 Serial.print(F("\t\tMinimum stop time in minutes: "));
184 Serial.println(get_minOFF() / 60);
185 }
186
187private:
193 bool try_turnON() const
194 {
195 if (relayIsON || duration < minOFF)
196 {
197 return false;
198 }
199
201
202 DBUGLN(F("Relay turned ON!"));
203
204 relayIsON = true;
205 duration = 0;
206
207 return true;
208 }
209
215 bool try_turnOFF() const
216 {
217 if (!relayIsON || duration < minON)
218 {
219 return false;
220 }
221
223
224 DBUGLN(F("Relay turned OFF!"));
225
226 relayIsON = false;
227 duration = 0;
228
229 return true;
230 }
231
232private:
233 const uint8_t relay_pin{ 0xff };
234 const int16_t surplusThreshold{ -1000 };
235 const int16_t importThreshold{ 200 };
236 const uint16_t minON{ 5 * 60 };
237 const uint16_t minOFF{ 5 * 60 };
239 mutable uint16_t duration{ 0 };
240 mutable bool relayIsON{ false };
241};
242
251template< uint8_t N, uint8_t D = 10 >
253{
254public:
259 explicit constexpr RelayEngine(const relayOutput (&ref)[N])
260 : relay(ref)
261 {
262 }
263
269 : relay(ref)
270 {
271 }
272
278 constexpr auto get_size() const
279 {
280 return N;
281 }
282
289 constexpr const auto& get_relay(uint8_t idx) const
290 {
291 return relay[idx];
292 }
293
299 inline static auto get_average()
300 {
301 return ewma_average.getAverageS();
302 }
303
309 inline static void update_average(int16_t currentPower)
310 {
311 ewma_average.addValue(currentPower);
312 }
313
318#if defined(__DOXYGEN__)
319 void inc_duration() const;
320#else
321 void inc_duration() const __attribute__((optimize("-O3")));
322#endif
323
328 void proceed_relays() const
329 {
330 if (settle_change != 0)
331 {
332 // A relay has been toggle less than a minute ago, wait until changes take effect
333 return;
334 }
335
336 if (ewma_average.getAverageS() > 0)
337 {
338 // Currently importing, try to turn OFF some relays
339 uint8_t idx{ N };
340 do
341 {
342 if (relay[--idx].proceed_relay(ewma_average.getAverageS()))
343 {
344 settle_change = 60;
345 return;
346 }
347 } while (idx);
348 }
349 else
350 {
351 // Remaining surplus, try to turn ON more relays
352 uint8_t idx{ 0 };
353 do
354 {
355 if (relay[idx].proceed_relay(ewma_average.getAverageS()))
356 {
357 settle_change = 60;
358 return;
359 }
360 } while (++idx < N);
361 }
362 }
363
368 void initializePins() const
369 {
370 uint8_t idx{ N };
371 do
372 {
373 pinMode(relay[--idx].get_pin(), OUTPUT);
374 delay(100);
375 } while (idx);
376 }
377
383 {
384 Serial.println(F("\t*** Relay(s) configuration ***"));
385 Serial.print(F("\t\tSliding average: "));
386 Serial.println(D);
387
388 for (uint8_t i = 0; i < N; ++i)
389 {
391 }
392 }
393
394private:
397 mutable uint8_t settle_change{ 60 };
400};
401
402template< uint8_t N, uint8_t D > void RelayEngine< N, D >::inc_duration() const
403{
404 uint8_t idx{ N };
405 do
406 {
407 relay[--idx].inc_duration();
408 } while (idx);
409
410 if (settle_change)
411 {
412 --settle_change;
413 }
414}
415
416#endif /* UTILS_RELAY_H */
Exponentially Weighted Moving Average.
Definition: ewma_avg.hpp:78
This class implements the relay management engine.
Definition: utils_relay.h:253
static EWMA_average< D *60/DATALOG_PERIOD_IN_SECONDS > ewma_average
Definition: utils_relay.h:399
constexpr auto get_size() const
Get the number of relays.
Definition: utils_relay.h:278
void proceed_relays() const
Proceed all relays in increasing order (surplus) or decreasing order (import)
Definition: utils_relay.h:328
static auto get_average()
Get the current average.
Definition: utils_relay.h:299
static void update_average(int16_t currentPower)
Update the sliding average.
Definition: utils_relay.h:309
const relayOutput relay[N]
Definition: utils_relay.h:395
void inc_duration() const
Increment the duration's state of each relay.
Definition: utils_relay.h:402
uint8_t settle_change
Definition: utils_relay.h:397
constexpr RelayEngine(integral_constant< uint8_t, D > ic, const relayOutput(&ref)[N])
Construct a list of relays with a custom sliding average.
Definition: utils_relay.h:268
constexpr const auto & get_relay(uint8_t idx) const
Get the relay object.
Definition: utils_relay.h:289
constexpr RelayEngine(const relayOutput(&ref)[N])
Construct a list of relays.
Definition: utils_relay.h:259
void printConfiguration() const
Print the configuration of each relay.
Definition: utils_relay.h:382
void initializePins() const
Initialize the pins used by the relays.
Definition: utils_relay.h:368
Relay diversion config and engine.
Definition: utils_relay.h:30
constexpr relayOutput()=delete
constexpr auto get_minOFF() const
Get the minimum OFF-time in seconds.
Definition: utils_relay.h:115
const int16_t importThreshold
Definition: utils_relay.h:235
const int16_t surplusThreshold
Definition: utils_relay.h:234
const uint8_t relay_pin
Definition: utils_relay.h:233
constexpr auto get_surplusThreshold() const
Get the surplus threshold which will turns ON the relay.
Definition: utils_relay.h:85
bool proceed_relay(const int32_t currentAvgPower) const
Proceed with the relay.
Definition: utils_relay.h:148
constexpr relayOutput(uint8_t _relay_pin, int16_t _surplusThreshold, int16_t _importThreshold, uint16_t _minON, uint16_t _minOFF)
Construct a new relay Config object with custom parameters.
Definition: utils_relay.h:65
bool relayIsON
Definition: utils_relay.h:240
bool try_turnOFF() const
Turn OFF the relay if the 'time' condition is met.
Definition: utils_relay.h:215
constexpr relayOutput(const uint8_t _relay_pin)
Construct a new relay Config object with default parameters.
Definition: utils_relay.h:39
uint16_t duration
Definition: utils_relay.h:239
const uint16_t minON
Definition: utils_relay.h:236
constexpr auto get_importThreshold() const
Get the import threshold which will turns OFF the relay.
Definition: utils_relay.h:95
void printRelayConfiguration(uint8_t idx) const
Print the configuration of the current relay-diversion.
Definition: utils_relay.h:166
constexpr relayOutput(uint8_t _relay_pin, int16_t _surplusThreshold, int16_t _importThreshold)
Construct a new relay Config object with default/custom parameters.
Definition: utils_relay.h:51
auto isRelayON() const
Return the state.
Definition: utils_relay.h:125
constexpr auto get_pin() const
Get the control pin of the relay.
Definition: utils_relay.h:75
const uint16_t minOFF
Definition: utils_relay.h:237
void inc_duration() const
Increment the duration of the current state.
Definition: utils_relay.h:135
bool try_turnON() const
Turn ON the relay if the 'time' condition is met.
Definition: utils_relay.h:193
constexpr auto get_minON() const
Get the minimum ON-time in seconds.
Definition: utils_relay.h:105
Basic configuration values to be set by the end-user.
constexpr uint16_t
Definition: config_system.h:32
constexpr uint8_t DATALOG_PERIOD_IN_SECONDS
Definition: config_system.h:31
Some macro for the Serial Output and Debugging.
#define DBUGLN(...)
Definition: debug.h:97
This file implements an Exponentially Weighted Moving Average template class.
Code for sliding-window average.
uint8_t i
Definition: test_main.cpp:94
Some useful but missing stl functions templates.
Some basics classes/types.
Some utility functions for pins manipulation.
constexpr void setPinON(const uint8_t pin)
Set the Pin state to ON for the specified pin.
Definition: utils_pins.h:116
constexpr void setPinOFF(const uint8_t pin)
Set the Pin state to OFF for the specified pin.
Definition: utils_pins.h:144