Refactor
This commit is contained in:
parent
9c5804dc9f
commit
dad14bae43
|
@ -22,21 +22,23 @@
|
||||||
#define WIFI_SSID ""
|
#define WIFI_SSID ""
|
||||||
// Wi-Fi password (required)
|
// Wi-Fi password (required)
|
||||||
#define WIFI_PASSWORD ""
|
#define WIFI_PASSWORD ""
|
||||||
// Wi-Fi hostname (for DHCP, uncomment if non-default desired)
|
// Hostname for DHCP DDNS, overrides the default (uncomment to enable)
|
||||||
// #define WIFI_HOSTNAME "my_host_name"
|
// #define WIFI_HOSTNAME "my_host_name"
|
||||||
// Wi-Fi static IPv4 address enabled or disabled (disable for DHCPv4)
|
// Use static IPv4 addressing, disable for DHCPv4
|
||||||
#define WIFI_IPV4_STATIC false
|
#define WIFI_IPV4_STATIC true
|
||||||
// Wi-Fi static IPv4 address
|
// Static IPv4 address
|
||||||
#define WIFI_IPV4_ADDRESS 192, 168, 1, 15
|
#define WIFI_IPV4_ADDRESS 192, 168, 1, 15
|
||||||
// Wi-Fi static IPv4 gateway address
|
// Static IPv4 gateway address
|
||||||
#define WIFI_IPV4_GATEWAY 192, 168, 1, 1
|
#define WIFI_IPV4_GATEWAY 192, 168, 1, 1
|
||||||
// Wi-Fi static IPv4 subnet mask
|
// Static IPv4 subnet mask
|
||||||
#define WIFI_IPV4_SUBNET_MASK 255, 255, 255, 0
|
#define WIFI_IPV4_SUBNET_MASK 255, 255, 255, 0
|
||||||
// Wi-Fi static IPv4 primary DNS server
|
// Static IPv4 primary DNS server
|
||||||
#define WIFI_IPV4_DNS_1 1, 1, 1, 1
|
#define WIFI_IPV4_DNS_1 1, 1, 1, 1
|
||||||
// Wi-Fi static IPv4 secondary DNS server
|
// Static IPv4 secondary DNS server
|
||||||
#define WIFI_IPV4_DNS_2 1, 0, 0, 1
|
#define WIFI_IPV4_DNS_2 1, 0, 0, 1
|
||||||
// HTTP server port
|
// HTTP server port
|
||||||
#define HTTP_SERVER_PORT 80
|
#define HTTP_SERVER_PORT 80
|
||||||
// HTTP metrics endpoint
|
// HTTP metrics endpoint
|
||||||
#define HTTP_METRICS_ENDPOINT "/metrics"
|
#define HTTP_METRICS_ENDPOINT "/metrics"
|
||||||
|
// Prometheus namespace, aka metric prefix
|
||||||
|
#define PROM_NAMESPACE "iot"
|
||||||
|
|
157
src/src.ino
157
src/src.ino
|
@ -1,11 +1,12 @@
|
||||||
#include <ESP8266WiFi.h>
|
#include <ESP8266WiFi.h>
|
||||||
#include <ESP8266WebServer.h>
|
#include <ESP8266WebServer.h>
|
||||||
#include <WiFiClient.h>
|
|
||||||
#include <DHTesp.h>
|
#include <DHTesp.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
|
#define EXPLODE4(arr) (arr[0], arr[1], arr[2], arr[3])
|
||||||
|
|
||||||
enum LogLevel {
|
enum LogLevel {
|
||||||
DEBUG,
|
DEBUG,
|
||||||
INFO,
|
INFO,
|
||||||
|
@ -28,78 +29,90 @@ float humidity, temperature, heat_index;
|
||||||
uint32_t previous_read_time = 0;
|
uint32_t previous_read_time = 0;
|
||||||
|
|
||||||
void setup(void) {
|
void setup(void) {
|
||||||
|
char message[128];
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
setup_dht_sensor();
|
setup_dht_sensor();
|
||||||
setup_wifi();
|
setup_wifi();
|
||||||
setup_http_server();
|
setup_http_server();
|
||||||
|
snprintf(message, 128, "Namespace: %s", PROM_NAMESPACE);
|
||||||
|
log(message);
|
||||||
|
log("Setup done");
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_dht_sensor() {
|
void setup_dht_sensor() {
|
||||||
log("Setting up DHT sensor ...");
|
log("Setting up DHT sensor");
|
||||||
dht_sensor.setup(DHT_PIN, DHTesp::DHT_TYPE);
|
dht_sensor.setup(DHT_PIN, DHTesp::DHT_TYPE);
|
||||||
delay(dht_sensor.getMinimumSamplingPeriod());
|
delay(dht_sensor.getMinimumSamplingPeriod());
|
||||||
// Test read
|
// Test read
|
||||||
read_sensors(true);
|
read_sensors(true);
|
||||||
log("DHT sensor ready.");
|
log("DHT sensor ready");
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_wifi() {
|
void setup_wifi() {
|
||||||
WiFi.mode(WIFI_STA);
|
|
||||||
char message[128];
|
char message[128];
|
||||||
|
log("Setting up Wi-Fi");
|
||||||
snprintf(message, 128, "Wi-Fi SSID: %s", WIFI_SSID);
|
snprintf(message, 128, "Wi-Fi SSID: %s", WIFI_SSID);
|
||||||
log(message);
|
log(message);
|
||||||
|
snprintf(message, 128, "MAC address: %s", WiFi.macAddress().c_str());
|
||||||
if (WIFI_IPV4_STATIC) {
|
|
||||||
IPAddress address(WIFI_IPV4_ADDRESS);
|
|
||||||
IPAddress subnet(WIFI_IPV4_SUBNET_MASK);
|
|
||||||
IPAddress gateway(WIFI_IPV4_GATEWAY);
|
|
||||||
IPAddress dns1(WIFI_IPV4_DNS_1);
|
|
||||||
IPAddress dns2(WIFI_IPV4_DNS_2);
|
|
||||||
snprintf(message, 128, "Static IPv4 address: %d.%d.%d.%d", address[0], address[1], address[2], address[3]);
|
|
||||||
log(message);
|
log(message);
|
||||||
snprintf(message, 128, "Static IPv4 subnet mask: %d.%d.%d.%d", subnet[0], subnet[1], subnet[2], subnet[3]);
|
|
||||||
log(message);
|
|
||||||
snprintf(message, 128, "Static IPv4 gateway: %d.%d.%d.%d", gateway[0], gateway[1], gateway[2], gateway[3]);
|
|
||||||
log(message);
|
|
||||||
snprintf(message, 128, "Static IPv4 primary DNS server: %d.%d.%d.%d", dns1[0], dns1[1], dns1[2], dns1[3]);
|
|
||||||
log(message);
|
|
||||||
snprintf(message, 128, "Static IPv4 secondary DNS server: %d.%d.%d.%d", dns2[0], dns2[1], dns2[2], dns2[3]);
|
|
||||||
log(message);
|
|
||||||
if (!WiFi.config(address, gateway, subnet, dns1, dns2)) {
|
|
||||||
log("Failed to configure Wi-Fi.", LogLevel::ERROR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log("Wi-Fi connecting ...");
|
|
||||||
#ifdef WIFI_HOSTNAME
|
|
||||||
snprintf(message, 128, "Initial hostname: %s", WiFi.hostname().c_str());
|
snprintf(message, 128, "Initial hostname: %s", WiFi.hostname().c_str());
|
||||||
log(message);
|
log(message);
|
||||||
log("Requesting hostname " WIFI_HOSTNAME);
|
|
||||||
if (!WiFi.hostname(WIFI_HOSTNAME)) {
|
WiFi.mode(WIFI_STA);
|
||||||
log("Hostname request failed");
|
|
||||||
} else {
|
#if WIFI_IPV4_STATIC == true
|
||||||
log("Hostname request succeeded");
|
log("Using static IPv4 adressing");
|
||||||
|
IPAddress static_address(WIFI_IPV4_ADDRESS);
|
||||||
|
IPAddress static_subnet(WIFI_IPV4_SUBNET_MASK);
|
||||||
|
IPAddress static_gateway(WIFI_IPV4_GATEWAY);
|
||||||
|
IPAddress static_dns1(WIFI_IPV4_DNS_1);
|
||||||
|
IPAddress static_dns2(WIFI_IPV4_DNS_2);
|
||||||
|
if (!WiFi.config(static_address, static_gateway, static_subnet, static_dns1, static_dns2)) {
|
||||||
|
log("Failed to configure static addressing", LogLevel::ERROR);
|
||||||
}
|
}
|
||||||
snprintf(message, 128, "New hostname: %s", WiFi.hostname().c_str());
|
|
||||||
log(message);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WIFI_HOSTNAME
|
||||||
|
log("Requesting hostname: " WIFI_HOSTNAME);
|
||||||
|
if (!WiFi.hostname(WIFI_HOSTNAME)) {
|
||||||
|
log("Hostname changed");
|
||||||
|
} else {
|
||||||
|
log("Failed to change hostname (too long?)");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
|
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
|
||||||
while (WiFi.status() != WL_CONNECTED) {
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
log("Wi-Fi waiting ...", LogLevel::DEBUG);
|
log("Wi-Fi connection not ready, waiting", LogLevel::DEBUG);
|
||||||
delay(500);
|
delay(500);
|
||||||
}
|
}
|
||||||
const IPAddress &address = WiFi.localIP();
|
|
||||||
log("Wi-Fi connected.");
|
log("Wi-Fi connected.");
|
||||||
snprintf(message, 128, "IPv4 address: %d.%d.%d.%d", address[0], address[1], address[2], address[3]);
|
snprintf(message, 128, "SSID: %s", WiFi.SSID().c_str());
|
||||||
|
log(message);
|
||||||
|
snprintf(message, 128, "BSSID: %s", WiFi.BSSIDstr().c_str());
|
||||||
|
log(message);
|
||||||
|
snprintf(message, 128, "Hostname: %s", WiFi.hostname().c_str());
|
||||||
|
log(message);
|
||||||
|
snprintf(message, 128, "IPv4 address: %s", WiFi.localIP().toString().c_str());
|
||||||
|
log(message);
|
||||||
|
snprintf(message, 128, "IPv4 subnet mask: %s", WiFi.subnetMask().toString().c_str());
|
||||||
|
log(message);
|
||||||
|
snprintf(message, 128, "IPv4 gateway: %s", WiFi.gatewayIP().toString().c_str());
|
||||||
|
log(message);
|
||||||
|
snprintf(message, 128, "Primary DNS server: %s", WiFi.dnsIP(0).toString().c_str());
|
||||||
|
log(message);
|
||||||
|
snprintf(message, 128, "Secondary DNS server: %s", WiFi.dnsIP(1).toString().c_str());
|
||||||
log(message);
|
log(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_http_server() {
|
void setup_http_server() {
|
||||||
http_server.on("/", HTTPMethod::HTTP_GET, handle_http_home_client);
|
char message[128];
|
||||||
http_server.on(HTTP_METRICS_ENDPOINT, HTTPMethod::HTTP_GET, handle_http_metrics_client);
|
http_server.on("/", HTTPMethod::HTTP_GET, handle_http_root);
|
||||||
|
http_server.on(HTTP_METRICS_ENDPOINT, HTTPMethod::HTTP_GET, handle_http_metrics);
|
||||||
|
http_server.onNotFound(handle_http_not_found);
|
||||||
http_server.begin();
|
http_server.begin();
|
||||||
log("HTTP server started.");
|
log("HTTP server started.");
|
||||||
char message[128];
|
|
||||||
snprintf(message, 128, "Metrics endpoint: %s", HTTP_METRICS_ENDPOINT);
|
snprintf(message, 128, "Metrics endpoint: %s", HTTP_METRICS_ENDPOINT);
|
||||||
log(message);
|
log(message);
|
||||||
}
|
}
|
||||||
|
@ -108,7 +121,8 @@ void loop(void) {
|
||||||
http_server.handleClient();
|
http_server.handleClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_http_home_client() {
|
void handle_http_root() {
|
||||||
|
log_request();
|
||||||
static size_t const BUFSIZE = 256;
|
static size_t const BUFSIZE = 256;
|
||||||
static char const *response_template =
|
static char const *response_template =
|
||||||
"Prometheus ESP8266 DHT Exporter by HON95.\n"
|
"Prometheus ESP8266 DHT Exporter by HON95.\n"
|
||||||
|
@ -121,25 +135,26 @@ void handle_http_home_client() {
|
||||||
http_server.send(200, "text/plain; charset=utf-8", response);
|
http_server.send(200, "text/plain; charset=utf-8", response);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_http_metrics_client() {
|
void handle_http_metrics() {
|
||||||
|
log_request();
|
||||||
static size_t const BUFSIZE = 1024;
|
static size_t const BUFSIZE = 1024;
|
||||||
static char const *response_template =
|
static char const *response_template =
|
||||||
"# HELP iot_info Metadata about the device.\n"
|
"# HELP " PROM_NAMESPACE "_info Metadata about the device.\n"
|
||||||
"# TYPE iot_info gauge\n"
|
"# TYPE " PROM_NAMESPACE "_info gauge\n"
|
||||||
"# UNIT iot_info \n"
|
"# UNIT " PROM_NAMESPACE "_info \n"
|
||||||
"iot_info{version=\"%s\",board=\"%s\",sensor=\"%s\"} 1\n"
|
PROM_NAMESPACE "_info{version=\"%s\",board=\"%s\",sensor=\"%s\"} 1\n"
|
||||||
"# HELP iot_air_humidity_percent Air humidity.\n"
|
"# HELP " PROM_NAMESPACE "_air_humidity_percent Air humidity.\n"
|
||||||
"# TYPE iot_air_humidity_percent gauge\n"
|
"# TYPE " PROM_NAMESPACE "_air_humidity_percent gauge\n"
|
||||||
"# UNIT iot_air_humidity_percent %%\n"
|
"# UNIT " PROM_NAMESPACE "_air_humidity_percent %%\n"
|
||||||
"iot_air_humidity_percent %f\n"
|
PROM_NAMESPACE "_air_humidity_percent %f\n"
|
||||||
"# HELP iot_air_temperature_celsius Air temperature.\n"
|
"# HELP " PROM_NAMESPACE "_air_temperature_celsius Air temperature.\n"
|
||||||
"# TYPE iot_air_temperature_celsius gauge\n"
|
"# TYPE " PROM_NAMESPACE "_air_temperature_celsius gauge\n"
|
||||||
"# UNIT iot_air_temperature_celsius \u00B0C\n"
|
"# UNIT " PROM_NAMESPACE "_air_temperature_celsius \u00B0C\n"
|
||||||
"iot_air_temperature_celsius %f\n"
|
PROM_NAMESPACE "_air_temperature_celsius %f\n"
|
||||||
"# HELP iot_air_heat_index_celsius Apparent air temperature, based on temperature and humidity.\n"
|
"# HELP " PROM_NAMESPACE "_air_heat_index_celsius Apparent air temperature, based on temperature and humidity.\n"
|
||||||
"# TYPE iot_air_heat_index_celsius gauge\n"
|
"# TYPE " PROM_NAMESPACE "_air_heat_index_celsius gauge\n"
|
||||||
"# UNIT iot_air_heat_index_celsius \u00B0C\n"
|
"# UNIT " PROM_NAMESPACE "_air_heat_index_celsius \u00B0C\n"
|
||||||
"iot_air_heat_index_celsius %f\n";
|
PROM_NAMESPACE "_air_heat_index_celsius %f\n";
|
||||||
|
|
||||||
read_sensors();
|
read_sensors();
|
||||||
if (isnan(humidity) || isnan(temperature) || isnan(heat_index)) {
|
if (isnan(humidity) || isnan(temperature) || isnan(heat_index)) {
|
||||||
|
@ -152,6 +167,11 @@ void handle_http_metrics_client() {
|
||||||
http_server.send(200, "text/plain; charset=utf-8", response);
|
http_server.send(200, "text/plain; charset=utf-8", response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_http_not_found() {
|
||||||
|
log_request();
|
||||||
|
http_server.send(404, "text/plain; charset=utf-8", "Not found.");
|
||||||
|
}
|
||||||
|
|
||||||
void read_sensors(boolean force) {
|
void read_sensors(boolean force) {
|
||||||
uint32_t min_interval = max(dht_sensor.getMinimumSamplingPeriod(), READ_INTERVAL);
|
uint32_t min_interval = max(dht_sensor.getMinimumSamplingPeriod(), READ_INTERVAL);
|
||||||
uint32_t current_time = millis();
|
uint32_t current_time = millis();
|
||||||
|
@ -211,6 +231,27 @@ bool read_sensor(float (*function)(), float *value) {
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void log_request() {
|
||||||
|
char message[128];
|
||||||
|
char method_name[16];
|
||||||
|
get_http_method_name(method_name, 16, http_server.method());
|
||||||
|
snprintf(message, 128, "Request: client=%s:%u method=%s path=%s",
|
||||||
|
http_server.client().remoteIP().toString().c_str(), http_server.client().remotePort(), method_name, http_server.uri().c_str());
|
||||||
|
log(message, LogLevel::INFO);
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_http_method_name(char *name, size_t name_length, HTTPMethod method) {
|
||||||
|
switch (method) {
|
||||||
|
case HTTP_ANY:
|
||||||
|
snprintf(name, name_length, "ANY");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
snprintf(name, name_length, "UNKNOWN");
|
||||||
|
break;
|
||||||
|
//, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void log(char const *message, LogLevel level) {
|
void log(char const *message, LogLevel level) {
|
||||||
if (DEBUG_MODE == 0 && level == LogLevel::DEBUG) {
|
if (DEBUG_MODE == 0 && level == LogLevel::DEBUG) {
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue