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

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. }