Skip to content

Commit 6b01dc9

Browse files
authored
Merge pull request #193 from tobiasschuerg/fix/timestamp
fix: timestamp
2 parents 8f4ab57 + 9091de3 commit 6b01dc9

19 files changed

+189
-67
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
# Changelog
2+
## Unreleased
3+
### Fixes
4+
- [193](https://github.com/tobiasschuerg/InfluxDB-Client-for-Arduino/pull/193) - Automatically adjusting point timestamp according to the setting of write precision.
5+
26
## 3.12.0 [2022-03-21]
37
### Features
48
- [185](https://github.com/tobiasschuerg/InfluxDB-Client-for-Arduino/pull/185) - Added diagnostic server connection state getter `bool InfluxDBClient::isConnected()`

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -678,10 +678,10 @@ boolean success = influx.write();
678678
## Troubleshooting
679679
All db methods return status. Value `false` means something went wrong. Call `getLastErrorMessage()` to get the error message.
680680

681-
When error message doesn't help to explain the bad behavior, go to the library sources and in the file `src/InfluxDBClient.cpp` uncomment line 32:
681+
When error message doesn't help to explain the bad behavior, go to the library sources and in the file `src/util/debug.h` uncomment line 33:
682682
```cpp
683683
// Uncomment bellow in case of a problem and rebuild sketch
684-
#define INFLUXDB_CLIENT_DEBUG
684+
#define INFLUXDB_CLIENT_DEBUG_ENABLE
685685
```
686686
Then upload your sketch again and see the debug output in the Serial Monitor.
687687

src/BucketsClient.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
#include "BucketsClient.h"
2828
#include "util/helpers.h"
2929

30-
//#define INFLUXDB_CLIENT_DEBUG_ENABLE
3130
#include "util/debug.h"
3231

3332
static const char *propTemplate PROGMEM = "\"%s\":";

src/HTTPService.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
#include "Platform.h"
44
#include "Version.h"
55

6-
// Uncomment bellow in case of a problem and rebuild sketch
7-
//#define INFLUXDB_CLIENT_DEBUG_ENABLE
86
#include "util/debug.h"
97

108
static const char UserAgent[] PROGMEM = "influxdb-client-arduino/" INFLUXDB_CLIENT_VERSION " (" INFLUXDB_CLIENT_PLATFORM " " INFLUXDB_CLIENT_PLATFORM_VERSION ")";

src/InfluxData.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929

3030
void InfluxData::setTimestamp(long int seconds)
3131
{
32-
_timestamp = timeStampToString(seconds) + "000000000";
32+
_timestamp = timeStampToString(seconds,9);
33+
strcat(_timestamp, "000000000");
3334
}
3435

3536
String InfluxData::toString() const {

src/InfluxDbClient.cpp

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@
2828
#include "Platform.h"
2929
#include "Version.h"
3030

31-
// Uncomment bellow in case of a problem and rebuild sketch
32-
//#define INFLUXDB_CLIENT_DEBUG_ENABLE
3331
#include "util/debug.h"
3432

3533
static const char TooEarlyMessage[] PROGMEM = "Cannot send request yet because of applied retry strategy. Remaining ";
@@ -287,17 +285,49 @@ void InfluxDBClient::reserveBuffer(int size) {
287285
}
288286
}
289287

290-
bool InfluxDBClient::writePoint(Point & point) {
291-
if (point.hasFields()) {
292-
if(_writeOptions._writePrecision != WritePrecision::NoTime && !point.hasTime()) {
288+
void InfluxDBClient::addZerosToTimestamp(Point &point, int zeroes) {
289+
char *ts = point._timestamp, *s;
290+
point._timestamp = new char[strlen(point._timestamp) + 1 + zeroes];
291+
strcpy(point._timestamp, ts);
292+
s = point._timestamp+strlen(ts);
293+
for(int i=0;i<zeroes;i++) {
294+
*s++ = '0';
295+
}
296+
*s = 0;
297+
delete [] ts;
298+
}
299+
300+
void InfluxDBClient::checkPrecisions(Point & point) {
301+
if(_writeOptions._writePrecision != WritePrecision::NoTime) {
302+
if(!point.hasTime()) {
293303
point.setTime(_writeOptions._writePrecision);
304+
// Check different write precisions
305+
} else if(point._tsWritePrecision != WritePrecision::NoTime && point._tsWritePrecision != _writeOptions._writePrecision) {
306+
int diff = int(point._tsWritePrecision) - int(_writeOptions._writePrecision);
307+
if(diff > 0) { //point has higher precision, cut
308+
point._timestamp[strlen(point._timestamp)-diff*3] = 0;
309+
} else { //point has lower precision, add zeroes
310+
addZerosToTimestamp(point, diff*-3);
311+
}
294312
}
313+
// check someone set WritePrecision on point and not on client. NS precision is ok, cause it is default on server
314+
} else if(point.hasTime() && point._tsWritePrecision != WritePrecision::NoTime && point._tsWritePrecision != WritePrecision::NS) {
315+
int diff = int(WritePrecision::NS) - int(point._tsWritePrecision);
316+
addZerosToTimestamp(point, diff*3);
317+
}
318+
}
319+
320+
bool InfluxDBClient::writePoint(Point & point) {
321+
if (point.hasFields()) {
322+
checkPrecisions(point);
295323
String line = pointToLineProtocol(point);
296324
return writeRecord(line);
297325
}
298326
return false;
299327
}
300328

329+
330+
301331
InfluxDBClient::Batch::Batch(uint16_t size):_size(size) {
302332
buffer = new char*[size];
303333
for(int i=0;i< _size; i++) {

src/InfluxDbClient.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class Test;
5050
* Automaticaly retries failed writes during next write, if server is overloaded.
5151
*/
5252
class InfluxDBClient {
53+
friend class Test;
5354
public:
5455
// Creates InfluxDBClient unconfigured instance.
5556
// Call to setConnectionParams is required to set up client
@@ -221,7 +222,6 @@ class InfluxDBClient {
221222
virtual size_t write(uint8_t data) override;
222223

223224
};
224-
friend class Test;
225225
ConnectionInfo _connInfo;
226226
// Cached full write url
227227
String _writeUrl;
@@ -263,6 +263,10 @@ class InfluxDBClient {
263263
// flashOnlyFull - whether to flush only full batches
264264
// Returns true if successful, false in case of any error
265265
bool flushBufferInternal(bool flashOnlyFull);
266+
// Checks precision of point and mofifies if needed
267+
void checkPrecisions(Point & point);
268+
// helper which adds zeroes to timestamo of point to increase precision
269+
static void addZerosToTimestamp(Point &point, int zeroes);
266270
};
267271

268272

src/Options.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,12 @@ WriteOptions& WriteOptions::addDefaultTag(const String &name, const String &valu
3232
if(_defaultTags.length() > 0) {
3333
_defaultTags += ',';
3434
}
35-
_defaultTags += escapeKey(name);
35+
char *s = escapeKey(name);
36+
_defaultTags += s;
37+
delete [] s;
38+
s = escapeKey(value);
3639
_defaultTags += '=';
37-
_defaultTags += escapeKey(value);
40+
_defaultTags += s;
41+
delete [] s;
3842
return *this;
3943
}

src/Point.cpp

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,32 +28,39 @@
2828
#include "Point.h"
2929
#include "util/helpers.h"
3030

31-
Point::Point(const String & measurement):
32-
_measurement(escapeKey(measurement, false)),
33-
_tags(""),
34-
_fields(""),
35-
_timestamp("")
31+
Point::Point(const String & measurement)
3632
{
33+
_measurement = escapeKey(measurement, false);
34+
_timestamp = nullptr;
35+
_tsWritePrecision = WritePrecision::NoTime;
36+
}
3737

38+
Point::~Point() {
39+
delete [] _measurement;
40+
delete [] _timestamp;
3841
}
3942

4043
void Point::addTag(const String &name, String value) {
4144
if(_tags.length() > 0) {
4245
_tags += ',';
4346
}
44-
_tags += escapeKey(name);
47+
char *s = escapeKey(name);
48+
_tags += s;
49+
delete [] s;
4550
_tags += '=';
46-
_tags += escapeKey(value);
51+
s = escapeKey(value);
52+
_tags += s;
53+
delete [] s;
4754
}
4855

4956
void Point::addField(const String &name, long long value) {
50-
char buff[50];
57+
char buff[23];
5158
snprintf(buff, 50, "%lld", value);
5259
putField(name, String(buff)+"i");
5360
}
5461

5562
void Point::addField(const String &name, unsigned long long value) {
56-
char buff[50];
63+
char buff[23];
5764
snprintf(buff, 50, "%llu", value);
5865
putField(name, String(buff)+"i");
5966
}
@@ -110,7 +117,9 @@ void Point::putField(const String &name, const String &value) {
110117
if(_fields.length() > 0) {
111118
_fields += ',';
112119
}
113-
_fields += escapeKey(name);
120+
char *s = escapeKey(name);
121+
_fields += s;
122+
delete [] s;
114123
_fields += '=';
115124
_fields += value;
116125
}
@@ -121,7 +130,7 @@ String Point::toLineProtocol(const String &includeTags) const {
121130

122131
String Point::createLineProtocol(const String &incTags) const {
123132
String line;
124-
line.reserve(_measurement.length() + 1 + incTags.length() + 1 + _tags.length() + 1 + _fields.length() + 1 + _timestamp.length());
133+
line.reserve(strLen(_measurement) + 1 + incTags.length() + 1 + _tags.length() + 1 + _fields.length() + 1 + strLen(_timestamp));
125134
line += _measurement;
126135
if(incTags.length()>0) {
127136
line += ",";
@@ -160,22 +169,33 @@ void Point::setTime(WritePrecision precision) {
160169
setTime(getTimeStamp(&tv,0));
161170
break;
162171
case WritePrecision::NoTime:
163-
_timestamp = "";
172+
setTime((char *)nullptr);
164173
break;
165174
}
175+
_tsWritePrecision = precision;
166176
}
167177

168178
void Point::setTime(unsigned long long timestamp) {
169-
_timestamp = timeStampToString(timestamp);
179+
setTime(timeStampToString(timestamp));
180+
}
181+
182+
void Point::setTime(const String &timestamp) {
183+
setTime(cloneStr(timestamp.c_str()));
184+
}
185+
186+
void Point::setTime(const char *timestamp) {
187+
setTime(cloneStr(timestamp));
170188
}
171189

172-
void Point::setTime(const String &timestamp) {
190+
void Point::setTime(char *timestamp) {
191+
delete [] _timestamp;
173192
_timestamp = timestamp;
174193
}
175194

176195
void Point::clearFields() {
177196
_fields = (char *)nullptr;
178-
_timestamp = (char *)nullptr;
197+
delete [] _timestamp;
198+
_timestamp = nullptr;
179199
}
180200

181201
void Point:: clearTags() {

src/Point.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class Point {
3939
friend class InfluxDBClient;
4040
public:
4141
Point(const String &measurement);
42+
virtual ~Point();
4243
// Adds string tag
4344
void addTag(const String &name, String value);
4445
// Add field with various types
@@ -62,6 +63,8 @@ friend class InfluxDBClient;
6263
void setTime(unsigned long long timestamp);
6364
// Set timestamp in offset since epoch (1.1.1970 00:00:00). Correct precision must be set InfluxDBClient::setWriteOptions.
6465
void setTime(const String &timestamp);
66+
// Set timestamp in offset since epoch (1.1.1970 00:00:00). Correct precision must be set InfluxDBClient::setWriteOptions.
67+
void setTime(const char *timestamp);
6568
// Clear all fields. Usefull for reusing point
6669
void clearFields();
6770
// Clear tags
@@ -71,19 +74,22 @@ friend class InfluxDBClient;
7174
// True if a point contains at least one tag
7275
bool hasTags() const { return _tags.length() > 0; }
7376
// True if a point contains timestamp
74-
bool hasTime() const { return _timestamp.length() > 0; }
77+
bool hasTime() const { return strLen(_timestamp) > 0; }
7578
// Creates line protocol with optionally added tags
7679
String toLineProtocol(const String &includeTags = "") const;
7780
// returns current timestamp
7881
String getTime() const { return _timestamp; }
7982
protected:
80-
String _measurement;
83+
char *_measurement;
8184
String _tags;
8285
String _fields;
83-
String _timestamp;
86+
char *_timestamp;
87+
WritePrecision _tsWritePrecision;
8488
protected:
8589
// method for formating field into line protocol
8690
void putField(const String &name, const String &value);
91+
// set timestamp
92+
void setTime(char *timestamp);
8793
// Creates line protocol string
8894
String createLineProtocol(const String &incTags) const;
8995
};

0 commit comments

Comments
 (0)