STA and MQTT status info in webpage

This commit is contained in:
2021-07-15 14:12:01 +02:00
parent 39dd28b456
commit e720ef15d5
10 changed files with 112 additions and 39 deletions

View File

@@ -30,7 +30,7 @@ espchrono::millis_clock::time_point last_bmp085_readout;
void init_bmp()
{
if (!config::enable_bmp)
if (!config::enable_i2c || !config::enable_bmp)
return;
bmp.construct(10085);
@@ -55,7 +55,7 @@ void init_bmp()
void update_bmp()
{
if (!config::enable_bmp)
if (!config::enable_i2c || !config::enable_bmp)
return;
if (bmpInitialized) {
@@ -79,7 +79,7 @@ void update_bmp()
bmpValue.altitude = bmp->pressureToAltitude(seaLevelPressure, bmpValue.pressure);
ESP_LOGI(TAG, "read bmp Altitude: %.1f m", bmpValue.altitude);
if (mqttClient && mqttConnected) {
if (mqttConnected) {
if (!lastBmpValue)
mqttVerbosePub(config::topic_bmp085_availability, "online", 0, 1);
if (!lastBmpValue || espchrono::ago(last_bmp085_pressure_pub) >= config::valueUpdateInterval) {
@@ -109,7 +109,7 @@ void update_bmp()
bmpOffline:
if (lastBmpValue && espchrono::ago(lastBmpValue->timestamp) >= config::availableTimeoutTime) {
ESP_LOGW(TAG, "bmp timeouted");
if (mqttClient && mqttConnected)
if (mqttConnected)
mqttVerbosePub(config::topic_bmp085_availability, "offline", 0, 1);
lastBmpValue = std::nullopt;
}

View File

@@ -60,7 +60,7 @@ void update_dht()
ESP_LOGI(TAG, "read dht temperature: %.1f C", dhtValue.temperature);
ESP_LOGI(TAG, "read dht humidity: %.1f %%", dhtValue.humidity);
if (mqttClient && mqttConnected) {
if (mqttConnected) {
if (!lastDhtValue)
mqttVerbosePub(config::topic_dht11_availability, "online", 0, 1);
if (!lastDhtValue || espchrono::ago(last_dht11_temperature_pub) >= config::valueUpdateInterval) {
@@ -82,7 +82,7 @@ void update_dht()
dhtOffline:
if (lastDhtValue && espchrono::ago(lastDhtValue->timestamp) >= config::availableTimeoutTime) {
ESP_LOGW(TAG, "dht timeouted");
if (mqttClient && mqttConnected)
if (mqttConnected)
mqttVerbosePub(config::topic_dht11_availability, "offline", 0, 1);
lastDhtValue = std::nullopt;
}

View File

@@ -7,12 +7,16 @@
#include "myconfig.h"
#include "mymqtt.h"
#include "feature_lamp.h"
#include "espchrono.h"
using namespace std::chrono_literals;
namespace deckenlampe {
std::atomic<bool> switchState;
namespace {
uint8_t switchDebounce{};
espchrono::millis_clock::time_point last_switch_readout;
bool readSwitch();
} // namespace
@@ -30,6 +34,10 @@ void update_switch()
if (!config::enable_switch)
return;
if (espchrono::ago(last_switch_readout) < 20ms)
return;
last_switch_readout = espchrono::millis_clock::now();
const auto newState = readSwitch();
if (newState == switchState.load())
switchDebounce = 0;
@@ -40,14 +48,14 @@ void update_switch()
switchState = newState;
if (mqttClient && mqttConnected)
if (mqttConnected)
mqttVerbosePub(config::topic_switch_status, switchState ? "ON" : "OFF", 0, 1);
if (config::enable_lamp) {
lampState = !lampState;
writeLamp(lampState);
if (mqttClient && mqttConnected)
if (mqttConnected)
mqttVerbosePub(config::topic_lamp_status, lampState ? "ON" : "OFF", 0, 1);
}
}

View File

@@ -28,7 +28,7 @@ espchrono::millis_clock::time_point last_tsl2561_readout;
void init_tsl()
{
if (!config::enable_tsl)
if (!config::enable_i2c || !config::enable_tsl)
return;
tsl.construct(TSL2561_ADDR_FLOAT, 12345);
@@ -69,7 +69,7 @@ void init_tsl()
void update_tsl()
{
if (!config::enable_tsl)
if (!config::enable_i2c || !config::enable_tsl)
return;
if (tslInitialized) {
@@ -87,7 +87,7 @@ void update_tsl()
};
ESP_LOGI(TAG, "read tsl: %.1f lux", tslValue.lux);
if (mqttClient && mqttConnected) {
if (mqttConnected) {
if (!lastTslValue)
mqttVerbosePub(config::topic_tsl2561_availability, "online", 0, 1);
if (!lastTslValue || espchrono::ago(last_tsl2561_lux_pub) >= config::valueUpdateInterval) {
@@ -111,7 +111,7 @@ void update_tsl()
tslOffline:
if (lastTslValue && espchrono::ago(lastTslValue->timestamp) >= config::availableTimeoutTime) {
ESP_LOGW(TAG, "tsl timeouted");
if (mqttClient && mqttConnected)
if (mqttConnected)
mqttVerbosePub(config::topic_tsl2561_availability, "offline", 0, 1);
lastTslValue = std::nullopt;
}

View File

@@ -1,9 +1,5 @@
#include "sdkconfig.h"
// system includes
#include <chrono>
#include <atomic>
// esp-idf includes
#include <esp_log.h>
#include <freertos/FreeRTOS.h>
@@ -17,12 +13,8 @@
#include <esp_system.h>
// Arduino includes
#include <Arduino.h>
#include <Wire.h>
// 3rdparty lib includes
#include <fmt/core.h>
// local includes
#include "tickchrono.h"
#include "myconfig.h"
@@ -35,6 +27,7 @@
#include "feature_dht.h"
#include "feature_tsl.h"
#include "feature_bmp.h"
#include "espchrono.h"
using namespace std::chrono_literals;
@@ -88,6 +81,7 @@ extern "C" void app_main()
init_switch();
if (config::enable_i2c)
{
ESP_LOGI(TAG, "calling Wire.begin()...");
const auto result = Wire.begin(config::pins_sda, config::pins_scl);

View File

@@ -20,6 +20,11 @@ constexpr const std::string_view sta_key = "Passwort_123";
constexpr const std::string_view ap_ssid = "deckenlampe1";
constexpr const std::string_view ap_key = "Passwort_123";
constexpr const bool enable_webserver = true;
constexpr const bool enable_mdns = true;
constexpr const bool enable_mqtt = true;
constexpr const std::string_view broker_url = "mqtt://192.168.0.2/";
constexpr const bool enable_lamp = true;
@@ -42,6 +47,7 @@ constexpr const std::string_view topic_dht11_availability = "dahoam/wohnzimmer/d
constexpr const std::string_view topic_dht11_temperature = "dahoam/wohnzimmer/dht11_1/temperature";
constexpr const std::string_view topic_dht11_humidity = "dahoam/wohnzimmer/dht11_1/humidity";
constexpr const bool enable_i2c = true;
constexpr const gpio_num_t pins_sda = GPIO_NUM_16;
constexpr const gpio_num_t pins_scl = GPIO_NUM_17;

View File

@@ -14,6 +14,9 @@ constexpr const char * const TAG = "MDNS";
void init_mdns()
{
if (!config::enable_mdns)
return;
{
const auto result = mdns_init();
ESP_LOG_LEVEL_LOCAL((result == ESP_OK ? ESP_LOG_INFO : ESP_LOG_ERROR), TAG, "mdns_init(): %s", esp_err_to_name(result));
@@ -35,6 +38,7 @@ void init_mdns()
// return result;
}
if (config::enable_webserver)
{
const auto result = mdns_service_add(NULL, "_http", "_tcp", 80, NULL, 0);
ESP_LOG_LEVEL_LOCAL((result == ESP_OK ? ESP_LOG_INFO : ESP_LOG_ERROR), TAG, "mdns_service_add(): %s", esp_err_to_name(result));
@@ -45,6 +49,7 @@ void init_mdns()
void update_mdns()
{
if (!config::enable_mdns)
return;
}
} // namespace deckenlampe

View File

@@ -16,8 +16,9 @@
#include "cppmacros.h"
namespace deckenlampe {
std::atomic<bool> mqttConnected;
espcpputils::mqtt_client mqttClient;
std::atomic<bool> mqttStarted;
std::atomic<bool> mqttConnected;
namespace {
constexpr const char * const TAG = "MQTT";
@@ -27,6 +28,9 @@ void mqttEventHandler(void *event_handler_arg, esp_event_base_t event_base, int3
void init_mqtt()
{
if (!config::enable_mqtt)
return;
esp_mqtt_client_config_t mqtt_cfg = {
.uri = config::broker_url.data(),
};
@@ -42,18 +46,24 @@ void init_mqtt()
{
const auto result = mqttClient.register_event(MQTT_EVENT_ANY, mqttEventHandler, NULL);
ESP_LOG_LEVEL_LOCAL((result == ESP_OK ? ESP_LOG_INFO : ESP_LOG_ERROR), TAG, "esp_mqtt_client_register_event(): %s", esp_err_to_name(result));
//if (result != ESP_OK)
// return result;
if (result != ESP_OK)
return;
}
const auto result = mqttClient.start();
ESP_LOG_LEVEL_LOCAL((result == ESP_OK ? ESP_LOG_INFO : ESP_LOG_ERROR), TAG, "esp_mqtt_client_start(): %s", esp_err_to_name(result));
//if (result != ESP_OK)
// return result;
{
const auto result = mqttClient.start();
ESP_LOG_LEVEL_LOCAL((result == ESP_OK ? ESP_LOG_INFO : ESP_LOG_ERROR), TAG, "esp_mqtt_client_start(): %s", esp_err_to_name(result));
if (result != ESP_OK)
return;
}
mqttStarted = true;
}
void update_mqtt()
{
if (!config::enable_mqtt)
return;
}
int mqttVerbosePub(std::string_view topic, std::string_view value, int qos, int retain)
@@ -115,7 +125,7 @@ void mqttEventHandler(void *event_handler_arg, esp_event_base_t event_base, int3
}
}
if (config::enable_tsl) {
if (config::enable_i2c && config::enable_tsl) {
mqttVerbosePub(config::topic_tsl2561_availability, lastTslValue ? "online" : "offline", 0, 1);
if (lastTslValue) {
if (mqttVerbosePub(config::topic_tsl2561_lux, fmt::format("{:.1f}", lastTslValue->lux), 0, 1) >= 0)
@@ -123,7 +133,7 @@ void mqttEventHandler(void *event_handler_arg, esp_event_base_t event_base, int3
}
}
if (config::enable_bmp) {
if (config::enable_i2c && config::enable_bmp) {
mqttVerbosePub(config::topic_bmp085_availability, lastBmpValue ? "online" : "offline", 0, 1);
if (lastBmpValue) {
if (mqttVerbosePub(config::topic_bmp085_pressure, fmt::format("{:.1f}", lastBmpValue->pressure), 0, 1) >= 0)
@@ -166,7 +176,7 @@ void mqttEventHandler(void *event_handler_arg, esp_event_base_t event_base, int3
if (config::enable_lamp) {
bool newState = (lampState = (value == "ON"));
writeLamp(newState);
if (mqttClient && mqttConnected)
if (mqttConnected)
mqttVerbosePub(config::topic_lamp_status, newState ? "ON" : "OFF", 0, 1);
} else {
ESP_LOGW(TAG, "received lamp set without lamp support enabled!");

View File

@@ -8,8 +8,9 @@
#include "wrappers/mqtt_client.h"
namespace deckenlampe {
extern std::atomic<bool> mqttConnected;
extern espcpputils::mqtt_client mqttClient;
extern std::atomic<bool> mqttStarted;
extern std::atomic<bool> mqttConnected;
void init_mqtt();
void update_mqtt();

View File

@@ -26,6 +26,9 @@ httpd_handle_t httpdHandle;
namespace {
constexpr const char * const TAG = "WEBSERVER";
template<typename T> T htmlentities(const T &val) { return val; } // TODO
template<typename T> T htmlentities(T &&val) { return val; } // TODO
esp_err_t webserver_root_handler(httpd_req_t *req);
esp_err_t webserver_on_handler(httpd_req_t *req);
esp_err_t webserver_off_handler(httpd_req_t *req);
@@ -35,6 +38,9 @@ esp_err_t webserver_reboot_handler(httpd_req_t *req);
void init_webserver()
{
if (!config::enable_webserver)
return;
{
httpd_config_t httpConfig HTTPD_DEFAULT_CONFIG();
@@ -61,6 +67,8 @@ void init_webserver()
void update_webserver()
{
if (!config::enable_webserver)
return;
}
namespace {
@@ -107,14 +115,14 @@ esp_err_t webserver_root_handler(httpd_req_t *req)
body += "DHT11 not available at the moment<br/>\n";
}
if (config::enable_tsl) {
if (config::enable_i2c && config::enable_tsl) {
if (lastTslValue) {
body += fmt::format("TSL2561 Brightness: {:.1f} lux<br/>\n", lastTslValue->lux);
} else
body += "TSL2561 not available at the moment<br/>\n";
}
if (config::enable_bmp) {
if (config::enable_i2c && config::enable_bmp) {
if (lastBmpValue) {
body += fmt::format("BMP085 Pressure: {:.1f} lux<br/>\n", lastBmpValue->pressure);
body += fmt::format("BMP085 Temperature: {:.1f} C<br/>\n", lastBmpValue->temperature);
@@ -124,9 +132,39 @@ esp_err_t webserver_root_handler(httpd_req_t *req)
}
body += "<br/>\n"
"<h2>wifi scan result</h2>\n";
"<h2>wifi</h2>\n"
"<table border=\"1\">\n";
body += fmt::format("<tr><th>state machine state</th><td>{}</td></tr>\n", wifi_stack::toString(wifi_stack::wifiStateMachineState));
{
const auto staStatus = wifi_stack::get_sta_status();
body += fmt::format("<tr><th>STA status</th><td>{}</td></tr>\n", wifi_stack::toString(staStatus));
if (staStatus == wifi_stack::WiFiStaStatus::WL_CONNECTED) {
if (const auto result = wifi_stack::get_sta_ap_info(); result) {
body += fmt::format("<tr><th>STA rssi</th><td>{}dB</td></tr>\n", result->rssi);
body += fmt::format("<tr><th>STA SSID</th><td>{}</td></tr>\n", htmlentities(result->ssid));
body += fmt::format("<tr><th>STA channel</th><td>{}</td></tr>\n", result->primary);
body += fmt::format("<tr><th>STA BSSID</th><td>{}</td></tr>\n", wifi_stack::toString(wifi_stack::mac_t{result->bssid}));
} else {
body += fmt::format("<tr><td colspan=\"2\">get_sta_ap_info() failed: {}</td></tr>\n", htmlentities(result.error()));
}
if (const auto result = wifi_stack::get_ip_info(TCPIP_ADAPTER_IF_STA)) {
body += fmt::format("<tr><th>STA ip</th><td>{}</td></tr>\n", wifi_stack::toString(result->ip));
body += fmt::format("<tr><th>STA netmask</th><td>{}</td></tr>\n", wifi_stack::toString(result->netmask));
body += fmt::format("<tr><th>STA gw</th><td>{}</td></tr>\n", wifi_stack::toString(result->gw));
} else {
body += fmt::format("<tr><td colspan=\"2\">get_ip_info() failed: {}</td></tr>\n", htmlentities(result.error()));
}
}
}
body += fmt::format("<tr><th>scan status</th><td>{}</td></tr>\n", wifi_stack::toString(wifi_stack::get_scan_status()));
body += "</table>\n"
"<h3>scan result</h3>\n";
if (const auto &scanResult = wifi_stack::get_scan_result()) {
body += fmt::format("scan age: {}s<br />\n", std::chrono::round<std::chrono::seconds>(espchrono::ago(scanResult->finished)).count());
body += "<table border=\"1\">\n"
"<thead>\n"
"<tr>\n"
@@ -152,7 +190,7 @@ esp_err_t webserver_root_handler(httpd_req_t *req)
"<td>{}</td>\n"
"<td>{}</td>\n"
"</tr>\n",
entry.ssid,
htmlentities(entry.ssid),
wifi_stack::toString(entry.authmode),
wifi_stack::toString(entry.pairwise_cipher),
wifi_stack::toString(entry.group_cipher),
@@ -167,6 +205,17 @@ esp_err_t webserver_root_handler(httpd_req_t *req)
body += "<span style=\"color: red;\">no wifi scan result at the moment!</span><br/>\n";
}
body += "<br/>\n"
"<h2>MQTT</h2>\n"
"<table border=\"1\">\n";
body += fmt::format("<tr><th>client url</th><td>{}</td></tr>\n", htmlentities(config::broker_url));
body += fmt::format("<tr><th>client constructed</th><td>{}</td></tr>\n", mqttClient ? "true" : "false");
if (mqttClient) {
body += fmt::format("<tr><th>client started</th><td>{}</td></tr>\n", mqttStarted ? "true" : "false");
body += fmt::format("<tr><th>client connected</th><td>{}</td></tr>\n", mqttConnected ? "true" : "false");
}
body += "</table>\n";
CALL_AND_EXIT_ON_ERROR(httpd_resp_set_type, req, "text/html")
CALL_AND_EXIT_ON_ERROR(httpd_resp_send, req, body.data(), body.size())
@@ -183,7 +232,7 @@ esp_err_t webserver_on_handler(httpd_req_t *req)
const bool state = (lampState = true);
writeLamp(state);
if (mqttClient && mqttConnected)
if (mqttConnected)
mqttVerbosePub(config::topic_lamp_status, state ? "ON" : "OFF", 0, 1);
std::string_view body{"ON called..."};
@@ -203,7 +252,7 @@ esp_err_t webserver_off_handler(httpd_req_t *req)
const bool state = (lampState = false);
writeLamp(state);
if (mqttClient && mqttConnected)
if (mqttConnected)
mqttVerbosePub(config::topic_lamp_status, state ? "ON" : "OFF", 0, 1);
std::string_view body{"OFF called..."};
@@ -223,7 +272,7 @@ esp_err_t webserver_toggle_handler(httpd_req_t *req)
const bool state = (lampState = !lampState);
writeLamp(state);
if (mqttClient && mqttConnected)
if (mqttConnected)
mqttVerbosePub(config::topic_lamp_status, state ? "ON" : "OFF", 0, 1);
std::string_view body{"TOGGLE called..."};