added espasyncota lib
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -40,3 +40,6 @@
|
|||||||
[submodule "components/esp-nimble-cpp"]
|
[submodule "components/esp-nimble-cpp"]
|
||||||
path = components/esp-nimble-cpp
|
path = components/esp-nimble-cpp
|
||||||
url = git@github.com:0xFEEDC0DE64/esp-nimble-cpp.git
|
url = git@github.com:0xFEEDC0DE64/esp-nimble-cpp.git
|
||||||
|
[submodule "components/espasyncota"]
|
||||||
|
path = components/espasyncota
|
||||||
|
url = git@github.com:0xFEEDC0DE64/espasyncota.git
|
||||||
|
Submodule components/cpputils updated: 89bff1a8dc...b12426ffee
1
components/espasyncota
Submodule
1
components/espasyncota
Submodule
Submodule components/espasyncota added at bbc1f643e2
Submodule components/espchrono updated: 7f8a185678...4d2e9305dc
Submodule components/espcpputils updated: 3a350f1189...78fa43edcf
Submodule components/espwifistack updated: 01189ca833...717d877a44
Submodule components/fmt updated: 4b11c94036...d3c349f69d
@@ -12,6 +12,7 @@ set(headers
|
|||||||
myconfig.h
|
myconfig.h
|
||||||
mymdns.h
|
mymdns.h
|
||||||
mymqtt.h
|
mymqtt.h
|
||||||
|
myota.h
|
||||||
mywifi.h
|
mywifi.h
|
||||||
nvswrappers.h
|
nvswrappers.h
|
||||||
webserver.h
|
webserver.h
|
||||||
@@ -29,13 +30,14 @@ set(sources
|
|||||||
myconfig.cpp
|
myconfig.cpp
|
||||||
mymdns.cpp
|
mymdns.cpp
|
||||||
mymqtt.cpp
|
mymqtt.cpp
|
||||||
|
myota.cpp
|
||||||
mywifi.cpp
|
mywifi.cpp
|
||||||
webserver.cpp
|
webserver.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(dependencies
|
set(dependencies
|
||||||
freertos nvs_flash esp_http_server esp_https_ota mdns app_update esp_system mqtt
|
freertos nvs_flash esp_http_server esp_https_ota mdns app_update esp_system mqtt
|
||||||
arduino-esp32 cpputils date esp-nimble-cpp espchrono espcpputils espwifistack expected fmt
|
arduino-esp32 cpputils date esp-nimble-cpp espasyncota espchrono espcpputils espwifistack expected fmt
|
||||||
Adafruit_BMP085_Unified Adafruit_TSL2561 DHT-sensor-library
|
Adafruit_BMP085_Unified Adafruit_TSL2561 DHT-sensor-library
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -39,7 +39,8 @@ void init_bmp()
|
|||||||
bmpInitialized = bmp->begin();
|
bmpInitialized = bmp->begin();
|
||||||
ESP_LOGI(TAG, "finished with %s", bmpInitialized ? "true" : "false");
|
ESP_LOGI(TAG, "finished with %s", bmpInitialized ? "true" : "false");
|
||||||
|
|
||||||
if (bmpInitialized) {
|
if (bmpInitialized)
|
||||||
|
{
|
||||||
sensor_t sensor = bmp->getSensor();
|
sensor_t sensor = bmp->getSensor();
|
||||||
ESP_LOGI(TAG, "------------------------------------");
|
ESP_LOGI(TAG, "------------------------------------");
|
||||||
ESP_LOGI(TAG, "Sensor: %s", sensor.name);
|
ESP_LOGI(TAG, "Sensor: %s", sensor.name);
|
||||||
@@ -58,14 +59,17 @@ void update_bmp()
|
|||||||
if (!config::enable_i2c.value() || !config::enable_bmp.value())
|
if (!config::enable_i2c.value() || !config::enable_bmp.value())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (bmpInitialized) {
|
if (bmpInitialized)
|
||||||
|
{
|
||||||
if (espchrono::ago(last_bmp085_readout) < 5s)
|
if (espchrono::ago(last_bmp085_readout) < 5s)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
last_bmp085_readout = espchrono::millis_clock::now();
|
last_bmp085_readout = espchrono::millis_clock::now();
|
||||||
|
|
||||||
if (std::optional<Adafruit_BMP085_Unified::TemperatureAndPressure> values = bmp->getTemperatureAndPressure()) {
|
if (std::optional<Adafruit_BMP085_Unified::TemperatureAndPressure> values = bmp->getTemperatureAndPressure())
|
||||||
if (values->temperature && values->pressure) {
|
{
|
||||||
|
if (values->temperature && values->pressure)
|
||||||
|
{
|
||||||
BmpValue bmpValue {
|
BmpValue bmpValue {
|
||||||
.timestamp = espchrono::millis_clock::now(),
|
.timestamp = espchrono::millis_clock::now(),
|
||||||
.pressure = values->pressure,
|
.pressure = values->pressure,
|
||||||
@@ -79,35 +83,46 @@ void update_bmp()
|
|||||||
bmpValue.altitude = bmp->pressureToAltitude(seaLevelPressure, bmpValue.pressure);
|
bmpValue.altitude = bmp->pressureToAltitude(seaLevelPressure, bmpValue.pressure);
|
||||||
ESP_LOGI(TAG, "read bmp Altitude: %.1f m", bmpValue.altitude);
|
ESP_LOGI(TAG, "read bmp Altitude: %.1f m", bmpValue.altitude);
|
||||||
|
|
||||||
if (mqttConnected) {
|
if (mqttConnected)
|
||||||
|
{
|
||||||
if (!lastBmpValue)
|
if (!lastBmpValue)
|
||||||
mqttVerbosePub(config::topic_bmp085_availability.value(), "online", 0, 1);
|
mqttVerbosePub(config::topic_bmp085_availability.value(), "online", 0, 1);
|
||||||
if (!lastBmpValue || espchrono::ago(last_bmp085_pressure_pub) >= config::valueUpdateInterval.value()) {
|
if (!lastBmpValue || espchrono::ago(last_bmp085_pressure_pub) >= config::valueUpdateInterval.value())
|
||||||
|
{
|
||||||
if (mqttVerbosePub(config::topic_bmp085_pressure.value(), fmt::format("{:.1f}", bmpValue.pressure), 0, 1) >= 0)
|
if (mqttVerbosePub(config::topic_bmp085_pressure.value(), fmt::format("{:.1f}", bmpValue.pressure), 0, 1) >= 0)
|
||||||
last_bmp085_pressure_pub = espchrono::millis_clock::now();
|
last_bmp085_pressure_pub = espchrono::millis_clock::now();
|
||||||
}
|
}
|
||||||
if (!lastBmpValue || espchrono::ago(last_bmp085_temperature_pub) >= config::valueUpdateInterval.value()) {
|
if (!lastBmpValue || espchrono::ago(last_bmp085_temperature_pub) >= config::valueUpdateInterval.value())
|
||||||
|
{
|
||||||
if (mqttVerbosePub(config::topic_bmp085_temperature.value(), fmt::format("{:.1f}", bmpValue.temperature), 0, 1) >= 0)
|
if (mqttVerbosePub(config::topic_bmp085_temperature.value(), fmt::format("{:.1f}", bmpValue.temperature), 0, 1) >= 0)
|
||||||
last_bmp085_temperature_pub = espchrono::millis_clock::now();
|
last_bmp085_temperature_pub = espchrono::millis_clock::now();
|
||||||
}
|
}
|
||||||
if (!lastBmpValue || espchrono::ago(last_bmp085_altitude_pub) >= config::valueUpdateInterval.value()) {
|
if (!lastBmpValue || espchrono::ago(last_bmp085_altitude_pub) >= config::valueUpdateInterval.value())
|
||||||
|
{
|
||||||
if (mqttVerbosePub(config::topic_bmp085_altitude.value(), fmt::format("{:.1f}", bmpValue.altitude), 0, 1) >= 0)
|
if (mqttVerbosePub(config::topic_bmp085_altitude.value(), fmt::format("{:.1f}", bmpValue.altitude), 0, 1) >= 0)
|
||||||
last_bmp085_altitude_pub = espchrono::millis_clock::now();
|
last_bmp085_altitude_pub = espchrono::millis_clock::now();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lastBmpValue = bmpValue;
|
lastBmpValue = bmpValue;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ESP_LOGW(TAG, "bmp sensor error");
|
ESP_LOGW(TAG, "bmp sensor error");
|
||||||
goto bmpOffline;
|
goto bmpOffline;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ESP_LOGW(TAG, "bmp failed");
|
ESP_LOGW(TAG, "bmp failed");
|
||||||
goto bmpOffline;
|
goto bmpOffline;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
bmpOffline:
|
bmpOffline:
|
||||||
if (lastBmpValue && espchrono::ago(lastBmpValue->timestamp) >= config::availableTimeoutTime.value()) {
|
if (lastBmpValue && espchrono::ago(lastBmpValue->timestamp) >= config::availableTimeoutTime.value())
|
||||||
|
{
|
||||||
ESP_LOGW(TAG, "bmp timeouted");
|
ESP_LOGW(TAG, "bmp timeouted");
|
||||||
if (mqttConnected)
|
if (mqttConnected)
|
||||||
mqttVerbosePub(config::topic_bmp085_availability.value(), "offline", 0, 1);
|
mqttVerbosePub(config::topic_bmp085_availability.value(), "offline", 0, 1);
|
||||||
|
@@ -44,13 +44,15 @@ void update_dht()
|
|||||||
if (!config::enable_dht.value())
|
if (!config::enable_dht.value())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (dhtInitialized) {
|
if (dhtInitialized)
|
||||||
|
{
|
||||||
if (espchrono::ago(last_dht11_readout) < 5s)
|
if (espchrono::ago(last_dht11_readout) < 5s)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
last_dht11_readout = espchrono::millis_clock::now();
|
last_dht11_readout = espchrono::millis_clock::now();
|
||||||
|
|
||||||
if (const auto data = dht->read()) {
|
if (const auto data = dht->read())
|
||||||
|
{
|
||||||
DhtValue dhtValue {
|
DhtValue dhtValue {
|
||||||
.timestamp = espchrono::millis_clock::now(),
|
.timestamp = espchrono::millis_clock::now(),
|
||||||
.temperature = dht->readTemperature(*data),
|
.temperature = dht->readTemperature(*data),
|
||||||
@@ -60,27 +62,35 @@ void update_dht()
|
|||||||
ESP_LOGI(TAG, "read dht temperature: %.1f C", dhtValue.temperature);
|
ESP_LOGI(TAG, "read dht temperature: %.1f C", dhtValue.temperature);
|
||||||
ESP_LOGI(TAG, "read dht humidity: %.1f %%", dhtValue.humidity);
|
ESP_LOGI(TAG, "read dht humidity: %.1f %%", dhtValue.humidity);
|
||||||
|
|
||||||
if (mqttConnected) {
|
if (mqttConnected)
|
||||||
|
{
|
||||||
if (!lastDhtValue)
|
if (!lastDhtValue)
|
||||||
mqttVerbosePub(config::topic_dht11_availability.value(), "online", 0, 1);
|
mqttVerbosePub(config::topic_dht11_availability.value(), "online", 0, 1);
|
||||||
if (!lastDhtValue || espchrono::ago(last_dht11_temperature_pub) >= config::valueUpdateInterval.value()) {
|
if (!lastDhtValue || espchrono::ago(last_dht11_temperature_pub) >= config::valueUpdateInterval.value())
|
||||||
|
{
|
||||||
if (mqttVerbosePub(config::topic_dht11_temperature.value(), fmt::format("{:.1f}", dhtValue.temperature), 0, 1) >= 0)
|
if (mqttVerbosePub(config::topic_dht11_temperature.value(), fmt::format("{:.1f}", dhtValue.temperature), 0, 1) >= 0)
|
||||||
last_dht11_temperature_pub = espchrono::millis_clock::now();
|
last_dht11_temperature_pub = espchrono::millis_clock::now();
|
||||||
}
|
}
|
||||||
if (!lastDhtValue || espchrono::ago(last_dht11_humidity_pub) >= config::valueUpdateInterval.value()) {
|
if (!lastDhtValue || espchrono::ago(last_dht11_humidity_pub) >= config::valueUpdateInterval.value())
|
||||||
|
{
|
||||||
if (mqttVerbosePub(config::topic_dht11_humidity.value(), fmt::format("{:.1f}", dhtValue.humidity), 0, 1) >= 0)
|
if (mqttVerbosePub(config::topic_dht11_humidity.value(), fmt::format("{:.1f}", dhtValue.humidity), 0, 1) >= 0)
|
||||||
last_dht11_humidity_pub = espchrono::millis_clock::now();
|
last_dht11_humidity_pub = espchrono::millis_clock::now();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lastDhtValue = dhtValue;
|
lastDhtValue = dhtValue;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ESP_LOGW(TAG, "dht failed");
|
ESP_LOGW(TAG, "dht failed");
|
||||||
goto dhtOffline;
|
goto dhtOffline;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
dhtOffline:
|
dhtOffline:
|
||||||
if (lastDhtValue && espchrono::ago(lastDhtValue->timestamp) >= config::availableTimeoutTime.value()) {
|
if (lastDhtValue && espchrono::ago(lastDhtValue->timestamp) >= config::availableTimeoutTime.value())
|
||||||
|
{
|
||||||
ESP_LOGW(TAG, "dht timeouted");
|
ESP_LOGW(TAG, "dht timeouted");
|
||||||
if (mqttConnected)
|
if (mqttConnected)
|
||||||
mqttVerbosePub(config::topic_dht11_availability.value(), "offline", 0, 1);
|
mqttVerbosePub(config::topic_dht11_availability.value(), "offline", 0, 1);
|
||||||
|
@@ -41,9 +41,11 @@ void update_switch()
|
|||||||
const auto newState = readSwitch();
|
const auto newState = readSwitch();
|
||||||
if (newState == switchState.load())
|
if (newState == switchState.load())
|
||||||
switchDebounce = 0;
|
switchDebounce = 0;
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
switchDebounce++;
|
switchDebounce++;
|
||||||
if (switchDebounce >= 10) {
|
if (switchDebounce >= 10)
|
||||||
|
{
|
||||||
switchDebounce = 0;
|
switchDebounce = 0;
|
||||||
|
|
||||||
switchState = newState;
|
switchState = newState;
|
||||||
@@ -51,7 +53,8 @@ void update_switch()
|
|||||||
if (mqttConnected)
|
if (mqttConnected)
|
||||||
mqttVerbosePub(config::topic_switch_status.value(), switchState ? "ON" : "OFF", 0, 1);
|
mqttVerbosePub(config::topic_switch_status.value(), switchState ? "ON" : "OFF", 0, 1);
|
||||||
|
|
||||||
if (config::enable_lamp.value()) {
|
if (config::enable_lamp.value())
|
||||||
|
{
|
||||||
lampState = !lampState;
|
lampState = !lampState;
|
||||||
writeLamp(lampState);
|
writeLamp(lampState);
|
||||||
|
|
||||||
|
@@ -37,7 +37,8 @@ void init_tsl()
|
|||||||
tslInitialized = tsl->begin(true);
|
tslInitialized = tsl->begin(true);
|
||||||
ESP_LOGI(TAG, "finished with %s", tslInitialized ? "true" : "false");
|
ESP_LOGI(TAG, "finished with %s", tslInitialized ? "true" : "false");
|
||||||
|
|
||||||
if (tslInitialized) {
|
if (tslInitialized)
|
||||||
|
{
|
||||||
sensor_t sensor = tsl->getSensor();
|
sensor_t sensor = tsl->getSensor();
|
||||||
ESP_LOGI(TAG, "------------------------------------");
|
ESP_LOGI(TAG, "------------------------------------");
|
||||||
ESP_LOGI(TAG, "Sensor: %s", sensor.name);
|
ESP_LOGI(TAG, "Sensor: %s", sensor.name);
|
||||||
@@ -72,44 +73,56 @@ void update_tsl()
|
|||||||
if (!config::enable_i2c.value() || !config::enable_tsl.value())
|
if (!config::enable_i2c.value() || !config::enable_tsl.value())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (tslInitialized) {
|
if (tslInitialized)
|
||||||
|
{
|
||||||
if (espchrono::ago(last_tsl2561_readout) < 5s)
|
if (espchrono::ago(last_tsl2561_readout) < 5s)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
last_tsl2561_readout = espchrono::millis_clock::now();
|
last_tsl2561_readout = espchrono::millis_clock::now();
|
||||||
|
|
||||||
if (std::optional<sensors_event_t> event = tsl->getEvent()) {
|
if (std::optional<sensors_event_t> event = tsl->getEvent())
|
||||||
|
{
|
||||||
/* Display the results (light is measured in lux) */
|
/* Display the results (light is measured in lux) */
|
||||||
if (event->light) {
|
if (event->light)
|
||||||
|
{
|
||||||
TslValue tslValue {
|
TslValue tslValue {
|
||||||
.timestamp = espchrono::millis_clock::now(),
|
.timestamp = espchrono::millis_clock::now(),
|
||||||
.lux = event->light
|
.lux = event->light
|
||||||
};
|
};
|
||||||
ESP_LOGI(TAG, "read tsl: %.1f lux", tslValue.lux);
|
ESP_LOGI(TAG, "read tsl: %.1f lux", tslValue.lux);
|
||||||
|
|
||||||
if (mqttConnected) {
|
if (mqttConnected)
|
||||||
|
{
|
||||||
if (!lastTslValue)
|
if (!lastTslValue)
|
||||||
mqttVerbosePub(config::topic_tsl2561_availability.value(), "online", 0, 1);
|
mqttVerbosePub(config::topic_tsl2561_availability.value(), "online", 0, 1);
|
||||||
if (!lastTslValue || espchrono::ago(last_tsl2561_lux_pub) >= config::valueUpdateInterval.value()) {
|
if (!lastTslValue || espchrono::ago(last_tsl2561_lux_pub) >= config::valueUpdateInterval.value())
|
||||||
|
{
|
||||||
if (mqttVerbosePub(config::topic_tsl2561_lux.value(), fmt::format("{:.1f}", tslValue.lux), 0, 1) >= 0)
|
if (mqttVerbosePub(config::topic_tsl2561_lux.value(), fmt::format("{:.1f}", tslValue.lux), 0, 1) >= 0)
|
||||||
last_tsl2561_lux_pub = espchrono::millis_clock::now();
|
last_tsl2561_lux_pub = espchrono::millis_clock::now();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lastTslValue = tslValue;
|
lastTslValue = tslValue;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* If event.light = 0 lux the sensor is probably saturated
|
/* If event.light = 0 lux the sensor is probably saturated
|
||||||
* and no reliable data could be generated! */
|
* and no reliable data could be generated! */
|
||||||
ESP_LOGW(TAG, "tsl sensor overload %f", event->light);
|
ESP_LOGW(TAG, "tsl sensor overload %f", event->light);
|
||||||
goto tslOffline;
|
goto tslOffline;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ESP_LOGW(TAG, "tsl failed");
|
ESP_LOGW(TAG, "tsl failed");
|
||||||
goto tslOffline;
|
goto tslOffline;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
tslOffline:
|
tslOffline:
|
||||||
if (lastTslValue && espchrono::ago(lastTslValue->timestamp) >= config::availableTimeoutTime.value()) {
|
if (lastTslValue && espchrono::ago(lastTslValue->timestamp) >= config::availableTimeoutTime.value())
|
||||||
|
{
|
||||||
ESP_LOGW(TAG, "tsl timeouted");
|
ESP_LOGW(TAG, "tsl timeouted");
|
||||||
if (mqttConnected)
|
if (mqttConnected)
|
||||||
mqttVerbosePub(config::topic_tsl2561_availability.value(), "offline", 0, 1);
|
mqttVerbosePub(config::topic_tsl2561_availability.value(), "offline", 0, 1);
|
||||||
|
@@ -23,6 +23,7 @@
|
|||||||
#include "webserver.h"
|
#include "webserver.h"
|
||||||
#include "mymdns.h"
|
#include "mymdns.h"
|
||||||
#include "mymqtt.h"
|
#include "mymqtt.h"
|
||||||
|
#include "myota.h"
|
||||||
#include "feature_lamp.h"
|
#include "feature_lamp.h"
|
||||||
#include "feature_switch.h"
|
#include "feature_switch.h"
|
||||||
#include "feature_dht.h"
|
#include "feature_dht.h"
|
||||||
@@ -99,6 +100,8 @@ extern "C" void app_main()
|
|||||||
|
|
||||||
init_mqtt();
|
init_mqtt();
|
||||||
|
|
||||||
|
init_ota();
|
||||||
|
|
||||||
init_dht();
|
init_dht();
|
||||||
|
|
||||||
init_tsl();
|
init_tsl();
|
||||||
@@ -130,6 +133,9 @@ extern "C" void app_main()
|
|||||||
update_mqtt();
|
update_mqtt();
|
||||||
vPortYield();
|
vPortYield();
|
||||||
|
|
||||||
|
update_ota();
|
||||||
|
vPortYield();
|
||||||
|
|
||||||
update_dht();
|
update_dht();
|
||||||
vPortYield();
|
vPortYield();
|
||||||
|
|
||||||
|
@@ -102,15 +102,18 @@ namespace {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
void loadParam(ConfigWrapper<T> &config)
|
void loadParam(ConfigWrapper<T> &config)
|
||||||
{
|
{
|
||||||
if (const auto len = std::strlen(config.nvsKey()); len > 15) {
|
if (const auto len = std::strlen(config.nvsKey()); len > 15)
|
||||||
|
{
|
||||||
ESP_LOGE(TAG, "%s too long %zd (%zd)", config.nvsKey(), len, len-15);
|
ESP_LOGE(TAG, "%s too long %zd (%zd)", config.nvsKey(), len, len-15);
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const auto value = config.readFromFlash()) {
|
if (const auto value = config.readFromFlash())
|
||||||
|
{
|
||||||
if (*value)
|
if (*value)
|
||||||
config.setValue(**value);
|
config.setValue(**value);
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
ESP_LOGE(TAG, "error loading config %s: %.*s", config.name(), value.error().size(), value.error().data());
|
ESP_LOGE(TAG, "error loading config %s: %.*s", config.name(), value.error().size(), value.error().data());
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@@ -70,7 +70,8 @@ int mqttVerbosePub(std::string_view topic, std::string_view value, int qos, int
|
|||||||
{
|
{
|
||||||
ESP_LOGD(TAG, "topic=\"%.*s\" value=\"%.*s\"", topic.size(), topic.data(), value.size(), value.data());
|
ESP_LOGD(TAG, "topic=\"%.*s\" value=\"%.*s\"", topic.size(), topic.data(), value.size(), value.data());
|
||||||
|
|
||||||
if (!mqttClient) {
|
if (!mqttClient)
|
||||||
|
{
|
||||||
ESP_LOGE(TAG, "mqttClient not constructed!");
|
ESP_LOGE(TAG, "mqttClient not constructed!");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -90,7 +91,8 @@ void mqttEventHandler(void *event_handler_arg, esp_event_base_t event_base, int3
|
|||||||
|
|
||||||
const esp_mqtt_event_t *data = reinterpret_cast<const esp_mqtt_event_t *>(event_data);
|
const esp_mqtt_event_t *data = reinterpret_cast<const esp_mqtt_event_t *>(event_data);
|
||||||
|
|
||||||
switch (esp_mqtt_event_id_t(event_id)) {
|
switch (esp_mqtt_event_id_t(event_id))
|
||||||
|
{
|
||||||
case MQTT_EVENT_ERROR:
|
case MQTT_EVENT_ERROR:
|
||||||
ESP_LOGE(TAG, "%s event_id=%s", event_base, "MQTT_EVENT_ERROR");
|
ESP_LOGE(TAG, "%s event_id=%s", event_base, "MQTT_EVENT_ERROR");
|
||||||
|
|
||||||
@@ -110,20 +112,24 @@ void mqttEventHandler(void *event_handler_arg, esp_event_base_t event_base, int3
|
|||||||
|
|
||||||
mqttConnected = true;
|
mqttConnected = true;
|
||||||
|
|
||||||
if (config::enable_lamp.value()) {
|
if (config::enable_lamp.value())
|
||||||
|
{
|
||||||
mqttVerbosePub(config::topic_lamp_availability.value(), "online", 0, 1);
|
mqttVerbosePub(config::topic_lamp_availability.value(), "online", 0, 1);
|
||||||
mqttVerbosePub(config::topic_lamp_status.value(), lampState.load() ? "ON" : "OFF", 0, 1);
|
mqttVerbosePub(config::topic_lamp_status.value(), lampState.load() ? "ON" : "OFF", 0, 1);
|
||||||
mqttClient.subscribe(config::topic_lamp_set.value(), 0);
|
mqttClient.subscribe(config::topic_lamp_set.value(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config::enable_switch.value()) {
|
if (config::enable_switch.value())
|
||||||
|
{
|
||||||
mqttVerbosePub(config::topic_switch_availability.value(), "online", 0, 1);
|
mqttVerbosePub(config::topic_switch_availability.value(), "online", 0, 1);
|
||||||
mqttVerbosePub(config::topic_switch_status.value(), switchState.load() ? "ON" : "OFF", 0, 1);
|
mqttVerbosePub(config::topic_switch_status.value(), switchState.load() ? "ON" : "OFF", 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config::enable_dht.value()) {
|
if (config::enable_dht.value())
|
||||||
|
{
|
||||||
mqttVerbosePub(config::topic_dht11_availability.value(), lastDhtValue ? "online" : "offline", 0, 1);
|
mqttVerbosePub(config::topic_dht11_availability.value(), lastDhtValue ? "online" : "offline", 0, 1);
|
||||||
if (lastDhtValue) {
|
if (lastDhtValue)
|
||||||
|
{
|
||||||
if (mqttVerbosePub(config::topic_dht11_temperature.value(), fmt::format("{:.1f}", lastDhtValue->temperature), 0, 1) >= 0)
|
if (mqttVerbosePub(config::topic_dht11_temperature.value(), fmt::format("{:.1f}", lastDhtValue->temperature), 0, 1) >= 0)
|
||||||
last_dht11_temperature_pub = espchrono::millis_clock::now();
|
last_dht11_temperature_pub = espchrono::millis_clock::now();
|
||||||
if (mqttVerbosePub(config::topic_dht11_humidity.value(), fmt::format("{:.1f}", lastDhtValue->humidity), 0, 1) >= 0)
|
if (mqttVerbosePub(config::topic_dht11_humidity.value(), fmt::format("{:.1f}", lastDhtValue->humidity), 0, 1) >= 0)
|
||||||
@@ -131,17 +137,21 @@ void mqttEventHandler(void *event_handler_arg, esp_event_base_t event_base, int3
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config::enable_i2c.value() && config::enable_tsl.value()) {
|
if (config::enable_i2c.value() && config::enable_tsl.value())
|
||||||
|
{
|
||||||
mqttVerbosePub(config::topic_tsl2561_availability.value(), lastTslValue ? "online" : "offline", 0, 1);
|
mqttVerbosePub(config::topic_tsl2561_availability.value(), lastTslValue ? "online" : "offline", 0, 1);
|
||||||
if (lastTslValue) {
|
if (lastTslValue)
|
||||||
|
{
|
||||||
if (mqttVerbosePub(config::topic_tsl2561_lux.value(), fmt::format("{:.1f}", lastTslValue->lux), 0, 1) >= 0)
|
if (mqttVerbosePub(config::topic_tsl2561_lux.value(), fmt::format("{:.1f}", lastTslValue->lux), 0, 1) >= 0)
|
||||||
last_tsl2561_lux_pub = espchrono::millis_clock::now();
|
last_tsl2561_lux_pub = espchrono::millis_clock::now();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config::enable_i2c.value() && config::enable_bmp.value()) {
|
if (config::enable_i2c.value() && config::enable_bmp.value())
|
||||||
|
{
|
||||||
mqttVerbosePub(config::topic_bmp085_availability.value(), lastBmpValue ? "online" : "offline", 0, 1);
|
mqttVerbosePub(config::topic_bmp085_availability.value(), lastBmpValue ? "online" : "offline", 0, 1);
|
||||||
if (lastBmpValue) {
|
if (lastBmpValue)
|
||||||
|
{
|
||||||
if (mqttVerbosePub(config::topic_bmp085_pressure.value(), fmt::format("{:.1f}", lastBmpValue->pressure), 0, 1) >= 0)
|
if (mqttVerbosePub(config::topic_bmp085_pressure.value(), fmt::format("{:.1f}", lastBmpValue->pressure), 0, 1) >= 0)
|
||||||
last_bmp085_pressure_pub = espchrono::millis_clock::now();
|
last_bmp085_pressure_pub = espchrono::millis_clock::now();
|
||||||
if (mqttVerbosePub(config::topic_bmp085_temperature.value(), fmt::format("{:.1f}", lastBmpValue->temperature), 0, 1) >= 0)
|
if (mqttVerbosePub(config::topic_bmp085_temperature.value(), fmt::format("{:.1f}", lastBmpValue->temperature), 0, 1) >= 0)
|
||||||
@@ -178,16 +188,22 @@ void mqttEventHandler(void *event_handler_arg, esp_event_base_t event_base, int3
|
|||||||
|
|
||||||
ESP_LOGI(TAG, "%s event_id=%s topic=%.*s data=%.*s", event_base, "MQTT_EVENT_DATA", topic.size(), topic.data(), value.size(), value.data());
|
ESP_LOGI(TAG, "%s event_id=%s topic=%.*s data=%.*s", event_base, "MQTT_EVENT_DATA", topic.size(), topic.data(), value.size(), value.data());
|
||||||
|
|
||||||
if (topic == config::topic_lamp_set.value()) {
|
if (topic == config::topic_lamp_set.value())
|
||||||
if (config::enable_lamp.value()) {
|
{
|
||||||
|
if (config::enable_lamp.value())
|
||||||
|
{
|
||||||
bool newState = (lampState = (value == "ON"));
|
bool newState = (lampState = (value == "ON"));
|
||||||
writeLamp(newState);
|
writeLamp(newState);
|
||||||
if (mqttConnected)
|
if (mqttConnected)
|
||||||
mqttVerbosePub(config::topic_lamp_status.value(), newState ? "ON" : "OFF", 0, 1);
|
mqttVerbosePub(config::topic_lamp_status.value(), newState ? "ON" : "OFF", 0, 1);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ESP_LOGW(TAG, "received lamp set without lamp support enabled!");
|
ESP_LOGW(TAG, "received lamp set without lamp support enabled!");
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ESP_LOGW(TAG, "received unknown data topic=%.*s data=%.*s", topic.size(), topic.data(), value.size(), value.data());
|
ESP_LOGW(TAG, "received unknown data topic=%.*s data=%.*s", topic.size(), topic.data(), value.size(), value.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
49
main/myota.cpp
Normal file
49
main/myota.cpp
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#include "myota.h"
|
||||||
|
|
||||||
|
// esp-idf includes
|
||||||
|
#include <esp_log.h>
|
||||||
|
|
||||||
|
// local includes
|
||||||
|
#include "delayedconstruction.h"
|
||||||
|
#include "espasyncota.h"
|
||||||
|
#include "espwifistack.h"
|
||||||
|
|
||||||
|
namespace deckenlampe {
|
||||||
|
namespace {
|
||||||
|
constexpr const char * const TAG = "OTA";
|
||||||
|
|
||||||
|
cpputils::DelayedConstruction<EspAsyncOta> _asyncOta;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
EspAsyncOta &asyncOta{_asyncOta.getUnsafe()};
|
||||||
|
|
||||||
|
void init_ota()
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "called");
|
||||||
|
|
||||||
|
_asyncOta.construct();
|
||||||
|
|
||||||
|
if (const auto result = _asyncOta->startTask(); !result)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "starting OTA task failed: %.*s", result.error().size(), result.error().data());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_ota()
|
||||||
|
{
|
||||||
|
_asyncOta->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
tl::expected<void, std::string> triggerOta(std::string_view url)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "%.*s", url.size(), url.data());
|
||||||
|
|
||||||
|
if (const auto result = _asyncOta->trigger(url, {}, {}, {}); !result)
|
||||||
|
return tl::make_unexpected(std::move(result).error());
|
||||||
|
|
||||||
|
wifi_stack::delete_scan_result();
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
} // namespace deckenlampe
|
19
main/myota.h
Normal file
19
main/myota.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// system includes
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
// 3rdparty lib includes
|
||||||
|
#include <tl/expected.hpp>
|
||||||
|
// forward declares
|
||||||
|
class EspAsyncOta;
|
||||||
|
|
||||||
|
namespace deckenlampe {
|
||||||
|
extern EspAsyncOta &asyncOta;
|
||||||
|
|
||||||
|
void init_ota();
|
||||||
|
void update_ota();
|
||||||
|
|
||||||
|
tl::expected<void, std::string> triggerOta(std::string_view url);
|
||||||
|
} // namespace deckenlampe
|
@@ -25,40 +25,35 @@ wifi_stack::config makeWifiConfig()
|
|||||||
return wifi_stack::config {
|
return wifi_stack::config {
|
||||||
.wifiEnabled = true,
|
.wifiEnabled = true,
|
||||||
.hostname = config::hostname.value(),
|
.hostname = config::hostname.value(),
|
||||||
.wifis = std::array<wifi_stack::wifi_entry, 10> {
|
.sta = {
|
||||||
wifi_stack::wifi_entry { .ssid = config::sta_ssid.value(), .key = config::sta_key.value() },
|
.wifis = std::array<wifi_stack::wifi_entry, 10> {
|
||||||
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
wifi_stack::wifi_entry { .ssid = config::sta_ssid.value(), .key = config::sta_key.value() },
|
||||||
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
||||||
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
||||||
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
||||||
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
||||||
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
||||||
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
||||||
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
||||||
wifi_stack::wifi_entry { .ssid = {}, .key = {} }
|
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
||||||
},
|
wifi_stack::wifi_entry { .ssid = {}, .key = {} }
|
||||||
.sta_ip = {
|
},
|
||||||
.staticIpEnabled = false,
|
.min_rssi = -90
|
||||||
// .staticIp = {},
|
|
||||||
// .staticGateway = {},
|
|
||||||
// .staticSubnet = {},
|
|
||||||
// .staticDns1 = {},
|
|
||||||
// .staticDns2 = {}
|
|
||||||
},
|
},
|
||||||
.ap = {
|
.ap = {
|
||||||
{
|
.ssid = config::ap_ssid.value(),
|
||||||
.ssid = config::ap_ssid.value(),
|
.key = config::ap_key.value(),
|
||||||
.key = config::ap_key.value()
|
.static_ip = {
|
||||||
|
.ip = ap_ip,
|
||||||
|
.subnet = ap_subnet,
|
||||||
|
.gateway = ap_ip
|
||||||
},
|
},
|
||||||
.channel = 1,
|
.channel = 1,
|
||||||
.authmode = WIFI_AUTH_WPA2_PSK,
|
.authmode = WIFI_AUTH_WPA2_PSK,
|
||||||
.ssid_hidden = false,
|
.ssid_hidden = false,
|
||||||
.max_connection = 4,
|
.max_connection = 4,
|
||||||
.beacon_interval = 100,
|
.beacon_interval = 100
|
||||||
.ip = ap_ip,
|
}
|
||||||
.subnet = ap_subnet
|
|
||||||
},
|
|
||||||
.min_rssi = -90
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@@ -25,6 +25,8 @@
|
|||||||
#include "strutils.h"
|
#include "strutils.h"
|
||||||
#include "espchrono.h"
|
#include "espchrono.h"
|
||||||
#include "numberparsing.h"
|
#include "numberparsing.h"
|
||||||
|
#include "myota.h"
|
||||||
|
#include "espasyncota.h"
|
||||||
|
|
||||||
namespace deckenlampe {
|
namespace deckenlampe {
|
||||||
httpd_handle_t httpdHandle;
|
httpd_handle_t httpdHandle;
|
||||||
@@ -98,14 +100,16 @@ esp_err_t webserver_root_handler(httpd_req_t *req)
|
|||||||
{
|
{
|
||||||
std::string query;
|
std::string query;
|
||||||
|
|
||||||
if (const size_t queryLength = httpd_req_get_url_query_len(req)) {
|
if (const size_t queryLength = httpd_req_get_url_query_len(req))
|
||||||
|
{
|
||||||
query.resize(queryLength);
|
query.resize(queryLength);
|
||||||
CALL_AND_EXIT_ON_ERROR(httpd_req_get_url_query_str, req, query.data(), query.size() + 1)
|
CALL_AND_EXIT_ON_ERROR(httpd_req_get_url_query_str, req, query.data(), query.size() + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string body;
|
std::string body;
|
||||||
|
|
||||||
if (config::enable_lamp.value()) {
|
if (config::enable_lamp.value())
|
||||||
|
{
|
||||||
body += "<a href=\"/on\">on</a><br/>\n"
|
body += "<a href=\"/on\">on</a><br/>\n"
|
||||||
"<a href=\"/off\">off</a><br/>\n"
|
"<a href=\"/off\">off</a><br/>\n"
|
||||||
"<a href=\"/toggle\">toggle</a><br/>\n";
|
"<a href=\"/toggle\">toggle</a><br/>\n";
|
||||||
@@ -146,11 +150,14 @@ esp_err_t webserver_root_handler(httpd_req_t *req)
|
|||||||
|
|
||||||
esp_err_t webserver_dht_display(httpd_req_t *req, std::string &body)
|
esp_err_t webserver_dht_display(httpd_req_t *req, std::string &body)
|
||||||
{
|
{
|
||||||
if (config::enable_dht.value()) {
|
if (config::enable_dht.value())
|
||||||
if (lastDhtValue) {
|
{
|
||||||
|
if (lastDhtValue)
|
||||||
|
{
|
||||||
body += fmt::format("DHT11 Temperature: {:.1f} C<br/>\n", lastDhtValue->temperature);
|
body += fmt::format("DHT11 Temperature: {:.1f} C<br/>\n", lastDhtValue->temperature);
|
||||||
body += fmt::format("DHT11 Humidity: {:.1f} %<br/>\n", lastDhtValue->humidity);
|
body += fmt::format("DHT11 Humidity: {:.1f} %<br/>\n", lastDhtValue->humidity);
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
body += "DHT11 not available at the moment<br/>\n";
|
body += "DHT11 not available at the moment<br/>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,10 +166,13 @@ esp_err_t webserver_dht_display(httpd_req_t *req, std::string &body)
|
|||||||
|
|
||||||
esp_err_t webserver_tsl_display(httpd_req_t *req, std::string &body)
|
esp_err_t webserver_tsl_display(httpd_req_t *req, std::string &body)
|
||||||
{
|
{
|
||||||
if (config::enable_i2c.value() && config::enable_tsl.value()) {
|
if (config::enable_i2c.value() && config::enable_tsl.value())
|
||||||
if (lastTslValue) {
|
{
|
||||||
|
if (lastTslValue)
|
||||||
|
{
|
||||||
body += fmt::format("TSL2561 Brightness: {:.1f} lux<br/>\n", lastTslValue->lux);
|
body += fmt::format("TSL2561 Brightness: {:.1f} lux<br/>\n", lastTslValue->lux);
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
body += "TSL2561 not available at the moment<br/>\n";
|
body += "TSL2561 not available at the moment<br/>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,12 +181,15 @@ esp_err_t webserver_tsl_display(httpd_req_t *req, std::string &body)
|
|||||||
|
|
||||||
esp_err_t webserver_bmp_display(httpd_req_t *req, std::string &body)
|
esp_err_t webserver_bmp_display(httpd_req_t *req, std::string &body)
|
||||||
{
|
{
|
||||||
if (config::enable_i2c.value() && config::enable_bmp.value()) {
|
if (config::enable_i2c.value() && config::enable_bmp.value())
|
||||||
if (lastBmpValue) {
|
{
|
||||||
|
if (lastBmpValue)
|
||||||
|
{
|
||||||
body += fmt::format("BMP085 Pressure: {:.1f} lux<br/>\n", lastBmpValue->pressure);
|
body += fmt::format("BMP085 Pressure: {:.1f} lux<br/>\n", lastBmpValue->pressure);
|
||||||
body += fmt::format("BMP085 Temperature: {:.1f} C<br/>\n", lastBmpValue->temperature);
|
body += fmt::format("BMP085 Temperature: {:.1f} C<br/>\n", lastBmpValue->temperature);
|
||||||
body += fmt::format("BMP085 Altitude: {:.1f} m<br/>\n", lastBmpValue->altitude);
|
body += fmt::format("BMP085 Altitude: {:.1f} m<br/>\n", lastBmpValue->altitude);
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
body += "BMP085 not available at the moment<br/>\n";
|
body += "BMP085 not available at the moment<br/>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,21 +205,28 @@ esp_err_t webserver_wifi_display(httpd_req_t *req, std::string &body)
|
|||||||
{
|
{
|
||||||
const auto staStatus = wifi_stack::get_sta_status();
|
const auto staStatus = wifi_stack::get_sta_status();
|
||||||
body += fmt::format("<tr><th>STA status</th><td>{}</td></tr>\n", wifi_stack::toString(staStatus));
|
body += fmt::format("<tr><th>STA status</th><td>{}</td></tr>\n", wifi_stack::toString(staStatus));
|
||||||
if (staStatus == wifi_stack::WiFiStaStatus::WL_CONNECTED) {
|
if (staStatus == wifi_stack::WiFiStaStatus::WL_CONNECTED)
|
||||||
if (const auto result = wifi_stack::get_sta_ap_info(); result) {
|
{
|
||||||
|
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 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 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 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}));
|
body += fmt::format("<tr><th>STA BSSID</th><td>{}</td></tr>\n", wifi_stack::toString(wifi_stack::mac_t{result->bssid}));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
body += fmt::format("<tr><td colspan=\"2\">get_sta_ap_info() failed: {}</td></tr>\n", htmlentities(result.error()));
|
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)) {
|
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 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 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));
|
body += fmt::format("<tr><th>STA gw</th><td>{}</td></tr>\n", wifi_stack::toString(result->gw));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
body += fmt::format("<tr><td colspan=\"2\">get_ip_info() failed: {}</td></tr>\n", htmlentities(result.error()));
|
body += fmt::format("<tr><td colspan=\"2\">get_ip_info() failed: {}</td></tr>\n", htmlentities(result.error()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,7 +236,8 @@ esp_err_t webserver_wifi_display(httpd_req_t *req, std::string &body)
|
|||||||
body += "</table>\n"
|
body += "</table>\n"
|
||||||
"<h3>scan result</h3>\n";
|
"<h3>scan result</h3>\n";
|
||||||
|
|
||||||
if (const auto &scanResult = wifi_stack::get_scan_result()) {
|
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 += fmt::format("scan age: {}s<br />\n", std::chrono::round<std::chrono::seconds>(espchrono::ago(scanResult->finished)).count());
|
||||||
body += "<table border=\"1\">\n"
|
body += "<table border=\"1\">\n"
|
||||||
"<thead>\n"
|
"<thead>\n"
|
||||||
@@ -232,7 +253,8 @@ esp_err_t webserver_wifi_display(httpd_req_t *req, std::string &body)
|
|||||||
"</thead>\n"
|
"</thead>\n"
|
||||||
"<tbody>\n";
|
"<tbody>\n";
|
||||||
|
|
||||||
for (const auto &entry : scanResult->entries) {
|
for (const auto &entry : scanResult->entries)
|
||||||
|
{
|
||||||
body += fmt::format(
|
body += fmt::format(
|
||||||
"<tr>\n"
|
"<tr>\n"
|
||||||
"<td>{}</td>\n"
|
"<td>{}</td>\n"
|
||||||
@@ -254,7 +276,9 @@ esp_err_t webserver_wifi_display(httpd_req_t *req, std::string &body)
|
|||||||
|
|
||||||
body += "</tbody>\n"
|
body += "</tbody>\n"
|
||||||
"</table>\n";
|
"</table>\n";
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
body += "<span style=\"color: red;\">no wifi scan result at the moment!</span><br/>\n";
|
body += "<span style=\"color: red;\">no wifi scan result at the moment!</span><br/>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,13 +287,15 @@ esp_err_t webserver_wifi_display(httpd_req_t *req, std::string &body)
|
|||||||
|
|
||||||
esp_err_t webserver_mqtt_display(httpd_req_t *req, std::string &body)
|
esp_err_t webserver_mqtt_display(httpd_req_t *req, std::string &body)
|
||||||
{
|
{
|
||||||
if (config::enable_mqtt.value()) {
|
if (config::enable_mqtt.value())
|
||||||
|
{
|
||||||
body += "<br/>\n"
|
body += "<br/>\n"
|
||||||
"<h2>MQTT</h2>\n"
|
"<h2>MQTT</h2>\n"
|
||||||
"<table border=\"1\">\n";
|
"<table border=\"1\">\n";
|
||||||
body += fmt::format("<tr><th>client url</th><td>{}</td></tr>\n", htmlentities(config::broker_url.value()));
|
body += fmt::format("<tr><th>client url</th><td>{}</td></tr>\n", htmlentities(config::broker_url.value()));
|
||||||
body += fmt::format("<tr><th>client constructed</th><td>{}</td></tr>\n", mqttClient ? "true" : "false");
|
body += fmt::format("<tr><th>client constructed</th><td>{}</td></tr>\n", mqttClient ? "true" : "false");
|
||||||
if (mqttClient) {
|
if (mqttClient)
|
||||||
|
{
|
||||||
body += fmt::format("<tr><th>client started</th><td>{}</td></tr>\n", mqttStarted ? "true" : "false");
|
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 += fmt::format("<tr><th>client connected</th><td>{}</td></tr>\n", mqttConnected ? "true" : "false");
|
||||||
}
|
}
|
||||||
@@ -292,21 +318,27 @@ std::string webserver_form_for_config(httpd_req_t *req, ConfigWrapper<bool> &con
|
|||||||
|
|
||||||
{
|
{
|
||||||
char valueBufEncoded[256];
|
char valueBufEncoded[256];
|
||||||
if (const auto result = httpd_query_key_value(query.data(), config.nvsKey(), valueBufEncoded, 256); result == ESP_OK) {
|
if (const auto result = httpd_query_key_value(query.data(), config.nvsKey(), valueBufEncoded, 256); result == ESP_OK)
|
||||||
|
{
|
||||||
char valueBuf[257];
|
char valueBuf[257];
|
||||||
espcpputils::urldecode(valueBuf, valueBufEncoded);
|
espcpputils::urldecode(valueBuf, valueBufEncoded);
|
||||||
|
|
||||||
std::string_view value{valueBuf};
|
std::string_view value{valueBuf};
|
||||||
|
|
||||||
if (value == "true" || value == "false") {
|
if (value == "true" || value == "false")
|
||||||
|
{
|
||||||
if (const auto result = config.writeToFlash(value == "true"))
|
if (const auto result = config.writeToFlash(value == "true"))
|
||||||
str += "<span style=\"color: green;\">Successfully saved</span>";
|
str += "<span style=\"color: green;\">Successfully saved</span>";
|
||||||
else
|
else
|
||||||
str += fmt::format("<span style=\"color: red;\">Error while saving: {}</span>", htmlentities(result.error()));
|
str += fmt::format("<span style=\"color: red;\">Error while saving: {}</span>", htmlentities(result.error()));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
str += fmt::format("<span style=\"color: red;\">Error while saving: Invalid value \"{}\"</span>", htmlentities(value));
|
str += fmt::format("<span style=\"color: red;\">Error while saving: Invalid value \"{}\"</span>", htmlentities(value));
|
||||||
}
|
}
|
||||||
} else if (result != ESP_ERR_NOT_FOUND) {
|
}
|
||||||
|
else if (result != ESP_ERR_NOT_FOUND)
|
||||||
|
{
|
||||||
ESP_LOGE(TAG, "httpd_query_key_value() %s failed with %s", config.nvsKey(), esp_err_to_name(result));
|
ESP_LOGE(TAG, "httpd_query_key_value() %s failed with %s", config.nvsKey(), esp_err_to_name(result));
|
||||||
str += fmt::format("<span style=\"color: red;\">Error while saving: httpd_query_key_value() failed with {}</span>", esp_err_to_name(result));
|
str += fmt::format("<span style=\"color: red;\">Error while saving: httpd_query_key_value() failed with {}</span>", esp_err_to_name(result));
|
||||||
}
|
}
|
||||||
@@ -331,7 +363,8 @@ std::string webserver_form_for_config(httpd_req_t *req, ConfigWrapper<std::strin
|
|||||||
|
|
||||||
{
|
{
|
||||||
char valueBufEncoded[256];
|
char valueBufEncoded[256];
|
||||||
if (const auto result = httpd_query_key_value(query.data(), config.nvsKey(), valueBufEncoded, 256); result == ESP_OK) {
|
if (const auto result = httpd_query_key_value(query.data(), config.nvsKey(), valueBufEncoded, 256); result == ESP_OK)
|
||||||
|
{
|
||||||
char valueBuf[257];
|
char valueBuf[257];
|
||||||
espcpputils::urldecode(valueBuf, valueBufEncoded);
|
espcpputils::urldecode(valueBuf, valueBufEncoded);
|
||||||
|
|
||||||
@@ -339,7 +372,9 @@ std::string webserver_form_for_config(httpd_req_t *req, ConfigWrapper<std::strin
|
|||||||
str += "<span style=\"color: green;\">Successfully saved</span>";
|
str += "<span style=\"color: green;\">Successfully saved</span>";
|
||||||
else
|
else
|
||||||
str += fmt::format("<span style=\"color: red;\">Error while saving: {}</span>", htmlentities(result.error()));
|
str += fmt::format("<span style=\"color: red;\">Error while saving: {}</span>", htmlentities(result.error()));
|
||||||
} else if (result != ESP_ERR_NOT_FOUND) {
|
}
|
||||||
|
else if (result != ESP_ERR_NOT_FOUND)
|
||||||
|
{
|
||||||
ESP_LOGE(TAG, "httpd_query_key_value() %s failed with %s", config.nvsKey(), esp_err_to_name(result));
|
ESP_LOGE(TAG, "httpd_query_key_value() %s failed with %s", config.nvsKey(), esp_err_to_name(result));
|
||||||
str += fmt::format("<span style=\"color: red;\">Error while saving: httpd_query_key_value() failed with {}</span>", esp_err_to_name(result));
|
str += fmt::format("<span style=\"color: red;\">Error while saving: httpd_query_key_value() failed with {}</span>", esp_err_to_name(result));
|
||||||
}
|
}
|
||||||
@@ -362,21 +397,27 @@ std::string webserver_form_for_config(httpd_req_t *req, ConfigWrapper<gpio_num_t
|
|||||||
|
|
||||||
{
|
{
|
||||||
char valueBufEncoded[256];
|
char valueBufEncoded[256];
|
||||||
if (const auto result = httpd_query_key_value(query.data(), config.nvsKey(), valueBufEncoded, 256); result == ESP_OK) {
|
if (const auto result = httpd_query_key_value(query.data(), config.nvsKey(), valueBufEncoded, 256); result == ESP_OK)
|
||||||
|
{
|
||||||
char valueBuf[257];
|
char valueBuf[257];
|
||||||
espcpputils::urldecode(valueBuf, valueBufEncoded);
|
espcpputils::urldecode(valueBuf, valueBufEncoded);
|
||||||
|
|
||||||
std::string_view value{valueBuf};
|
std::string_view value{valueBuf};
|
||||||
|
|
||||||
if (auto parsed = cpputils::fromString<std::underlying_type_t<gpio_num_t>>(value)) {
|
if (auto parsed = cpputils::fromString<std::underlying_type_t<gpio_num_t>>(value))
|
||||||
|
{
|
||||||
if (const auto result = config.writeToFlash(gpio_num_t(*parsed)))
|
if (const auto result = config.writeToFlash(gpio_num_t(*parsed)))
|
||||||
str += "<span style=\"color: green;\">Successfully saved</span>";
|
str += "<span style=\"color: green;\">Successfully saved</span>";
|
||||||
else
|
else
|
||||||
str += fmt::format("<span style=\"color: red;\">Error while saving: {}</span>", htmlentities(result.error()));
|
str += fmt::format("<span style=\"color: red;\">Error while saving: {}</span>", htmlentities(result.error()));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
str += fmt::format("<span style=\"color: red;\">Error while saving: Invalid value \"{}\"</span>", htmlentities(value));
|
str += fmt::format("<span style=\"color: red;\">Error while saving: Invalid value \"{}\"</span>", htmlentities(value));
|
||||||
}
|
}
|
||||||
} else if (result != ESP_ERR_NOT_FOUND) {
|
}
|
||||||
|
else if (result != ESP_ERR_NOT_FOUND)
|
||||||
|
{
|
||||||
ESP_LOGE(TAG, "httpd_query_key_value() %s failed with %s", config.nvsKey(), esp_err_to_name(result));
|
ESP_LOGE(TAG, "httpd_query_key_value() %s failed with %s", config.nvsKey(), esp_err_to_name(result));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -398,21 +439,27 @@ std::string webserver_form_for_config(httpd_req_t *req, ConfigWrapper<espchrono:
|
|||||||
|
|
||||||
{
|
{
|
||||||
char valueBufEncoded[256];
|
char valueBufEncoded[256];
|
||||||
if (const auto result = httpd_query_key_value(query.data(), config.nvsKey(), valueBufEncoded, 256); result == ESP_OK) {
|
if (const auto result = httpd_query_key_value(query.data(), config.nvsKey(), valueBufEncoded, 256); result == ESP_OK)
|
||||||
|
{
|
||||||
char valueBuf[257];
|
char valueBuf[257];
|
||||||
espcpputils::urldecode(valueBuf, valueBufEncoded);
|
espcpputils::urldecode(valueBuf, valueBufEncoded);
|
||||||
|
|
||||||
std::string_view value{valueBuf};
|
std::string_view value{valueBuf};
|
||||||
|
|
||||||
if (auto parsed = cpputils::fromString<espchrono::seconds32::rep>(value)) {
|
if (auto parsed = cpputils::fromString<espchrono::seconds32::rep>(value))
|
||||||
|
{
|
||||||
if (const auto result = config.writeToFlash(espchrono::seconds32(*parsed)))
|
if (const auto result = config.writeToFlash(espchrono::seconds32(*parsed)))
|
||||||
str += "<span style=\"color: green;\">Successfully saved</span>";
|
str += "<span style=\"color: green;\">Successfully saved</span>";
|
||||||
else
|
else
|
||||||
str += fmt::format("<span style=\"color: red;\">Error while saving: {}</span>", htmlentities(result.error()));
|
str += fmt::format("<span style=\"color: red;\">Error while saving: {}</span>", htmlentities(result.error()));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
str += fmt::format("<span style=\"color: red;\">Error while saving: Invalid value \"{}\"</span>", htmlentities(value));
|
str += fmt::format("<span style=\"color: red;\">Error while saving: Invalid value \"{}\"</span>", htmlentities(value));
|
||||||
}
|
}
|
||||||
} else if (result != ESP_ERR_NOT_FOUND) {
|
}
|
||||||
|
else if (result != ESP_ERR_NOT_FOUND)
|
||||||
|
{
|
||||||
ESP_LOGE(TAG, "httpd_query_key_value() %s failed with %s", config.nvsKey(), esp_err_to_name(result));
|
ESP_LOGE(TAG, "httpd_query_key_value() %s failed with %s", config.nvsKey(), esp_err_to_name(result));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -442,7 +489,7 @@ esp_err_t webserver_config_display(httpd_req_t *req, std::string &body, std::str
|
|||||||
"</thead>\n"
|
"</thead>\n"
|
||||||
"<tbody>\n";
|
"<tbody>\n";
|
||||||
|
|
||||||
config::foreachConfig([&](auto &config){
|
config::foreachConfig([&](auto &config) {
|
||||||
using cpputils::toString;
|
using cpputils::toString;
|
||||||
using espchrono::toString;
|
using espchrono::toString;
|
||||||
|
|
||||||
@@ -456,12 +503,14 @@ esp_err_t webserver_config_display(httpd_req_t *req, std::string &body, std::str
|
|||||||
//htmlentities(toString(config.value())),
|
//htmlentities(toString(config.value())),
|
||||||
webserver_form_for_config(req, config, query),
|
webserver_form_for_config(req, config, query),
|
||||||
[&]() -> std::string {
|
[&]() -> std::string {
|
||||||
if (const auto result = config.readFromFlash()) {
|
if (const auto result = config.readFromFlash())
|
||||||
|
{
|
||||||
if (*result)
|
if (*result)
|
||||||
return htmlentities(toString(**result));
|
return htmlentities(toString(**result));
|
||||||
else
|
else
|
||||||
return "<span style=\"color: grey;\">not set</span>";
|
return "<span style=\"color: grey;\">not set</span>";
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
return fmt::format("<span style=\"color: red\">{}</span>", htmlentities(result.error()));
|
return fmt::format("<span style=\"color: red\">{}</span>", htmlentities(result.error()));
|
||||||
}());
|
}());
|
||||||
});
|
});
|
||||||
@@ -474,7 +523,8 @@ esp_err_t webserver_config_display(httpd_req_t *req, std::string &body, std::str
|
|||||||
|
|
||||||
esp_err_t webserver_on_handler(httpd_req_t *req)
|
esp_err_t webserver_on_handler(httpd_req_t *req)
|
||||||
{
|
{
|
||||||
if (!config::enable_lamp.value()) {
|
if (!config::enable_lamp.value())
|
||||||
|
{
|
||||||
ESP_LOGW(TAG, "lamp support not enabled!");
|
ESP_LOGW(TAG, "lamp support not enabled!");
|
||||||
CALL_AND_EXIT(httpd_resp_send_err, req, HTTPD_400_BAD_REQUEST, "lamp support not enabled!")
|
CALL_AND_EXIT(httpd_resp_send_err, req, HTTPD_400_BAD_REQUEST, "lamp support not enabled!")
|
||||||
}
|
}
|
||||||
@@ -492,7 +542,8 @@ esp_err_t webserver_on_handler(httpd_req_t *req)
|
|||||||
|
|
||||||
esp_err_t webserver_off_handler(httpd_req_t *req)
|
esp_err_t webserver_off_handler(httpd_req_t *req)
|
||||||
{
|
{
|
||||||
if (!config::enable_lamp.value()) {
|
if (!config::enable_lamp.value())
|
||||||
|
{
|
||||||
ESP_LOGW(TAG, "lamp support not enabled!");
|
ESP_LOGW(TAG, "lamp support not enabled!");
|
||||||
CALL_AND_EXIT(httpd_resp_send_err, req, HTTPD_400_BAD_REQUEST, "lamp support not enabled!")
|
CALL_AND_EXIT(httpd_resp_send_err, req, HTTPD_400_BAD_REQUEST, "lamp support not enabled!")
|
||||||
}
|
}
|
||||||
@@ -510,7 +561,8 @@ esp_err_t webserver_off_handler(httpd_req_t *req)
|
|||||||
|
|
||||||
esp_err_t webserver_toggle_handler(httpd_req_t *req)
|
esp_err_t webserver_toggle_handler(httpd_req_t *req)
|
||||||
{
|
{
|
||||||
if (!config::enable_lamp.value()) {
|
if (!config::enable_lamp.value())
|
||||||
|
{
|
||||||
ESP_LOGW(TAG, "lamp support not enabled!");
|
ESP_LOGW(TAG, "lamp support not enabled!");
|
||||||
CALL_AND_EXIT(httpd_resp_send_err, req, HTTPD_400_BAD_REQUEST, "lamp support not enabled!")
|
CALL_AND_EXIT(httpd_resp_send_err, req, HTTPD_400_BAD_REQUEST, "lamp support not enabled!")
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user