read config from nvs

This commit is contained in:
2021-07-15 16:38:04 +02:00
parent e720ef15d5
commit 2cd82d3413
19 changed files with 500 additions and 172 deletions

View File

@@ -2,11 +2,13 @@ idf_build_get_property(project_dir PROJECT_DIR)
message(STATUS "The project dir is: ${project_dir}")
set(headers
configwrapper.h
feature_bmp.h
feature_dht.h
feature_lamp.h
feature_switch.h
feature_tsl.h
futurecpp.h
myconfig.h
mymdns.h
mymqtt.h
@@ -15,6 +17,7 @@ set(headers
)
set(sources
configwrapper.cpp
feature_bmp.cpp
feature_dht.cpp
feature_lamp.cpp

8
main/configwrapper.cpp Normal file
View File

@@ -0,0 +1,8 @@
#include "configwrapper.h"
// system includes
// local includes
namespace deckenlampe {
} // namespace deckenlampe

150
main/configwrapper.h Normal file
View File

@@ -0,0 +1,150 @@
#pragma once
// system includes
#include <string>
#include <cstdint>
#include <utility>
// esp-idf includes
#include <nvs.h>
#include <hal/gpio_types.h>
// 3rdparty lib includes
#include <tl/expected.hpp>
#include <fmt/core.h>
// local includes
#include "espchrono.h"
#include "futurecpp.h"
namespace deckenlampe {
extern nvs_handle_t nvsHandle;
template<typename T> esp_err_t nvs_get(nvs_handle handle, const char* key, T* out_value) = delete;
template<typename T> esp_err_t nvs_set(nvs_handle handle, const char* key, T value) = delete;
template<typename T>
class ConfigWrapper
{
public:
ConfigWrapper(const char *key, const T &value) : m_key{key}, m_value{value} {}
const char *key() const { return m_key; }
const T &value() const { return m_value; }
void setValue(const T &value) { m_value = value; }
tl::expected<T, std::string> readFromFlash() const;
tl::expected<void, std::string> writeToFlash(const T &value);
private:
const char * const m_key;
T m_value;
};
template<typename T>
tl::expected<T, std::string> ConfigWrapper<T>::readFromFlash() const
{
T val;
const auto result = nvs_get(nvsHandle, m_key, &val);
//ESP_LOG_LEVEL_LOCAL((result == ESP_OK ? ESP_LOG_INFO : ESP_LOG_ERROR), TAG, "nvs_flash_init(): %s", esp_err_to_name(result));
if (result == ESP_OK)
return val;
else
return tl::make_unexpected(fmt::format("nvs_get() {} failed with {}", m_key, esp_err_to_name(result)));
}
template<typename T>
tl::expected<void, std::string> ConfigWrapper<T>::writeToFlash(const T &value)
{
return {};
}
template<> inline esp_err_t nvs_get(nvs_handle handle, const char* key, int8_t* out_value) { return nvs_get_i8 (handle, key, out_value); }
template<> inline esp_err_t nvs_get(nvs_handle handle, const char* key, uint8_t* out_value) { return nvs_get_u8 (handle, key, out_value); }
template<> inline esp_err_t nvs_get(nvs_handle handle, const char* key, int16_t* out_value) { return nvs_get_i16(handle, key, out_value); }
template<> inline esp_err_t nvs_get(nvs_handle handle, const char* key, uint16_t* out_value){ return nvs_get_u16(handle, key, out_value); }
template<> inline esp_err_t nvs_get(nvs_handle handle, const char* key, int32_t* out_value) { return nvs_get_i32(handle, key, out_value); }
template<> inline esp_err_t nvs_get(nvs_handle handle, const char* key, uint32_t* out_value){ return nvs_get_u32(handle, key, out_value); }
template<> inline esp_err_t nvs_get(nvs_handle handle, const char* key, int64_t* out_value) { return nvs_get_i64(handle, key, out_value); }
template<> inline esp_err_t nvs_get(nvs_handle handle, const char* key, uint64_t* out_value){ return nvs_get_u64(handle, key, out_value); }
template<> inline esp_err_t nvs_get(nvs_handle handle, const char* key, bool* out_value)
{
uint8_t temp;
const auto result = nvs_get(handle, key, &temp);
if (result == ESP_OK && out_value)
*out_value = temp;
return result;
}
template<> inline esp_err_t nvs_get(nvs_handle handle, const char* key, gpio_num_t* out_value)
{
std::underlying_type_t<gpio_num_t> temp;
const auto result = nvs_get(handle, key, &temp);
if (result == ESP_OK && out_value)
*out_value = gpio_num_t(temp);
return result;
}
template<> inline esp_err_t nvs_get(nvs_handle handle, const char* key, float* out_value)
{
uint32_t temp;
const auto result = nvs_get(handle, key, &temp);
if (result == ESP_OK)
*out_value = std::bit_cast<float>(temp);
return result;
}
template<> inline esp_err_t nvs_get(nvs_handle handle, const char* key, double* out_value)
{
uint64_t temp;
const auto result = nvs_get(handle, key, &temp);
if (result == ESP_OK)
*out_value = std::bit_cast<double>(temp);
return result;
}
template<> inline esp_err_t nvs_get(nvs_handle handle, const char* key, std::string* out_value)
{
size_t length;
if (const esp_err_t result = nvs_get_str(handle, key, nullptr, &length); result != ESP_OK)
return result;
char buf[length];
if (const esp_err_t result = nvs_get_str(handle, key, buf, &length); result != ESP_OK)
return result;
*out_value = buf;
return ESP_OK;
}
template<> inline esp_err_t nvs_set(nvs_handle handle, const char* key, int8_t value) { return nvs_set_i8 (handle, key, value); }
template<> inline esp_err_t nvs_set(nvs_handle handle, const char* key, uint8_t value) { return nvs_set_u8 (handle, key, value); }
template<> inline esp_err_t nvs_set(nvs_handle handle, const char* key, int16_t value) { return nvs_set_i16(handle, key, value); }
template<> inline esp_err_t nvs_set(nvs_handle handle, const char* key, uint16_t value) { return nvs_set_u16(handle, key, value); }
template<> inline esp_err_t nvs_set(nvs_handle handle, const char* key, int32_t value) { return nvs_set_i32(handle, key, value); }
template<> inline esp_err_t nvs_set(nvs_handle handle, const char* key, uint32_t value) { return nvs_set_u32(handle, key, value); }
template<> inline esp_err_t nvs_set(nvs_handle handle, const char* key, int64_t value) { return nvs_set_i64(handle, key, value); }
template<> inline esp_err_t nvs_set(nvs_handle handle, const char* key, uint64_t value) { return nvs_set_u64(handle, key, value); }
template<> inline esp_err_t nvs_set(nvs_handle handle, const char* key, bool value) { return nvs_set_u8 (handle, key, value); }
template<> inline esp_err_t nvs_set(nvs_handle handle, const char* key, gpio_num_t value) { return nvs_set (handle, key, std::to_underlying(value)); }
template<> inline esp_err_t nvs_set(nvs_handle handle, const char* key, float value) { return nvs_set(handle, key, std::bit_cast<uint32_t>(value)); }
template<> inline esp_err_t nvs_set(nvs_handle handle, const char* key, double value) { return nvs_set(handle, key, std::bit_cast<uint64_t>(value)); }
template<> inline esp_err_t nvs_set(nvs_handle handle, const char* key, const std::string &value) { return nvs_set_str(handle, key, value.c_str()); }
#define IMPLEMENT_NVS_GET_SET_CHRONO(Name) \
template<> inline esp_err_t nvs_get(nvs_handle handle, const char* key, Name* out_value) \
{ \
Name::rep temp; \
const auto result = nvs_get(handle, key, &temp); \
if (result == ESP_OK && out_value) \
*out_value = Name{temp}; \
return result; \
} \
\
template<> inline esp_err_t nvs_set(nvs_handle handle, const char* key, Name value) { return nvs_set(handle, key, Name::rep(value.count())); }
IMPLEMENT_NVS_GET_SET_CHRONO(espchrono::milliseconds32)
IMPLEMENT_NVS_GET_SET_CHRONO(espchrono::seconds32)
IMPLEMENT_NVS_GET_SET_CHRONO(espchrono::minutes32)
IMPLEMENT_NVS_GET_SET_CHRONO(espchrono::hours32)
#undef IMPLEMENT_NVS_GET_SET_CHRONO
} // namespace deckenlampe

View File

@@ -30,7 +30,7 @@ espchrono::millis_clock::time_point last_bmp085_readout;
void init_bmp()
{
if (!config::enable_i2c || !config::enable_bmp)
if (!config::enable_i2c.value() || !config::enable_bmp.value())
return;
bmp.construct(10085);
@@ -55,7 +55,7 @@ void init_bmp()
void update_bmp()
{
if (!config::enable_i2c || !config::enable_bmp)
if (!config::enable_i2c.value() || !config::enable_bmp.value())
return;
if (bmpInitialized) {
@@ -81,17 +81,17 @@ void update_bmp()
if (mqttConnected) {
if (!lastBmpValue)
mqttVerbosePub(config::topic_bmp085_availability, "online", 0, 1);
if (!lastBmpValue || espchrono::ago(last_bmp085_pressure_pub) >= config::valueUpdateInterval) {
if (mqttVerbosePub(config::topic_bmp085_pressure, fmt::format("{:.1f}", bmpValue.pressure), 0, 1) >= 0)
mqttVerbosePub(config::topic_bmp085_availability.value(), "online", 0, 1);
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)
last_bmp085_pressure_pub = espchrono::millis_clock::now();
}
if (!lastBmpValue || espchrono::ago(last_bmp085_temperature_pub) >= config::valueUpdateInterval) {
if (mqttVerbosePub(config::topic_bmp085_temperature, fmt::format("{:.1f}", bmpValue.temperature), 0, 1) >= 0)
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)
last_bmp085_temperature_pub = espchrono::millis_clock::now();
}
if (!lastBmpValue || espchrono::ago(last_bmp085_altitude_pub) >= config::valueUpdateInterval) {
if (mqttVerbosePub(config::topic_bmp085_altitude, fmt::format("{:.1f}", bmpValue.altitude), 0, 1) >= 0)
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)
last_bmp085_altitude_pub = espchrono::millis_clock::now();
}
}
@@ -107,10 +107,10 @@ void update_bmp()
}
} else {
bmpOffline:
if (lastBmpValue && espchrono::ago(lastBmpValue->timestamp) >= config::availableTimeoutTime) {
if (lastBmpValue && espchrono::ago(lastBmpValue->timestamp) >= config::availableTimeoutTime.value()) {
ESP_LOGW(TAG, "bmp timeouted");
if (mqttConnected)
mqttVerbosePub(config::topic_bmp085_availability, "offline", 0, 1);
mqttVerbosePub(config::topic_bmp085_availability.value(), "offline", 0, 1);
lastBmpValue = std::nullopt;
}
}

View File

@@ -29,10 +29,10 @@ espchrono::millis_clock::time_point last_dht11_readout;
void init_dht()
{
if (!config::enable_dht)
if (!config::enable_dht.value())
return;
dht.construct(config::pins_dht, DHT11);
dht.construct(config::pins_dht.value(), DHT11);
ESP_LOGI(TAG, "calling dht.begin()...");
dhtInitialized = dht->begin();
@@ -41,7 +41,7 @@ void init_dht()
void update_dht()
{
if (!config::enable_dht)
if (!config::enable_dht.value())
return;
if (dhtInitialized) {
@@ -62,13 +62,13 @@ void update_dht()
if (mqttConnected) {
if (!lastDhtValue)
mqttVerbosePub(config::topic_dht11_availability, "online", 0, 1);
if (!lastDhtValue || espchrono::ago(last_dht11_temperature_pub) >= config::valueUpdateInterval) {
if (mqttVerbosePub(config::topic_dht11_temperature, fmt::format("{:.1f}", dhtValue.temperature), 0, 1) >= 0)
mqttVerbosePub(config::topic_dht11_availability.value(), "online", 0, 1);
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)
last_dht11_temperature_pub = espchrono::millis_clock::now();
}
if (!lastDhtValue || espchrono::ago(last_dht11_humidity_pub) >= config::valueUpdateInterval) {
if (mqttVerbosePub(config::topic_dht11_humidity, fmt::format("{:.1f}", dhtValue.humidity), 0, 1) >= 0)
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)
last_dht11_humidity_pub = espchrono::millis_clock::now();
}
}
@@ -80,10 +80,10 @@ void update_dht()
}
} else {
dhtOffline:
if (lastDhtValue && espchrono::ago(lastDhtValue->timestamp) >= config::availableTimeoutTime) {
if (lastDhtValue && espchrono::ago(lastDhtValue->timestamp) >= config::availableTimeoutTime.value()) {
ESP_LOGW(TAG, "dht timeouted");
if (mqttConnected)
mqttVerbosePub(config::topic_dht11_availability, "offline", 0, 1);
mqttVerbosePub(config::topic_dht11_availability.value(), "offline", 0, 1);
lastDhtValue = std::nullopt;
}
}

View File

@@ -11,23 +11,23 @@ std::atomic<bool> lampState;
void init_lamp()
{
if (!config::enable_lamp)
if (!config::enable_lamp.value())
return;
pinMode(config::pins_lamp, OUTPUT);
pinMode(config::pins_lamp.value(), OUTPUT);
writeLamp(lampState);
}
void update_lamp()
{
if (!config::enable_lamp)
if (!config::enable_lamp.value())
return;
}
void writeLamp(bool state)
{
if (config::invertLamp)
if (config::invertLamp.value())
state = !state;
digitalWrite(config::pins_lamp, state ? HIGH : LOW);
digitalWrite(config::pins_lamp.value(), state ? HIGH : LOW);
}
} // namespace deckenlampe

View File

@@ -23,15 +23,15 @@ bool readSwitch();
void init_switch()
{
if (!config::enable_switch)
if (!config::enable_switch.value())
return;
pinMode(config::pins_switch, INPUT);
pinMode(config::pins_switch.value(), INPUT);
}
void update_switch()
{
if (!config::enable_switch)
if (!config::enable_switch.value())
return;
if (espchrono::ago(last_switch_readout) < 20ms)
@@ -49,14 +49,14 @@ void update_switch()
switchState = newState;
if (mqttConnected)
mqttVerbosePub(config::topic_switch_status, switchState ? "ON" : "OFF", 0, 1);
mqttVerbosePub(config::topic_switch_status.value(), switchState ? "ON" : "OFF", 0, 1);
if (config::enable_lamp) {
if (config::enable_lamp.value()) {
lampState = !lampState;
writeLamp(lampState);
if (mqttConnected)
mqttVerbosePub(config::topic_lamp_status, lampState ? "ON" : "OFF", 0, 1);
mqttVerbosePub(config::topic_lamp_status.value(), lampState ? "ON" : "OFF", 0, 1);
}
}
}
@@ -65,8 +65,8 @@ void update_switch()
namespace {
bool readSwitch()
{
bool state = digitalRead(config::pins_switch) == HIGH;
if (config::invert_switch)
bool state = digitalRead(config::pins_switch.value()) == HIGH;
if (config::invert_switch.value())
state = !state;
return state;
}

View File

@@ -28,7 +28,7 @@ espchrono::millis_clock::time_point last_tsl2561_readout;
void init_tsl()
{
if (!config::enable_i2c || !config::enable_tsl)
if (!config::enable_i2c.value() || !config::enable_tsl.value())
return;
tsl.construct(TSL2561_ADDR_FLOAT, 12345);
@@ -69,7 +69,7 @@ void init_tsl()
void update_tsl()
{
if (!config::enable_i2c || !config::enable_tsl)
if (!config::enable_i2c.value() || !config::enable_tsl.value())
return;
if (tslInitialized) {
@@ -89,9 +89,9 @@ void update_tsl()
if (mqttConnected) {
if (!lastTslValue)
mqttVerbosePub(config::topic_tsl2561_availability, "online", 0, 1);
if (!lastTslValue || espchrono::ago(last_tsl2561_lux_pub) >= config::valueUpdateInterval) {
if (mqttVerbosePub(config::topic_tsl2561_lux, fmt::format("{:.1f}", tslValue.lux), 0, 1) >= 0)
mqttVerbosePub(config::topic_tsl2561_availability.value(), "online", 0, 1);
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)
last_tsl2561_lux_pub = espchrono::millis_clock::now();
}
}
@@ -109,10 +109,10 @@ void update_tsl()
}
} else {
tslOffline:
if (lastTslValue && espchrono::ago(lastTslValue->timestamp) >= config::availableTimeoutTime) {
if (lastTslValue && espchrono::ago(lastTslValue->timestamp) >= config::availableTimeoutTime.value()) {
ESP_LOGW(TAG, "tsl timeouted");
if (mqttConnected)
mqttVerbosePub(config::topic_tsl2561_availability, "offline", 0, 1);
mqttVerbosePub(config::topic_tsl2561_availability.value(), "offline", 0, 1);
lastTslValue = std::nullopt;
}
}

29
main/futurecpp.h Normal file
View File

@@ -0,0 +1,29 @@
#pragma once
// system includes
#include <cstring>
#include <limits>
// C++20 backports (until espressif finally updates their aged compiler suite)
namespace std {
template <class To, class From>
typename std::enable_if_t<
sizeof(To) == sizeof(From) && std::is_trivially_copyable_v<From> && std::is_trivially_copyable_v<To>,
To>
// constexpr support needs compiler magic
bit_cast(const From& src) noexcept
{
static_assert(std::is_trivially_constructible_v<To>,
"This implementation additionally requires destination type to be trivially constructible");
To dst;
std::memcpy(&dst, &src, sizeof(To));
return dst;
}
template <typename EnumT, typename = std::enable_if_t<std::is_enum<EnumT>{}>>
constexpr std::underlying_type_t<EnumT> to_underlying(EnumT e) noexcept {
return static_cast<std::underlying_type_t<EnumT>>(e);
}
} // namespace std

View File

@@ -81,10 +81,10 @@ extern "C" void app_main()
init_switch();
if (config::enable_i2c)
if (config::enable_i2c.value())
{
ESP_LOGI(TAG, "calling Wire.begin()...");
const auto result = Wire.begin(config::pins_sda, config::pins_scl);
const auto result = Wire.begin(config::pins_sda.value(), config::pins_scl.value());
ESP_LOGI(TAG, "finished with %s", result ? "true" : "false");
}
@@ -104,31 +104,41 @@ extern "C" void app_main()
while (true)
{
update_config();
update_lamp();
update_wifi();
update_webserver();
update_mdns();
update_mqtt();
update_dht();
update_tsl();
update_bmp();
update_switch();
#if defined(CONFIG_ESP_TASK_WDT_PANIC) || defined(CONFIG_ESP_TASK_WDT)
if (const auto result = esp_task_wdt_reset(); result != ESP_OK)
ESP_LOGE(TAG, "esp_task_wdt_reset() failed with %s", esp_err_to_name(result));
#endif
update_config();
vPortYield();
update_lamp();
vPortYield();
update_wifi();
vPortYield();
update_webserver();
vPortYield();
update_mdns();
vPortYield();
update_mqtt();
vPortYield();
update_dht();
vPortYield();
update_tsl();
vPortYield();
update_bmp();
vPortYield();
update_switch();
vPortYield();
#ifdef CONFIG_APP_ROLLBACK_ENABLE
if (ota_state == ESP_OTA_IMG_PENDING_VERIFY)
{
@@ -138,7 +148,7 @@ extern "C" void app_main()
}
#endif
vPortYield();
vTaskDelay(std::chrono::ceil<espcpputils::ticks>(20ms).count());
}
}

View File

@@ -4,11 +4,70 @@
#include <nvs_flash.h>
#include <esp_log.h>
using namespace std::chrono_literals;
namespace deckenlampe {
nvs_handle_t nvsHandle;
namespace config {
ConfigWrapper<std::string> hostname{"hostname", "deckenlampe1"};
ConfigWrapper<std::string> sta_ssid{"sta_ssid", "ScheissAP"};
ConfigWrapper<std::string> sta_key{"sta_key", "Passwort_123"};
ConfigWrapper<std::string> ap_ssid{"ap_ssid", "deckenlampe1"};
ConfigWrapper<std::string> ap_key{"ap_key", "Passwort_123"};
ConfigWrapper<bool> enable_webserver{"enable_webserver", true};
ConfigWrapper<bool> enable_mdns{"enable_mdns", true};
ConfigWrapper<bool> enable_mqtt{"enable_mqtt", true};
ConfigWrapper<std::string> broker_url{"broker_url", "mqtt://192.168.0.2/"};
ConfigWrapper<bool> enable_lamp{"enable_lamp", true};
ConfigWrapper<gpio_num_t> pins_lamp{"pins_lamp", GPIO_NUM_4};
ConfigWrapper<bool> invertLamp{"invertLamp", true};
ConfigWrapper<std::string> topic_lamp_availability{"topic_lamp_availability", "dahoam/wohnzimmer/deckenlicht1/available"};
ConfigWrapper<std::string> topic_lamp_status{"topic_lamp_status", "dahoam/wohnzimmer/deckenlicht1/status"};
ConfigWrapper<std::string> topic_lamp_set{"topic_lamp_set", "dahoam/wohnzimmer/deckenlicht1/set"};
ConfigWrapper<bool> enable_switch{"enable_switch", true};
ConfigWrapper<gpio_num_t> pins_switch{"pins_switch", GPIO_NUM_35};
ConfigWrapper<bool> invert_switch{"invert_switch", true};
ConfigWrapper<std::string> topic_switch_availability{"topic_switch_availability", "dahoam/wohnzimmer/schalter1/available"};
ConfigWrapper<std::string> topic_switch_status{"topic_switch_status", "dahoam/wohnzimmer/schalter1/status"};
ConfigWrapper<bool> enable_dht{"enable_dht", true};
ConfigWrapper<gpio_num_t> pins_dht{"pins_dht", GPIO_NUM_33};
ConfigWrapper<std::string> topic_dht11_availability{"topic_dht11_availability", "dahoam/wohnzimmer/dht11_1/available"};
ConfigWrapper<std::string> topic_dht11_temperature{"topic_dht11_temperature", "dahoam/wohnzimmer/dht11_1/temperature"};
ConfigWrapper<std::string> topic_dht11_humidity{"topic_dht11_humidity", "dahoam/wohnzimmer/dht11_1/humidity"};
ConfigWrapper<bool> enable_i2c{"enable_i2c", true};
ConfigWrapper<gpio_num_t> pins_sda{"pins_sda", GPIO_NUM_16};
ConfigWrapper<gpio_num_t> pins_scl{"pins_scl", GPIO_NUM_17};
ConfigWrapper<bool> enable_tsl{"enable_tsl", true};
ConfigWrapper<std::string> topic_tsl2561_availability{"topic_tsl2561_availability", "dahoam/wohnzimmer/tsl2561_1/available"};
ConfigWrapper<std::string> topic_tsl2561_lux{"topic_tsl2561_lux", "dahoam/wohnzimmer/tsl2561_1/lux"};
ConfigWrapper<bool> enable_bmp{"enable_bmp", true};
ConfigWrapper<std::string> topic_bmp085_availability{"topic_bmp085_availability", "dahoam/wohnzimmer/bmp085_1/available"};
ConfigWrapper<std::string> topic_bmp085_pressure{"topic_bmp085_pressure", "dahoam/wohnzimmer/bmp085_1/pressure"};
ConfigWrapper<std::string> topic_bmp085_temperature{"topic_bmp085_temperature", "dahoam/wohnzimmer/bmp085_1/temperature"};
ConfigWrapper<std::string> topic_bmp085_altitude{"topic_bmp085_altitude", "dahoam/wohnzimmer/bmp085_1/altitude"};
ConfigWrapper<espchrono::seconds32> availableTimeoutTime{"availableTimeoutTime", 1min};
ConfigWrapper<espchrono::seconds32> valueUpdateInterval{"valueUpdateInterval", 15s};
} // namespace config
namespace {
constexpr const char * const TAG = "CONFIG";
template<typename T>
void loadParam(ConfigWrapper<T> &config);
} // namespace
void init_config()
@@ -16,21 +75,70 @@ void init_config()
{
const auto result = nvs_flash_init();
ESP_LOG_LEVEL_LOCAL((result == ESP_OK ? ESP_LOG_INFO : ESP_LOG_ERROR), TAG, "nvs_flash_init(): %s", esp_err_to_name(result));
//if (result != ESP_OK)
// return result;
if (result != ESP_OK)
return;
}
{
const auto result = nvs_open("deckenlampe", NVS_READWRITE, &nvsHandle);
ESP_LOG_LEVEL_LOCAL((result == ESP_OK ? ESP_LOG_INFO : ESP_LOG_ERROR), TAG, "nvs_open(): %s", esp_err_to_name(result));
//if (result != ESP_OK)
// return result;
constexpr const char* name = "deckenlampe";
const auto result = nvs_open(name, NVS_READWRITE, &nvsHandle);
ESP_LOG_LEVEL_LOCAL((result == ESP_OK ? ESP_LOG_INFO : ESP_LOG_ERROR), TAG, "nvs_open() %s: %s", name, esp_err_to_name(result));
if (result != ESP_OK)
return;
}
// TODO
loadParam(config::hostname);
loadParam(config::sta_ssid);
loadParam(config::sta_key);
loadParam(config::ap_ssid);
loadParam(config::ap_key);
loadParam(config::enable_webserver);
loadParam(config::enable_mdns);
loadParam(config::enable_mqtt);
loadParam(config::broker_url);
loadParam(config::enable_lamp);
loadParam(config::pins_lamp);
loadParam(config::invertLamp);
loadParam(config::topic_lamp_availability);
loadParam(config::topic_lamp_status);
loadParam(config::topic_lamp_set);
loadParam(config::enable_switch);
loadParam(config::pins_switch);
loadParam(config::invert_switch);
loadParam(config::topic_switch_availability);
loadParam(config::topic_switch_status);
loadParam(config::enable_dht);
loadParam(config::pins_dht);
loadParam(config::topic_dht11_availability);
loadParam(config::topic_dht11_temperature);
loadParam(config::topic_dht11_humidity);
loadParam(config::enable_i2c);
loadParam(config::pins_sda);
loadParam(config::pins_scl);
loadParam(config::enable_tsl);
loadParam(config::topic_tsl2561_availability);
loadParam(config::topic_tsl2561_lux);
loadParam(config::enable_bmp);
loadParam(config::topic_bmp085_availability);
loadParam(config::topic_bmp085_pressure);
loadParam(config::topic_bmp085_temperature);
loadParam(config::topic_bmp085_altitude);
loadParam(config::availableTimeoutTime);
loadParam(config::valueUpdateInterval);
}
void update_config()
{
}
namespace {
template<typename T>
void loadParam(ConfigWrapper<T> &config)
{
if (const auto value = config.readFromFlash())
config.setValue(*value);
else
ESP_LOGE(TAG, "error loading param %s: %.*s", config.key(), value.error().size(), value.error().data());
}
} // namespace
} // namespace deckenlamp

View File

@@ -1,68 +1,71 @@
#pragma once
// system includes
#include <string_view>
#include <chrono>
#include <string>
// esp-idf includes
#include <nvs.h>
#include <hal/gpio_types.h>
// local includes
#include "espchrono.h"
#include "configwrapper.h"
namespace deckenlampe {
extern nvs_handle_t nvsHandle;
namespace config {
constexpr const std::string_view hostname = "deckenlampe1";
extern ConfigWrapper<std::string> hostname;
constexpr const std::string_view sta_ssid = "ScheissAP";
constexpr const std::string_view sta_key = "Passwort_123";
extern ConfigWrapper<std::string> sta_ssid;
extern ConfigWrapper<std::string> sta_key;
constexpr const std::string_view ap_ssid = "deckenlampe1";
constexpr const std::string_view ap_key = "Passwort_123";
extern ConfigWrapper<std::string> ap_ssid;
extern ConfigWrapper<std::string> ap_key;
constexpr const bool enable_webserver = true;
extern ConfigWrapper<bool> enable_webserver;
constexpr const bool enable_mdns = true;
extern ConfigWrapper<bool> enable_mdns;
constexpr const bool enable_mqtt = true;
constexpr const std::string_view broker_url = "mqtt://192.168.0.2/";
extern ConfigWrapper<bool> enable_mqtt;
extern ConfigWrapper<std::string> broker_url;
constexpr const bool enable_lamp = true;
constexpr const gpio_num_t pins_lamp = GPIO_NUM_25;
constexpr const bool invertLamp = true;
constexpr const std::string_view topic_lamp_availability = "dahoam/wohnzimmer/deckenlicht1/available";
constexpr const std::string_view topic_lamp_status = "dahoam/wohnzimmer/deckenlicht1/status";
constexpr const std::string_view topic_lamp_set = "dahoam/wohnzimmer/deckenlicht1/set";
extern ConfigWrapper<bool> enable_lamp;
extern ConfigWrapper<gpio_num_t> pins_lamp;
extern ConfigWrapper<bool> invertLamp;
extern ConfigWrapper<std::string> topic_lamp_availability;
extern ConfigWrapper<std::string> topic_lamp_status;
extern ConfigWrapper<std::string> topic_lamp_set;
constexpr const bool enable_switch = true;
constexpr const gpio_num_t pins_switch = GPIO_NUM_35;
constexpr const bool invert_switch = true;
constexpr const std::string_view topic_switch_availability = "dahoam/wohnzimmer/schalter1/available";
constexpr const std::string_view topic_switch_status = "dahoam/wohnzimmer/schalter1/status";
extern ConfigWrapper<bool> enable_switch;
extern ConfigWrapper<gpio_num_t> pins_switch;
extern ConfigWrapper<bool> invert_switch;
extern ConfigWrapper<std::string> topic_switch_availability;
extern ConfigWrapper<std::string> topic_switch_status;
constexpr const bool enable_dht = true;
constexpr const gpio_num_t pins_dht = GPIO_NUM_33;
constexpr const std::string_view topic_dht11_availability = "dahoam/wohnzimmer/dht11_1/available";
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";
extern ConfigWrapper<bool> enable_dht;
extern ConfigWrapper<gpio_num_t> pins_dht;
extern ConfigWrapper<std::string> topic_dht11_availability;
extern ConfigWrapper<std::string> topic_dht11_temperature;
extern ConfigWrapper<std::string> topic_dht11_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;
extern ConfigWrapper<bool> enable_i2c;
extern ConfigWrapper<gpio_num_t> pins_sda;
extern ConfigWrapper<gpio_num_t> pins_scl;
constexpr const bool enable_tsl = true;
constexpr const std::string_view topic_tsl2561_availability = "dahoam/wohnzimmer/tsl2561_1/available";
constexpr const std::string_view topic_tsl2561_lux = "dahoam/wohnzimmer/tsl2561_1/lux";
extern ConfigWrapper<bool> enable_tsl;
extern ConfigWrapper<std::string> topic_tsl2561_availability;
extern ConfigWrapper<std::string> topic_tsl2561_lux;
constexpr const bool enable_bmp = true;
constexpr const std::string_view topic_bmp085_availability = "dahoam/wohnzimmer/bmp085_1/available";
constexpr const std::string_view topic_bmp085_pressure = "dahoam/wohnzimmer/bmp085_1/pressure";
constexpr const std::string_view topic_bmp085_temperature = "dahoam/wohnzimmer/bmp085_1/temperature";
constexpr const std::string_view topic_bmp085_altitude = "dahoam/wohnzimmer/bmp085_1/altitude";
extern ConfigWrapper<bool> enable_bmp;
extern ConfigWrapper<std::string> topic_bmp085_availability;
extern ConfigWrapper<std::string> topic_bmp085_pressure;
extern ConfigWrapper<std::string> topic_bmp085_temperature;
extern ConfigWrapper<std::string> topic_bmp085_altitude;
constexpr const std::chrono::minutes availableTimeoutTime{1};
constexpr const std::chrono::seconds valueUpdateInterval{15};
extern ConfigWrapper<espchrono::seconds32> availableTimeoutTime;
extern ConfigWrapper<espchrono::seconds32> valueUpdateInterval;
} // namespace configs
void init_config();

View File

@@ -14,7 +14,7 @@ constexpr const char * const TAG = "MDNS";
void init_mdns()
{
if (!config::enable_mdns)
if (!config::enable_mdns.value())
return;
{
@@ -25,20 +25,20 @@ void init_mdns()
}
{
const auto result = mdns_hostname_set(config::hostname.data());
const auto result = mdns_hostname_set(config::hostname.value().c_str());
ESP_LOG_LEVEL_LOCAL((result == ESP_OK ? ESP_LOG_INFO : ESP_LOG_ERROR), TAG, "mdns_hostname_set(): %s", esp_err_to_name(result));
//if (result != ESP_OK)
// return result;
}
{
const auto result = mdns_instance_name_set(config::hostname.data());
const auto result = mdns_instance_name_set(config::hostname.value().c_str());
ESP_LOG_LEVEL_LOCAL((result == ESP_OK ? ESP_LOG_INFO : ESP_LOG_ERROR), TAG, "mdns_instance_name_set(): %s", esp_err_to_name(result));
//if (result != ESP_OK)
// return result;
}
if (config::enable_webserver)
if (config::enable_webserver.value())
{
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));
@@ -49,7 +49,7 @@ void init_mdns()
void update_mdns()
{
if (!config::enable_mdns)
if (!config::enable_mdns.value())
return;
}
} // namespace deckenlampe

View File

@@ -28,11 +28,11 @@ void mqttEventHandler(void *event_handler_arg, esp_event_base_t event_base, int3
void init_mqtt()
{
if (!config::enable_mqtt)
if (!config::enable_mqtt.value())
return;
esp_mqtt_client_config_t mqtt_cfg = {
.uri = config::broker_url.data(),
.uri = config::broker_url.value().data(),
};
mqttClient = espcpputils::mqtt_client{&mqtt_cfg};
@@ -62,13 +62,19 @@ void init_mqtt()
void update_mqtt()
{
if (!config::enable_mqtt)
if (!config::enable_mqtt.value())
return;
}
int mqttVerbosePub(std::string_view topic, std::string_view value, int qos, int retain)
{
ESP_LOGD(TAG, "topic=\"%.*s\" value=\"%.*s\"", topic.size(), topic.data(), value.size(), value.data());
if (!mqttClient) {
ESP_LOGE(TAG, "mqttClient not constructed!");
return -1;
}
const auto pending_msg_id = mqttClient.publish(topic, value, qos, retain);
if (pending_msg_id < 0)
ESP_LOGE(TAG, "topic=\"%.*s\" value=\"%.*s\" failed pending_msg_id=%i", topic.size(), topic.data(), value.size(), value.data(), pending_msg_id);
@@ -104,43 +110,43 @@ void mqttEventHandler(void *event_handler_arg, esp_event_base_t event_base, int3
mqttConnected = true;
if (config::enable_lamp) {
mqttVerbosePub(config::topic_lamp_availability, "online", 0, 1);
mqttVerbosePub(config::topic_lamp_status, lampState.load() ? "ON" : "OFF", 0, 1);
mqttClient.subscribe(config::topic_lamp_set, 0);
if (config::enable_lamp.value()) {
mqttVerbosePub(config::topic_lamp_availability.value(), "online", 0, 1);
mqttVerbosePub(config::topic_lamp_status.value(), lampState.load() ? "ON" : "OFF", 0, 1);
mqttClient.subscribe(config::topic_lamp_set.value(), 0);
}
if (config::enable_switch) {
mqttVerbosePub(config::topic_switch_availability, "online", 0, 1);
mqttVerbosePub(config::topic_switch_status, switchState.load() ? "ON" : "OFF", 0, 1);
if (config::enable_switch.value()) {
mqttVerbosePub(config::topic_switch_availability.value(), "online", 0, 1);
mqttVerbosePub(config::topic_switch_status.value(), switchState.load() ? "ON" : "OFF", 0, 1);
}
if (config::enable_dht) {
mqttVerbosePub(config::topic_dht11_availability, lastDhtValue ? "online" : "offline", 0, 1);
if (config::enable_dht.value()) {
mqttVerbosePub(config::topic_dht11_availability.value(), lastDhtValue ? "online" : "offline", 0, 1);
if (lastDhtValue) {
if (mqttVerbosePub(config::topic_dht11_temperature, 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();
if (mqttVerbosePub(config::topic_dht11_humidity, fmt::format("{:.1f}", lastDhtValue->humidity), 0, 1) >= 0)
if (mqttVerbosePub(config::topic_dht11_humidity.value(), fmt::format("{:.1f}", lastDhtValue->humidity), 0, 1) >= 0)
last_dht11_humidity_pub = espchrono::millis_clock::now();
}
}
if (config::enable_i2c && config::enable_tsl) {
mqttVerbosePub(config::topic_tsl2561_availability, lastTslValue ? "online" : "offline", 0, 1);
if (config::enable_i2c.value() && config::enable_tsl.value()) {
mqttVerbosePub(config::topic_tsl2561_availability.value(), lastTslValue ? "online" : "offline", 0, 1);
if (lastTslValue) {
if (mqttVerbosePub(config::topic_tsl2561_lux, 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();
}
}
if (config::enable_i2c && config::enable_bmp) {
mqttVerbosePub(config::topic_bmp085_availability, lastBmpValue ? "online" : "offline", 0, 1);
if (config::enable_i2c.value() && config::enable_bmp.value()) {
mqttVerbosePub(config::topic_bmp085_availability.value(), lastBmpValue ? "online" : "offline", 0, 1);
if (lastBmpValue) {
if (mqttVerbosePub(config::topic_bmp085_pressure, 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();
if (mqttVerbosePub(config::topic_bmp085_temperature, fmt::format("{:.1f}", lastBmpValue->temperature), 0, 1) >= 0)
if (mqttVerbosePub(config::topic_bmp085_temperature.value(), fmt::format("{:.1f}", lastBmpValue->temperature), 0, 1) >= 0)
last_bmp085_temperature_pub = espchrono::millis_clock::now();
if (mqttVerbosePub(config::topic_bmp085_altitude, fmt::format("{:.1f}", lastBmpValue->altitude), 0, 1) >= 0)
if (mqttVerbosePub(config::topic_bmp085_altitude.value(), fmt::format("{:.1f}", lastBmpValue->altitude), 0, 1) >= 0)
last_bmp085_altitude_pub = espchrono::millis_clock::now();
}
}
@@ -172,12 +178,12 @@ 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());
if (topic == config::topic_lamp_set) {
if (config::enable_lamp) {
if (topic == config::topic_lamp_set.value()) {
if (config::enable_lamp.value()) {
bool newState = (lampState = (value == "ON"));
writeLamp(newState);
if (mqttConnected)
mqttVerbosePub(config::topic_lamp_status, newState ? "ON" : "OFF", 0, 1);
mqttVerbosePub(config::topic_lamp_status.value(), newState ? "ON" : "OFF", 0, 1);
} else {
ESP_LOGW(TAG, "received lamp set without lamp support enabled!");
}

View File

@@ -24,9 +24,9 @@ wifi_stack::config makeWifiConfig()
{
return wifi_stack::config {
.wifiEnabled = true,
.hostname = std::string{config::hostname},
.hostname = config::hostname.value(),
.wifis = std::array<wifi_stack::wifi_entry, 10> {
wifi_stack::wifi_entry { .ssid = std::string{config::sta_ssid}, .key = std::string{config::sta_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 = {} },
@@ -47,16 +47,16 @@ wifi_stack::config makeWifiConfig()
},
.ap = {
{
.ssid = std::string{config::ap_ssid},
.key = std::string{config::ap_key}
.ssid = config::ap_ssid.value(),
.key = config::ap_key.value()
},
.channel = 1,
.authmode = WIFI_AUTH_WPA2_PSK,
.ssid_hidden = false,
.max_connection = 4,
.beacon_interval = 100,
.ip{192, 168, 4, 1},
.subnet{255, 255, 255, 0}
.ip = ap_ip,
.subnet = ap_subnet
},
.min_rssi = -90
};

View File

@@ -1,6 +1,12 @@
#pragma once
// local includes
#include "espwifiutils.h"
namespace deckenlampe {
constexpr const wifi_stack::ip_address_t ap_ip{192, 168, 4, 1};
constexpr const wifi_stack::ip_address_t ap_subnet{255, 255, 255, 0};
void init_wifi();
void update_wifi();
} // namespace deckenlampe

View File

@@ -38,11 +38,12 @@ esp_err_t webserver_reboot_handler(httpd_req_t *req);
void init_webserver()
{
if (!config::enable_webserver)
if (!config::enable_webserver.value())
return;
{
httpd_config_t httpConfig HTTPD_DEFAULT_CONFIG();
httpConfig.core_id = 1;
const auto result = httpd_start(&httpdHandle, &httpConfig);
ESP_LOG_LEVEL_LOCAL((result == ESP_OK ? ESP_LOG_INFO : ESP_LOG_ERROR), TAG, "httpd_start(): %s", esp_err_to_name(result));
@@ -67,7 +68,7 @@ void init_webserver()
void update_webserver()
{
if (!config::enable_webserver)
if (!config::enable_webserver.value())
return;
}
@@ -92,7 +93,7 @@ esp_err_t webserver_root_handler(httpd_req_t *req)
{
std::string body = "this is work in progress...<br/>\n";
if (config::enable_lamp) {
if (config::enable_lamp.value()) {
body += "<a href=\"/on\">on</a><br/>\n"
"<a href=\"/off\">off</a><br/>\n"
"<a href=\"/toggle\">toggle</a><br/>\n";
@@ -101,13 +102,13 @@ esp_err_t webserver_root_handler(httpd_req_t *req)
body += "<a href=\"/reboot\">reboot</a><br/>\n"
"<br/>\n";
if (config::enable_lamp)
if (config::enable_lamp.value())
body += fmt::format("Lamp: {}<br/>\n", lampState ? "ON" : "OFF");
if (config::enable_switch)
if (config::enable_switch.value())
body += fmt::format("Switch: {}<br/>\n", switchState ? "ON" : "OFF");
if (config::enable_dht) {
if (config::enable_dht.value()) {
if (lastDhtValue) {
body += fmt::format("DHT11 Temperature: {:.1f} C<br/>\n", lastDhtValue->temperature);
body += fmt::format("DHT11 Humidity: {:.1f} %<br/>\n", lastDhtValue->humidity);
@@ -115,14 +116,14 @@ esp_err_t webserver_root_handler(httpd_req_t *req)
body += "DHT11 not available at the moment<br/>\n";
}
if (config::enable_i2c && config::enable_tsl) {
if (config::enable_i2c.value() && config::enable_tsl.value()) {
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_i2c && config::enable_bmp) {
if (config::enable_i2c.value() && config::enable_bmp.value()) {
if (lastBmpValue) {
body += fmt::format("BMP085 Pressure: {:.1f} lux<br/>\n", lastBmpValue->pressure);
body += fmt::format("BMP085 Temperature: {:.1f} C<br/>\n", lastBmpValue->temperature);
@@ -205,16 +206,18 @@ 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";
}
if (config::enable_mqtt.value()) {
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 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");
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())
@@ -224,7 +227,7 @@ esp_err_t webserver_root_handler(httpd_req_t *req)
esp_err_t webserver_on_handler(httpd_req_t *req)
{
if (!config::enable_lamp) {
if (!config::enable_lamp.value()) {
ESP_LOGW(TAG, "lamp support not enabled!");
CALL_AND_EXIT_ON_ERROR(httpd_resp_send_err, req, HTTPD_400_BAD_REQUEST, "lamp support not enabled!")
}
@@ -233,7 +236,7 @@ esp_err_t webserver_on_handler(httpd_req_t *req)
writeLamp(state);
if (mqttConnected)
mqttVerbosePub(config::topic_lamp_status, state ? "ON" : "OFF", 0, 1);
mqttVerbosePub(config::topic_lamp_status.value(), state ? "ON" : "OFF", 0, 1);
std::string_view body{"ON called..."};
CALL_AND_EXIT_ON_ERROR(httpd_resp_set_type, req, "text/html")
@@ -244,7 +247,7 @@ esp_err_t webserver_on_handler(httpd_req_t *req)
esp_err_t webserver_off_handler(httpd_req_t *req)
{
if (!config::enable_lamp) {
if (!config::enable_lamp.value()) {
ESP_LOGW(TAG, "lamp support not enabled!");
CALL_AND_EXIT_ON_ERROR(httpd_resp_send_err, req, HTTPD_400_BAD_REQUEST, "lamp support not enabled!")
}
@@ -253,7 +256,7 @@ esp_err_t webserver_off_handler(httpd_req_t *req)
writeLamp(state);
if (mqttConnected)
mqttVerbosePub(config::topic_lamp_status, state ? "ON" : "OFF", 0, 1);
mqttVerbosePub(config::topic_lamp_status.value(), state ? "ON" : "OFF", 0, 1);
std::string_view body{"OFF called..."};
CALL_AND_EXIT_ON_ERROR(httpd_resp_set_type, req, "text/html")
@@ -264,7 +267,7 @@ esp_err_t webserver_off_handler(httpd_req_t *req)
esp_err_t webserver_toggle_handler(httpd_req_t *req)
{
if (!config::enable_lamp) {
if (!config::enable_lamp.value()) {
ESP_LOGW(TAG, "lamp support not enabled!");
CALL_AND_EXIT_ON_ERROR(httpd_resp_send_err, req, HTTPD_400_BAD_REQUEST, "lamp support not enabled!")
}
@@ -273,7 +276,7 @@ esp_err_t webserver_toggle_handler(httpd_req_t *req)
writeLamp(state);
if (mqttConnected)
mqttVerbosePub(config::topic_lamp_status, state ? "ON" : "OFF", 0, 1);
mqttVerbosePub(config::topic_lamp_status.value(), state ? "ON" : "OFF", 0, 1);
std::string_view body{"TOGGLE called..."};
CALL_AND_EXIT_ON_ERROR(httpd_resp_set_type, req, "text/html")

View File

@@ -976,7 +976,9 @@ CONFIG_MDNS_TIMER_PERIOD_MS=100
# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set
# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set
# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set
# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set
CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED=y
# CONFIG_MQTT_USE_CORE_0 is not set
CONFIG_MQTT_USE_CORE_1=y
# CONFIG_MQTT_CUSTOM_OUTBOX is not set
# end of ESP-MQTT Configurations