ESP32 / ESP8266 & BME280 / SHT2x sensor with InfluxDB support
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

main.cpp 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821
  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 <Wire.h>
  15. #include <Adafruit_BME280.h>
  16. #include <SHT2x.h>
  17. #if defined(ARDUINO_ARCH_ESP8266)
  18. #include <ESP8266WiFi.h>
  19. #include <ESP8266WebServer.h>
  20. #include <ESP8266mDNS.h>
  21. #define ESP_PLATFORM_NAME "ESP8266"
  22. #elif defined(ARDUINO_ARCH_ESP32)
  23. #include <WiFi.h>
  24. #include <WebServer.h>
  25. #include <ESPmDNS.h>
  26. #define ESP_PLATFORM_NAME "ESP32"
  27. #endif
  28. #include "config.h"
  29. #include "moisture.h"
  30. #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
  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("<p>");
  207. message += F("Version: ");
  208. message += esp_env_version;
  209. message += F("<br>");
  210. message += F("Location: ");
  211. message += sensor_location;
  212. #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
  213. message += F("<br>");
  214. message += F("MAC: ");
  215. message += WiFi.macAddress();
  216. #endif
  217. message += F("</p>");
  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("<p>");
  269. if (found_bme1) {
  270. message += F("BME280 Low:");
  271. message += F("<br>");
  272. message += F("Temperature: ");
  273. message += String(bme1_temp());
  274. message += F("<br>");
  275. message += F("Humidity: ");
  276. message += String(bme1_humid());
  277. message += F("<br>");
  278. message += F("Pressure: ");
  279. message += String(bme1_pressure());
  280. } else {
  281. message += F("BME280 (low) not connected!");
  282. }
  283. message += F("</p>");
  284. message += F("<p>");
  285. if (found_bme2) {
  286. message += F("BME280 High:");
  287. message += F("<br>");
  288. message += F("Temperature: ");
  289. message += String(bme2_temp());
  290. message += F("<br>");
  291. message += F("Humidity: ");
  292. message += String(bme2_humid());
  293. message += F("<br>");
  294. message += F("Pressure: ");
  295. message += String(bme2_pressure());
  296. } else {
  297. message += F("BME280 (high) not connected!");
  298. }
  299. message += F("</p>");
  300. message += F("<p>");
  301. if (found_sht) {
  302. message += F("SHT21:");
  303. message += F("<br>");
  304. message += F("Temperature: ");
  305. message += String(sht_temp());
  306. message += F("<br>");
  307. message += F("Humidity: ");
  308. message += String(sht_humid());
  309. } else {
  310. //message += F("SHT21 not connected!");
  311. }
  312. message += F("</p>");
  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("<p>");
  332. message += F("Sensor ");
  333. message += String(i + 1);
  334. message += F(":<br>");
  335. message += F("Moisture: ");
  336. message += String(moisture);
  337. message += F(" / ");
  338. message += String(moisture_max());
  339. message += F("</p>");
  340. }
  341. }
  342. if (moisture_count() <= 0) {
  343. message += F("<p>");
  344. message += F("No moisture sensors configured!");
  345. message += F("</p>");
  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. Wire.begin();
  409. found_bme1 = (!bme1.begin(BME_I2C_ADDRESS_1, &Wire)) ? false : true;
  410. found_bme2 = (!bme2.begin(BME_I2C_ADDRESS_2, &Wire)) ? false : true;
  411. #endif
  412. found_sht = sht.GetAlive();
  413. // Build hostname string
  414. String hostname = SENSOR_HOSTNAME_PREFIX;
  415. hostname += sensor_location;
  416. #if defined(ARDUINO_ARCH_ESP8266)
  417. // Connect to WiFi AP
  418. WiFi.hostname(hostname);
  419. WiFi.mode(WIFI_STA);
  420. WiFi.begin(ssid, password);
  421. while (WiFi.status() != WL_CONNECTED) {
  422. delay(LED_CONNECT_BLINK_INTERVAL);
  423. digitalWrite(BUILTIN_LED_PIN, !digitalRead(BUILTIN_LED_PIN));
  424. }
  425. #elif defined(ARDUINO_ARCH_ESP32)
  426. // Set hostname workaround
  427. WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE);
  428. WiFi.setHostname(hostname.c_str());
  429. // Workaround for WiFi connecting only every 2nd reset
  430. // https://github.com/espressif/arduino-esp32/issues/2501#issuecomment-513602522
  431. WiFi.onEvent([](WiFiEvent_t event, WiFiEventInfo_t info) {
  432. if (info.disconnected.reason == 202) {
  433. esp_sleep_enable_timer_wakeup(10);
  434. esp_deep_sleep_start();
  435. delay(100);
  436. }
  437. }, WiFiEvent_t::SYSTEM_EVENT_STA_DISCONNECTED);
  438. // Connect to WiFi AP
  439. WiFi.mode(WIFI_STA);
  440. WiFi.begin(ssid, password);
  441. while (WiFi.status() != WL_CONNECTED) {
  442. delay(LED_CONNECT_BLINK_INTERVAL);
  443. digitalWrite(BUILTIN_LED_PIN, !digitalRead(BUILTIN_LED_PIN));
  444. }
  445. // Set hostname workaround
  446. WiFi.setHostname(hostname.c_str());
  447. #elif defined(ARDUINO_ARCH_AVR)
  448. Serial.begin(115200);
  449. Serial1.begin(115200);
  450. WiFi.init(&Serial1);
  451. Serial.print(F("Connecting WiFi"));
  452. WiFi.begin(ssid, password);
  453. while (WiFi.status() != WL_CONNECTED) {
  454. delay(LED_CONNECT_BLINK_INTERVAL);
  455. digitalWrite(BUILTIN_LED_PIN, !digitalRead(BUILTIN_LED_PIN));
  456. Serial.print(F("."));
  457. }
  458. Serial.println(F("\nWiFi connected!"));
  459. #endif
  460. #ifdef ENABLE_INFLUXDB_LOGGING
  461. // Setup InfluxDB Client
  462. influx.setDb(INFLUXDB_DATABASE);
  463. #endif // ENABLE_INFLUXDB_LOGGING
  464. #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
  465. // Setup HTTP Server
  466. MDNS.begin(hostname.c_str());
  467. updater.setup(&server);
  468. server.on("/", handleRoot);
  469. #ifdef ENABLE_RELAIS_TEST
  470. server.on("/relaistest", handleRelaisTest);
  471. #endif
  472. MDNS.addService("http", "tcp", 80);
  473. #endif
  474. server.begin();
  475. }
  476. #if defined(ARDUINO_ARCH_AVR)
  477. void http_server() {
  478. // listen for incoming clients
  479. WiFiClient client = server.available();
  480. if (client) {
  481. Serial.println(F("new http client"));
  482. // an http request ends with a blank line
  483. boolean currentLineIsBlank = true;
  484. while (client.connected()) {
  485. if (client.available()) {
  486. char c = client.read();
  487. Serial.write(c);
  488. // if you've gotten to the end of the line (received a newline
  489. // character) and the line is blank, the http request has ended,
  490. // so you can send a reply
  491. if ((c == '\n') && currentLineIsBlank) {
  492. // send a standard http response header
  493. client.println(F("HTTP/1.1 200 OK"));
  494. client.println(F("Content-Type: text/html"));
  495. client.println(F("Connection: close"));
  496. client.println();
  497. handleRoot(client);
  498. break;
  499. }
  500. if (c == '\n') {
  501. // you're starting a new line
  502. currentLineIsBlank = true;
  503. } else if (c != '\r') {
  504. // you've gotten a character on the current line
  505. currentLineIsBlank = false;
  506. }
  507. }
  508. }
  509. // give the web browser time to receive the data
  510. delay(10);
  511. // close the connection
  512. client.stop();
  513. Serial.println(F("http client disconnected"));
  514. }
  515. }
  516. #endif
  517. void handleServers() {
  518. #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
  519. server.handleClient();
  520. #else
  521. http_server();
  522. #endif
  523. #if defined(ARDUINO_ARCH_ESP8266)
  524. MDNS.update();
  525. #endif
  526. }
  527. #ifdef ENABLE_INFLUXDB_LOGGING
  528. static boolean writeMeasurement(InfluxData &measurement) {
  529. boolean success = influx.write(measurement);
  530. if (!success) {
  531. error_count++;
  532. for (int i = 0; i < 10; i++) {
  533. digitalWrite(BUILTIN_LED_PIN, LOW); // LED on
  534. delay(LED_ERROR_BLINK_INTERVAL);
  535. digitalWrite(BUILTIN_LED_PIN, HIGH); // LED off
  536. delay(LED_ERROR_BLINK_INTERVAL);
  537. }
  538. }
  539. return success;
  540. }
  541. void writeDatabase() {
  542. #if defined(ARDUINO_ARCH_AVR)
  543. Serial.println(F("Writing to InfluxDB"));
  544. InfluxData measurement("");
  545. #endif
  546. if (found_bme1) {
  547. #if defined(ARDUINO_ARCH_AVR)
  548. measurement.clear();
  549. measurement.setName("environment");
  550. #else
  551. InfluxData measurement("environment");
  552. #endif
  553. measurement.addTag("location", sensor_location);
  554. measurement.addTag("placement", "1");
  555. measurement.addTag("sensor", "bme280");
  556. #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
  557. measurement.addTag("device", WiFi.macAddress());
  558. #endif
  559. measurement.addValue("temperature", bme1_temp());
  560. measurement.addValue("pressure", bme1_pressure());
  561. measurement.addValue("humidity", bme1_humid());
  562. Serial.println(F("Writing bme1"));
  563. writeMeasurement(measurement);
  564. Serial.println(F("Done!"));
  565. }
  566. if (found_bme2) {
  567. #if defined(ARDUINO_ARCH_AVR)
  568. measurement.clear();
  569. measurement.setName("environment");
  570. #else
  571. InfluxData measurement("environment");
  572. #endif
  573. measurement.addTag("location", sensor_location);
  574. measurement.addTag("placement", "2");
  575. measurement.addTag("sensor", "bme280");
  576. #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
  577. measurement.addTag("device", WiFi.macAddress());
  578. #endif
  579. measurement.addValue("temperature", bme2_temp());
  580. measurement.addValue("pressure", bme2_pressure());
  581. measurement.addValue("humidity", bme2_humid());
  582. Serial.println(F("Writing bme2"));
  583. writeMeasurement(measurement);
  584. Serial.println(F("Done!"));
  585. }
  586. if (found_sht) {
  587. #if defined(ARDUINO_ARCH_AVR)
  588. measurement.clear();
  589. measurement.setName("environment");
  590. #else
  591. InfluxData measurement("environment");
  592. #endif
  593. measurement.addTag("location", sensor_location);
  594. measurement.addTag("sensor", "sht21");
  595. #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
  596. measurement.addTag("device", WiFi.macAddress());
  597. #endif
  598. measurement.addValue("temperature", sht_temp());
  599. measurement.addValue("humidity", sht_humid());
  600. Serial.println(F("Writing sht"));
  601. writeMeasurement(measurement);
  602. Serial.println(F("Done!"));
  603. }
  604. for (int i = 0; i < moisture_count(); i++) {
  605. int moisture = moisture_read(i);
  606. if (moisture < moisture_max()) {
  607. #if defined(ARDUINO_ARCH_AVR)
  608. measurement.clear();
  609. measurement.setName("moisture");
  610. #else
  611. InfluxData measurement("moisture");
  612. #endif
  613. measurement.addTag("location", sensor_location);
  614. String sensor(i + 1, DEC);
  615. measurement.addTag("sensor", sensor);
  616. #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
  617. measurement.addTag("device", WiFi.macAddress());
  618. #endif
  619. measurement.addValue("value", moisture);
  620. measurement.addValue("maximum", moisture_max());
  621. Serial.print(F("Writing moisture "));
  622. Serial.println(i);
  623. writeMeasurement(measurement);
  624. Serial.println(F("Done!"));
  625. }
  626. }
  627. Serial.println(F("All Done!"));
  628. }
  629. #endif // ENABLE_INFLUXDB_LOGGING
  630. void loop() {
  631. unsigned long time = millis();
  632. #ifdef ENABLE_RELAIS_TEST
  633. relais_run();
  634. #endif // ENABLE_RELAIS_TEST
  635. if ((time - last_server_handle_time) >= SERVER_HANDLE_INTERVAL) {
  636. last_server_handle_time = time;
  637. handleServers();
  638. }
  639. #ifdef ENABLE_INFLUXDB_LOGGING
  640. if ((time - last_db_write_time) >= DB_WRITE_INTERVAL) {
  641. last_db_write_time = time;
  642. writeDatabase();
  643. }
  644. #ifdef INFLUX_MAX_ERRORS_RESET
  645. if (error_count >= INFLUX_MAX_ERRORS_RESET) {
  646. #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
  647. ESP.restart();
  648. #endif
  649. }
  650. #endif // INFLUX_MAX_ERRORS_RESET
  651. #endif // ENABLE_INFLUXDB_LOGGING
  652. // blink heartbeat LED
  653. if ((time - last_led_blink_time) >= LED_BLINK_INTERVAL) {
  654. last_led_blink_time = time;
  655. digitalWrite(BUILTIN_LED_PIN, !digitalRead(BUILTIN_LED_PIN));
  656. }
  657. #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
  658. // reset ESP every 6h to be safe
  659. if (time >= (6 * 60 * 60 * 1000)) {
  660. ESP.restart();
  661. }
  662. #endif
  663. }