Browse Source

Direct InfluxDB HTTP support

fastled
Xose Pérez 7 years ago
parent
commit
55bec8f033
13 changed files with 244 additions and 62 deletions
  1. +5
    -0
      code/espurna/analog.ino
  2. +10
    -0
      code/espurna/config/general.h
  3. +1
    -0
      code/espurna/config/prototypes.h
  4. +5
    -0
      code/espurna/dht.ino
  5. +4
    -0
      code/espurna/ds18b20.ino
  6. +6
    -0
      code/espurna/emon.ino
  7. +10
    -0
      code/espurna/espurna.ino
  8. +59
    -0
      code/espurna/influxdb.ino
  9. +10
    -0
      code/espurna/pow.ino
  10. +13
    -0
      code/espurna/relay.ino
  11. +61
    -61
      code/espurna/static/index.html.gz.h
  12. +12
    -0
      code/espurna/web.ino
  13. +48
    -1
      code/html/index.html

+ 5
- 0
code/espurna/analog.ino View File

@ -47,6 +47,11 @@ void analogLoop() {
domoticzSend("dczAnaIdx", 0, String(analog).c_str());
#endif
// Send to InfluxDB
#if ENABLE_INFLUXDB
influxDBSend(MQTT_TOPIC_ANALOG, analog);
#endif
// Update websocket clients
char buffer[100];
sprintf_P(buffer, PSTR("{\"analogVisible\": 1, \"analogValue\": %d}"), analog);


+ 10
- 0
code/espurna/config/general.h View File

@ -183,6 +183,7 @@
#define MQTT_TOPIC_APP "app"
#define MQTT_TOPIC_INTERVAL "interval"
#define MQTT_TOPIC_HOSTNAME "hostname"
#define MQTT_TOPIC_ANALOG "analog"
// Periodic reports
#define MQTT_REPORT_STATUS 1
@ -261,6 +262,15 @@
#define DOMOTICZ_IN_TOPIC "domoticz/in"
#define DOMOTICZ_OUT_TOPIC "domoticz/out"
// -----------------------------------------------------------------------------
// INFLUXDB
// -----------------------------------------------------------------------------
#ifndef ENABLE_INFLUXDB
#define ENABLE_INFLUXDB 1
#endif
#define INFLUXDB_PORT 8086
// -----------------------------------------------------------------------------
// NTP
// -----------------------------------------------------------------------------


+ 1
- 0
code/espurna/config/prototypes.h View File

@ -16,3 +16,4 @@ template<typename T> String getSetting(const String& key, T defaultValue);
template<typename T> String getSetting(const String& key, unsigned int index, T defaultValue);
template<typename T> void domoticzSend(const char * key, T value);
template<typename T> void domoticzSend(const char * key, T nvalue, const char * svalue);
template<typename T> bool influxDBSend(const char * topic, T payload);

+ 5
- 0
code/espurna/dht.ino View File

@ -93,6 +93,11 @@ void dhtLoop() {
}
#endif
#if ENABLE_INFLUXDB
influxDBSend(getSetting("dhtTmpTopic", DHT_TEMPERATURE_TOPIC).c_str(), temperature);
influxDBSend(getSetting("dhtHumTopic", DHT_HUMIDITY_TOPIC).c_str(), humidity);
#endif
// Update websocket clients
char buffer[100];
sprintf_P(buffer, PSTR("{\"dhtVisible\": 1, \"dhtTmp\": %s, \"dhtHum\": %s, \"tmpUnits\": %d}"), temperature, humidity, tmpUnits);


+ 4
- 0
code/espurna/ds18b20.ino View File

@ -99,6 +99,10 @@ void dsLoop() {
domoticzSend("dczTmpIdx", 0, _dsTemperatureStr);
#endif
#if ENABLE_INFLUXDB
influxDBSend(getSetting("dsTmpTopic", DS_TEMPERATURE_TOPIC).c_str(), _dsTemperatureStr);
#endif
// Update websocket clients
char buffer[100];
sprintf_P(buffer, PSTR("{\"dsVisible\": 1, \"dsTmp\": %s, \"tmpUnits\": %d}"), getDSTemperatureStr(), tmpUnits);


+ 6
- 0
code/espurna/emon.ino View File

@ -189,6 +189,12 @@ void powerMonitorLoop() {
}
#endif
#if ENABLE_INFLUXDB
influxDBSend(getSetting("emonPowerTopic", EMON_APOWER_TOPIC).c_str(), power);
//influxDBSend(getSetting("emonCurrTopic", EMON_CURRENT_TOPIC).c_str(), c);
//influxDBSend(getSetting("emonEnergyTopic", EMON_ENERGY_TOPIC).c_str(), e);
#endif
// Reset counters
sum = measurements = 0;


+ 10
- 0
code/espurna/espurna.ino View File

@ -51,6 +51,7 @@ void heartbeat() {
#endif
}
#if (MQTT_REPORT_INTERVAL)
mqttSend(MQTT_TOPIC_INTERVAL, HEARTBEAT_INTERVAL / 1000);
#endif
@ -74,9 +75,15 @@ void heartbeat() {
#endif
#if (MQTT_REPORT_UPTIME)
mqttSend(MQTT_TOPIC_UPTIME, String(uptime_seconds).c_str());
#if ENABLE_INFLUXDB
influxDBSend(MQTT_TOPIC_UPTIME, String(uptime_seconds).c_str());
#endif
#endif
#if (MQTT_REPORT_FREEHEAP)
mqttSend(MQTT_TOPIC_FREEHEAP, String(free_heap).c_str());
#if ENABLE_INFLUXDB
influxDBSend(MQTT_TOPIC_FREEHEAP, String(free_heap).c_str());
#endif
#endif
#if (MQTT_REPORT_RELAY)
relayMQTT();
@ -189,6 +196,9 @@ void setup() {
#if ENABLE_NOFUSS
nofussSetup();
#endif
#if ENABLE_INFLUXDB
influxDBSetup();
#endif
#if ENABLE_POW
powSetup();
#endif


+ 59
- 0
code/espurna/influxdb.ino View File

@ -0,0 +1,59 @@
/*
I2C MODULE
Copyright (C) 2017 by Xose Pérez <xose dot perez at gmail dot com>
*/
#if ENABLE_INFLUXDB
#include "ESPAsyncTCP.h"
#include "SyncClient.h"
bool influxDBEnabled = false;
template<typename T> bool influxDBSend(const char * topic, T payload) {
if (!influxDBEnabled) return true;
SyncClient client;
if (!client.connect(getSetting("idbHost").c_str(), getSetting("idbPort", INFLUXDB_PORT).toInt())) {
DEBUG_MSG_P(("[INFLUXDB] Connection failed\n"));
return false;
}
client.setTimeout(2);
char data[64];
sprintf(data, "%s,device=%s value=%s", topic, getSetting("hostname", HOSTNAME).c_str(), String(payload).c_str());
DEBUG_MSG_P(("[INFLUXDB] Data: %s\n"), data);
char request[250];
sprintf(request, "POST /write?db=%s&u=%s&p=%s HTTP/1.1\r\nHost: %s:%d\r\nContent-Length: %d\r\n\r\n%s",
getSetting("idbDatabase").c_str(), getSetting("idbUsername").c_str(), getSetting("idbPassword").c_str(),
getSetting("idbHost").c_str(), getSetting("idbPort", INFLUXDB_PORT).toInt(),
strlen(data), data);
if (client.printf(request) > 0) {
while (client.connected() && client.available() == 0) delay(1);
while (client.available()) client.read();
if (client.connected()) client.stop();
return true;
}
client.stop();
DEBUG_MSG_P(("[INFLUXDB] Sent failed\n"));
while (client.connected()) delay(0);
return false;
}
void influxDBConfigure() {
influxDBEnabled = getSetting("idbHost").length() > 0;
}
void influxDBSetup() {
influxDBConfigure();
}
#endif

+ 10
- 0
code/espurna/pow.ino View File

@ -286,6 +286,16 @@ void powLoop() {
}
#endif
#if ENABLE_INFLUXDB
influxDBSend(getSetting("powPowerTopic", POW_POWER_TOPIC).c_str(), String(power).c_str());
//influxDBSend(getSetting("powEnergyTopic", POW_ENERGY_TOPIC).c_str(), e);
//influxDBSend(getSetting("powCurrentTopic", POW_CURRENT_TOPIC).c_str(), String(current, 3).c_str());
//influxDBSend(getSetting("powVoltageTopic", POW_VOLTAGE_TOPIC).c_str(), String(voltage).c_str());
//influxDBSend(getSetting("powAPowerTopic", POW_APOWER_TOPIC).c_str(), String(apparent).c_str());
//influxDBSend(getSetting("powRPowerTopic", POW_RPOWER_TOPIC).c_str(), String(reactive).c_str());
//influxDBSend(getSetting("powPFactorTopic", POW_PFACTOR_TOPIC).c_str(), String(factor, 2).c_str());
#endif
// Reset counters
power_sum = current_sum = voltage_sum = 0;
report_count = POW_REPORT_EVERY;


+ 13
- 0
code/espurna/relay.ino View File

@ -386,6 +386,15 @@ void relayMQTT(unsigned char id) {
mqttSend(MQTT_TOPIC_RELAY, id, relayStatus(id) ? "1" : "0");
}
#if ENABLE_INFLUXDB
void relayInfluxDB(unsigned char id) {
if (id >= _relays.size()) return;
char buffer[10];
sprintf(buffer, "%s,id=%d", MQTT_TOPIC_RELAY, id);
influxDBSend(buffer, relayStatus(id) ? "1" : "0");
}
#endif
void relayMQTT() {
for (unsigned int i=0; i < _relays.size(); i++) {
relayMQTT(i);
@ -528,6 +537,10 @@ void relayLoop(void) {
relayDomoticzSend(id);
#endif
#if ENABLE_INFLUXDB
relayInfluxDB(id);
#endif
_relays[id].scheduledReport = false;
}


+ 61
- 61
code/espurna/static/index.html.gz.h
File diff suppressed because it is too large
View File


+ 12
- 0
code/espurna/web.ino View File

@ -348,6 +348,9 @@ void _wsParse(uint32_t client_id, uint8_t * payload, size_t length) {
#if ENABLE_FAUXMO
fauxmoConfigure();
#endif
#if ENABLE_INFLUXDB
influxDBConfigure();
#endif
buildTopics();
#if ENABLE_RF
@ -493,6 +496,15 @@ void _wsStart(uint32_t client_id) {
#endif
#if ENABLE_INFLUXDB
root["idbVisible"] = 1;
root["idbHost"] = getSetting("idbHost");
root["idbPort"] = getSetting("idbPort", INFLUXDB_PORT).toInt();
root["idbDatabase"] = getSetting("idbDatabase");
root["idbUsername"] = getSetting("idbUsername");
root["idbPassword"] = getSetting("idbPassword");
#endif
#if ENABLE_FAUXMO
root["fauxmoVisible"] = 1;
root["fauxmoEnabled"] = getSetting("fauxmoEnabled", FAUXMO_ENABLED).toInt() == 1;


+ 48
- 1
code/html/index.html View File

@ -106,6 +106,10 @@
<a href="#" class="pure-menu-link" data="panel-domoticz">DOMOTICZ</a>
</li>
<li class="pure-menu-item module module-idb">
<a href="#" class="pure-menu-link" data="panel-idb">INFLUXDB</a>
</li>
<li class="pure-menu-item module module-pow">
<a href="#" class="pure-menu-link" data="panel-power">POWER</a>
</li>
@ -451,7 +455,7 @@
<div class="pure-g">
<label class="pure-u-1 pure-u-md-1-4" for="mqttPassword">MQTT Password</label>
<input class="pure-u-1 pure-u-md-3-4" name="mqttPassword" type="text" size="20" tabindex="24" placeholder="Leave blank if no user/pass" />
<input class="pure-u-1 pure-u-md-3-4" name="mqttPassword" type="password" size="20" tabindex="24" placeholder="Leave blank if no user/pass" />
</div>
<div class="pure-g">
@ -589,6 +593,49 @@
</div>
<div class="panel" id="panel-idb">
<div class="header">
<h1>INFLUXDB</h1>
<h2>
Configure the connection to your InfluxDB server. Leave the host field empty to disable InfluxDB connection.
</h2>
</div>
<div class="page">
<fieldset>
<div class="pure-g">
<label class="pure-u-1 pure-u-md-1-4" for="idbHost">Host</label>
<input class="pure-u-1 pure-u-md-3-4" name="idbHost" type="text" tabindex="41" />
</div>
<div class="pure-g">
<label class="pure-u-1 pure-u-md-1-4" for="idbPort">Port</label>
<input class="pure-u-1 pure-u-md-3-4" name="idbPort" type="text" tabindex="42" />
</div>
<div class="pure-g">
<label class="pure-u-1 pure-u-md-1-4" for="idbDatabase">Database</label>
<input class="pure-u-1 pure-u-md-3-4" name="idbDatabase" type="text" tabindex="43" />
</div>
<div class="pure-g">
<label class="pure-u-1 pure-u-md-1-4" for="idbUsername">Username</label>
<input class="pure-u-1 pure-u-md-3-4" name="idbUsername" type="text" tabindex="44" />
</div>
<div class="pure-g">
<label class="pure-u-1 pure-u-md-1-4" for="idbPassword">Password</label>
<input class="pure-u-1 pure-u-md-3-4" name="idbPassword" type="password" tabindex="45" />
</div>
</fieldset>
</div>
</div>
<div class="panel" id="panel-power">
<div class="header">


Loading…
Cancel
Save