3-phase PV router
Loading...
Searching...
No Matches
teleinfo.h
Go to the documentation of this file.
1
24#ifndef TELEINFO_H
25#define TELEINFO_H
26
27#include "config_system.h"
28#include "config.h"
29
49inline static constexpr size_t lineSize(size_t tagLen, size_t valueLen)
50{
51 return 1 + tagLen + 1 + valueLen + 1 + 1 + 1; // LF+tag+TAB+value+TAB+checksum+CR
52}
53
95inline static constexpr size_t calcBufferSize()
96{
97 size_t size{ 1 }; // STX
98
99 size += lineSize(1, 6); // P (signed 6 digits)
100
101 if constexpr (NO_OF_PHASES > 1)
102 {
103 size += NO_OF_PHASES * lineSize(2, 5); // V1-Vn (unsigned 5 digits) - voltage
104
105 size += NO_OF_PHASES * lineSize(2, 6); // P1-Pn (signed 6 digits) - instant power
106
107 size += NO_OF_DUMPLOADS * lineSize(2, 3); // D1-Dn (unsigned 3 digits) - diversion rate
108 }
109 else
110 {
111 size += lineSize(1, 5); // V (unsigned 5 digits) - voltage
112
113 size += lineSize(1, 4); // D (unsigned 4 digits) - diverted power
114 size += lineSize(1, 5); // E (unsigned 5 digits) - diverted energy
115 }
116
117 if constexpr (RELAY_DIVERSION)
118 {
119 size += lineSize(1, 6); // R (signed 6 digits) - mean power for relay diversion
120 size += relays.size() * lineSize(2, 1); // R1-Rn (1 (ON), 0 (OFF)) - relay state
121 }
122
123 if constexpr (TEMP_SENSOR_PRESENT)
124 {
125 size += temperatureSensing.size() * lineSize(2, 4); // T1-Tn (4 digits) - temperature
126 }
127
128 size += lineSize(1, 5); // N (unsigned 5 digits) - absence of diverted energy count
129
130 if constexpr (DUAL_TARIFF)
131 {
132 size += lineSize(2, 1); // TA (1 digit) - tariff state (0=high/on-peak, 1=low/off-peak)
133 }
134
135 size += lineSize(4, 2); // S_MC (unsigned 2 digits) - sample sets per mains cycle
136 size += lineSize(1, 5); // S (unsigned 5 digits) - sample count
137
138 size += 1; // ETX
139
140 return size;
141}
142
166{
167private:
168 static const char STX{ 0x02 };
169 static const char ETX{ 0x03 };
170 static const char LF{ 0x0A };
171 static const char CR{ 0x0D };
172 static const char TAB{ 0x09 };
173
175 size_t bufferPos{ 0 };
176
183 [[nodiscard]] uint8_t calculateChecksum(size_t startPos, size_t endPos) const
184 {
185 uint8_t sum{ 0 };
186 auto* ptr = buffer + startPos;
187 const auto* end = buffer + endPos;
188
189 // Process 4 bytes at once for longer segments
190 while (ptr + 4 <= end)
191 {
192 sum += *ptr++;
193 sum += *ptr++;
194 sum += *ptr++;
195 sum += *ptr++;
196 }
197
198 // Handle remaining bytes
199 while (ptr < end)
200 {
201 sum += *ptr++;
202 }
203
204 return (sum & 0x3F) + 0x20;
205 }
206
211 __attribute__((always_inline)) void writeTag(const char* tag, uint8_t index)
212 {
213 auto* ptr{ tag };
214 while (*ptr) buffer[bufferPos++] = *ptr++;
215
216 // If an index is provided, append it to the tag
217 if (index != 0)
218 {
219 buffer[bufferPos++] = static_cast< char >('0' + index); // Convert index to a character
220 }
221
223 }
224
225public:
229 __attribute__((always_inline)) void startFrame()
230 {
231 bufferPos = 0;
232 buffer[bufferPos++] = STX;
233 }
234
240 void send(const char* tag, int16_t value, uint8_t index = 0)
241 {
242 buffer[bufferPos++] = LF;
243
244 const auto startPos{ bufferPos };
245
246 writeTag(tag, index);
247 auto str = itoa(value, buffer + bufferPos, 10);
248 bufferPos += strlen(str); // Advance bufferPos by the length of the written string
249 buffer[bufferPos++] = TAB;
250
251 const auto crc{ calculateChecksum(startPos, bufferPos) };
252 buffer[bufferPos++] = crc;
253
254 buffer[bufferPos++] = CR;
255 }
256
260 __attribute__((always_inline)) void endFrame()
261 {
262 buffer[bufferPos++] = ETX;
263 Serial.write(buffer, bufferPos);
264 }
265};
266
267#endif /* TELEINFO_H */
A class for managing and sending telemetry information in a structured frame format.
Definition teleinfo.h:166
uint8_t index
Definition teleinfo.h:212
static const char TAB
Definition teleinfo.h:172
__attribute__((always_inline)) void endFrame()
Finalizes the frame by adding the end character and sending the buffer over Serial.
Definition teleinfo.h:260
void send(const char *tag, int16_t value, uint8_t index=0)
Sends a telemetry value as an integer.
Definition teleinfo.h:240
static const char STX
Definition teleinfo.h:168
uint8_t calculateChecksum(size_t startPos, size_t endPos) const
Calculates the checksum for a portion of the buffer.
Definition teleinfo.h:183
size_t bufferPos
Definition teleinfo.h:175
static const char CR
Definition teleinfo.h:171
char buffer[calcBufferSize()]
Definition teleinfo.h:174
__attribute__((always_inline)) void writeTag(const char *tag
Writes a tag to the buffer.
__attribute__((always_inline)) void startFrame()
Initializes a new frame by resetting the buffer and adding the start character.
Definition teleinfo.h:229
static const char ETX
Definition teleinfo.h:169
static const char LF
Definition teleinfo.h:170
Standard three-phase PVRouter setup with 2 dump loads.
constexpr bool RELAY_DIVERSION
Definition config.h:51
constexpr TemperatureSensing temperatureSensing
Definition config.h:150
constexpr RelayEngine relays
Definition config.h:126
constexpr bool DUAL_TARIFF
Definition config.h:52
constexpr uint8_t NO_OF_DUMPLOADS
Definition config.h:42
constexpr bool TEMP_SENSOR_PRESENT
Definition config.h:53
Basic configuration values to be set by the end-user.
constexpr uint8_t NO_OF_PHASES
static constexpr size_t calcBufferSize()
Calculates the total buffer size required for the telemetry frame.
Definition teleinfo.h:95
static constexpr size_t lineSize(size_t tagLen, size_t valueLen)
Calculates the size of a single telemetry line in the frame.
Definition teleinfo.h:49
constexpr size_t size(const _Tp(&)[_Nm]) noexcept
Helper function to retrieve the dimension of a C-array.
Definition types.h:87