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.

main.cpp 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820
  1. /*
  2. * main.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 <Adafruit_BME280.h>
  15. #include <SHT2x.h>
  16. #if defined(ARDUINO_ARCH_ESP8266)
  17. #include <ESP8266WiFi.h>
  18. #include <ESP8266WebServer.h>
  19. #include <ESP8266mDNS.h>
  20. #define ESP_PLATFORM_NAME "ESP8266"
  21. #elif defined(ARDUINO_ARCH_ESP32)
  22. #include <WiFi.h>
  23. #include <WebServer.h>
  24. #include <ESPmDNS.h>
  25. #define ESP_PLATFORM_NAME "ESP32"
  26. #endif
  27. #include "config.h"
  28. #include "moisture.h"
  29. #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
  30. #include <Wire.h>
  31. #include "SimpleUpdater.h"
  32. #define BUILTIN_LED_PIN 1
  33. UPDATE_WEB_SERVER server(80);
  34. SimpleUpdater updater;
  35. #elif defined(ARDUINO_ARCH_AVR)
  36. #define ESP_PLATFORM_NAME "Uno WiFi"
  37. #define BUILTIN_LED_PIN 13
  38. #endif
  39. #ifdef ENABLE_INFLUXDB_LOGGING
  40. #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
  41. #include <InfluxDb.h>
  42. #else
  43. #include "SimpleInflux.h"
  44. #endif
  45. Influxdb influx(INFLUXDB_HOST, INFLUXDB_PORT);
  46. #define INFLUX_MAX_ERRORS_RESET 10
  47. int error_count = 0;
  48. #endif // ENABLE_INFLUXDB_LOGGING
  49. #define SHT_I2C_ADDRESS HTDU21D_ADDRESS
  50. #define BME_I2C_ADDRESS_1 0x76
  51. #define BME_I2C_ADDRESS_2 0x77
  52. #if defined(ARDUINO_ARCH_ESP8266)
  53. #define I2C_SDA_PIN 2
  54. #define I2C_SCL_PIN 0
  55. TwoWire Wire2;
  56. SHT2x sht(SHT_I2C_ADDRESS, &Wire2);
  57. #elif defined(ARDUINO_ARCH_ESP32)
  58. SHT2x sht(SHT_I2C_ADDRESS, &Wire);
  59. #elif defined(ARDUINO_ARCH_AVR)
  60. #include <UnoWiFiDevEdSerial1.h>
  61. #include <WiFiLink.h>
  62. WiFiServer server(80);
  63. SHT2x sht(SHT_I2C_ADDRESS, &Wire);
  64. #endif
  65. //#define ENABLE_RELAIS_TEST
  66. Adafruit_BME280 bme1, bme2;
  67. bool found_bme1 = false;
  68. bool found_bme2 = false;
  69. bool found_sht = false;
  70. unsigned long last_server_handle_time = 0;
  71. unsigned long last_db_write_time = 0;
  72. unsigned long last_led_blink_time = 0;
  73. #ifdef ENABLE_RELAIS_TEST
  74. #include "relais.h"
  75. static void relaisTest() {
  76. for (int i = 0; i < 10; i++) {
  77. relais_enable(i, 400 + (i * 1000));
  78. delay(100);
  79. }
  80. }
  81. void handleRelaisTest() {
  82. String message = F("<html><head>");
  83. message += F("<title>" ESP_PLATFORM_NAME " Environment Sensor</title>");
  84. message += F("</head><body>");
  85. message += F("<p>Relais Test started!</p>");
  86. message += F("<p><a href=\"/\">Return to Home</a></p>");
  87. message += F("</body></html>");
  88. server.send(200, "text/html", message);
  89. relaisTest();
  90. }
  91. #endif // ENABLE_RELAIS_TEST
  92. static float bme1_temp(void) {
  93. while (1) {
  94. float a = bme1.readTemperature();
  95. float b = bme1.readTemperature();
  96. if ((a > b) && ((a - b) < 2.0)) {
  97. return (a + b) / 2.0;
  98. }
  99. if ((a < b) && ((b - a) < 2.0)) {
  100. return (a + b) / 2.0;
  101. }
  102. }
  103. return 0.0;
  104. }
  105. static float bme2_temp(void) {
  106. while (1) {
  107. float a = bme2.readTemperature();
  108. float b = bme2.readTemperature();
  109. if ((a > b) && ((a - b) < 2.0)) {
  110. return (a + b) / 2.0;
  111. }
  112. if ((a < b) && ((b - a) < 2.0)) {
  113. return (a + b) / 2.0;
  114. }
  115. }
  116. return 0.0;
  117. }
  118. static float bme1_humid(void) {
  119. while (1) {
  120. float a = bme1.readHumidity();
  121. float b = bme1.readHumidity();
  122. if ((a > b) && ((a - b) < 2.0)) {
  123. return (a + b) / 2.0;
  124. }
  125. if ((a < b) && ((b - a) < 2.0)) {
  126. return (a + b) / 2.0;
  127. }
  128. }
  129. return 0.0;
  130. }
  131. static float bme2_humid(void) {
  132. while (1) {
  133. float a = bme2.readHumidity();
  134. float b = bme2.readHumidity();
  135. if ((a > b) && ((a - b) < 2.0)) {
  136. return (a + b) / 2.0;
  137. }
  138. if ((a < b) && ((b - a) < 2.0)) {
  139. return (a + b) / 2.0;
  140. }
  141. }
  142. return 0.0;
  143. }
  144. static float bme1_pressure(void) {
  145. while (1) {
  146. float a = bme1.readPressure();
  147. float b = bme1.readPressure();
  148. if ((a > b) && ((a - b) < 2.0)) {
  149. return (a + b) / 2.0;
  150. }
  151. if ((a < b) && ((b - a) < 2.0)) {
  152. return (a + b) / 2.0;
  153. }
  154. }
  155. return 0.0;
  156. }
  157. static float bme2_pressure(void) {
  158. while (1) {
  159. float a = bme2.readPressure();
  160. float b = bme2.readPressure();
  161. if ((a > b) && ((a - b) < 2.0)) {
  162. return (a + b) / 2.0;
  163. }
  164. if ((a < b) && ((b - a) < 2.0)) {
  165. return (a + b) / 2.0;
  166. }
  167. }
  168. return 0.0;
  169. }
  170. static float sht_temp(void) {
  171. while (1) {
  172. float a = sht.GetTemperature();
  173. float b = sht.GetTemperature();
  174. if ((a > b) && ((a - b) < 2.0)) {
  175. return (a + b) / 2.0;
  176. }
  177. if ((a < b) && ((b - a) < 2.0)) {
  178. return (a + b) / 2.0;
  179. }
  180. }
  181. return 0.0;
  182. }
  183. static float sht_humid(void) {
  184. while (1) {
  185. float a = sht.GetHumidity();
  186. float b = sht.GetHumidity();
  187. if ((a > b) && ((a - b) < 2.0)) {
  188. return (a + b) / 2.0;
  189. }
  190. if ((a < b) && ((b - a) < 2.0)) {
  191. return (a + b) / 2.0;
  192. }
  193. }
  194. return 0.0;
  195. }
  196. #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
  197. void handleRoot() {
  198. #else
  199. void handleRoot(WiFiClient &client) {
  200. #endif
  201. String message;
  202. message += F("<html><head>");
  203. message += F("<title>" ESP_PLATFORM_NAME " Environment Sensor</title>");
  204. message += F("</head><body>");
  205. message += F("<h1>" ESP_PLATFORM_NAME " Environment Sensor</h1>");
  206. message += F("\n<p>\n");
  207. message += F("Version: ");
  208. message += esp_env_version;
  209. message += F("\n<br>\n");
  210. message += F("Location: ");
  211. message += sensor_location;
  212. #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
  213. message += F("\n<br>\n");
  214. message += F("MAC: ");
  215. message += WiFi.macAddress();
  216. #endif
  217. message += F("\n</p>\n");
  218. #if defined(ARDUINO_ARCH_AVR)
  219. do {
  220. size_t len = message.length(), off = 0;
  221. while (off < len) {
  222. if ((len - off) >= 50) {
  223. client.write(message.c_str() + off, 50);
  224. off += 50;
  225. } else {
  226. client.write(message.c_str() + off, len - off);
  227. off = len;
  228. }
  229. }
  230. message = "";
  231. } while (false);
  232. #endif
  233. #if defined(ARDUINO_ARCH_ESP8266)
  234. message += F("<p>");
  235. message += F("Reset reason: ");
  236. message += ESP.getResetReason();
  237. message += F("<br>");
  238. message += F("Free heap: ");
  239. message += String(ESP.getFreeHeap());
  240. message += F(" (");
  241. message += String(ESP.getHeapFragmentation());
  242. message += F("% fragmentation)");
  243. message += F("<br>");
  244. message += F("Free sketch space: ");
  245. message += String(ESP.getFreeSketchSpace());
  246. message += F("<br>");
  247. message += F("Flash chip real size: ");
  248. message += String(ESP.getFlashChipRealSize());
  249. if (ESP.getFlashChipSize() != ESP.getFlashChipRealSize()) {
  250. message += F("<br>");
  251. message += F("WARNING: sdk chip size (");
  252. message += (ESP.getFlashChipSize());
  253. message += F(") does not match!");
  254. }
  255. message += F("</p>");
  256. #elif defined(ARDUINO_ARCH_ESP32)
  257. message += F("<p>");
  258. message += F("Free heap: ");
  259. message += String(ESP.getFreeHeap() / 1024.0);
  260. message += F("k<br>");
  261. message += F("Free sketch space: ");
  262. message += String(ESP.getFreeSketchSpace() / 1024.0);
  263. message += F("k<br>");
  264. message += F("Flash chip size: ");
  265. message += String(ESP.getFlashChipSize() / 1024.0);
  266. message += F("k</p>");
  267. #endif
  268. message += F("\n<p>\n");
  269. if (found_bme1) {
  270. message += F("BME280 Low:");
  271. message += F("\n<br>\n");
  272. message += F("Temperature: ");
  273. message += String(bme1_temp());
  274. message += F("\n<br>\n");
  275. message += F("Humidity: ");
  276. message += String(bme1_humid());
  277. message += F("\n<br>\n");
  278. message += F("Pressure: ");
  279. message += String(bme1_pressure());
  280. } else {
  281. message += F("BME280 (low) not connected!");
  282. }
  283. message += F("\n</p>\n");
  284. message += F("\n<p>\n");
  285. if (found_bme2) {
  286. message += F("BME280 High:");
  287. message += F("\n<br>\n");
  288. message += F("Temperature: ");
  289. message += String(bme2_temp());
  290. message += F("\n<br>\n");
  291. message += F("Humidity: ");
  292. message += String(bme2_humid());
  293. message += F("\n<br>\n");
  294. message += F("Pressure: ");
  295. message += String(bme2_pressure());
  296. } else {
  297. message += F("BME280 (high) not connected!");
  298. }
  299. message += F("\n</p>\n");
  300. message += F("\n<p>\n");
  301. if (found_sht) {
  302. message += F("SHT21:");
  303. message += F("\n<br>\n");
  304. message += F("Temperature: ");
  305. message += String(sht_temp());
  306. message += F("\n<br>\n");
  307. message += F("Humidity: ");
  308. message += String(sht_humid());
  309. } else {
  310. message += F("SHT21 not connected!");
  311. }
  312. message += F("\n</p>\n");
  313. #if defined(ARDUINO_ARCH_AVR)
  314. do {
  315. size_t len = message.length(), off = 0;
  316. while (off < len) {
  317. if ((len - off) >= 50) {
  318. client.write(message.c_str() + off, 50);
  319. off += 50;
  320. } else {
  321. client.write(message.c_str() + off, len - off);
  322. off = len;
  323. }
  324. }
  325. message = "";
  326. } while (false);
  327. #endif
  328. for (int i = 0; i < moisture_count(); i++) {
  329. int moisture = moisture_read(i);
  330. if (moisture < moisture_max()) {
  331. message += F("\n<p>\n");
  332. message += F("Sensor ");
  333. message += String(i + 1);
  334. message += F(":\n<br>\n");
  335. message += F("Moisture: ");
  336. message += String(moisture);
  337. message += F(" / ");
  338. message += String(moisture_max());
  339. message += F("\n</p>\n");
  340. }
  341. }
  342. if (moisture_count() <= 0) {
  343. message += F("\n<p>\n");
  344. message += F("No moisture sensors configured!");
  345. message += F("\n</p>\n");
  346. }
  347. #if ! defined(ARDUINO_ARCH_AVR)
  348. message += F("<p>");
  349. message += F("Try <a href=\"/update\">/update</a> for OTA firmware updates!");
  350. message += F("</p>");
  351. #endif
  352. message += F("<p>");
  353. #ifdef ENABLE_INFLUXDB_LOGGING
  354. message += F("InfluxDB: ");
  355. message += INFLUXDB_DATABASE;
  356. message += F(" @ ");
  357. message += INFLUXDB_HOST;
  358. message += F(":");
  359. message += String(INFLUXDB_PORT);
  360. #else
  361. message += F("InfluxDB logging not enabled!");
  362. #endif
  363. message += F("</p>");
  364. #ifdef ENABLE_RELAIS_TEST
  365. message += F("<p><a href=\"/relaistest\">Relais Test</a></p>");
  366. #endif // ENABLE_RELAIS_TEST
  367. message += F("</body></html>");
  368. #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
  369. server.send(200, "text/html", message);
  370. #else
  371. do {
  372. size_t len = message.length(), off = 0;
  373. while (off < len) {
  374. if ((len - off) >= 50) {
  375. client.write(message.c_str() + off, 50);
  376. off += 50;
  377. } else {
  378. client.write(message.c_str() + off, len - off);
  379. off = len;
  380. }
  381. }
  382. } while (false);
  383. #endif
  384. }
  385. void setup() {
  386. pinMode(BUILTIN_LED_PIN, OUTPUT);
  387. #ifdef ENABLE_RELAIS_TEST
  388. relais_init();
  389. #endif // ENABLE_RELAIS_TEST
  390. // Blink LED for init
  391. for (int i = 0; i < 2; i++) {
  392. digitalWrite(BUILTIN_LED_PIN, LOW); // LED on
  393. delay(LED_INIT_BLINK_INTERVAL);
  394. digitalWrite(BUILTIN_LED_PIN, HIGH); // LED off
  395. delay(LED_INIT_BLINK_INTERVAL);
  396. }
  397. moisture_init();
  398. // Init I2C and try to connect to sensors
  399. #if defined(ARDUINO_ARCH_ESP8266)
  400. Wire2.begin(I2C_SDA_PIN, I2C_SCL_PIN);
  401. found_bme1 = (!bme1.begin(BME_I2C_ADDRESS_1, &Wire2)) ? false : true;
  402. found_bme2 = (!bme2.begin(BME_I2C_ADDRESS_2, &Wire2)) ? false : true;
  403. #elif defined(ARDUINO_ARCH_ESP32)
  404. Wire.begin();
  405. found_bme1 = (!bme1.begin(BME_I2C_ADDRESS_1, &Wire)) ? false : true;
  406. found_bme2 = (!bme2.begin(BME_I2C_ADDRESS_2, &Wire)) ? false : true;
  407. #elif defined(ARDUINO_ARCH_AVR)
  408. found_bme1 = (!bme1.begin(BME_I2C_ADDRESS_1, &Wire)) ? false : true;
  409. found_bme2 = (!bme2.begin(BME_I2C_ADDRESS_2, &Wire)) ? false : true;
  410. #endif
  411. found_sht = sht.GetAlive();
  412. // Build hostname string
  413. String hostname = SENSOR_HOSTNAME_PREFIX;
  414. hostname += sensor_location;
  415. #if defined(ARDUINO_ARCH_ESP8266)
  416. // Connect to WiFi AP
  417. WiFi.hostname(hostname);
  418. WiFi.mode(WIFI_STA);
  419. WiFi.begin(ssid, password);
  420. while (WiFi.status() != WL_CONNECTED) {
  421. delay(LED_CONNECT_BLINK_INTERVAL);
  422. digitalWrite(BUILTIN_LED_PIN, !digitalRead(BUILTIN_LED_PIN));
  423. }
  424. #elif defined(ARDUINO_ARCH_ESP32)
  425. // Set hostname workaround
  426. WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE);
  427. WiFi.setHostname(hostname.c_str());
  428. // Workaround for WiFi connecting only every 2nd reset
  429. // https://github.com/espressif/arduino-esp32/issues/2501#issuecomment-513602522
  430. WiFi.onEvent([](WiFiEvent_t event, WiFiEventInfo_t info) {
  431. if (info.disconnected.reason == 202) {
  432. esp_sleep_enable_timer_wakeup(10);
  433. esp_deep_sleep_start();
  434. delay(100);
  435. }
  436. }, WiFiEvent_t::SYSTEM_EVENT_STA_DISCONNECTED);
  437. // Connect to WiFi AP
  438. WiFi.mode(WIFI_STA);
  439. WiFi.begin(ssid, password);
  440. while (WiFi.status() != WL_CONNECTED) {
  441. delay(LED_CONNECT_BLINK_INTERVAL);
  442. digitalWrite(BUILTIN_LED_PIN, !digitalRead(BUILTIN_LED_PIN));
  443. }
  444. // Set hostname workaround
  445. WiFi.setHostname(hostname.c_str());
  446. #elif defined(ARDUINO_ARCH_AVR)
  447. Serial.begin(115200);
  448. Serial1.begin(115200);
  449. WiFi.init(&Serial1);
  450. Serial.print(F("Connecting WiFi"));
  451. WiFi.begin(ssid, password);
  452. while (WiFi.status() != WL_CONNECTED) {
  453. delay(LED_CONNECT_BLINK_INTERVAL);
  454. digitalWrite(BUILTIN_LED_PIN, !digitalRead(BUILTIN_LED_PIN));
  455. Serial.print(F("."));
  456. }
  457. Serial.println(F("\nWiFi connected!"));
  458. #endif
  459. #ifdef ENABLE_INFLUXDB_LOGGING
  460. // Setup InfluxDB Client
  461. influx.setDb(INFLUXDB_DATABASE);
  462. #endif // ENABLE_INFLUXDB_LOGGING
  463. #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
  464. // Setup HTTP Server
  465. MDNS.begin(hostname.c_str());
  466. updater.setup(&server);
  467. server.on("/", handleRoot);
  468. #ifdef ENABLE_RELAIS_TEST
  469. server.on("/relaistest", handleRelaisTest);
  470. #endif
  471. MDNS.addService("http", "tcp", 80);
  472. #endif
  473. server.begin();
  474. }
  475. #if defined(ARDUINO_ARCH_AVR)
  476. void http_server() {
  477. // listen for incoming clients
  478. WiFiClient client = server.available();
  479. if (client) {
  480. Serial.println(F("new http client"));
  481. // an http request ends with a blank line
  482. boolean currentLineIsBlank = true;
  483. while (client.connected()) {
  484. if (client.available()) {
  485. char c = client.read();
  486. Serial.write(c);
  487. // if you've gotten to the end of the line (received a newline
  488. // character) and the line is blank, the http request has ended,
  489. // so you can send a reply
  490. if ((c == '\n') && currentLineIsBlank) {
  491. // send a standard http response header
  492. client.println(F("HTTP/1.1 200 OK"));
  493. client.println(F("Content-Type: text/html"));
  494. client.println(F("Connection: close"));
  495. client.println();
  496. handleRoot(client);
  497. break;
  498. }
  499. if (c == '\n') {
  500. // you're starting a new line
  501. currentLineIsBlank = true;
  502. } else if (c != '\r') {
  503. // you've gotten a character on the current line
  504. currentLineIsBlank = false;
  505. }
  506. }
  507. }
  508. // give the web browser time to receive the data
  509. delay(10);
  510. // close the connection
  511. client.stop();
  512. Serial.println(F("http client disconnected"));
  513. }
  514. }
  515. #endif
  516. void handleServers() {
  517. #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
  518. server.handleClient();
  519. #else
  520. http_server();
  521. #endif
  522. #if defined(ARDUINO_ARCH_ESP8266)
  523. MDNS.update();
  524. #endif
  525. }
  526. #ifdef ENABLE_INFLUXDB_LOGGING
  527. static boolean writeMeasurement(InfluxData &measurement) {
  528. boolean success = influx.write(measurement);
  529. if (!success) {
  530. error_count++;
  531. for (int i = 0; i < 10; i++) {
  532. digitalWrite(BUILTIN_LED_PIN, LOW); // LED on
  533. delay(LED_ERROR_BLINK_INTERVAL);
  534. digitalWrite(BUILTIN_LED_PIN, HIGH); // LED off
  535. delay(LED_ERROR_BLINK_INTERVAL);
  536. }
  537. }
  538. return success;
  539. }
  540. void writeDatabase() {
  541. #if defined(ARDUINO_ARCH_AVR)
  542. Serial.println(F("Writing to InfluxDB"));
  543. InfluxData measurement("");
  544. #endif
  545. if (found_bme1) {
  546. #if defined(ARDUINO_ARCH_AVR)
  547. measurement.clear();
  548. measurement.setName("environment");
  549. #else
  550. InfluxData measurement("environment");
  551. #endif
  552. measurement.addTag("location", sensor_location);
  553. measurement.addTag("placement", "1");
  554. measurement.addTag("sensor", "bme280");
  555. #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
  556. measurement.addTag("device", WiFi.macAddress());
  557. #endif
  558. measurement.addValue("temperature", bme1_temp());
  559. measurement.addValue("pressure", bme1_pressure());
  560. measurement.addValue("humidity", bme1_humid());
  561. Serial.println(F("Writing bme1"));
  562. writeMeasurement(measurement);
  563. Serial.println(F("Done!"));
  564. }
  565. if (found_bme2) {
  566. #if defined(ARDUINO_ARCH_AVR)
  567. measurement.clear();
  568. measurement.setName("environment");
  569. #else
  570. InfluxData measurement("environment");
  571. #endif
  572. measurement.addTag("location", sensor_location);
  573. measurement.addTag("placement", "2");
  574. measurement.addTag("sensor", "bme280");
  575. #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
  576. measurement.addTag("device", WiFi.macAddress());
  577. #endif
  578. measurement.addValue("temperature", bme2_temp());
  579. measurement.addValue("pressure", bme2_pressure());
  580. measurement.addValue("humidity", bme2_humid());
  581. Serial.println(F("Writing bme2"));
  582. writeMeasurement(measurement);
  583. Serial.println(F("Done!"));
  584. }
  585. if (found_sht) {
  586. #if defined(ARDUINO_ARCH_AVR)
  587. measurement.clear();
  588. measurement.setName("environment");
  589. #else
  590. InfluxData measurement("environment");
  591. #endif
  592. measurement.addTag("location", sensor_location);
  593. measurement.addTag("sensor", "sht21");
  594. #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
  595. measurement.addTag("device", WiFi.macAddress());
  596. #endif
  597. measurement.addValue("temperature", sht_temp());
  598. measurement.addValue("humidity", sht_humid());
  599. Serial.println(F("Writing sht"));
  600. writeMeasurement(measurement);
  601. Serial.println(F("Done!"));
  602. }
  603. for (int i = 0; i < moisture_count(); i++) {
  604. int moisture = moisture_read(i);
  605. if (moisture < moisture_max()) {
  606. #if defined(ARDUINO_ARCH_AVR)
  607. measurement.clear();
  608. measurement.setName("moisture");
  609. #else
  610. InfluxData measurement("moisture");
  611. #endif
  612. measurement.addTag("location", sensor_location);
  613. String sensor(i + 1, DEC);
  614. measurement.addTag("sensor", sensor);
  615. #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
  616. measurement.addTag("device", WiFi.macAddress());
  617. #endif
  618. measurement.addValue("value", moisture);
  619. measurement.addValue("maximum", moisture_max());
  620. Serial.print(F("Writing moisture "));
  621. Serial.println(i);
  622. writeMeasurement(measurement);
  623. Serial.println(F("Done!"));
  624. }
  625. }
  626. Serial.println(F("All Done!"));
  627. }
  628. #endif // ENABLE_INFLUXDB_LOGGING
  629. void loop() {
  630. unsigned long time = millis();
  631. #ifdef ENABLE_RELAIS_TEST
  632. relais_run();
  633. #endif // ENABLE_RELAIS_TEST
  634. if ((time - last_server_handle_time) >= SERVER_HANDLE_INTERVAL) {
  635. last_server_handle_time = time;
  636. handleServers();
  637. }
  638. #ifdef ENABLE_INFLUXDB_LOGGING
  639. if ((time - last_db_write_time) >= DB_WRITE_INTERVAL) {
  640. last_db_write_time = time;
  641. writeDatabase();
  642. }
  643. #ifdef INFLUX_MAX_ERRORS_RESET
  644. if (error_count >= INFLUX_MAX_ERRORS_RESET) {
  645. #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
  646. ESP.restart();
  647. #endif
  648. }
  649. #endif // INFLUX_MAX_ERRORS_RESET
  650. #endif // ENABLE_INFLUXDB_LOGGING
  651. // blink heartbeat LED
  652. if ((time - last_led_blink_time) >= LED_BLINK_INTERVAL) {
  653. last_led_blink_time = time;
  654. digitalWrite(BUILTIN_LED_PIN, !digitalRead(BUILTIN_LED_PIN));
  655. }
  656. #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
  657. // reset ESP every 6h to be safe
  658. if (time >= (6 * 60 * 60 * 1000)) {
  659. ESP.restart();
  660. }
  661. #endif
  662. }