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
91inline static constexpr size_t calcBufferSize()
92{
93 size_t size{ 1 }; // STX
94
95 size += lineSize(1, 6); // P (signed 6 digits)
96
97 if constexpr (NO_OF_PHASES > 1)
98 {
99 size += NO_OF_PHASES * lineSize(2, 5); // V1-Vn (unsigned 5 digits) - voltage
100
101 size += NO_OF_DUMPLOADS * lineSize(2, 3); // D1-Dn (unsigned 3 digits) - diversion rate
102 }
103 else
104 {
105 size += lineSize(1, 5); // V (unsigned 5 digits) - voltage
106
107 size += lineSize(1, 4); // D (unsigned 4 digits) - diverted power
108 size += lineSize(1, 5); // E (unsigned 5 digits) - diverted energy
109 }
110
111 if constexpr (RELAY_DIVERSION)
112 {
113 size += lineSize(1, 6); // R (signed 6 digits) - mean power for relay diversion
114 size += relays.get_size() * lineSize(2, 1); // R1-Rn (1 (ON), 0 (OFF)) - relay state
115 }
116
117 if constexpr (TEMP_SENSOR_PRESENT)
118 {
119 size += temperatureSensing.get_size() * lineSize(2, 4); // T1-Tn (4 digits) - temperature
120 }
121
122 size += lineSize(1, 5); // N (unsigned 5 digits) - absence of diverted energy count
123
124 size += lineSize(4, 2); // S_MC (unsigned 2 digits) - sample sets per mains cycle
125 size += lineSize(1, 5); // S (unsigned 5 digits) - sample count
126
127 size += 1; // ETX
128
129 return size;
130}
131
155{
156private:
157 static const char STX{ 0x02 };
158 static const char ETX{ 0x03 };
159 static const char LF{ 0x0A };
160 static const char CR{ 0x0D };
161 static const char TAB{ 0x09 };
162
164 size_t bufferPos{ 0 };
165
172 [[nodiscard]] uint8_t calculateChecksum(size_t startPos, size_t endPos) const
173 {
174 uint8_t sum{ 0 };
175 auto* ptr = buffer + startPos;
176 const auto* end = buffer + endPos;
177
178 // Process 4 bytes at once for longer segments
179 while (ptr + 4 <= end)
180 {
181 sum += *ptr++;
182 sum += *ptr++;
183 sum += *ptr++;
184 sum += *ptr++;
185 }
186
187 // Handle remaining bytes
188 while (ptr < end)
189 {
190 sum += *ptr++;
191 }
192
193 return (sum & 0x3F) + 0x20;
194 }
195
200 __attribute__((always_inline)) void writeTag(const char* tag, uint8_t index)
201 {
202 auto* ptr{ tag };
203 while (*ptr) buffer[bufferPos++] = *ptr++;
204
205 // If an index is provided, append it to the tag
206 if (index != 0)
207 {
208 buffer[bufferPos++] = static_cast< char >('0' + index); // Convert index to a character
209 }
210
212 }
213
214public:
218 __attribute__((always_inline)) void startFrame()
219 {
220 bufferPos = 0;
221 buffer[bufferPos++] = STX;
222 }
223
229 void send(const char* tag, int16_t value, uint8_t index = 0)
230 {
231 buffer[bufferPos++] = LF;
232
233 const auto startPos{ bufferPos };
234
235 writeTag(tag, index);
236 auto str = itoa(value, buffer + bufferPos, 10);
237 bufferPos += strlen(str); // Advance bufferPos by the length of the written string
238 buffer[bufferPos++] = TAB;
239
240 const auto crc{ calculateChecksum(startPos, bufferPos) };
241 buffer[bufferPos++] = crc;
242
243 buffer[bufferPos++] = CR;
244 }
245
249 __attribute__((always_inline)) void endFrame()
250 {
251 buffer[bufferPos++] = ETX;
252 Serial.write(buffer, bufferPos);
253 }
254};
255
256#endif /* TELEINFO_H */
A class for managing and sending telemetry information in a structured frame format.
Definition teleinfo.h:155
uint8_t index
Definition teleinfo.h:201
static const char TAB
Definition teleinfo.h:161
__attribute__((always_inline)) void endFrame()
Finalizes the frame by adding the end character and sending the buffer over Serial.
Definition teleinfo.h:249
void send(const char *tag, int16_t value, uint8_t index=0)
Sends a telemetry value as an integer.
Definition teleinfo.h:229
static const char STX
Definition teleinfo.h:157
uint8_t calculateChecksum(size_t startPos, size_t endPos) const
Calculates the checksum for a portion of the buffer.
Definition teleinfo.h:172
size_t bufferPos
Definition teleinfo.h:164
static const char CR
Definition teleinfo.h:160
char buffer[calcBufferSize()]
Definition teleinfo.h:163
__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:218
static const char ETX
Definition teleinfo.h:158
static const char LF
Definition teleinfo.h:159
Configuration values to be set by the end-user.
constexpr bool RELAY_DIVERSION
Definition config.h:40
constexpr TemperatureSensing temperatureSensing
Definition config.h:98
constexpr RelayEngine relays
Definition config.h:91
constexpr uint8_t NO_OF_DUMPLOADS
Definition config.h:32
constexpr bool TEMP_SENSOR_PRESENT
Definition config.h:42
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:91
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