Added influxdb support

This commit is contained in:
Magnus 2021-04-05 15:00:52 +02:00
parent db842d6b4c
commit e8d02de96b
17 changed files with 407 additions and 177 deletions

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -119,6 +119,8 @@
</div>
</form>
<hr class="my-2">
<div class="form-group row">
<label for="calibrate-btn" class="col-sm-4 col-form-label">Current calibration values:</label>
<label for="calibrate-btn" class="col-sm-4 col-form-label" id="gyro-calibration-data">Loading...</label>
@ -147,19 +149,49 @@
<div class="form-group row">
<label for="http-push" class="col-sm-4 col-form-label">Http URL 1:</label>
<div class="col-sm-8">
<input type="url" maxlength="90" class="form-control" name="http-push" id="http-push">
<input type="url" maxlength="100" class="form-control" name="http-push" id="http-push">
</div>
</div>
<div class="form-group row">
<label for="http-push2" class="col-sm-4 col-form-label">Http URL 2:</label>
<div class="col-sm-8">
<input type="url" maxlength="90" class="form-control" name="http-push2" id="http-push2">
<input type="url" maxlength="100" class="form-control" name="http-push2" id="http-push2">
</div>
</div>
<hr class="my-2">
<div class="form-group row">
<label for="inputBrewfatherPush" class="col-sm-4 col-form-label">Brewfather URL:</label>
<div class="col-sm-8">
<input type="url" maxlength="90" class="form-control" name="brewfather-push" id="brewfather-push">
<input type="url" maxlength="100" class="form-control" name="brewfather-push" id="brewfather-push">
</div>
</div>
<hr class="my-2">
<div class="form-group row">
<label for="influxdb2-push" class="col-sm-4 col-form-label">InfluxDB v2 URL:</label>
<div class="col-sm-8">
<input type="url" maxlength="100" class="form-control" name="influxdb2-push" id="influxdb2-push">
</div>
</div>
<div class="form-group row">
<label for="influxdb2-org" class="col-sm-4 col-form-label">InfluxDB v2 Organisation:</label>
<div class="col-sm-8">
<input type="text" maxlength="50" class="form-control" name="influxdb2-org" id="influxdb2-org">
</div>
</div>
<div class="form-group row">
<label for="influxdb2-bucket" class="col-sm-4 col-form-label">InfluxDB v2 Bucket:</label>
<div class="col-sm-8">
<input type="text" maxlength="50" class="form-control" name="influxdb2-bucket" id="influxdb2-bucket">
</div>
</div>
<div class="form-group row">
<label for="influxdb2-auth" class="col-sm-4 col-form-label">InfluxDB v2 Auth. Token:</label>
<div class="col-sm-8">
<input type="text" maxlength="100" class="form-control" name="influxdb2-auth" id="influxdb2-auth">
</div>
</div>
<div class="form-group row">
@ -319,6 +351,10 @@
$("#http-push").val(cfg["http-push"]);
$("#http-push2").val(cfg["http-push2"]);
$("#brewfather-push").val(cfg["brewfather-push"]);
$("#influxdb2-push").val(cfg["influxdb2-push"]);
$("#influxdb2-org").val(cfg["influxdb2-org"]);
$("#influxdb2-bucket").val(cfg["influxdb2-bucket"]);
$("#influxdb2-auth").val(cfg["influxdb2-auth"]);
$("#sleep-interval").val(cfg["sleep-interval"]);
$("#voltage-factor").val(cfg["voltage-factor"]);
$("#gravity-formula").val(cfg["gravity-formula"]);

File diff suppressed because one or more lines are too long

View File

@ -118,7 +118,7 @@
$('#spinner').show();
$.getJSON(url, function (cfg) {
console.log( cfg );
$("#app-ver").text(cfg["app-ver"] + " (html 0.3.2)");
$("#app-ver").text(cfg["app-ver"] + " (html 0.3.5)");
$("#mdns").text(cfg["mdns"]);
$("#id").text(cfg["id"]);
})

View File

@ -14,4 +14,4 @@
<button type="button" class="btn btn-warning" id="wifi-reset-btn">Factory default settings</button>
</div>
</div>
--><hr class="my-4"></div><script type="text/javascript">function getConfig(){var n="/api/device";$("#spinner").show(),$.getJSON(n,function(n){console.log(n),$("#app-ver").text(n["app-ver"]+" (html 0.3.2)"),$("#mdns").text(n.mdns),$("#id").text(n.id)}).fail(function(){showError("Unable to get data from the device.")}).always(function(){$("#spinner").hide()})}window.onload=getConfig</script><!-- START FOOTER --><div class="container-fluid themed-container bg-primary text-light">(C) Copyright 2021 Magnus Persson</div></body></html>
--><hr class="my-4"></div><script type="text/javascript">function getConfig(){var n="/api/device";$("#spinner").show(),$.getJSON(n,function(n){console.log(n),$("#app-ver").text(n["app-ver"]+" (html 0.3.5)"),$("#mdns").text(n.mdns),$("#id").text(n.id)}).fail(function(){showError("Unable to get data from the device.")}).always(function(){$("#spinner").hide()})}window.onload=getConfig</script><!-- START FOOTER --><div class="container-fluid themed-container bg-primary text-light">(C) Copyright 2021 Magnus Persson</div></body></html>

View File

@ -23,12 +23,11 @@ build_flags = #-O0 -Wl,-Map,output.map
-D BAUD=${common_env_data.monitor_speed}
-D ACTIVATE_OTA
#-D SKIP_SLEEPMODE
-D COLLECT_PERFDATA
-D USE_LITTLEFS=true
-D EMBED_HTML
-D USER_SSID=\""\"" # =\""myssid\""
-D USER_SSID_PWD=\""\"" # =\""mypwd\""
-D CFG_APPVER="\"0.3.2\""
-D CFG_APPVER="\"0.3.5\""
lib_deps =
# https://github.com/jrowberg/i2cdevlib.git # Using local copy of this library
https://github.com/codeplea/tinyexpr
@ -51,7 +50,8 @@ extra_scripts =
build_unflags = ${common_env_data.build_unflags}
build_flags =
${common_env_data.build_flags}
-D LOG_LEVEL=6
-D COLLECT_PERFDATA # This option will collect runtime data for a few defined methods to measure time, dumped to serial or influxdb
-D LOG_LEVEL=6 # Maximum log level for the debug build.
lib_deps =
${common_env_data.lib_deps}
board = ${common_env_data.board}

View File

@ -55,9 +55,13 @@ void Config::createJson(DynamicJsonDocument& doc) {
doc[ CFG_PARAM_ID ] = getID();
doc[ CFG_PARAM_OTA ] = getOtaURL();
doc[ CFG_PARAM_TEMPFORMAT ] = String( getTempFormat() );
doc[ CFG_PARAM_PUSH_BREWFATHER ] = getBrewfatherPushTarget();
doc[ CFG_PARAM_PUSH_HTTP ] = getHttpPushTarget();
doc[ CFG_PARAM_PUSH_HTTP2 ] = getHttpPushTarget2();
doc[ CFG_PARAM_PUSH_BREWFATHER ] = getBrewfatherPushUrl();
doc[ CFG_PARAM_PUSH_HTTP ] = getHttpPushUrl();
doc[ CFG_PARAM_PUSH_HTTP2 ] = getHttpPushUrl2();
doc[ CFG_PARAM_PUSH_INFLUXDB2 ] = getInfluxDb2PushUrl();
doc[ CFG_PARAM_PUSH_INFLUXDB2_ORG ] = getInfluxDb2PushOrg();
doc[ CFG_PARAM_PUSH_INFLUXDB2_BUCKET ] = getInfluxDb2PushBucket();
doc[ CFG_PARAM_PUSH_INFLUXDB2_AUTH ] = getInfluxDb2PushToken();
doc[ CFG_PARAM_SLEEP_INTERVAL ] = getSleepInterval();
// doc[ CFG_PARAM_PUSH_INTERVAL ] = getSleepInterval(); // TODO: @deprecated
doc[ CFG_PARAM_VOLTAGEFACTOR ] = getVoltageFactor();
@ -133,6 +137,8 @@ bool Config::loadFile() {
return false;
}
Log.notice(F("CFG : Size of configuration %d bytes." CR), configFile.size() );
DynamicJsonDocument doc(CFG_JSON_BUFSIZE);
DeserializationError err = deserializeJson(doc, configFile);
#if LOG_LEVEL==6
@ -158,11 +164,19 @@ bool Config::loadFile() {
setTempFormat( s.charAt(0) );
}
if( !doc[ CFG_PARAM_PUSH_BREWFATHER ].isNull() )
setBrewfatherPushTarget( doc[ CFG_PARAM_PUSH_BREWFATHER ] );
setBrewfatherPushUrl( doc[ CFG_PARAM_PUSH_BREWFATHER ] );
if( !doc[ CFG_PARAM_PUSH_HTTP ].isNull() )
setHttpPushTarget( doc[ CFG_PARAM_PUSH_HTTP ] );
setHttpPushUrl( doc[ CFG_PARAM_PUSH_HTTP ] );
if( !doc[ CFG_PARAM_PUSH_HTTP2 ].isNull() )
setHttpPushTarget2( doc[ CFG_PARAM_PUSH_HTTP2 ] );
setHttpPushUrl2( doc[ CFG_PARAM_PUSH_HTTP2 ] );
if( !doc[ CFG_PARAM_PUSH_INFLUXDB2 ].isNull() )
setInfluxDb2PushUrl( doc[ CFG_PARAM_PUSH_INFLUXDB2 ] );
if( !doc[ CFG_PARAM_PUSH_INFLUXDB2_ORG ].isNull() )
setInfluxDb2PushOrg( doc[ CFG_PARAM_PUSH_INFLUXDB2_ORG ] );
if( !doc[ CFG_PARAM_PUSH_INFLUXDB2_BUCKET ].isNull() )
setInfluxDb2PushBucket( doc[ CFG_PARAM_PUSH_INFLUXDB2_BUCKET ] );
if( !doc[ CFG_PARAM_PUSH_INFLUXDB2_AUTH ].isNull() )
setInfluxDb2PushToken( doc[ CFG_PARAM_PUSH_INFLUXDB2_AUTH ] );
if( !doc[ CFG_PARAM_SLEEP_INTERVAL ].isNull() )
setSleepInterval( doc[ CFG_PARAM_SLEEP_INTERVAL ].as<int>() );
if( !doc[ CFG_PARAM_PUSH_INTERVAL ].isNull() ) // TODO: @deprecated
@ -231,16 +245,18 @@ void Config::debug() {
Log.verbose(F("CFG : Dumping configration " CFG_FILENAME "." CR));
Log.verbose(F("CFG : ID; '%s'." CR), getID());
Log.verbose(F("CFG : mDNS; '%s'." CR), getMDNS() );
Log.verbose(F("CFG : Sleep interval; %d." CR), getSleepInterval() );
Log.verbose(F("CFG : OTA; '%s'." CR), getOtaURL() );
Log.verbose(F("CFG : Temp; %c." CR), getTempFormat() );
Log.verbose(F("CFG : Temp Adj; %F." CR), getTempSensorAdj() );
Log.verbose(F("CFG : VoltageFactor; %F." CR), getVoltageFactor() );
Log.verbose(F("CFG : Gravity formula; '%s'." CR), getGravityFormula() );
Log.verbose(F("CFG : Gravity format; '%c'." CR), getGravityFormat() );
Log.verbose(F("CFG : Push brewfather; '%s'." CR), getBrewfatherPushTarget() );
Log.verbose(F("CFG : Push http; '%s'." CR), getHttpPushTarget() );
Log.verbose(F("CFG : Push http2; '%s'." CR), getHttpPushTarget2() );
Log.verbose(F("CFG : Sleep interval; %d." CR), getSleepInterval() );
Log.verbose(F("CFG : Push brewfather; '%s'." CR), getBrewfatherPushUrl() );
Log.verbose(F("CFG : Push http; '%s'." CR), getHttpPushUrl() );
Log.verbose(F("CFG : Push http2; '%s'." CR), getHttpPushUrl2() );
Log.verbose(F("CFG : InfluxDb2; '%s', '%s', '%s', '%s'." CR), getInfluxDb2PushUrl(), getInfluxDb2PushOrg(),
getInfluxDb2PushBucket(), getInfluxDb2PushToken() );
// Log.verbose(F("CFG : Accel offset\t%d\t%d\t%d" CR), gyroCalibration.ax, gyroCalibration.ay, gyroCalibration.az );
// Log.verbose(F("CFG : Gyro offset \t%d\t%d\t%d" CR), gyroCalibration.gx, gyroCalibration.gy, gyroCalibration.gz );
#endif

View File

@ -31,7 +31,7 @@ SOFTWARE.
#include <stdlib.h>
// defintions
#define CFG_JSON_BUFSIZE 1000
#define CFG_JSON_BUFSIZE 2000
#define CFG_APPNAME "GravityMon " // Name of firmware
#define CFG_FILENAME "/gravitymon.json" // Name of config file
@ -48,6 +48,10 @@ SOFTWARE.
#define CFG_PARAM_PUSH_BREWFATHER "brewfather-push" // URL (brewfather format)
#define CFG_PARAM_PUSH_HTTP "http-push" // URL (iSpindle format)
#define CFG_PARAM_PUSH_HTTP2 "http-push2" // URL (iSpindle format)
#define CFG_PARAM_PUSH_INFLUXDB2 "influxdb2-push" // URL (iSpindle format)
#define CFG_PARAM_PUSH_INFLUXDB2_ORG "influxdb2-org" // URL (iSpindle format)
#define CFG_PARAM_PUSH_INFLUXDB2_BUCKET "influxdb2-bucket" // URL (iSpindle format)
#define CFG_PARAM_PUSH_INFLUXDB2_AUTH "influxdb2-auth" // URL (iSpindle format)
#define CFG_PARAM_SLEEP_INTERVAL "sleep-interval" // Sleep interval
// TODO: @deprecated setting
#define CFG_PARAM_PUSH_INTERVAL "push-interval" // Time between push
@ -98,9 +102,15 @@ class Config {
int sleepInterval;
// Push target settings
String brewfatherPushTarget;
String httpPushTarget;
String httpPushTarget2;
String brewfatherPushUrl; // URL For brewfather
String httpPushUrl; // URL 1 for standard http
String httpPushUrl2; // URL 2 for standard http
String influxDb2Url; // URL for InfluxDB v2
String influxDb2Org; // Organisation for InfluxDB v2
String influxDb2Bucket; // Bucket for InfluxDB v2
String influxDb2Token; // Auth Token for InfluxDB v2
// Gravity and temperature calculations
String gravityFormula;
@ -122,19 +132,31 @@ class Config {
const char* getOtaURL() { return otaURL.c_str(); }
void setOtaURL( String s ) { otaURL = s; saveNeeded = true; }
bool isOtaActive() { return otaURL.length()>0?true:false; }
bool isOtaActive() { return otaURL.length()?true:false; }
const char* getBrewfatherPushTarget() { return brewfatherPushTarget.c_str(); }
void setBrewfatherPushTarget( String s ) { brewfatherPushTarget = s; saveNeeded = true; }
bool isBrewfatherActive() { return brewfatherPushTarget.length()>0?true:false; }
// Brewfather
const char* getBrewfatherPushUrl() { return brewfatherPushUrl.c_str(); }
void setBrewfatherPushUrl( String s ) { brewfatherPushUrl = s; saveNeeded = true; }
bool isBrewfatherActive() { return brewfatherPushUrl.length()?true:false; }
const char* getHttpPushTarget() { return httpPushTarget.c_str(); }
void setHttpPushTarget( String s ) { httpPushTarget = s; saveNeeded = true; }
bool isHttpActive() { return httpPushTarget.length()>0?true:false; }
// Standard HTTP
const char* getHttpPushUrl() { return httpPushUrl.c_str(); }
void setHttpPushUrl( String s ) { httpPushUrl = s; saveNeeded = true; }
bool isHttpActive() { return httpPushUrl.length()?true:false; }
const char* getHttpPushUrl2() { return httpPushUrl2.c_str(); }
void setHttpPushUrl2( String s ) { httpPushUrl2 = s; saveNeeded = true; }
bool isHttpActive2() { return httpPushUrl2.length()?true:false; }
const char* getHttpPushTarget2() { return httpPushTarget2.c_str(); }
void setHttpPushTarget2( String s ) { httpPushTarget2 = s; saveNeeded = true; }
bool isHttpActive2() { return httpPushTarget2.length()>0?true:false; }
// InfluxDB2
const char* getInfluxDb2PushUrl() { return influxDb2Url.c_str(); }
void setInfluxDb2PushUrl( String s ) { influxDb2Url = s; saveNeeded = true; }
bool isInfluxDb2Active() { return influxDb2Url.length()?true:false; }
const char* getInfluxDb2PushOrg() { return influxDb2Org.c_str(); }
void setInfluxDb2PushOrg( String s ) { influxDb2Org = s; saveNeeded = true; }
const char* getInfluxDb2PushBucket() { return influxDb2Bucket.c_str(); }
void setInfluxDb2PushBucket( String s ) { influxDb2Bucket = s; saveNeeded = true; }
const char* getInfluxDb2PushToken() { return influxDb2Token.c_str(); }
void setInfluxDb2PushToken( String s ) { influxDb2Token = s; saveNeeded = true; }
int getSleepInterval() { return sleepInterval; }
void setSleepInterval( int v ) { sleepInterval = v; saveNeeded = true; }

View File

@ -23,9 +23,10 @@ SOFTWARE.
*/
#include "helper.h"
#include "config.h"
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
SerialDebug mySerial;
PerfLogging myPerfLogging;
BatteryVoltage myBatteryVoltage;
//
@ -94,6 +95,115 @@ void BatteryVoltage::read() {
#endif
}
#if defined( COLLECT_PERFDATA )
PerfLogging myPerfLogging;
//
// Clear the current cache
//
void PerfLogging::clear() {
if( first == 0 )
return;
PerfEntry* pe = first;
do {
PerfEntry* p = pe;
pe = pe->next;
delete p;
} while( pe != 0 );
first = 0;
}
//
// Start measuring this performance point
//
void PerfLogging::start( const char* key ) {
PerfEntry* pe = add( key );
pe->start = millis();
}
//
// Finalize measuring of this performance point
//
void PerfLogging::stop( const char* key ) {
PerfEntry* pe = find( key );
if( pe != 0 ) {
pe->end = millis();
unsigned long t = pe->end - pe->start;
if( t > pe->max )
pe->max = t;
}
}
//
// Print the collected performance data
//
void PerfLogging::print() {
PerfEntry* pe = first;
while( pe != 0 ) {
//Log.notice( F("PERF: %s=%l ms (%l, %l)" CR), pe->key, (pe->end - pe->start), pe->start, pe->end );
Log.notice( F("PERF: %s %lms" CR), pe->key, pe->max );
pe = pe->next;
}
}
//
// Push collected performance data to influx (use influx configuration)
//
void PerfLogging::pushInflux() {
if( !myConfig.isInfluxDb2Active() )
return;
WiFiClient client;
HTTPClient http;
String serverPath = String(myConfig.getInfluxDb2PushUrl()) + "/api/v2/write?org=" +
String(myConfig.getInfluxDb2PushOrg()) + "&bucket=" +
String(myConfig.getInfluxDb2PushBucket());
http.begin( client, serverPath);
// Create body for influxdb2, format used
// key,host=mdns value=0.0
String body;
PerfEntry* pe = first;
while( pe != 0 ) {
char buf[100];
sprintf( &buf[0], "%s,host=%s,device=%s value=%ld\n", pe->key, myConfig.getMDNS(), myConfig.getID(), pe->max);
body += &buf[0];
pe = pe->next;
}
#if LOG_LEVEL==6
Log.verbose(F("PERF: url %s." CR), serverPath.c_str());
Log.verbose(F("PERF: data %s." CR), body.c_str() );
#endif
// Send HTTP POST request
String auth = "Token " + String( myConfig.getInfluxDb2PushToken() );
http.addHeader(F("Authorization"), auth.c_str() );
int httpResponseCode = http.POST(body);
if (httpResponseCode==204) {
Log.notice(F("PUSH: InfluxDB2 HTTP Response code %d" CR), httpResponseCode);
} else {
Log.error(F("PUSH: InfluxDB2 HTTP Response code %d" CR), httpResponseCode);
}
http.end();
}
#endif // COLLECT_PERFDATA
//
// Convert float to formatted string with n decimals. Buffer should be at least 10 chars.
//

View File

@ -58,18 +58,6 @@ class BatteryVoltage {
};
#if defined( COLLECT_PERFDATA )
// Use these to collect performance data from various parts of the code
#define LOG_PERF_START(s) myPerfLogging.start(s)
#define LOG_PERF_STOP(s) myPerfLogging.stop(s)
#define LOG_PERF_PRINT() myPerfLogging.print()
#define LOG_PERF_CLEAR() myPerfLogging.clear()
#else
// These will disable the performance collection
#define LOG_PERF_START(s)
#define LOG_PERF_STOP(s)
#define LOG_PERF_PRINT()
#define LOG_PERF_CLEAR()
#endif
class PerfLogging {
private:
@ -124,67 +112,36 @@ class PerfLogging {
return pe;
};
public:
//
// Clear the current cache
//
void clear() {
if( first == 0 )
return;
PerfEntry* pe = first;
do {
PerfEntry* p = pe;
pe = pe->next;
delete p;
} while( pe != 0 );
first = 0;
}
//
// Start measuring this performance point
//
void start( const char* key ) {
PerfEntry* pe = add( key );
pe->start = millis();
}
//
// Finalize measuring of this performance point
//
void stop( const char* key ) {
PerfEntry* pe = find( key );
if( pe != 0 ) {
pe->end = millis();
unsigned long t = pe->end - pe->start;
if( t > pe->max )
pe->max = t;
}
}
//
// Print the collected performance data
//
void print() {
PerfEntry* pe = first;
while( pe != 0 ) {
//Log.notice( F("PERF: %s=%l ms (%l, %l)" CR), pe->key, (pe->end - pe->start), pe->start, pe->end );
Log.notice( F("PERF: %s %lms" CR), pe->key, pe->max );
pe = pe->next;
}
}
void clear();
void start( const char* key );
void stop( const char* key );
void print();
void pushInflux();
};
extern PerfLogging myPerfLogging;
// Use these to collect performance data from various parts of the code
#define LOG_PERF_START(s) myPerfLogging.start(s)
#define LOG_PERF_STOP(s) myPerfLogging.stop(s)
#define LOG_PERF_PRINT() myPerfLogging.print()
#define LOG_PERF_CLEAR() myPerfLogging.clear()
#define LOG_PERF_PUSH() myPerfLogging.pushInflux()
#else
// These will disable the performance collection
#define LOG_PERF_START(s)
#define LOG_PERF_STOP(s)
#define LOG_PERF_PRINT()
#define LOG_PERF_CLEAR()
#define LOG_PERF_PUSH()
#endif // COLLECT_PERFDATA
// Global instance created
extern SerialDebug mySerial;
extern PerfLogging myPerfLogging;
extern BatteryVoltage myBatteryVoltage;
#endif // _HELPER_H

View File

@ -91,6 +91,7 @@ void checkSleepMode( float angle, float volt ) {
// Setup
//
void setup() {
LOG_PERF_START("run-time");
LOG_PERF_START("main-setup");
startMillis = millis();
@ -160,8 +161,8 @@ void setup() {
}
LOG_PERF_STOP("main-setup");
LOG_PERF_PRINT();
LOG_PERF_CLEAR();
LOG_PERF_PRINT(); // Dump data to serial
LOG_PERF_PUSH(); // Dump data to influx
}
//
@ -227,6 +228,8 @@ void loop() {
LittleFS.end();
myGyro.enterSleep();
drd->stop();
LOG_PERF_STOP("run-time");
LOG_PERF_PUSH();
LOG_PERF_PRINT();
delay(100);
deepSleep( myConfig.getSleepInterval() );

View File

@ -53,15 +53,67 @@ void PushTarget::send(float angle, float gravity, float temp, float runTime, boo
if( myConfig.isHttpActive() ) {
LOG_PERF_START("push-http");
sendHttp( myConfig.getHttpPushTarget(), angle, gravity, temp, runTime );
sendHttp( myConfig.getHttpPushUrl(), angle, gravity, temp, runTime );
LOG_PERF_STOP("push-http");
}
if( myConfig.isHttpActive2() ) {
LOG_PERF_START("push-http2");
sendHttp( myConfig.getHttpPushTarget2(), angle, gravity, temp, runTime );
sendHttp( myConfig.getHttpPushUrl2(), angle, gravity, temp, runTime );
LOG_PERF_STOP("push-http2");
}
if( myConfig.isInfluxDb2Active() ) {
LOG_PERF_START("push-influxdb2");
sendInfluxDb2( angle, gravity, temp, runTime );
LOG_PERF_STOP("push-influxdb2");
}
}
//
// Send to influx db v2
//
void PushTarget::sendInfluxDb2(float angle, float gravity, float temp, float runTime) {
Log.notice(F("PUSH: Sending values to influxdb2 angle=%F, gravity=%F, temp=%F." CR), angle, gravity, temp );
WiFiClient client;
HTTPClient http;
String serverPath = String(myConfig.getInfluxDb2PushUrl()) + "/api/v2/write?org=" +
String(myConfig.getInfluxDb2PushOrg()) + "&bucket=" +
String(myConfig.getInfluxDb2PushBucket());
http.begin( client, serverPath);
// Create body for influxdb2
char buf[1024];
sprintf( &buf[0], "gravity,host=%s,device=%s,format=%s value=%.4f\n"
"temp,host=%s,device=%s,format=%c value=%.1f\n"
"battery,host=%s,device=%s value=%.2f\n"
"rssi,host=%s,device=%s value=%d\n",
// TODO: Add support for plato format
myConfig.getMDNS(), myConfig.getID(), "SG", gravity,
myConfig.getMDNS(), myConfig.getID(), myConfig.getTempFormat(), temp,
myConfig.getMDNS(), myConfig.getID(), myBatteryVoltage.getVoltage(),
myConfig.getMDNS(), myConfig.getID(), WiFi.RSSI() );
#if LOG_LEVEL==6
Log.verbose(F("PUSH: url %s." CR), serverPath.c_str());
Log.verbose(F("PUSH: data %s." CR), &buf[0] );
#endif
// Send HTTP POST request
String auth = "Token " + String( myConfig.getInfluxDb2PushToken() );
http.addHeader(F("Authorization"), auth.c_str() );
int httpResponseCode = http.POST(&buf[0]);
if (httpResponseCode==204) {
Log.notice(F("PUSH: InfluxDB2 HTTP Response code %d" CR), httpResponseCode);
} else {
Log.error(F("PUSH: InfluxDB2 HTTP Response code %d" CR), httpResponseCode);
}
http.end();
}
//
@ -91,22 +143,15 @@ void PushTarget::sendBrewfather(float angle, float gravity, float temp ) {
//
doc["name"] = myConfig.getMDNS();
doc["temp"] = reduceFloatPrecision( temp, 1);
//doc["aux_temp"] = 0;
//doc["ext_temp"] = 0;
doc["temp_unit"] = String( myConfig.getTempFormat() );
//doc["pressure"] = ;
//doc["pressure_unit"] = ;
doc["battery"] = reduceFloatPrecision( myBatteryVoltage.getVoltage(), 2 );
// TODO: Add support for plato format
doc["gravity"] = reduceFloatPrecision( gravity, 4 );
doc["gravity_unit"] = myConfig.isGravitySG()?"G":"P";
//doc["ph"] = 0;
//doc["bpm"] = 0;
//doc["comment"] = "";
//doc["beer"] = "";
WiFiClient client;
HTTPClient http;
String serverPath = myConfig.getBrewfatherPushTarget();
String serverPath = myConfig.getBrewfatherPushUrl();
// Your Domain name with URL path or IP address with path
http.begin( client, serverPath);
@ -122,9 +167,9 @@ void PushTarget::sendBrewfather(float angle, float gravity, float temp ) {
int httpResponseCode = http.POST(json);
if (httpResponseCode==200) {
Log.notice(F("PUSH: HTTP Response code %d" CR), httpResponseCode);
Log.notice(F("PUSH: Brewfather HTTP Response code %d" CR), httpResponseCode);
} else {
Log.error(F("PUSH: HTTP Response code %d" CR), httpResponseCode);
Log.error(F("PUSH: Brewfather HTTP Response code %d" CR), httpResponseCode);
}
http.end();
@ -145,12 +190,14 @@ void PushTarget::sendHttp( String serverPath, float angle, float gravity, float
doc["interval"] = myConfig.getSleepInterval();
doc["temperature"] = reduceFloatPrecision( temp, 1 );
doc["temp-units"] = String( myConfig.getTempFormat() );
// TODO: Add support for plato format
doc["gravity"] = reduceFloatPrecision( gravity, 4 );
doc["angle"] = reduceFloatPrecision( angle, 2);
doc["battery"] = reduceFloatPrecision( myBatteryVoltage.getVoltage(), 2 );
doc["rssi"] = WiFi.RSSI();
// Some additional information
doc["gravity-units"] = "SG";
doc["run-time"] = reduceFloatPrecision( runTime, 2 );
WiFiClient client;

View File

@ -39,6 +39,7 @@ class PushTarget {
void sendBrewfather(float angle, float gravity, float temp );
void sendHttp(String serverPath, float angle, float gravity, float temp, float runTime);
void sendInfluxDb2(float angle, float gravity, float temp, float runTime);
public:
PushTarget() { ms = millis(); }

View File

@ -36,7 +36,6 @@ INCBIN(AboutHtm, "data/about.min.htm" );
// Minium web interface for uploading htm files
INCBIN(UploadHtm, "data/upload.min.htm" );
#endif
// EOF

View File

@ -56,6 +56,7 @@ extern bool sleepModeAlwaysSkip;
// Callback from webServer when / has been accessed.
//
void webHandleDevice() {
LOG_PERF_START("webserver-api-device");
#if LOG_LEVEL==6
Log.verbose(F("WEB : webServer callback for /api/config." CR));
#endif
@ -71,12 +72,14 @@ void webHandleDevice() {
String out;
serializeJson(doc, out);
server.send(200, "application/json", out.c_str() );
LOG_PERF_STOP("webserver-api-device");
}
//
// Callback from webServer when / has been accessed.
//
void webHandleConfig() {
LOG_PERF_START("webserver-api-config");
#if LOG_LEVEL==6
Log.verbose(F("WEB : webServer callback for /api/config." CR));
#endif
@ -98,12 +101,14 @@ void webHandleConfig() {
String out;
serializeJson(doc, out);
server.send(200, "application/json", out.c_str() );
LOG_PERF_STOP("webserver-api-config");
}
//
// Callback from webServer when / has been accessed.
//
void webHandleUpload() {
LOG_PERF_START("webserver-api-upload");
#if LOG_LEVEL==6
Log.verbose(F("WEB : webServer callback for /api/upload." CR));
#endif
@ -122,6 +127,7 @@ void webHandleUpload() {
String out;
serializeJson(doc, out);
server.send(200, "application/json", out.c_str() );
LOG_PERF_STOP("webserver-api-upload");
}
//
@ -130,7 +136,7 @@ void webHandleUpload() {
File uploadFile;
void webHandleUploadFile() {
Log.notice(F("WEB : webServer callback for /api/upload/file." CR));
LOG_PERF_START("webserver-api-upload-file");
#if LOG_LEVEL==6
Log.verbose(F("WEB : webServer callback for /api/upload/file." CR));
#endif
@ -164,12 +170,14 @@ void webHandleUploadFile() {
} else {
server.send(500, "text/plain", "Couldn't create file.");
}
LOG_PERF_STOP("webserver-api-upload-file");
}
//
// Callback from webServer when / has been accessed.
//
void webHandleCalibrate() {
LOG_PERF_START("webserver-api-calibrate");
String id = server.arg( CFG_PARAM_ID );
#if LOG_LEVEL==6
Log.verbose(F("WEB : webServer callback for /api/calibrate." CR));
@ -177,10 +185,12 @@ void webHandleCalibrate() {
if( !id.equalsIgnoreCase( myConfig.getID() ) ) {
Log.error(F("WEB : Wrong ID received %s, expected %s" CR), id.c_str(), myConfig.getID());
server.send(400, "text/plain", "Invalid ID.");
LOG_PERF_STOP("webserver-api-calibrate");
return;
}
myGyro.calibrateSensor();
server.send(200, "text/plain", "Device calibrated" );
LOG_PERF_STOP("webserver-api-calibrate");
}
//
@ -206,6 +216,7 @@ void webHandleFactoryReset() {
// Callback from webServer when / has been accessed.
//
void webHandleStatus() {
LOG_PERF_START("webserver-api-status");
#if LOG_LEVEL==6
Log.verbose(F("WEB : webServer callback for /api/status." CR));
#endif
@ -231,6 +242,7 @@ void webHandleStatus() {
String out;
serializeJson(doc, out);
server.send(200, "application/json", out.c_str() );
LOG_PERF_STOP("webserver-api-status");
}
//
@ -255,6 +267,7 @@ void webHandleClearWIFI() {
// Used to force the device to never sleep.
//
void webHandleStatusSleepmode() {
LOG_PERF_START("webserver-api-sleepmode");
String id = server.arg( CFG_PARAM_ID );
#if LOG_LEVEL==6
Log.verbose(F("WEB : webServer callback for /api/status/sleepmode." CR) );
@ -262,6 +275,7 @@ void webHandleStatusSleepmode() {
if( !id.equalsIgnoreCase( myConfig.getID() ) ) {
Log.error(F("WEB : Wrong ID received %s, expected %s" CR), id.c_str(), myConfig.getID());
server.send(400, "text/plain", "Invalid ID.");
LOG_PERF_STOP("webserver-api-sleepmode");
return;
}
#if LOG_LEVEL==6
@ -272,12 +286,14 @@ void webHandleStatusSleepmode() {
else
sleepModeAlwaysSkip = false;
server.send(200, "text/plain", "Sleep mode updated" );
LOG_PERF_STOP("webserver-api-sleepmode");
}
//
// Update device settings.
//
void webHandleConfigDevice() {
LOG_PERF_START("webserver-api-config-device");
String id = server.arg( CFG_PARAM_ID );
#if LOG_LEVEL==6
Log.verbose(F("WEB : webServer callback for /api/config/device." CR) );
@ -285,6 +301,7 @@ void webHandleConfigDevice() {
if( !id.equalsIgnoreCase( myConfig.getID() ) ) {
Log.error(F("WEB : Wrong ID received %s, expected %s" CR), id.c_str(), myConfig.getID());
server.send(400, "text/plain", "Invalid ID.");
LOG_PERF_STOP("webserver-api-config-device");
return;
}
#if LOG_LEVEL==6
@ -296,12 +313,14 @@ void webHandleConfigDevice() {
myConfig.saveFile();
server.sendHeader("Location", "/config.htm#collapseOne", true);
server.send(302, "text/plain", "Device config updated" );
LOG_PERF_STOP("webserver-api-config-device");
}
//
// Update push settings.
//
void webHandleConfigPush() {
LOG_PERF_START("webserver-api-config-push");
String id = server.arg( CFG_PARAM_ID );
#if LOG_LEVEL==6
Log.verbose(F("WEB : webServer callback for /api/config/push." CR) );
@ -309,23 +328,34 @@ void webHandleConfigPush() {
if( !id.equalsIgnoreCase( myConfig.getID() ) ) {
Log.error(F("WEB : Wrong ID received %s, expected %s" CR), id.c_str(), myConfig.getID());
server.send(400, "text/plain", "Invalid ID.");
LOG_PERF_STOP("webserver-api-config-push");
return;
}
#if LOG_LEVEL==6
Log.verbose(F("WEB : http=%s, bf=%s interval=%s." CR), server.arg( CFG_PARAM_PUSH_HTTP ).c_str(), server.arg( CFG_PARAM_PUSH_BREWFATHER ).c_str(), server.arg( CFG_PARAM_PUSH_INTERVAL ).c_str() );
Log.verbose(F("WEB : http=%s,%s, bf=%s influx2=%s, %s, %s, %s." CR), server.arg( CFG_PARAM_PUSH_HTTP ).c_str(),
server.arg( CFG_PARAM_PUSH_HTTP2 ).c_str(), server.arg( CFG_PARAM_PUSH_BREWFATHER ).c_str(),
server.arg( CFG_PARAM_PUSH_INFLUXDB2 ).c_str(), server.arg( CFG_PARAM_PUSH_INFLUXDB2_ORG ).c_str(),
server.arg( CFG_PARAM_PUSH_INFLUXDB2_BUCKET ).c_str(), server.arg( CFG_PARAM_PUSH_INFLUXDB2_AUTH ).c_str()
);
#endif
myConfig.setHttpPushTarget( server.arg( CFG_PARAM_PUSH_HTTP ).c_str() );
myConfig.setHttpPushTarget2( server.arg( CFG_PARAM_PUSH_HTTP2 ).c_str() );
myConfig.setBrewfatherPushTarget( server.arg( CFG_PARAM_PUSH_BREWFATHER ).c_str() );
myConfig.setHttpPushUrl( server.arg( CFG_PARAM_PUSH_HTTP ).c_str() );
myConfig.setHttpPushUrl2( server.arg( CFG_PARAM_PUSH_HTTP2 ).c_str() );
myConfig.setBrewfatherPushUrl( server.arg( CFG_PARAM_PUSH_BREWFATHER ).c_str() );
myConfig.setInfluxDb2PushUrl( server.arg( CFG_PARAM_PUSH_INFLUXDB2 ).c_str() );
myConfig.setInfluxDb2PushOrg( server.arg( CFG_PARAM_PUSH_INFLUXDB2_ORG ).c_str() );
myConfig.setInfluxDb2PushBucket( server.arg( CFG_PARAM_PUSH_INFLUXDB2_BUCKET ).c_str() );
myConfig.setInfluxDb2PushToken( server.arg( CFG_PARAM_PUSH_INFLUXDB2_AUTH ).c_str() );
myConfig.saveFile();
server.sendHeader("Location", "/config.htm#collapseTwo", true);
server.send(302, "text/plain", "Push config updated" );
LOG_PERF_STOP("webserver-api-config-push");
}
//
// Update gravity settings.
//
void webHandleConfigGravity() {
LOG_PERF_START("webserver-api-config-gravity");
String id = server.arg( CFG_PARAM_ID );
#if LOG_LEVEL==6
Log.verbose(F("WEB : webServer callback for /api/config/gravity." CR) );
@ -333,6 +363,7 @@ void webHandleConfigGravity() {
if( !id.equalsIgnoreCase( myConfig.getID() ) ) {
Log.error(F("WEB : Wrong ID received %s, expected %s" CR), id.c_str(), myConfig.getID());
server.send(400, "text/plain", "Invalid ID.");
LOG_PERF_STOP("webserver-api-config-gravity");
return;
}
#if LOG_LEVEL==6
@ -343,12 +374,14 @@ void webHandleConfigGravity() {
myConfig.saveFile();
server.sendHeader("Location", "/config.htm#collapseThree", true);
server.send(302, "text/plain", "Gravity config updated" );
LOG_PERF_STOP("webserver-api-config-gravity");
}
//
// Update hardware settings.
//
void webHandleConfigHardware() {
LOG_PERF_START("webserver-api-config-hardware");
String id = server.arg( CFG_PARAM_ID );
#if LOG_LEVEL==6
Log.verbose(F("WEB : webServer callback for /api/config/hardware." CR) );
@ -356,6 +389,7 @@ void webHandleConfigHardware() {
if( !id.equalsIgnoreCase( myConfig.getID() ) ) {
Log.error(F("WEB : Wrong ID received %s, expected %s" CR), id.c_str(), myConfig.getID());
server.send(400, "text/plain", "Invalid ID.");
LOG_PERF_STOP("webserver-api-config-hardware");
return;
}
#if LOG_LEVEL==6
@ -367,6 +401,7 @@ void webHandleConfigHardware() {
myConfig.saveFile();
server.sendHeader("Location", "/config.htm#collapseFour", true);
server.send(302, "text/plain", "Hardware config updated" );
LOG_PERF_STOP("webserver-api-config-hardware");
}
//

View File

@ -1,26 +1,30 @@
{
"mdns": "gravitymon2",
"id": "ee1bfc",
"ota-url": "",
"mdns": "gravmon3",
"id": "7376ef",
"ota-url": "http://192.168.1.100:80/firmware/gravmon/",
"temp-format": "C",
"brewfather-push": "",
"http-push": "http://192.168.1.16:9090/api/v1/V7s7vRXLqnsW3HdxxRuD/telemetry",
"http-push2": "http://192.168.1.16:9090/test",
"brewfather-push": "http://log.brewfather.net/stream?id=KfkJU43jUFfj",
"http-push": "http://192.168.1.10:9090/api/v1/ZYfjlUNeiuyu9N/telemetry",
"http-push2": "http://192.168.1.10/ispindel",
"influxdb2-push": "http://192.168.1.10:8086",
"influxdb2-org": "hello",
"influxdb2-bucket": "spann",
"influxdb2-auth": "OijkU((jhfkh",
"sleep-interval": 30,
"push-interval": 30,
"voltage-factor": 1.59,
"gravity-formula": "0.0*tilt^3+0.0*tilt^2+0.0017978*tilt+0.9436",
"gravity-format": "G",
"temp-adjustment-value": 0,
"gravity-temp-adjustment": false,
"gyro-calibration-data": {
"ax": -4814,
"ay": 1143,
"az": 2270,
"gx": 47,
"gy": -25,
"gz": 47
"ax": -330,
"ay": -2249,
"az": 1170,
"gx": 99,
"gy": -6,
"gz": 4
},
"angle": 90.38,
"gravity": 1.1106,
"battery": 4.24
"angle": 90.93,
"gravity": 1.105,
"battery": 0.04
}