mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2026-01-28 17:49:08 +03:00
Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev
This commit is contained in:
@@ -636,15 +636,15 @@ void EMSESPShell::stopped() {
|
||||
// show welcome banner
|
||||
void EMSESPShell::display_banner() {
|
||||
println();
|
||||
printfln("┌──────────────────────────────────────────┐");
|
||||
printfln("│ %sEMS-ESP version %-12s%s │", COLOR_BOLD_ON, EMSESP_APP_VERSION, COLOR_BOLD_OFF);
|
||||
printfln("│ │");
|
||||
printfln("│ %shelp%s to show available commands │", COLOR_UNDERLINE, COLOR_RESET);
|
||||
printfln("│ %ssu%s to access admin commands │", COLOR_UNDERLINE, COLOR_RESET);
|
||||
printfln("│ │");
|
||||
printfln("│ %s%shttps://github.com/emsesp/EMS-ESP32%s │", COLOR_BRIGHT_GREEN, COLOR_UNDERLINE, COLOR_RESET);
|
||||
printfln("│ │");
|
||||
printfln("└──────────────────────────────────────────┘");
|
||||
printfln("┌───────────────────────────────────────┐");
|
||||
printfln("│ %sEMS-ESP version %-20s%s │", COLOR_BOLD_ON, EMSESP_APP_VERSION, COLOR_BOLD_OFF);
|
||||
printfln("│ │");
|
||||
printfln("│ %shelp%s to show available commands │", COLOR_UNDERLINE, COLOR_RESET);
|
||||
printfln("│ %ssu%s to access admin commands │", COLOR_UNDERLINE, COLOR_RESET);
|
||||
printfln("│ │");
|
||||
printfln("│ %s%shttps://github.com/emsesp/EMS-ESP32%s │", COLOR_BRIGHT_GREEN, COLOR_UNDERLINE, COLOR_RESET);
|
||||
printfln("│ │");
|
||||
printfln("└───────────────────────────────────────┘");
|
||||
println();
|
||||
|
||||
// set console name
|
||||
|
||||
@@ -218,7 +218,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef EMSESP_DEFAULT_ENTITY_FORMAT
|
||||
#define EMSESP_DEFAULT_ENTITY_FORMAT 1 // in MQTT discovery, use shortnames and not multiple (prefixed with base)
|
||||
#define EMSESP_DEFAULT_ENTITY_FORMAT 1 // in MQTT discovery, single instance, shortname (EntityFormat::SINGLE_SHORT)
|
||||
#endif
|
||||
|
||||
// matches Web UI settings
|
||||
@@ -241,13 +241,13 @@ enum {
|
||||
};
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#define EMSESP_PLATFORM "ESP32-C3";
|
||||
#define EMSESP_PLATFORM "ESP32-C3"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#define EMSESP_PLATFORM "ESP32-S2";
|
||||
#define EMSESP_PLATFORM "ESP32-S2"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#define EMSESP_PLATFORM "ESP32-S3";
|
||||
#define EMSESP_PLATFORM "ESP32-S3"
|
||||
#elif CONFIG_IDF_TARGET_ESP32 || EMSESP_STANDALONE
|
||||
#define EMSESP_PLATFORM "ESP32";
|
||||
#define EMSESP_PLATFORM "ESP32"
|
||||
#else
|
||||
#error Target CONFIG_IDF_TARGET is not supported
|
||||
#endif
|
||||
|
||||
@@ -1730,15 +1730,10 @@ void Boiler::process_UBASetPoints(std::shared_ptr<const Telegram> telegram) {
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
// 0x35 - not yet implemented, not readable, only for settings
|
||||
void Boiler::process_UBAFlags(std::shared_ptr<const Telegram> telegram) {
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// 0x1C
|
||||
// 08 00 1C 94 0B 0A 1D 31 08 00 80 00 00 00 -> message for 29.11.2020
|
||||
// 08 00 1C 94 0B 0A 1D 31 00 00 00 00 00 00 -> message reset
|
||||
|
||||
@@ -187,9 +187,6 @@ void Heatpump::process_HPMonitor2(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, airHumidity_, 1);
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
/*
|
||||
* Type 0x42B- HeatPump Monitor 1
|
||||
* e.g. "38 10 FF 00 03 2B 00 D1 08 2A 01"
|
||||
@@ -198,8 +195,6 @@ void Heatpump::process_HPMonitor1(std::shared_ptr<const Telegram> telegram) {
|
||||
// still to implement
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// 0x09A0
|
||||
// Heatpump(0x53) -> All(0x00), ?(0x09A0), data: 02 23 01 3E 01 39 00 5D 01 DE 01 38 00 40 00 5E 00 58 00 3F 01 34 00 02
|
||||
void Heatpump::process_HPTemperature(std::shared_ptr<const Telegram> telegram) {
|
||||
|
||||
@@ -162,9 +162,6 @@ void Heatsource::process_amSettingMessage(std::shared_ptr<const Telegram> telegr
|
||||
has_update(telegram, releaseWait_, 15); // pos 15: Boiler release wait time (min)
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
// 0x054F AM200 not broadcasted message, 7 bytes long
|
||||
// Boiler(0x60) -> Me(0x0B), amCommand(0x054F), data: 00 00 00 00 00 00 00
|
||||
void Heatsource::process_amCommandMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
@@ -182,8 +179,6 @@ void Heatsource::process_amExtraMessage(std::shared_ptr<const Telegram> telegram
|
||||
has_update(telegram, blockRemainWw_, 25); // minutes
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// Settings AM200
|
||||
|
||||
// pos 12: off(00)/Keelbypass(01)/(hc1pump(02) only standalone)
|
||||
|
||||
@@ -154,9 +154,6 @@ void Mixer::process_MMPLUSConfigMessage_HC(std::shared_ptr<const Telegram> teleg
|
||||
has_update(telegram, flowTempOffset_, 2); // Mixer increase [0-20 K]
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
// Thermostat(0x10) -> Mixer(0x20), ?(0x2E1), data: 01 1C 64 00 01
|
||||
// Thermostat(0x10) -> Mixing Module(0x20), (0x2E1), data: 01 00 00 00 01
|
||||
// Thermostat(0x10) -> Mixing Module(0x20), (0x2EB), data: 00
|
||||
@@ -180,8 +177,6 @@ void Mixer::process_IPMSetMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
// pos 1: pump in %?
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
bool Mixer::set_flowSetTemp(const char * value, const int8_t id) {
|
||||
int v;
|
||||
if (!Helpers::value2number(value, v)) {
|
||||
|
||||
@@ -614,9 +614,6 @@ void Thermostat::process_RC10Set(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, heatingpid_, 6);
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
// type 0xB2, mode setting Data: 04 00
|
||||
// not used, we read mode from monitor 0xB1
|
||||
void Thermostat::process_RC10Set_2(std::shared_ptr<const Telegram> telegram) {
|
||||
@@ -629,8 +626,6 @@ void Thermostat::process_RC10Set_2(std::shared_ptr<const Telegram> telegram) {
|
||||
// has_update(hc->mode, mode >> 1); // store as enum 0, 1, 2
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// 0xA8 - for reading the mode from the RC20 thermostat (0x17)
|
||||
// RC20Set(0xA8), data: 01 00 FF F6 01 06 00 01 0D 01 00 FF FF 01 02 02 02 00 00 05 1E 05 1E 02 1C 00 FF 00 00 26 02
|
||||
void Thermostat::process_RC20Set(std::shared_ptr<const Telegram> telegram) {
|
||||
@@ -1613,7 +1608,7 @@ void Thermostat::process_RCTime(std::shared_ptr<const Telegram> telegram) {
|
||||
tm_->tm_isdst = -1; // determine dst
|
||||
ttime = mktime(tm_); // thermostat time
|
||||
}
|
||||
struct timeval newnow = {.tv_sec = ttime};
|
||||
struct timeval newnow = {.tv_sec = ttime, .tv_usec = 0};
|
||||
settimeofday(&newnow, nullptr);
|
||||
LOG_INFO("ems-esp time set from thermostat");
|
||||
}
|
||||
|
||||
@@ -168,14 +168,11 @@ void Water::process_SM100wwStatus2(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, wwPumpMod_, 9);
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
// SM100wwCommand - 0x07AB
|
||||
// Thermostat(0x10) -> Solar Module(0x2A), (0x7AB), data: 01 00 01
|
||||
void Water::process_SM100wwCommand(std::shared_ptr<const Telegram> telegram) {
|
||||
// not implemented yet
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
/*
|
||||
* MM100 messages
|
||||
|
||||
@@ -1701,7 +1701,7 @@ bool EMSdevice::generate_values(JsonObject output, const int8_t tag_filter, cons
|
||||
char time_s[60];
|
||||
snprintf(time_s,
|
||||
sizeof(time_s),
|
||||
"%d %s %d %s %d %s",
|
||||
"%lu %s %lu %s %lu %s",
|
||||
(time_value / 1440),
|
||||
Helpers::translated_word(FL_(days)),
|
||||
((time_value % 1440) / 60),
|
||||
|
||||
@@ -37,12 +37,14 @@ WebSettingsService EMSESP::webSettingsService = WebSettingsService(&we
|
||||
WebCustomizationService EMSESP::webCustomizationService = WebCustomizationService(&webServer, &dummyFS, EMSESP::esp8266React.getSecurityManager());
|
||||
WebSchedulerService EMSESP::webSchedulerService = WebSchedulerService(&webServer, &dummyFS, EMSESP::esp8266React.getSecurityManager());
|
||||
WebCustomEntityService EMSESP::webCustomEntityService = WebCustomEntityService(&webServer, &dummyFS, EMSESP::esp8266React.getSecurityManager());
|
||||
WebModulesService EMSESP::webModulesService = WebModulesService(&webServer, &dummyFS, EMSESP::esp8266React.getSecurityManager());
|
||||
#else
|
||||
ESP8266React EMSESP::esp8266React(&webServer, &LittleFS);
|
||||
WebSettingsService EMSESP::webSettingsService = WebSettingsService(&webServer, &LittleFS, EMSESP::esp8266React.getSecurityManager());
|
||||
WebCustomizationService EMSESP::webCustomizationService = WebCustomizationService(&webServer, &LittleFS, EMSESP::esp8266React.getSecurityManager());
|
||||
WebSchedulerService EMSESP::webSchedulerService = WebSchedulerService(&webServer, &LittleFS, EMSESP::esp8266React.getSecurityManager());
|
||||
WebCustomEntityService EMSESP::webCustomEntityService = WebCustomEntityService(&webServer, &LittleFS, EMSESP::esp8266React.getSecurityManager());
|
||||
WebModulesService EMSESP::webModulesService = WebModulesService(&webServer, &LittleFS, EMSESP::esp8266React.getSecurityManager());
|
||||
#endif
|
||||
|
||||
WebActivityService EMSESP::webActivityService = WebActivityService(&webServer, EMSESP::esp8266React.getSecurityManager());
|
||||
@@ -1589,7 +1591,7 @@ void EMSESP::start() {
|
||||
nvs_.begin("ems-esp", false, "nvs"); // fallback to small nvs
|
||||
}
|
||||
#ifndef EMSESP_STANDALONE
|
||||
LOG_INFO("Starting EMS-ESP version %s from partition %s", EMSESP_APP_VERSION, esp_ota_get_running_partition()->label); // welcome message
|
||||
LOG_INFO("Starting EMS-ESP version %s from %s partition", EMSESP_APP_VERSION, esp_ota_get_running_partition()->label); // welcome message
|
||||
#else
|
||||
LOG_INFO("Starting EMS-ESP version %s", EMSESP_APP_VERSION); // welcome message
|
||||
#endif
|
||||
@@ -1634,6 +1636,8 @@ void EMSESP::start() {
|
||||
analogsensor_.start(); // Analog external sensors
|
||||
webLogService.start(); // apply settings to weblog service
|
||||
|
||||
webModulesService.begin(); // setup the external library modules
|
||||
|
||||
// Load our library of known devices into stack mem. Names are stored in Flash memory
|
||||
device_library_ = {
|
||||
#include "device_library.h"
|
||||
@@ -1663,6 +1667,7 @@ void EMSESP::loop() {
|
||||
publish_all_loop(); // with HA messages in parts to avoid flooding the mqtt queue
|
||||
mqtt_.loop(); // sends out anything in the MQTT queue
|
||||
webSchedulerService.loop(); // handle any scheduled jobs
|
||||
webModulesService.loop(); // loop through the external library modules
|
||||
|
||||
// force a query on the EMS devices to fetch latest data at a set interval (1 min)
|
||||
scheduled_fetch_values();
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "web/WebAPIService.h"
|
||||
#include "web/WebLogService.h"
|
||||
#include "web/WebCustomEntityService.h"
|
||||
#include "web/WebModulesService.h"
|
||||
|
||||
#include "emsdevicevalue.h"
|
||||
#include "emsdevice.h"
|
||||
@@ -65,6 +66,10 @@
|
||||
#include "command.h"
|
||||
#include "version.h"
|
||||
|
||||
// Load external modules
|
||||
class Module {}; // forward declaration
|
||||
#include <ModuleLibrary.h>
|
||||
|
||||
#define WATCH_ID_NONE 0 // no watch id set
|
||||
|
||||
// helpers for callback functions
|
||||
@@ -230,6 +235,7 @@ class EMSESP {
|
||||
static WebCustomizationService webCustomizationService;
|
||||
static WebSchedulerService webSchedulerService;
|
||||
static WebCustomEntityService webCustomEntityService;
|
||||
static WebModulesService webModulesService;
|
||||
|
||||
private:
|
||||
static std::string device_tostring(const uint8_t device_id);
|
||||
@@ -275,7 +281,6 @@ class EMSESP {
|
||||
#endif
|
||||
|
||||
protected:
|
||||
// EMSESP();
|
||||
static uuid::log::Logger logger_;
|
||||
};
|
||||
|
||||
|
||||
42
src/mqtt.cpp
42
src/mqtt.cpp
@@ -676,14 +676,14 @@ bool Mqtt::queue_publish(const std::string & topic, const std::string & payload)
|
||||
return queue_publish_message(topic, payload, mqtt_retain_);
|
||||
}
|
||||
|
||||
// MQTT Publish, using a user's retain flag - except for char * strings
|
||||
// MQTT Publish, using a user's retain flag - except for char * strings payload
|
||||
bool Mqtt::queue_publish(const char * topic, const char * payload) {
|
||||
return queue_publish_message((topic), payload, mqtt_retain_);
|
||||
return queue_publish_message(topic, payload, mqtt_retain_);
|
||||
}
|
||||
|
||||
// MQTT Publish, using a specific retain flag, topic is a flash string
|
||||
// MQTT Publish, using a user's retain flag - std::string payload
|
||||
bool Mqtt::queue_publish(const char * topic, const std::string & payload) {
|
||||
return queue_publish_message((topic), payload, mqtt_retain_);
|
||||
return queue_publish_message(topic, payload, mqtt_retain_);
|
||||
}
|
||||
|
||||
bool Mqtt::queue_publish(const char * topic, const JsonObjectConst payload) {
|
||||
@@ -697,7 +697,7 @@ bool Mqtt::queue_publish(const std::string & topic, const JsonObjectConst payloa
|
||||
|
||||
// MQTT Publish, using a specific retain flag, topic is a flash string, forcing retain flag
|
||||
bool Mqtt::queue_publish_retain(const char * topic, const std::string & payload, const bool retain) {
|
||||
return queue_publish_message((topic), payload, retain);
|
||||
return queue_publish_message(topic, payload, retain);
|
||||
}
|
||||
|
||||
// publish json doc, only if its not empty, using the retain flag
|
||||
@@ -841,18 +841,23 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
||||
|
||||
// build unique identifier also used as object_id which also becomes the Entity ID in HA
|
||||
char uniq_id[80];
|
||||
|
||||
// list of boiler entities that need conversion for 3.6 compatibility, add ww suffix
|
||||
// used when entity_format is SINGLE_OLD or MULTI_OLD to keep with 3.6.5
|
||||
// see #1714 - https://github.com/emsesp/EMS-ESP32/issues/1714
|
||||
const char * dhw_old[] =
|
||||
{FL_(nrgWw)[0], FL_(upTimeCompWw)[0], FL_(nrgConsCompWw)[0], FL_(auxElecHeatNrgConsWw)[0], FL_(nrgSuppWw)[0], FL_(wwAltOpPrioWw)[0], FL_(hpCircPumpWw)[0]};
|
||||
uint8_t num_dhw_old = sizeof(dhw_old) / sizeof(dhw_old[0]);
|
||||
|
||||
// create the uniq_d based on the entity format
|
||||
if (Mqtt::entity_format() == entityFormat::MULTI_SHORT) {
|
||||
// prefix base name to each uniq_id and use the shortname
|
||||
// base name + shortname
|
||||
snprintf(uniq_id, sizeof(uniq_id), "%s_%s_%s", mqtt_basename_.c_str(), device_name, entity_with_tag);
|
||||
} else if (Mqtt::entity_format() == entityFormat::SINGLE_SHORT) {
|
||||
// shortname, no mqtt base. This is the default version.
|
||||
// shortname (default)
|
||||
snprintf(uniq_id, sizeof(uniq_id), "%s_%s", device_name, entity_with_tag);
|
||||
} else if (Mqtt::entity_format() == entityFormat::SINGLE_OLD) {
|
||||
// shortname, remap to 3.6.
|
||||
// shortname, remap to 3.6
|
||||
if (has_tag && (device_type == EMSdevice::DeviceType::BOILER || device_type == EMSdevice::DeviceType::THERMOSTAT)
|
||||
&& tag == DeviceValue::DeviceValueTAG::TAG_DHW1) {
|
||||
snprintf(entity_with_tag, sizeof(entity_with_tag), "ww%s", entity);
|
||||
@@ -872,7 +877,7 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
||||
snprintf(uniq_id, sizeof(uniq_id), "%s_%s", device_name, entity_with_tag);
|
||||
}
|
||||
} else if (Mqtt::entity_format() == entityFormat::MULTI_OLD) {
|
||||
// shortname, remap to 3.6.
|
||||
// base name + shortname, remap to 3.6
|
||||
if (has_tag && (device_type == EMSdevice::DeviceType::BOILER || device_type == EMSdevice::DeviceType::THERMOSTAT)
|
||||
&& tag == DeviceValue::DeviceValueTAG::TAG_DHW1) {
|
||||
snprintf(entity_with_tag, sizeof(entity_with_tag), "ww%s", entity);
|
||||
@@ -1176,8 +1181,11 @@ void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, con
|
||||
doc[sc_ha] = F_(measurement);
|
||||
break;
|
||||
case DeviceValueUOM::WH:
|
||||
// https://github.com/emsesp/EMS-ESP32/issues/1796
|
||||
if (entity == FL_(energyToday)[0]) {
|
||||
doc[sc_ha] = F_(total_increasing);
|
||||
} else if (entity == FL_(energyLastHour)[0]) {
|
||||
doc[sc_ha] = "total";
|
||||
} else {
|
||||
doc[sc_ha] = F_(measurement);
|
||||
}
|
||||
@@ -1388,19 +1396,17 @@ void Mqtt::add_ha_sections_to_doc(const char * name,
|
||||
|
||||
char tpl[150];
|
||||
|
||||
// make local copy of state, as the pointer will get derefenced
|
||||
char state[50];
|
||||
strcpy(state, state_t);
|
||||
|
||||
// skip conditional Jinja2 templates if not home assistant
|
||||
if (discovery_type() == discoveryType::HOMEASSISTANT) {
|
||||
// EMS-ESP status check
|
||||
// snprintf(tpl, sizeof(tpl), "%s/status", Mqtt::base().c_str());
|
||||
// avty_json["t"] = tpl;
|
||||
// snprintf(tpl, sizeof(tpl), tpl_draft, "value == 'online'");
|
||||
// avty_json["val_tpl"] = tpl;
|
||||
// avty.add(avty_json); // returns 0 if no mem
|
||||
const char * tpl_draft = "{{'online' if %s else 'offline'}}";
|
||||
|
||||
// condition 1
|
||||
avty_json.clear();
|
||||
avty_json["t"] = state_t;
|
||||
avty_json["t"] = state;
|
||||
snprintf(tpl, sizeof(tpl), tpl_draft, cond1 == nullptr ? "value is defined" : cond1);
|
||||
avty_json["val_tpl"] = tpl;
|
||||
avty.add(avty_json); // returns 0 if no mem
|
||||
@@ -1408,7 +1414,7 @@ void Mqtt::add_ha_sections_to_doc(const char * name,
|
||||
// condition 2
|
||||
if (cond2 != nullptr) {
|
||||
avty_json.clear();
|
||||
avty_json["t"] = state_t;
|
||||
avty_json["t"] = state;
|
||||
snprintf(tpl, sizeof(tpl), tpl_draft, cond2);
|
||||
avty_json["val_tpl"] = tpl;
|
||||
avty.add(avty_json); // returns 0 if no mem
|
||||
@@ -1417,7 +1423,7 @@ void Mqtt::add_ha_sections_to_doc(const char * name,
|
||||
// negative condition
|
||||
if (negcond != nullptr) {
|
||||
avty_json.clear();
|
||||
avty_json["t"] = state_t;
|
||||
avty_json["t"] = state;
|
||||
snprintf(tpl, sizeof(tpl), "{{'offline' if %s else 'online'}}", negcond);
|
||||
avty_json["val_tpl"] = tpl;
|
||||
avty.add(avty_json); // returns 0 if no mem
|
||||
|
||||
@@ -138,10 +138,6 @@ class Mqtt {
|
||||
return discovery_prefix_ + "/";
|
||||
}
|
||||
|
||||
static void base(const char * base) {
|
||||
mqtt_base_ = base;
|
||||
}
|
||||
|
||||
static uint32_t publish_count() {
|
||||
return mqtt_message_id_;
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#else // ESP32 Before IDF 4.0
|
||||
#include "../rom/rtc.h"
|
||||
#endif
|
||||
#include <esp_mac.h>
|
||||
#endif
|
||||
|
||||
namespace emsesp {
|
||||
@@ -291,7 +292,7 @@ void System::system_restart(const char * partitionname) {
|
||||
}
|
||||
esp_ota_set_boot_partition(partition);
|
||||
}
|
||||
LOG_INFO("Restarting EMS-ESP from partition '%s'", partitionname);
|
||||
LOG_INFO("Restarting EMS-ESP from %s partition", partitionname);
|
||||
} else {
|
||||
LOG_INFO("Restarting EMS-ESP...");
|
||||
}
|
||||
@@ -963,10 +964,17 @@ void System::show_system(uuid::console::Shell & shell) {
|
||||
|
||||
shell.println("System:");
|
||||
shell.printfln(" Version: %s", EMSESP_APP_VERSION);
|
||||
shell.printfln(" Platform: %s", EMSESP_PLATFORM);
|
||||
shell.printfln(" Language: %s", locale().c_str());
|
||||
shell.printfln(" Board profile: %s", board_profile().c_str());
|
||||
shell.printfln(" Uptime: %s", uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3).c_str());
|
||||
#ifndef EMSESP_STANDALONE
|
||||
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/misc_system_api.html
|
||||
unsigned char mac_base[6] = {0};
|
||||
esp_efuse_mac_get_default(mac_base);
|
||||
esp_read_mac(mac_base, ESP_MAC_WIFI_STA);
|
||||
shell.printfln(" Base MAC Address: %02X:%02X:%02X:%02X:%02X:%02X", mac_base[0], mac_base[1], mac_base[2], mac_base[3], mac_base[4], mac_base[5]);
|
||||
|
||||
shell.printfln(" SDK version: %s", ESP.getSdkVersion());
|
||||
shell.printfln(" CPU frequency: %lu MHz", ESP.getCpuFreqMHz());
|
||||
shell.printfln(" Free heap/Max alloc: %lu KB / %lu KB", getHeapMem(), getMaxAllocMem());
|
||||
|
||||
@@ -1186,7 +1186,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
EMSESP::mqtt_.incoming("ems-esp/thermostat/mode/auto", "auto"); // invalid, not allowed
|
||||
|
||||
// check extended MQTT base
|
||||
Mqtt::base("home/cellar/heating");
|
||||
// Mqtt::base("home/cellar/heating");
|
||||
EMSESP::mqtt_.incoming("home/cellar/heating/thermostat/mode"); // empty payload
|
||||
|
||||
// Web API TESTS
|
||||
|
||||
@@ -73,12 +73,13 @@ void EMSuart::uart_event_task(void * pvParameters) {
|
||||
void EMSuart::start(const uint8_t tx_mode, const uint8_t rx_gpio, const uint8_t tx_gpio) {
|
||||
if (tx_mode_ == 0xFF) {
|
||||
uart_config_t uart_config = {
|
||||
.baud_rate = EMSUART_BAUD,
|
||||
.data_bits = UART_DATA_8_BITS,
|
||||
.parity = UART_PARITY_DISABLE,
|
||||
.stop_bits = UART_STOP_BITS_1,
|
||||
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
||||
.source_clk = UART_SCLK_APB,
|
||||
.baud_rate = EMSUART_BAUD,
|
||||
.data_bits = UART_DATA_8_BITS,
|
||||
.parity = UART_PARITY_DISABLE,
|
||||
.stop_bits = UART_STOP_BITS_1,
|
||||
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0, // not used - https://docs.espressif.com/projects/esp-idf/en/v3.3.6/api-reference/peripherals/uart.html
|
||||
.source_clk = UART_SCLK_APB,
|
||||
};
|
||||
#if defined(EMSUART_RX_INVERT)
|
||||
inverse_mask |= UART_SIGNAL_RXD_INV;
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define EMSESP_APP_VERSION "3.7.0-dev.12"
|
||||
#define EMSESP_APP_VERSION "3.7.0-dev.13"
|
||||
|
||||
91
src/web/WebModulesService.cpp
Normal file
91
src/web/WebModulesService.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* EMS-ESP - https://github.com/emsesp/EMS-ESP
|
||||
* Copyright 2020-2024 Paul Derbyshire
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "emsesp.h"
|
||||
#include "WebModulesService.h"
|
||||
|
||||
namespace emsesp {
|
||||
|
||||
ModuleLibrary moduleLibrary; // Module Library
|
||||
EMSESP * emsesp_; // forward declaration
|
||||
|
||||
WebModulesService::WebModulesService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager)
|
||||
: _httpEndpoint(WebModules::read, WebModules::update, this, server, EMSESP_MODULES_SERVICE_PATH, securityManager, AuthenticationPredicates::IS_AUTHENTICATED)
|
||||
, _fsPersistence(WebModules::read, WebModules::update, this, fs, EMSESP_MODULES_FILE) {
|
||||
}
|
||||
|
||||
// load the settings when the service starts
|
||||
void WebModulesService::begin() {
|
||||
EMSESP::logger().info("Starting Modules service");
|
||||
|
||||
#ifdef EMSESP_TEST
|
||||
moduleLibrary.start(emsesp_, true); // hot load the test modules as well
|
||||
#else
|
||||
moduleLibrary.start(emsesp_);
|
||||
#endif
|
||||
|
||||
_fsPersistence.readFromFS(); // read the file from FS - this will call the update function WebModules::update()
|
||||
}
|
||||
|
||||
void WebModulesService::loop() {
|
||||
moduleLibrary.loop(); // loop the external library modules
|
||||
}
|
||||
|
||||
// this creates the modules settings file, saving it to the file system
|
||||
// it adds data to an empty 'root' json object
|
||||
// and also calls when the Modules web page is refreshed/loaded
|
||||
void WebModules::read(WebModules & webModules, JsonObject root) {
|
||||
JsonDocument doc_modules;
|
||||
JsonObject root_modules = doc_modules.to<JsonObject>();
|
||||
moduleLibrary.list(root_modules); // get list the external library modules, put in a json object
|
||||
|
||||
JsonArray modules = root["modules"].to<JsonArray>();
|
||||
uint8_t counter = 0;
|
||||
for (const JsonObject module : root_modules["modules"].as<JsonArray>()) {
|
||||
JsonObject mi = modules.add<JsonObject>();
|
||||
mi["id"] = counter++; // id is only used to render the table and must be unique
|
||||
mi["key"] = module["key"].as<std::string>();
|
||||
mi["name"] = module["name"].as<std::string>();
|
||||
mi["author"] = module["author"].as<std::string>();
|
||||
mi["version"] = module["version"].as<std::string>();
|
||||
mi["status"] = module["status"].as<uint8_t>();
|
||||
mi["enabled"] = module["enabled"].as<bool>();
|
||||
mi["message"] = module["message"].as<std::string>();
|
||||
mi["license"] = module["license"].as<std::string>();
|
||||
}
|
||||
}
|
||||
|
||||
// read any Module settings from the settings file
|
||||
// and then apply the enable/disable that is set by the user
|
||||
// This function is called when ems-esp boots and also on a save from the Modules web page
|
||||
StateUpdateResult WebModules::update(JsonObject root, WebModules & webModules) {
|
||||
bool err = false;
|
||||
if (root["modules"].is<JsonArray>()) {
|
||||
for (const JsonObject module : root["modules"].as<JsonArray>()) {
|
||||
auto key = module["key"].as<const char *>();
|
||||
auto license = module["license"].as<const char *>();
|
||||
auto enable = module["enabled"].as<bool>();
|
||||
|
||||
err &= moduleLibrary.enable(key, license, enable);
|
||||
}
|
||||
}
|
||||
|
||||
return err ? StateUpdateResult::ERROR : StateUpdateResult::CHANGED;
|
||||
}
|
||||
|
||||
} // namespace emsesp
|
||||
50
src/web/WebModulesService.h
Normal file
50
src/web/WebModulesService.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* EMS-ESP - https://github.com/emsesp/EMS-ESP
|
||||
* Copyright 2020-2024 Paul Derbyshire
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef WebModulesService_h
|
||||
#define WebModulesService_h
|
||||
|
||||
#define EMSESP_MODULES_FILE "/config/emsespModules.json"
|
||||
#define EMSESP_MODULES_SERVICE_PATH "/rest/modules" // GET and POST
|
||||
|
||||
namespace emsesp {
|
||||
|
||||
class WebModules {
|
||||
public:
|
||||
static void read(WebModules & webModules, JsonObject root);
|
||||
static StateUpdateResult update(JsonObject root, WebModules & webModules);
|
||||
};
|
||||
|
||||
class WebModulesService : public StatefulService<WebModules> {
|
||||
public:
|
||||
WebModulesService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager);
|
||||
|
||||
void begin();
|
||||
void loop();
|
||||
|
||||
#ifndef EMSESP_STANDALONE
|
||||
private:
|
||||
#endif
|
||||
|
||||
HttpEndpoint<WebModules> _httpEndpoint;
|
||||
FSPersistence<WebModules> _fsPersistence;
|
||||
};
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
#endif
|
||||
@@ -31,10 +31,7 @@ void WebSchedulerService::begin() {
|
||||
_fsPersistence.readFromFS();
|
||||
|
||||
// save a local pointer to the scheduler item list
|
||||
EMSESP::webSchedulerService.read([&](WebScheduler & webScheduler) {
|
||||
//
|
||||
scheduleItems_ = &webScheduler.scheduleItems;
|
||||
});
|
||||
EMSESP::webSchedulerService.read([&](WebScheduler & webScheduler) { scheduleItems_ = &webScheduler.scheduleItems; });
|
||||
|
||||
EMSESP::logger().info("Starting Scheduler service");
|
||||
Mqtt::subscribe(EMSdevice::DeviceType::SCHEDULER, "scheduler/#", nullptr); // use empty function callback
|
||||
|
||||
@@ -251,7 +251,6 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) {
|
||||
settings.analog_enabled = root["analog_enabled"] | EMSESP_DEFAULT_ANALOG_ENABLED;
|
||||
check_flag(prev, settings.analog_enabled, ChangeFlags::ADC);
|
||||
|
||||
|
||||
//
|
||||
// these need system restarts first before settings are activated...
|
||||
//
|
||||
@@ -294,7 +293,6 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) {
|
||||
//
|
||||
// without checks or necessary restarts...
|
||||
//
|
||||
|
||||
settings.trace_raw = root["trace_raw"] | EMSESP_DEFAULT_TRACELOG_RAW;
|
||||
EMSESP::trace_raw(settings.trace_raw);
|
||||
|
||||
|
||||
@@ -70,6 +70,16 @@ void WebStatusService::systemStatus(AsyncWebServerRequest * request) {
|
||||
|
||||
root["ap_status"] = EMSESP::esp8266React.apStatus();
|
||||
|
||||
if (emsesp::EMSESP::system_.ethernet_connected()) {
|
||||
root["network_status"] = 10; // custom code #10 - ETHERNET_STATUS_CONNECTED
|
||||
root["wifi_rssi"] = 0;
|
||||
} else {
|
||||
root["network_status"] = static_cast<uint8_t>(WiFi.status());
|
||||
#ifndef EMSESP_STANDALONE
|
||||
root["wifi_rssi"] = WiFi.RSSI();
|
||||
#endif
|
||||
}
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user