Skip to content

Commit 3ff5c27

Browse files
authored
Feature: Added streamed query support (#65)
* Revert "Removed support for querying" This reverts commit bbacd33. * Revert "Removed querying from Readme" This reverts commit 4d46172. * Revert "Removed word reading as query support has been already removed" This reverts commit 86d79c2. * Revert "Removed word reading as query support has been already removed" This reverts commit 134f433. * Adopted to client.query * feat: support for streamed querying, parsed flux result
1 parent 89b0ea6 commit 3ff5c27

28 files changed

+2824
-389
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
node_modules
22
.vscode
3+
*.txt
4+
customSettings.h

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
# Changelog
2+
## Version 3.2 (in-production)
3+
- [NEW] Added possibility to read data from InfluxDB using Flux queries
24

35
## Version 3.1.3 (2020-04-27)
46
- [FIX] SecureWrite crash (#54)

README.md

Lines changed: 166 additions & 47 deletions
Large diffs are not rendered by default.
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
/**
2+
* QueryAggregated Example code for InfluxDBClient library for Arduino.
3+
*
4+
* This example demonstrates querying basic aggreagated statistic parameters of WiFi signal level measured and stored in BasicWrite and SecureWrite examples.
5+
*
6+
* Demonstrates connection to any InfluxDB instance accesible via:
7+
* - unsecured http://...
8+
* - secure https://... (appropriate certificate is required)
9+
* - InfluxDB 2 Cloud at https://cloud2.influxdata.com/ (certificate is preconfigured)
10+
*
11+
* Enter WiFi and InfluxDB parameters below
12+
**/
13+
14+
#if defined(ESP32)
15+
#include <WiFiMulti.h>
16+
WiFiMulti wifiMulti;
17+
#define DEVICE "ESP32"
18+
#elif defined(ESP8266)
19+
#include <ESP8266WiFiMulti.h>
20+
ESP8266WiFiMulti wifiMulti;
21+
#define DEVICE "ESP8266"
22+
#endif
23+
24+
#include <InfluxDbClient.h>
25+
#include <InfluxDbCloud.h>
26+
27+
// WiFi AP SSID
28+
#define WIFI_SSID "SSID"
29+
// WiFi password
30+
#define WIFI_PASSWORD "PASSWORD"
31+
// InfluxDB v2 server url, e.g. https://eu-central-1-1.aws.cloud2.influxdata.com (Use: InfluxDB UI -> Load Data -> Client Libraries)
32+
// InfluxDB 1.8+ (v2 compatibility API) server url, e.g. http://192.168.1.48:8086
33+
#define INFLUXDB_URL "server-url"
34+
// InfluxDB v2 server or cloud API authentication token (Use: InfluxDB UI -> Load Data -> Tokens -> <select token>)
35+
// InfluxDB 1.8+ (v2 compatibility API) use form user:password, eg. admin:adminpass
36+
#define INFLUXDB_TOKEN "server token"
37+
// InfluxDB v2 organization name or id (Use: InfluxDB UI -> Settings -> Profile -> <name under tile> )
38+
// InfluxDB 1.8+ (v2 compatibility API) leave empty
39+
#define INFLUXDB_ORG "org name/id"
40+
// InfluxDB v2 bucket name (Use: InfluxDB UI -> Load Data -> Buckets)
41+
// InfluxDB 1.8+ (v2 compatibility API) use database name
42+
#define INFLUXDB_BUCKET "bucket name"
43+
44+
// Set timezone string according to https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
45+
// Examples:
46+
// Pacific Time: "PST8PDT"
47+
// Eastern: "EST5EDT"
48+
// Japanesse: "JST-9"
49+
// Central Europe: "CET-1CEST,M3.5.0,M10.5.0/3"
50+
#define TZ_INFO "CET-1CEST,M3.5.0,M10.5.0/3"
51+
52+
// InfluxDB client instance with preconfigured InfluxCloud certificate
53+
InfluxDBClient client(INFLUXDB_URL, INFLUXDB_ORG, INFLUXDB_BUCKET, INFLUXDB_TOKEN, InfluxDbCloud2CACert);
54+
55+
void setup() {
56+
Serial.begin(115200);
57+
58+
// Setup wifi
59+
WiFi.mode(WIFI_STA);
60+
wifiMulti.addAP(WIFI_SSID, WIFI_PASSWORD);
61+
62+
Serial.print("Connecting to wifi");
63+
while (wifiMulti.run() != WL_CONNECTED) {
64+
Serial.print(".");
65+
delay(500);
66+
}
67+
Serial.println();
68+
69+
70+
// Accurate time is necessary for certificate validation
71+
// For the fastest time sync find NTP servers in your area: https://www.pool.ntp.org/zone/
72+
// Syncing progress and the time will be printed to Serial
73+
timeSync(TZ_INFO, "pool.ntp.org", "time.nis.gov");
74+
75+
// Check server connection
76+
if (client.validateConnection()) {
77+
Serial.print("Connected to InfluxDB: ");
78+
Serial.println(client.getServerUrl());
79+
} else {
80+
Serial.print("InfluxDB connection failed: ");
81+
Serial.println(client.getLastErrorMessage());
82+
}
83+
}
84+
85+
86+
void loop() {
87+
// Get max RSSI
88+
printAgregateResult("max");
89+
// Get mean RSSI
90+
printAgregateResult("mean");
91+
// Get min RSSI
92+
printAgregateResult("min");
93+
94+
//Wait 10s
95+
Serial.println("Wait 10s");
96+
delay(10000);
97+
}
98+
99+
// printAgregateResult queries db for aggregated RSSI value computed by given InfluxDB selector function (max, mean, min)
100+
// Prints composed query and the result values.
101+
void printAgregateResult(String selectorFunction) {
102+
// Construct a Flux query
103+
// Query will find RSSI for last hour for each connected WiFi network with this device computed by given selector function
104+
String query = "from(bucket: \"" INFLUXDB_BUCKET "\") |> range(start: -1h) |> filter(fn: (r) => r._measurement == \"wifi_status\" and r._field == \"rssi\"";
105+
query += " and r.device == \"" DEVICE "\")";
106+
query += "|> " + selectorFunction + "()";
107+
108+
// Print ouput header
109+
Serial.print("==== ");
110+
Serial.print(selectorFunction);
111+
Serial.println(" ====");
112+
113+
// Print composed query
114+
Serial.print("Querying with: ");
115+
Serial.println(query);
116+
117+
// Send query to the server and get result
118+
FluxQueryResult result = client.query(query);
119+
120+
// Iterate over rows. Even there is just one row, next() must be called at least once.
121+
while (result.next()) {
122+
// Get converted value for flux result column 'SSID'
123+
String ssid = result.getValueByName("SSID").getString();
124+
Serial.print("SSID '");
125+
Serial.print(ssid);
126+
127+
Serial.print("' with RSSI ");
128+
// Get converted value for flux result column '_value' where there is RSSI value
129+
// RSSI is integer value and so on min and max selected results,
130+
// whereas mean is computed and the result type is double.
131+
if(selectorFunction == "mean") {
132+
double value = result.getValueByName("_value").getDouble();
133+
Serial.print(value, 1);
134+
// computed value has not got a _time column, so omitting getting time here
135+
} else {
136+
long value = result.getValueByName("_value").getLong();
137+
Serial.print(value);
138+
139+
// Get converted value for the _time column
140+
FluxDateTime time = result.getValueByName("_time").getDateTime();
141+
142+
// Format date-time for printing
143+
// Format string according to http://www.cplusplus.com/reference/ctime/strftime/
144+
String timeStr = time.format("%F %T");
145+
146+
Serial.print(" at ");
147+
Serial.print(timeStr);
148+
}
149+
150+
151+
Serial.println();
152+
}
153+
154+
// Check if there was an error
155+
if(result.getError() != "") {
156+
Serial.print("Query result error: ");
157+
Serial.println(result.getError());
158+
}
159+
160+
// Close the result
161+
result.close();
162+
}
163+

examples/QueryTable/QueryTable.ino

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/**
2+
* QueryTable Example code for InfluxDBClient library for Arduino.
3+
*
4+
* This example demonstrates querying recent history of values of WiFi signal level measured and stored in BasicWrite and SecureWrite examples.
5+
*
6+
* Demonstrates connection to any InfluxDB instance accesible via:
7+
* - unsecured http://...
8+
* - secure https://... (appropriate certificate is required)
9+
* - InfluxDB 2 Cloud at https://cloud2.influxdata.com/ (certificate is preconfigured)
10+
*
11+
* Enter WiFi and InfluxDB parameters below
12+
**/
13+
14+
#if defined(ESP32)
15+
#include <WiFiMulti.h>
16+
WiFiMulti wifiMulti;
17+
#define DEVICE "ESP32"
18+
#elif defined(ESP8266)
19+
#include <ESP8266WiFiMulti.h>
20+
ESP8266WiFiMulti wifiMulti;
21+
#define DEVICE "ESP8266"
22+
#endif
23+
24+
#include <InfluxDbClient.h>
25+
#include <InfluxDbCloud.h>
26+
27+
// WiFi AP SSID
28+
#define WIFI_SSID "SSID"
29+
// WiFi password
30+
#define WIFI_PASSWORD "PASSWORD"
31+
// InfluxDB v2 server url, e.g. https://eu-central-1-1.aws.cloud2.influxdata.com (Use: InfluxDB UI -> Load Data -> Client Libraries)
32+
// InfluxDB 1.8+ (v2 compatibility API) server url, e.g. http://192.168.1.48:8086
33+
#define INFLUXDB_URL "server-url"
34+
// InfluxDB v2 server or cloud API authentication token (Use: InfluxDB UI -> Load Data -> Tokens -> <select token>)
35+
// InfluxDB 1.8+ (v2 compatibility API) use form user:password, eg. admin:adminpass
36+
#define INFLUXDB_TOKEN "server token"
37+
// InfluxDB v2 organization name or id (Use: InfluxDB UI -> Settings -> Profile -> <name under tile> )
38+
// InfluxDB 1.8+ (v2 compatibility API) leave empty
39+
#define INFLUXDB_ORG "org name/id"
40+
// InfluxDB v2 bucket name (Use: InfluxDB UI -> Load Data -> Buckets)
41+
// InfluxDB 1.8+ (v2 compatibility API) use database name
42+
#define INFLUXDB_BUCKET "bucket name"
43+
44+
// Set timezone string according to https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
45+
// Examples:
46+
// Pacific Time: "PST8PDT"
47+
// Eastern: "EST5EDT"
48+
// Japanesse: "JST-9"
49+
// Central Europe: "CET-1CEST,M3.5.0,M10.5.0/3"
50+
#define TZ_INFO "CET-1CEST,M3.5.0,M10.5.0/3"
51+
52+
// InfluxDB client instance with preconfigured InfluxCloud certificate
53+
InfluxDBClient client(INFLUXDB_URL, INFLUXDB_ORG, INFLUXDB_BUCKET, INFLUXDB_TOKEN, InfluxDbCloud2CACert);
54+
55+
void setup() {
56+
Serial.begin(115200);
57+
58+
// Setup wifi
59+
WiFi.mode(WIFI_STA);
60+
wifiMulti.addAP(WIFI_SSID, WIFI_PASSWORD);
61+
62+
Serial.print("Connecting to wifi");
63+
while (wifiMulti.run() != WL_CONNECTED) {
64+
Serial.print(".");
65+
delay(500);
66+
}
67+
Serial.println();
68+
69+
// Accurate time is necessary for certificate validation
70+
// For the fastest time sync find NTP servers in your area: https://www.pool.ntp.org/zone/
71+
// Syncing progress and the time will be printed to Serial
72+
timeSync(TZ_INFO, "pool.ntp.org", "time.nis.gov");
73+
74+
// Check server connection
75+
if (client.validateConnection()) {
76+
Serial.print("Connected to InfluxDB: ");
77+
Serial.println(client.getServerUrl());
78+
} else {
79+
Serial.print("InfluxDB connection failed: ");
80+
Serial.println(client.getLastErrorMessage());
81+
}
82+
}
83+
84+
void loop() {
85+
// Construct a Flux query
86+
// Query will list RSSI for last 24 hours for each connected WiFi network of this device type
87+
String query = "from(bucket: \"" INFLUXDB_BUCKET "\") |> range(start: -24h) |> filter(fn: (r) => r._measurement == \"wifi_status\" and r._field == \"rssi\"";
88+
query += " and r.device == \"" DEVICE "\")";
89+
90+
Serial.println("==== List results ====");
91+
92+
// Print composed query
93+
Serial.print("Querying with: ");
94+
Serial.println(query);
95+
96+
// Send query to the server and get result
97+
FluxQueryResult result = client.query(query);
98+
99+
// Iterate over rows. Even there is just one row, next() must be called at least once.
100+
while (result.next()) {
101+
// Check for new grouping key
102+
if(result.hasTableChanged()) {
103+
Serial.println("Table:");
104+
Serial.print(" ");
105+
// Print all columns name
106+
for(String &name: result.getColumnsName()) {
107+
Serial.print(name);
108+
Serial.print(",");
109+
}
110+
Serial.println();
111+
Serial.print(" ");
112+
// Print all columns datatype
113+
for(String &tp: result.getColumnsDatatype()) {
114+
Serial.print(tp);
115+
Serial.print(",");
116+
}
117+
Serial.println();
118+
}
119+
Serial.print(" ");
120+
// Print values of the row
121+
for(FluxValue &val: result.getValues()) {
122+
// Check wheter the value is null
123+
if(!val.isNull()) {
124+
// Use raw string, unconverted value
125+
Serial.print(val.getRawValue());
126+
} else {
127+
// Print null value substite
128+
Serial.print("<null>");
129+
}
130+
Serial.print(",");
131+
}
132+
Serial.println();
133+
}
134+
135+
// Check if there was an error
136+
if(result.getError().length() > 0) {
137+
Serial.print("Query result error: ");
138+
Serial.println(result.getError());
139+
}
140+
141+
// Close the result
142+
result.close();
143+
144+
//Wait 10s
145+
Serial.println("Wait 10s");
146+
delay(10000);
147+
}
148+

examples/SecureBatchWrite/SecureBatchWrite.ino

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -57,29 +57,6 @@ Point sensorStatus("wifi_status");
5757
// Number for loops to sync time using NTP
5858
int iterations = 0;
5959

60-
void timeSync() {
61-
// Synchronize UTC time with NTP servers
62-
// Accurate time is necessary for certificate validaton and writing in batches
63-
configTime(0, 0, "pool.ntp.org", "time.nis.gov");
64-
// Set timezone
65-
setenv("TZ", TZ_INFO, 1);
66-
67-
// Wait till time is synced
68-
Serial.print("Syncing time");
69-
int i = 0;
70-
while (time(nullptr) < 1000000000ul && i < 100) {
71-
Serial.print(".");
72-
delay(100);
73-
i++;
74-
}
75-
Serial.println();
76-
77-
// Show time
78-
time_t tnow = time(nullptr);
79-
Serial.print("Synchronized time: ");
80-
Serial.println(String(ctime(&tnow)));
81-
}
82-
8360
void setup() {
8461
Serial.begin(115200);
8562

@@ -98,8 +75,10 @@ void setup() {
9875
sensorStatus.addTag("device", DEVICE);
9976
sensorStatus.addTag("SSID", WiFi.SSID());
10077

101-
// Sync time for certificate validation
102-
timeSync();
78+
// Accurate time is necessary for certificate validation and writing in batches
79+
// For the fastest time sync find NTP servers in your area: https://www.pool.ntp.org/zone/
80+
// Syncing progress and the time will be printed to Serial.
81+
timeSync(TZ_INFO, "pool.ntp.org", "time.nis.gov");
10382

10483
// Check server connection
10584
if (client.validateConnection()) {

0 commit comments

Comments
 (0)