Skip to content

Commit

Permalink
Merge branch 'master' into fix/timestamp
Browse files Browse the repository at this point in the history
  • Loading branch information
vlastahajek committed Jul 7, 2020
2 parents 722c6a5 + 6e47386 commit fc14731
Show file tree
Hide file tree
Showing 12 changed files with 161 additions and 118 deletions.
9 changes: 7 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
# Changelog

## Version 3.3.0 (in progress)
- [FIX] More precice default timestamp generating, up to microseconds

- [NEW] Added possibility skip server certification validation (`setInsecure()` method)
- [NEW] Added possibility to query flux on secured InfuxDB 1.8 using V1 approach
- [NEW] `validateConnection()` can be used also for the [forward compatibility](https://docs.influxdata.com/influxdb/latest/tools/api/#influxdb-2-0-api-compatibility-endpoints) connection to InfluxDB 1.8
- [FIX] More precice default timestamp generating, up to microseconds
- [FIX] Debug compilation error
- [FIX] SecureBatchWrite compile error

## Version 3.2.0 (2020-06-09)
- [NEW] Added possibility to read data from InfluxDB using Flux queries
- [NEW] `timeSync` utility function for synchronous time synchronization using NTP
Expand Down
19 changes: 11 additions & 8 deletions examples/SecureBatchWrite/SecureBatchWrite.ino
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ ESP8266WiFiMulti wifiMulti;
#define WIFI_AUTH_OPEN ENC_TYPE_NONE
#endif

#include <InfluxDbClient.h
#include <InfluxDbClient.h>
#include <InfluxDbCloud.h>

// WiFi AP SSID
Expand All @@ -44,6 +44,10 @@ ESP8266WiFiMulti wifiMulti;
// Japanesse: "JST-9"
// Central Europe: "CET-1CEST,M3.5.0,M10.5.0/3"
#define TZ_INFO "CET-1CEST,M3.5.0,M10.5.0/3"
// NTP servers the for time syncronozation.
// For the fastest time sync find NTP servers in your area: https://www.pool.ntp.org/zone/
#define NTP_SERVER1 "pool.ntp.org"
#define NTP_SERVER2 "time.nis.gov"
#define WRITE_PRECISION WritePrecision::S
#define MAX_BATCH_SIZE 10
#define WRITE_BUFFER_SIZE 30
Expand Down Expand Up @@ -76,9 +80,8 @@ void setup() {
sensorStatus.addTag("SSID", WiFi.SSID());

// Accurate time is necessary for certificate validation and writing in batches
// For the fastest time sync find NTP servers in your area: https://www.pool.ntp.org/zone/
// Syncing progress and the time will be printed to Serial.
timeSync(TZ_INFO, "pool.ntp.org", "time.nis.gov");
timeSync(TZ_INFO, NTP_SERVER1, NTP_SERVER2);

// Check server connection
if (client.validateConnection()) {
Expand All @@ -89,22 +92,22 @@ void setup() {
Serial.println(client.getLastErrorMessage());
}

//Enable messages batching and retry buffer
// Enable messages batching and retry buffer
client.setWriteOptions(WRITE_PRECISION, MAX_BATCH_SIZE, WRITE_BUFFER_SIZE);
}

void loop() {
// Sync time for batching once per hour
if (iterations++ >= 360) {
timeSync();
timeSync(TZ_INFO, NTP_SERVER1, NTP_SERVER2);
iterations = 0;
}

//Report networks (low priority data) just in case we successfully wrote the previous batch
// Report networks (low priority data) just in case we successfully wrote the previous batch
if (client.isBufferEmpty()) {
// Report all the detected wifi networks
int networks = WiFi.scanNetworks();
//Set identical time for the whole network scan
// Set identical time for the whole network scan
time_t tnow = time(nullptr);
for (int i = 0; i < networks; i++) {
Point sensorNetworks("wifi_networks");
Expand Down Expand Up @@ -152,7 +155,7 @@ void loop() {
Serial.println(client.isBufferFull() ? "Yes" : "No");
}

//Wait 10s
// Wait 10s
Serial.println("Wait 10s");
delay(10000);
}
96 changes: 19 additions & 77 deletions src/InfluxDbClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <core_version.h>
#include "InfluxDbClient.h"
#include <core_version.h>

#define STRHELPER(x) #x
#define STR(x) STRHELPER(x) // stringifier
Expand All @@ -41,17 +41,14 @@
static const char UserAgent[] PROGMEM = "influxdb-client-arduino/" INFLUXDB_CLIENT_VERSION " (" INFLUXDB_CLIENT_PLATFORM " " INFLUXDB_CLIENT_PLATFORM_VERSION ")";

// Uncomment bellow in case of a problem and rebuild sketch
//#define INFLUXDB_CLIENT_DEBUG

//#define INFLUXDB_CLIENT_DEBUG_ENABLE
#include "util/debug.h"

static const char UnitialisedMessage[] PROGMEM = "Unconfigured instance";
// This cannot be put to PROGMEM due to the way how it is used
static const char RetryAfter[] = "Retry-After";
static const char TransferEnconding[] = "Transfer-Encoding";

static String escapeKey(String key);
static String escapeValue(const char *value);
static String escapeJSONString(String &value);

static String precisionToString(WritePrecision precision, uint8_t version = 2) {
Expand All @@ -70,7 +67,7 @@ static String precisionToString(WritePrecision precision, uint8_t version = 2) {
}

Point::Point(String measurement):
_measurement(measurement),
_measurement(escapeKey(measurement, false)),
_tags(""),
_fields(""),
_timestamp("")
Expand Down Expand Up @@ -194,12 +191,12 @@ void InfluxDBClient::setConnectionParamsV1(const char *serverUrl, const char *db
}

bool InfluxDBClient::init() {
INFLUXDB_CLIENT_DEBUG(F("Init\n"));
INFLUXDB_CLIENT_DEBUG(F(" Server url: %s\n"), _serverUrl.c_str());
INFLUXDB_CLIENT_DEBUG(F(" Org: %s\n"), _org.c_str());
INFLUXDB_CLIENT_DEBUG(F(" Bucket: %s\n"), _bucket.c_str());
INFLUXDB_CLIENT_DEBUG(F(" Token: %s\n"), _authToken.c_str());
INFLUXDB_CLIENT_DEBUG(F(" DB version: %d\n"), _dbVersion);
INFLUXDB_CLIENT_DEBUG("Init\n");
INFLUXDB_CLIENT_DEBUG(" Server url: %s\n", _serverUrl.c_str());
INFLUXDB_CLIENT_DEBUG(" Org: %s\n", _org.c_str());
INFLUXDB_CLIENT_DEBUG(" Bucket: %s\n", _bucket.c_str());
INFLUXDB_CLIENT_DEBUG(" Token: %s\n", _authToken.c_str());
INFLUXDB_CLIENT_DEBUG(" DB version: %d\n", _dbVersion);
if(_serverUrl.length() == 0 || (_dbVersion == 2 && (_org.length() == 0 || _bucket.length() == 0 || _authToken.length() == 0))) {
INFLUXDB_CLIENT_DEBUG("[E] Invalid parameters\n");
return false;
Expand All @@ -220,8 +217,9 @@ bool InfluxDBClient::init() {
wifiClientSec->setFingerprint(_certInfo);
}
}
if (_insecure)
if (_insecure) {
wifiClientSec->setInsecure();
}
#elif defined(ESP32)
WiFiClientSecure *wifiClientSec = new WiFiClientSecure;
if(_certInfo && strlen_P(_certInfo) > 0) {
Expand Down Expand Up @@ -269,18 +267,18 @@ void InfluxDBClient::clean() {
}

void InfluxDBClient::setUrls() {
INFLUXDB_CLIENT_DEBUG(F("setUrls\n"));
INFLUXDB_CLIENT_DEBUG("setUrls\n");
if(_dbVersion == 2) {
_writeUrl = _serverUrl;
_writeUrl += "/api/v2/write?org=";
_writeUrl += _org ;
_writeUrl += "&bucket=";
_writeUrl += _bucket;
INFLUXDB_CLIENT_DEBUG(F(" writeUrl: %s\n"), _writeUrl.c_str());
INFLUXDB_CLIENT_DEBUG(" writeUrl: %s\n", _writeUrl.c_str());
_queryUrl = _serverUrl;
_queryUrl += "/api/v2/query?org=";
_queryUrl += _org;
INFLUXDB_CLIENT_DEBUG(F(" queryUrl: %s\n"), _queryUrl.c_str());
INFLUXDB_CLIENT_DEBUG(" queryUrl: %s\n", _queryUrl.c_str());
} else {
_writeUrl = _serverUrl;
_writeUrl += "/write?db=";
Expand All @@ -293,15 +291,16 @@ void InfluxDBClient::setUrls() {
auth += "&p=";
auth += _password;
_writeUrl += auth;
_queryUrl += "?";
_queryUrl += auth;
}
INFLUXDB_CLIENT_DEBUG(F(" writeUrl: %s\n"), _writeUrl.c_str());
INFLUXDB_CLIENT_DEBUG(F(" queryUrl: %s\n"), _queryUrl.c_str());
INFLUXDB_CLIENT_DEBUG(" writeUrl: %s\n", _writeUrl.c_str());
INFLUXDB_CLIENT_DEBUG(" queryUrl: %s\n", _queryUrl.c_str());
}
if(_writePrecision != WritePrecision::NoTime) {
_writeUrl += "&precision=";
_writeUrl += precisionToString(_writePrecision, _dbVersion);
INFLUXDB_CLIENT_DEBUG(F(" writeUrl: %s\n"), _writeUrl.c_str());
INFLUXDB_CLIENT_DEBUG(" writeUrl: %s\n", _writeUrl.c_str());
}

}
Expand Down Expand Up @@ -505,7 +504,7 @@ bool InfluxDBClient::validateConnection() {
return false;
}
// on version 1.x /ping will by default return status code 204, without verbose
String url = _serverUrl + (_dbVersion==2?"/ready":"/ping?verbose=true");
String url = _serverUrl + (_dbVersion==2?"/health":"/ping?verbose=true");
INFLUXDB_CLIENT_DEBUG("[D] Validating connection to %s\n", url.c_str());

if(!_httpClient.begin(*_wifiClient, url)) {
Expand Down Expand Up @@ -649,63 +648,6 @@ void InfluxDBClient::postRequest(int expectedStatusCode) {
}
}

static String escapeKey(String key) {
String ret;
ret.reserve(key.length()+5); //5 is estimate of chars needs to escape,

for (char c: key)
{
switch (c)
{
case ' ':
case ',':
case '=':
ret += '\\';
break;
}

ret += c;
}
return ret;
}

static String escapeValue(const char *value) {
String ret;
int len = strlen_P(value);
ret.reserve(len+5); //5 is estimate of max chars needs to escape,
for(int i=0;i<len;i++)
{
switch (value[i])
{
case '\\':
case '\"':
ret += '\\';
break;
}

ret += value[i];
}
return ret;
}
static String escapeTagValue(const char *value) {
String ret;
int len = strlen_P(value);
ret.reserve(len+5); //5 is estimate of max chars needs to escape,
for(int i=0;i<len;i++)
{
switch (value[i])
{
case '\\':
case '\"':
ret += '\\';
break;
}

ret += value[i];
}
return ret;
}

static String escapeJSONString(String &value) {
String ret;
int d = 0;
Expand Down
7 changes: 4 additions & 3 deletions src/InfluxDbClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@
#define INFLUXDB_CLIENT_VERSION "3.2.0"

#include <Arduino.h>
#include "query/FluxParser.h"
#include "util/helpers.h"

#if defined(ESP8266)
# include <WiFiClientSecureBearSSL.h>
# include <ESP8266HTTPClient.h>
Expand All @@ -42,6 +39,10 @@
# error "This library currently supports only ESP8266 and ESP32."
#endif

#include "query/FluxParser.h"
#include "util/helpers.h"


#ifdef USING_AXTLS
#error AxTLS does not work
#endif
Expand Down
5 changes: 1 addition & 4 deletions src/query/CsvReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@
* SOFTWARE.
*/
#include "CsvReader.h"
// Uncomment bellow in case of a problem and rebuild sketch
#define INFLUXDB_CLIENT_DEBUG
#include "util/debug.h"

CsvReader::CsvReader(HttpStreamScanner *scanner) {
_scanner = scanner;
Expand Down Expand Up @@ -108,4 +105,4 @@ bool CsvReader::next() {
}
_row = fields;
return true;
}
}
16 changes: 8 additions & 8 deletions src/query/FluxParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

#include "FluxParser.h"
// Uncomment bellow in case of a problem and rebuild sketch
//#define INFLUXDB_CLIENT_DEBUG
//#define INFLUXDB_CLIENT_DEBUG_ENABLE
#include "util/debug.h"

FluxQueryResult::FluxQueryResult(CsvReader *reader) {
Expand Down Expand Up @@ -123,12 +123,12 @@ bool FluxQueryResult::next() {
if(!stat) {
if(_data->_reader->getError()< 0) {
_data->_error = HTTPClient::errorToString(_data->_reader->getError());
INFLUXDB_CLIENT_DEBUG(F("Error '%s'\n"), _data->_error.c_str());
INFLUXDB_CLIENT_DEBUG("Error '%s'\n", _data->_error.c_str());
}
return false;
}
std::vector<String> vals = _data->_reader->getRow();
INFLUXDB_CLIENT_DEBUG(F("[D] FluxQueryResult: vals.size %d\n"), vals.size());
INFLUXDB_CLIENT_DEBUG("[D] FluxQueryResult: vals.size %d\n", vals.size());
if(vals.size() < 2) {
goto readRow;
}
Expand All @@ -145,15 +145,15 @@ bool FluxQueryResult::next() {
reference = "," + vals[2];
}
_data->_error = message + reference;
INFLUXDB_CLIENT_DEBUG(F("Error '%s'\n"), _data->_error.c_str());
INFLUXDB_CLIENT_DEBUG("Error '%s'\n", _data->_error.c_str());
return false;
} else if (parsingState == ParsingStateNameRow) {
if (vals[1] == "error") {
parsingState = ParsingStateError;
} else {
if (vals.size()-1 != _data->_columnDatatypes.size()) {
_data->_error = String(F("Parsing error, header has different number of columns than table: ")) + String(vals.size()-1) + " vs " + String(_data->_columnDatatypes.size());
INFLUXDB_CLIENT_DEBUG(F("Error '%s'\n"), _data->_error.c_str());
INFLUXDB_CLIENT_DEBUG("Error '%s'\n", _data->_error.c_str());
return false;
} else {
for(int i=1;i < vals.size(); i++) {
Expand All @@ -166,12 +166,12 @@ bool FluxQueryResult::next() {
}
if(_data->_columnDatatypes.size() == 0) {
_data->_error = F("Parsing error, datatype annotation not found");
INFLUXDB_CLIENT_DEBUG(F("Error '%s'\n"), _data->_error.c_str());
INFLUXDB_CLIENT_DEBUG("Error '%s'\n", _data->_error.c_str());
return false;
}
if (vals.size()-1 != _data->_columnNames.size()) {
_data->_error = String(F("Parsing error, row has different number of columns than table: ")) + String(vals.size()-1) + " vs " + String(_data->_columnNames.size());
INFLUXDB_CLIENT_DEBUG(F("Error '%s'\n"), _data->_error.c_str());
INFLUXDB_CLIENT_DEBUG("Error '%s'\n", _data->_error.c_str());
return false;
}
for(int i=1;i < vals.size(); i++) {
Expand All @@ -180,7 +180,7 @@ bool FluxQueryResult::next() {
v = convertValue(vals[i], _data->_columnDatatypes[i-1]);
if(!v) {
_data->_error = String(F("Unsupported datatype: ")) + _data->_columnDatatypes[i-1];
INFLUXDB_CLIENT_DEBUG(F("Error '%s'\n"), _data->_error.c_str());
INFLUXDB_CLIENT_DEBUG("Error '%s'\n", _data->_error.c_str());
return false;
}
}
Expand Down
Loading

0 comments on commit fc14731

Please sign in to comment.