1-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
81inline static constexpr size_t calcBufferSize()
82{
83 size_t size{ 1 }; // STX
84
85 size += lineSize(1, 6); // P (signed 6 digits)
86
87 if constexpr (NO_OF_PHASES > 1)
88 {
89 size += NO_OF_PHASES * lineSize(2, 5); // V1-Vn (unsigned 5 digits) - voltage
90
91 size += NO_OF_DUMPLOADS * lineSize(2, 3); // L1-Ln (unsigned 3 digits) - diversion rate
92 }
93 else
94 {
95 size += lineSize(1, 5); // V (unsigned 5 digits) - voltage
96
97 size += lineSize(1, 4); // D (unsigned 4 digits) - diverted power
98 size += lineSize(1, 5); // E (unsigned 5 digits) - diverted energy
99 }
100
101 if constexpr (RELAY_DIVERSION)
102 {
103 size += lineSize(1, 6); // R (signed 6 digits) - mean power for relay diversion
104 size += relays.get_size() * lineSize(2, 1); // R1-Rn (1 (ON), 0 (OFF)) - relay state
105 }
106
107 if constexpr (TEMP_SENSOR_PRESENT)
108 {
109 size += temperatureSensing.get_size() * lineSize(2, 4); // T1-Tn (4 digits) - temperature
110 }
111
112 size += lineSize(1, 5); // N (unsigned 5 digits) - absence of diverted energy count
113
114 size += lineSize(4, 2); // S_MC (unsigned 2 digits) - sample sets per mains cycle
115 size += lineSize(1, 5); // S (unsigned 5 digits) - sample count
116
117 size += 1; // ETX
118
119 return size;
120}
121
145{
146private:
147 static const char STX{ 0x02 };
148 static const char ETX{ 0x03 };
149 static const char LF{ 0x0A };
150 static const char CR{ 0x0D };
151 static const char TAB{ 0x09 };
152
154 size_t bufferPos{ 0 };
155
162 [[nodiscard]] uint8_t calculateChecksum(size_t startPos, size_t endPos) const
163 {
164 uint8_t sum{ 0 };
165 auto* ptr = buffer + startPos;
166 const auto* end = buffer + endPos;
167
168 // Process 4 bytes at once for longer segments
169 while (ptr + 4 <= end)
170 {
171 sum += *ptr++;
172 sum += *ptr++;
173 sum += *ptr++;
174 sum += *ptr++;
175 }
176
177 // Handle remaining bytes
178 while (ptr < end)
179 {
180 sum += *ptr++;
181 }
182
183 return (sum & 0x3F) + 0x20;
184 }
185
190 __attribute__((always_inline)) void writeTag(const char* tag, uint8_t index)
191 {
192 auto* ptr{ tag };
193 while (*ptr) buffer[bufferPos++] = *ptr++;
194
195 // If an index is provided, append it to the tag
196 if (index != 0)
197 {
198 buffer[bufferPos++] = static_cast< char >('0' + index); // Convert index to a character
199 }
200
202 }
203
204public:
208 __attribute__((always_inline)) void startFrame()
209 {
210 bufferPos = 0;
211 buffer[bufferPos++] = STX;
212 }
213
219 void send(const char* tag, int16_t value, uint8_t index = 0)
220 {
221 buffer[bufferPos++] = LF;
222
223 const auto startPos{ bufferPos };
224
225 writeTag(tag, index);
226 auto str = itoa(value, buffer + bufferPos, 10);
227 bufferPos += strlen(str); // Advance bufferPos by the length of the written string
228 buffer[bufferPos++] = TAB;
229
230 const auto crc{ calculateChecksum(startPos, bufferPos) };
231 buffer[bufferPos++] = crc;
232
233 buffer[bufferPos++] = CR;
234 }
235
239 __attribute__((always_inline)) void endFrame()
240 {
241 buffer[bufferPos++] = ETX;
242 Serial.write(buffer, bufferPos);
243 }
244};
245
246#endif /* TELEINFO_H */
A class for managing and sending telemetry information in a structured frame format.
Definition teleinfo.h:145
uint8_t index
Definition teleinfo.h:191
static const char TAB
Definition teleinfo.h:151
__attribute__((always_inline)) void endFrame()
Finalizes the frame by adding the end character and sending the buffer over Serial.
Definition teleinfo.h:239
void send(const char *tag, int16_t value, uint8_t index=0)
Sends a telemetry value as an integer.
Definition teleinfo.h:219
static const char STX
Definition teleinfo.h:147
uint8_t calculateChecksum(size_t startPos, size_t endPos) const
Calculates the checksum for a portion of the buffer.
Definition teleinfo.h:162
size_t bufferPos
Definition teleinfo.h:154
static const char CR
Definition teleinfo.h:150
char buffer[calcBufferSize()]
Definition teleinfo.h:153
__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:208
static const char ETX
Definition teleinfo.h:148
static const char LF
Definition teleinfo.h:149
Configuration values to be set by the end-user.
constexpr bool RELAY_DIVERSION
Definition config.h:43
constexpr TemperatureSensing temperatureSensing
Definition config.h:89
constexpr RelayEngine relays
Definition config.h:79
constexpr uint8_t NO_OF_DUMPLOADS
Definition config.h:35
constexpr bool TEMP_SENSOR_PRESENT
Definition config.h:45
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:81
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:94