ESP32 / ESP8266 & BME280 / SHT2x sensor with InfluxDB support
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SimpleInflux.cpp 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. * SimpleInflux.cpp
  3. *
  4. * ESP8266 / ESP32 Environmental Sensor
  5. *
  6. * ----------------------------------------------------------------------------
  7. * "THE BEER-WARE LICENSE" (Revision 42):
  8. * <xythobuz@xythobuz.de> wrote this file. As long as you retain this notice
  9. * you can do whatever you want with this stuff. If we meet some day, and you
  10. * think this stuff is worth it, you can buy me a beer in return. Thomas Buck
  11. * ----------------------------------------------------------------------------
  12. */
  13. #include <Arduino.h>
  14. #include "DebugLog.h"
  15. #include "SimpleInflux.h"
  16. #ifdef DENABLE_SIMPLE_INFLUX
  17. #if defined(ARDUINO_ARCH_AVR)
  18. #include <WiFiLink.h>
  19. WiFiClient client;
  20. #elif defined(ARDUINO_ARCH_ESP8266)
  21. #include <ESP8266WiFi.h>
  22. #include <ESP8266HTTPClient.h>
  23. #include <WiFiClient.h>
  24. #endif
  25. void InfluxData::addTag(const char *name, const char *value) {
  26. if (tag_count < SIMPLE_INFLUX_MAX_ELEMENTS) {
  27. tag_name[tag_count] = name;
  28. tag_value[tag_count] = value;
  29. tag_count++;
  30. }
  31. }
  32. void InfluxData::addValue(const char *name, double value) {
  33. if (value_count < SIMPLE_INFLUX_MAX_ELEMENTS) {
  34. value_name[value_count] = name;
  35. value_value[value_count] = value;
  36. value_count++;
  37. }
  38. }
  39. // https://docs.influxdata.com/influxdb/v1.8/guides/write_data/
  40. boolean Influxdb::write(InfluxData &data) {
  41. //debug.print(F("Writing "));
  42. //debug.println(data.dataName());
  43. #if defined(ARDUINO_ARCH_AVR)
  44. client.stop();
  45. if (client.connect(db_host, db_port)) {
  46. client.print(F("POST /write?db="));
  47. client.print(db_name);
  48. client.println(F(" HTTP/1.1"));
  49. client.print(F("Host: "));
  50. client.print(db_host);
  51. client.print(F(":"));
  52. client.println(String(db_port));
  53. client.println(F("Connection: close"));
  54. int len = strlen(data.dataName()) + 1;
  55. for (int i = 0; i < data.tagCount(); i++) {
  56. len += strlen(data.tagName(i)) + strlen(data.tagValue(i)) + 2;
  57. }
  58. for (int i = 0; i < data.valueCount(); i++) {
  59. len += strlen(data.valueName(i)) + String(data.valueValue(i)).length() + 1;
  60. if (i > 0) {
  61. len += 1;
  62. }
  63. }
  64. client.print(F("Content-Length: "));
  65. client.println(String(len));
  66. client.println();
  67. client.print(data.dataName());
  68. for (int i = 0; i < data.tagCount(); i++) {
  69. client.print(F(","));
  70. client.print(data.tagName(i));
  71. client.print(F("="));
  72. //client.print(F("\""));
  73. client.print(data.tagValue(i));
  74. //client.print(F("\""));
  75. }
  76. client.print(F(" "));
  77. for (int i = 0; i < data.valueCount(); i++) {
  78. if (i > 0) {
  79. client.print(F(","));
  80. }
  81. client.print(data.valueName(i));
  82. client.print(F("="));
  83. client.print(data.valueValue(i));
  84. }
  85. // we're leaving out the timestamp, it's optional
  86. boolean currentLineIsBlank = true, contains_error = false;
  87. int compare_off = 0;
  88. String compare_to(F("X-Influxdb-Error"));
  89. while (client.connected()) {
  90. if (client.available()) {
  91. char c = client.read();
  92. if (c != '\r') {
  93. debug.write(c);
  94. }
  95. if (compare_off == compare_to.length()) {
  96. contains_error = true;
  97. } else if ((compare_off < compare_to.length()) && (c == compare_to[compare_off])) {
  98. if ((compare_off > 0) || currentLineIsBlank) {
  99. compare_off++;
  100. }
  101. } else {
  102. compare_off = 0;
  103. }
  104. if ((c == '\n') && currentLineIsBlank) {
  105. // http headers ended
  106. break;
  107. }
  108. if (c == '\n') {
  109. // you're starting a new line
  110. currentLineIsBlank = true;
  111. } else if (c != '\r') {
  112. // you've gotten a character on the current line
  113. currentLineIsBlank = false;
  114. }
  115. }
  116. }
  117. client.stop();
  118. debug.println(contains_error ? F("Request failed") : F("Request Done"));
  119. return !contains_error;
  120. } else {
  121. debug.println(F("Error connecting"));
  122. return false; // failed
  123. }
  124. #elif defined(ARDUINO_ARCH_ESP8266)
  125. String content = data.dataName();
  126. for (int i = 0; i < data.tagCount(); i++) {
  127. content += F(",");
  128. content += data.tagName(i);
  129. content += F("=");
  130. //content += F("\"");
  131. content += data.tagValue(i);
  132. //content += F("\"");
  133. }
  134. content += F(" ");
  135. for (int i = 0; i < data.valueCount(); i++) {
  136. if (i > 0) {
  137. content += F(",");
  138. }
  139. content += data.valueName(i);
  140. content += F("=");
  141. content += data.valueValue(i);
  142. }
  143. // we're leaving out the timestamp, it's optional
  144. WiFiClient client;
  145. HTTPClient http;
  146. http.setReuse(false);
  147. http.setTimeout(1500); // ms
  148. String uri("/write?db=");
  149. uri += db_name;
  150. http.begin(client, db_host, db_port, uri, false);
  151. //debug.print(F("Sending to Influx: "));
  152. //debug.println(content);
  153. int httpResponseCode = http.POST(content);
  154. String payload = http.getString();
  155. String compare_to(F("X-Influxdb-Error"));
  156. bool result = false; // error
  157. if ((httpResponseCode >= 200) && (httpResponseCode <= 299)
  158. && (payload.indexOf(compare_to) < 0)) {
  159. result = true; // success
  160. } else {
  161. debug.print(F("Got "));
  162. debug.print(httpResponseCode);
  163. debug.print(F(" response from Influx: "));
  164. debug.println(payload);
  165. }
  166. http.end();
  167. return result;
  168. #elif defined(ARDUINO_ARCH_ESP32)
  169. #error Not implemented for ESP32 yet
  170. #else
  171. return true; // success
  172. #endif
  173. }
  174. #endif