/* * ModularWeatherStation * * Copyright (C) 2021 Gergely Polonkai * Author: Gergely POLONKAI * * ModularWeatherStation is free software: you can redistribute it * and/or modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * ModularWeatherStation is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * As additional permission under GNU GPL version 3 section 7, you may * distribute non-source form of the Program without the copy of the * GNU GPL normally required by section 4, provided you inform the * receipents of GNU GPL by a written offer. * */ #include #include #include #include #include "config.h" #ifdef DHT_TYPE # include #endif // DHT_TYPE #ifdef HAVE_BH1750 # include # include #endif // HAVE_BH1750 ESP8266WebServer server(80); unsigned long last_update = 0; #ifdef DHT_TYPE DHT dht(DHT_PIN, DHT_TYPE); float temperature = 0.0; float humidity = 0.0; #endif // DHT_TYPE #ifdef RAIN_PIN bool raining = false; #endif // RAIN_PIN #ifdef HAVE_BH1750 BH1750 light; float light_level = 0; #endif // HAVE_BH1750 static const char TEXT_PLAIN[] PROGMEM = "text/plain"; void reply_not_found() { server.send(404, FPSTR(TEXT_PLAIN), "Not Found"); } void send_metrics() { static const size_t dht_size = 228; static const size_t rain_size = 86; static const size_t light_size = 72; size_t message_size = #ifdef DHT_TYPE dht_size + #endif // DHT_TYPE #ifdef RAIN_PIN rain_size + #endif // RAIN_PIN #ifdef HAVE_BH1750 light_size + #endif // HAVE_BH1750 1; char message[message_size]; snprintf(message, message_size, #ifdef DHT_TYPE "# HELP temperature_celsius Temperature in degrees Celsius\n" "# TYPE temperature_celsius gauge\n" "temperature_celsius %.2f\n" "# HELP relative_humidity Relative humidity, in percents\n" "# TYPE relative_humidity gauge\n" "relative_humidity %.2f\n" #endif // DHT_TYPE #ifdef RAIN_PIN "# HELP raining Boolean value checking if it is raining\n" "# TYPE raining gauge\n" "raining %d\n" #endif // RAIN_PIN #ifdef HAVE_BH1750 "# HELP light Ambient light, in lumens\n" "# TYPE light gauge\n" "light %.2f\n" #endif // HAVE_BH1750 #ifdef DHT_TYPE , temperature, humidity #endif // DHT_TYPE #ifdef RAIN_PIN , raining ? 1 : 0 #endif // RAIN_PIN #ifdef HAVE_BH1750 , light_level #endif // HAVE_BH1750 ); server.send(200, "text/plain; version=0.0.4; charset=utf-8", message); } void stop() { while (1) { delay(1000); } } void setup() { IPAddress address; Serial.begin(9600); WiFi.mode(WIFI_STA); WiFi.begin(WIFI_SSID, WIFI_PASS); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.println("Waiting for WiFi to connect..."); } address = WiFi.localIP(); Serial.print("WiFi Address: "); address.printTo(Serial); Serial.println(""); if (!MDNS.begin(MDNS_NAME)) { Serial.println("Error setting up mDNS responder!"); stop(); } server.on("/metrics", HTTP_GET, send_metrics); server.onNotFound(reply_not_found); server.begin(); MDNS.addService("http", "tcp", 80); // Initialize sensors #ifdef DHT_TYPE dht.begin(); #endif // DHT_TYPE #ifdef RAIN_PIN pinMode(RAIN_PIN, INPUT); #endif // RAIN_PIN #ifdef HAVE_BH1750 Wire.begin(I2C_SDA_PIN, I2C_SCL_PIN); if (!light.begin()) { Serial.println("Could not find the BH1750 sensor!"); stop(); } #endif // HAVE_BH1750 Serial.println("All set, starting the loop."); } void read_sensors() { // Turn on the LED to indicate that we’re working digitalWrite(LED_BUILTIN, LOW); #ifdef DHT_TYPE temperature = dht.readTemperature(); humidity = dht.readHumidity(); #endif #ifdef RAIN_PIN raining = (digitalRead(RAIN_PIN) == HIGH); #endif #ifdef HAVE_BH1750 light_level = light.readLightLevel(); #endif // HAVE_BH1750 // Turn off the LED to indicate work is finished digitalWrite(LED_BUILTIN, HIGH); } void loop() { unsigned long now = millis(); MDNS.update(); server.handleClient(); if (now - last_update >= 5000) { read_sensors(); last_update = now; } }