diff --git a/WeatherStation.ino b/WeatherStation.ino index 86d2454..9f12f8b 100644 --- a/WeatherStation.ino +++ b/WeatherStation.ino @@ -27,7 +27,6 @@ #include #include #include -#include #include "config.h" @@ -50,113 +49,24 @@ char *negotiated_hostname = NULL; bool hostname_verified = false; MDNSResponder::hMDNSService mdns_service = NULL; -ESP8266WebServer server(80); unsigned long last_update = 0; #ifdef DHT_TYPE DHT dht(DHT_PIN, DHT_TYPE); -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 -#if defined(DHT_TYPE) || defined(HAVE_BMP180) -float temperature = 0.0; -#endif // defined(DHT_TYPE) || defined(HAVE_BMP180) - #ifdef HAVE_BMP180 Adafruit_BMP085 BMP; -uint32_t pressure = 0; #endif // HAVE_BMP180 -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 temperature_size = 117; - static const size_t humidity_size = 111; - static const size_t rain_size = 86; - static const size_t light_size = 72; - static const size_t pressure_size = 82; - - size_t message_size = -#if defined(DHT_TYPE) || defined(HAVE_BMP180) - temperature_size + -#endif // defined(DHT_TYPE) || defined(HAVE_BMP180) -#ifdef DHT_TYPE - humidity_size + -#endif // DHT_TYPE -#ifdef RAIN_PIN - rain_size + -#endif // RAIN_PIN -#ifdef HAVE_BH1750 - light_size + -#endif // HAVE_BH1750 -#ifdef HAVE_BMP180 - pressure_size + -#endif // HAVE_BMP180 - 1; - char message[message_size]; - - snprintf(message, message_size, "" -#if defined(DHT_TYPE) || defined(HAVE_BMP180) - "# HELP temperature_celsius Temperature in degrees Celsius\n" - "# TYPE temperature_celsius gauge\n" - "temperature_celsius %.2f\n" -#endif // defined(DHT_TYPE) || defined(HAVE_BMP180) -#ifdef DHT_TYPE - "# 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 HAVE_BMP180 - "# HELP pressure Atmospheric pressure, in Pa\n" - "# TYPE pressure gauge\n" - "pressure %d\n" -#endif // HAVE_BMP180 -#if defined(DHT_TYPE) || defined(HAVE_BMP180) - , temperature -#endif // defined(DHT_TYPE) || defined(HAVE_BMP180) -#ifdef DHT_TYPE - , humidity -#endif // DHT_TYPE -#ifdef RAIN_PIN - , raining ? 1 : 0 -#endif // RAIN_PIN -#ifdef HAVE_BH1750 - , light_level -#endif // HAVE_BH1750 -#ifdef HAVE_BMP180 - , pressure -#endif // HAVE_BMP180 - ); - - server.send(200, "text/plain; version=0.0.4; charset=utf-8", message); -} +#if SYSTEM_MODE & MODE_PROM_PULL +#include "mode_pull.h" +PWSModePull mode(80); +#endif void stop() @@ -231,10 +141,7 @@ setup() stop(); } - server.on("/metrics", HTTP_GET, send_metrics); - server.onNotFound(reply_not_found); - - server.begin(); + mode.begin(); // Initialize sensors #ifdef DHT_TYPE @@ -267,6 +174,22 @@ setup() void read_sensors() { +#if defined(DHT_TYPE) || defined(HAVE_BMP180) + float temperature; +#endif +#ifdef DHT_TYPE + float humidity; +#endif +#ifdef RAIN_PIN + bool raining; +#endif +#ifdef HAVE_BH1750 + float light_level; +#endif +#ifdef HAVE_BMP180 + float pressure; +#endif + // Turn on the LED to indicate that we’re working digitalWrite(LED_BUILTIN, LOW); @@ -292,6 +215,24 @@ read_sensors() # endif // !DHT_TYPE #endif // HAVE_BMP180 + mode.sendValues( +#if defined(DHT_TYPE) || defined(HAVE_BMP180) + temperature, +#endif +#ifdef DHT_TYPE + humidity, +#endif +#ifdef RAIN_PIN + raining, +#endif +#ifdef HAVE_BH1750 + light, +#endif +#ifdef HAVE_BMP180 + pressure, +#endif + 0); + // Turn off the LED to indicate work is finished digitalWrite(LED_BUILTIN, HIGH); } @@ -302,7 +243,7 @@ loop() unsigned long now = millis(); MDNS.update(); - server.handleClient(); + mode.loop(); if (now - last_update >= 5000) { read_sensors(); diff --git a/config.h.sample b/config.h.sample index 34e6879..200f330 100644 --- a/config.h.sample +++ b/config.h.sample @@ -30,11 +30,19 @@ #define WIFI_SSID "YourWiFiName" #define WIFI_PASS "YourWiFiPass" -// The mDNS hostname you want this station to be visible as. This should be -// different for each station you install (e.g. if you want to measure the -// temperature and humidity of each room separately) +// The system name will be the name your station is available as. This +// should be different for each station you install (e.g. if you want to +// measure the temperature and humidity of each room separately) +// +// If mDNS is enabled (ie. in HTTP pull mode), this will be the advertised +// hostname. +// +// If MQTT is enabled, this will be the MQTT client ID. #define SYSTEM_NAME "internal-hostname" +// The mode this system should run in. See consts.h for the available values. +#define SYSTEM_MODE MODE_PULL + // If you have a DHT temperature+humidity sensor of this type will be used, // remove the #undef line and uncomment one of DHT11 or DHT22. You also have // to define the PIN your DHT sensor’s data (usually marked as DAT) is diff --git a/consts.h b/consts.h new file mode 100644 index 0000000..3470a84 --- /dev/null +++ b/consts.h @@ -0,0 +1,40 @@ +/* + * consts.h - Constants for the 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. + * + */ + +// Prometheus Pull mode. A Prometheus instance has to be configured to +// regularly pull values from the station. +#define MODE_PROM_PULL 1 + +// Prometheus Push mode. A Prometheus Push Gateway instance has to be +// configured in config.h where the station can regularly push values. +// +// It purposefully conflicts with MODE_PROM_PULL; the weather station code +// checks only for bit 1 to be present and if it is, it ignores bit 0 +#define MODE_PROM_PUSH 3 + +// MQTT mode. An MQTT broker address must be configured in config.h where +// the station can push values. +#define MODE_MQTT 4 diff --git a/mode_pull.cpp b/mode_pull.cpp new file mode 100644 index 0000000..00c2a89 --- /dev/null +++ b/mode_pull.cpp @@ -0,0 +1,176 @@ +#include + +#include "mode_pull.h" +#include "config.h" + +#if defined(DHT_TYPE) || defined(HAVE_BMP180) +float _temperature; +#endif +#ifdef DHT_TYPE +float _humidity; +#endif +#ifdef HAVE_BH1750 +float _light; +#endif +#ifdef HAVE_BMP180 +float _pressure; +#endif +#ifdef RAIN_PIN +bool _raining; +#endif + +static const char MIME_TEXT[] PROGMEM = "text/plain"; +static const char MIME_METRICS[] PROGMEM = "text/plain; version=0.0.4; charset=utf-8"; + +#if defined(DHT_TYPE) || defined(HAVE_BMP180) +# define TEMPL_TEMPERATURE \ + "# HELP temperature_celsius Temperature in degrees Celsius\n" \ + "# TYPE temperature_celsius gauge\n" \ + "temperature_celsius %.2f\n" +#endif +#ifdef DHT_TYPE +# define TEMPL_HUMIDITY \ + "# HELP relative_humidity Relative humidity, in percents\n" \ + "# TYPE relative_humidity gauge\n" \ + "relative_humidity %.2f\n" +#endif +#ifdef RAIN_PIN +# define TEMPL_RAIN \ + "# HELP raining Boolean value checking if it is raining\n" \ + "# TYPE raining gauge\n" \ + "raining %d\n" +#endif +#ifdef HAVE_BH1750 +# define TEMPL_LIGHT \ + "# HELP light Ambient light, in lumens\n" \ + "# TYPE light gauge\n" \ + "light %.2f\n" +#endif +#ifdef HAVE_BMP180 +# define TEMPL_PRESSURE \ + "# HELP pressure Atmospheric pressure, in Pa\n" \ + "# TYPE pressure gauge\n" \ + "pressure %d\n" +#endif + +ESP8266WebServer server; + +static void +_replyNotFound() +{ + server.send(404, FPSTR(MIME_TEXT), "Not Found"); +} + +static void +_sendMetrics() +{ + size_t message_size = +#if defined(DHT_TYPE) || defined(HAVE_BMP180) + sizeof(TEMPL_TEMPERATURE) + +#endif // defined(DHT_TYPE) || defined(HAVE_BMP180) +#ifdef DHT_TYPE + sizeof(TEMPL_HUMIDITY) + +#endif // DHT_TYPE +#ifdef RAIN_PIN + sizeof(TEMPL_RAIN) + +#endif // RAIN_PIN +#ifdef HAVE_BH1750 + sizeof(TEMPL_LIGHT) + +#endif // HAVE_BH1750 +#ifdef HAVE_BMP180 + sizeof(TEMPL_PRESSURE) + +#endif // HAVE_BMP180 + 1; + char message[message_size]; + + snprintf(message, message_size, "" +#if defined(DHT_TYPE) || defined(HAVE_BMP180) + TEMPL_TEMPERATURE +#endif // defined(DHT_TYPE) || defined(HAVE_BMP180) +#ifdef DHT_TYPE + TEMPL_HUMIDITY +#endif // DHT_TYPE +#ifdef RAIN_PIN + TEMPL_RAIN +#endif // RAIN_PIN +#ifdef HAVE_BH1750 + TEMPL_LIGHT +#endif // HAVE_BH1750 +#ifdef HAVE_BMP180 + TEMPL_PRESSURE +#endif // HAVE_BMP180 +#if defined(DHT_TYPE) || defined(HAVE_BMP180) + , _temperature +#endif // defined(DHT_TYPE) || defined(HAVE_BMP180) +#ifdef DHT_TYPE + , _humidity +#endif // DHT_TYPE +#ifdef RAIN_PIN + , _raining ? 1 : 0 +#endif // RAIN_PIN +#ifdef HAVE_BH1750 + , _light_level +#endif // HAVE_BH1750 +#ifdef HAVE_BMP180 + , _pressure +#endif // HAVE_BMP180 + ); + + server.send(200, MIME_METRICS, message); +} + +PWSModePull::PWSModePull(int port) +{ + _port = port; +} + +void +PWSModePull::begin() +{ + server.on("/metrics", HTTP_GET, _sendMetrics); + server.onNotFound(_replyNotFound); + + server.begin(_port); +} + +void +PWSModePull::loop() +{ + server.handleClient(); +} + +void +PWSModePull::sendValues( +#if defined(DHT_TYPE) || defined(HAVE_BMP180) + float temperature, +#endif +#ifdef DHT_TYPE + float humidity, +#endif +#ifdef RAIN_PIN + bool raining, +#endif +#ifdef HAVE_BH1750 + float light, +#endif +#ifdef HAVE_BMP180 + float pressure, +#endif + ...) +{ +#if defined(DHT_TYPE) || defined(HAVE_BMP180) + _temperature = temperature; +#endif +#ifdef DHT_TYPE + _humidity = humidity; +#endif +#ifdef RAIN_PIN + _raining = raining; +#endif +#ifdef HAVE_BH1750 + _light = light; +#endif +#ifdef HAVE_BMP180 + _pressure = pressure; +#endif +} diff --git a/mode_pull.h b/mode_pull.h new file mode 100644 index 0000000..e730662 --- /dev/null +++ b/mode_pull.h @@ -0,0 +1,31 @@ +#ifndef __PWS_MODE_PULL_H +# define __PWS_MODE_PULL_H + +# include "config.h" + +class PWSModePull { + public: + PWSModePull(int port); + void begin(); + void loop(); + void sendValues( +#if defined(DHT_TYPE) || defined(HAVE_BMP180) + float temperature, +#endif +#ifdef DHT_TYPE + float humidity, +#endif +#ifdef RAIN_PIN + bool raining, +#endif +#ifdef HAVE_BH1750 + float light, +#endif +#ifdef HAVE_BMP180 + float pressure, +#endif + ...); + private: + int _port; +}; +#endif // __PWS_MODE_PULL_H