mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-08 08:49:52 +03:00
Merge remote-tracking branch 'origin/flash_optimization' into dev #646
This commit is contained in:
@@ -32,7 +32,7 @@ void AnalogSensor::start() {
|
||||
analogSetAttenuation(ADC_2_5db); // for all channels 1.5V
|
||||
|
||||
|
||||
LOG_INFO(F("Starting Analog sensor service"));
|
||||
LOG_INFO("Starting Analog sensor service");
|
||||
|
||||
// Add API call for /info
|
||||
Command::add(
|
||||
@@ -44,7 +44,7 @@ void AnalogSensor::start() {
|
||||
EMSdevice::DeviceType::ANALOGSENSOR,
|
||||
F_(setvalue),
|
||||
[&](const char * value, const int8_t id) { return command_setvalue(value, id); },
|
||||
F("set io value"), // TODO this needs translating
|
||||
("set io value"), // TODO translate this
|
||||
CommandFlag::ADMIN_ONLY);
|
||||
Command::add(
|
||||
EMSdevice::DeviceType::ANALOGSENSOR,
|
||||
@@ -123,12 +123,12 @@ void AnalogSensor::reload() {
|
||||
for (auto & sensor : sensors_) {
|
||||
sensor.ha_registered = false; // force HA configs to be re-created
|
||||
if (sensor.type() == AnalogType::ADC) {
|
||||
LOG_DEBUG(F("Adding analog ADC sensor on GPIO%d"), sensor.gpio());
|
||||
LOG_DEBUG("Adding analog ADC sensor on GPIO%d", sensor.gpio());
|
||||
// analogSetPinAttenuation does not work with analogReadMilliVolts
|
||||
sensor.analog_ = 0; // initialize
|
||||
sensor.last_reading_ = 0;
|
||||
} else if (sensor.type() == AnalogType::COUNTER) {
|
||||
LOG_DEBUG(F("Adding analog I/O Counter sensor on GPIO%d"), sensor.gpio());
|
||||
LOG_DEBUG("Adding analog I/O Counter sensor on GPIO%d", sensor.gpio());
|
||||
pinMode(sensor.gpio(), INPUT_PULLUP);
|
||||
#ifndef ARDUINO_LOLIN_C3_MINI
|
||||
if (sensor.gpio() == 25 || sensor.gpio() == 26) {
|
||||
@@ -139,7 +139,7 @@ void AnalogSensor::reload() {
|
||||
sensor.poll_ = digitalRead(sensor.gpio());
|
||||
publish_sensor(sensor);
|
||||
} else if (sensor.type() == AnalogType::TIMER || sensor.type() == AnalogType::RATE) {
|
||||
LOG_DEBUG(F("Adding analog Timer/Rate sensor on GPIO%d"), sensor.gpio());
|
||||
LOG_DEBUG("Adding analog Timer/Rate sensor on GPIO%d", sensor.gpio());
|
||||
pinMode(sensor.gpio(), INPUT_PULLUP);
|
||||
sensor.polltime_ = uuid::get_uptime();
|
||||
sensor.last_polltime_ = uuid::get_uptime();
|
||||
@@ -148,7 +148,7 @@ void AnalogSensor::reload() {
|
||||
sensor.set_value(0);
|
||||
publish_sensor(sensor);
|
||||
} else if (sensor.type() == AnalogType::DIGITAL_IN) {
|
||||
LOG_DEBUG(F("Adding analog Read sensor on GPIO%d"), sensor.gpio());
|
||||
LOG_DEBUG("Adding analog Read sensor on GPIO%d", sensor.gpio());
|
||||
pinMode(sensor.gpio(), INPUT_PULLUP);
|
||||
sensor.set_value(digitalRead(sensor.gpio())); // initial value
|
||||
sensor.set_uom(0); // no uom, just for safe measures
|
||||
@@ -156,7 +156,7 @@ void AnalogSensor::reload() {
|
||||
sensor.poll_ = digitalRead(sensor.gpio());
|
||||
publish_sensor(sensor);
|
||||
} else if (sensor.type() == AnalogType::DIGITAL_OUT) {
|
||||
LOG_DEBUG(F("Adding analog Write sensor on GPIO%d"), sensor.gpio());
|
||||
LOG_DEBUG("Adding analog Write sensor on GPIO%d", sensor.gpio());
|
||||
pinMode(sensor.gpio(), OUTPUT);
|
||||
if (sensor.gpio() == 25 || sensor.gpio() == 26) {
|
||||
if (sensor.offset() > 255) {
|
||||
@@ -175,7 +175,7 @@ void AnalogSensor::reload() {
|
||||
sensor.set_uom(0); // no uom, just for safe measures
|
||||
publish_sensor(sensor);
|
||||
} else if (sensor.type() >= AnalogType::PWM_0) {
|
||||
LOG_DEBUG(F("Adding PWM output sensor on GPIO%d"), sensor.gpio());
|
||||
LOG_DEBUG("Adding PWM output sensor on GPIO%d", sensor.gpio());
|
||||
uint channel = sensor.type() - AnalogType::PWM_0;
|
||||
ledcSetup(channel, sensor.factor(), 13);
|
||||
ledcAttachPin(sensor.gpio(), channel);
|
||||
@@ -277,7 +277,7 @@ bool AnalogSensor::update(uint8_t gpio, const std::string & name, float offset,
|
||||
found_sensor = true; // found the record
|
||||
// see if it's marked for deletion
|
||||
if (type == AnalogType::MARK_DELETED) {
|
||||
LOG_DEBUG(F("Removing analog sensor GPIO %d"), gpio);
|
||||
LOG_DEBUG("Removing analog sensor GPIO %d", gpio);
|
||||
settings.analogCustomizations.remove(AnalogCustomization);
|
||||
} else {
|
||||
// update existing record
|
||||
@@ -286,7 +286,7 @@ bool AnalogSensor::update(uint8_t gpio, const std::string & name, float offset,
|
||||
AnalogCustomization.factor = factor;
|
||||
AnalogCustomization.uom = uom;
|
||||
AnalogCustomization.type = type;
|
||||
LOG_DEBUG(F("Customizing existing analog GPIO %d"), gpio);
|
||||
LOG_DEBUG("Customizing existing analog GPIO %d", gpio);
|
||||
}
|
||||
return StateUpdateResult::CHANGED; // persist the change
|
||||
}
|
||||
@@ -312,7 +312,7 @@ bool AnalogSensor::update(uint8_t gpio, const std::string & name, float offset,
|
||||
newSensor.uom = uom;
|
||||
newSensor.type = type;
|
||||
settings.analogCustomizations.push_back(newSensor);
|
||||
LOG_DEBUG(F("Adding new customization for analog sensor GPIO %d"), gpio);
|
||||
LOG_DEBUG("Adding new customization for analog sensor GPIO %d", gpio);
|
||||
return StateUpdateResult::CHANGED; // persist the change
|
||||
},
|
||||
"local");
|
||||
@@ -338,9 +338,9 @@ void AnalogSensor::publish_sensor(const Sensor & sensor) const {
|
||||
if (Mqtt::publish_single()) {
|
||||
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||
if (Mqtt::publish_single2cmd()) {
|
||||
snprintf(topic, sizeof(topic), "%s/%s", read_flash_string(F_(analogsensor)).c_str(), sensor.name().c_str());
|
||||
snprintf(topic, sizeof(topic), "%s/%s", (F_(analogsensor)), sensor.name().c_str());
|
||||
} else {
|
||||
snprintf(topic, sizeof(topic), "%s%s/%s", read_flash_string(F_(analogsensor)).c_str(), "_data", sensor.name().c_str());
|
||||
snprintf(topic, sizeof(topic), "%s%s/%s", (F_(analogsensor)), "_data", sensor.name().c_str());
|
||||
}
|
||||
char payload[10];
|
||||
Mqtt::publish(topic, Helpers::render_value(payload, sensor.value(), 2)); // always publish as floats
|
||||
@@ -353,7 +353,7 @@ void AnalogSensor::remove_ha_topic(const uint8_t gpio) const {
|
||||
return;
|
||||
}
|
||||
#ifdef EMSESP_DEBUG
|
||||
LOG_DEBUG(F("Removing HA config for analog sensor GPIO %d"), gpio);
|
||||
LOG_DEBUG("Removing HA config for analog sensor GPIO %d", gpio);
|
||||
#endif
|
||||
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||
snprintf(topic, sizeof(topic), "sensor/%s/analogsensor_%d/config", Mqtt::basename().c_str(), gpio);
|
||||
@@ -403,7 +403,7 @@ void AnalogSensor::publish_values(const bool force) {
|
||||
|
||||
// create HA config
|
||||
if (Mqtt::ha_enabled() && (!sensor.ha_registered || force)) {
|
||||
LOG_DEBUG(F("Recreating HA config for analog sensor GPIO %d"), sensor.gpio());
|
||||
LOG_DEBUG("Recreating HA config for analog sensor GPIO %d", sensor.gpio());
|
||||
|
||||
StaticJsonDocument<EMSESP_JSON_SIZE_MEDIUM> config;
|
||||
|
||||
@@ -447,7 +447,7 @@ void AnalogSensor::publish_values(const bool force) {
|
||||
}
|
||||
}
|
||||
|
||||
Mqtt::publish(F("analogsensor_data"), doc.as<JsonObject>());
|
||||
Mqtt::publish("analogsensor_data", doc.as<JsonObject>());
|
||||
}
|
||||
|
||||
// called from emsesp.cpp, similar to the emsdevice->get_value_info
|
||||
|
||||
@@ -82,7 +82,7 @@ uint8_t Command::process(const char * path, const bool is_admin, const JsonObjec
|
||||
// validate the device, make sure it exists
|
||||
uint8_t device_type = EMSdevice::device_name_2_device_type(device_s);
|
||||
if (!device_has_commands(device_type)) {
|
||||
LOG_DEBUG(F("Command failed: unknown device '%s'"), device_s);
|
||||
LOG_DEBUG("Command failed: unknown device '%s'", device_s);
|
||||
return message(CommandRet::ERROR, "unknown device", output);
|
||||
}
|
||||
|
||||
@@ -170,15 +170,15 @@ uint8_t Command::process(const char * path, const bool is_admin, const JsonObjec
|
||||
std::string Command::return_code_string(const uint8_t return_code) {
|
||||
switch (return_code) {
|
||||
case CommandRet::ERROR:
|
||||
return read_flash_string(F("Error"));
|
||||
return ("Error");
|
||||
case CommandRet::OK:
|
||||
return read_flash_string(F("OK"));
|
||||
return ("OK");
|
||||
case CommandRet::NOT_FOUND:
|
||||
return read_flash_string(F("Not Found"));
|
||||
return ("Not Found");
|
||||
case CommandRet::NOT_ALLOWED:
|
||||
return read_flash_string(F("Not Authorized"));
|
||||
return ("Not Authorized");
|
||||
case CommandRet::FAIL:
|
||||
return read_flash_string(F("Failed"));
|
||||
return ("Failed");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -248,7 +248,7 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char *
|
||||
if ((device_type > EMSdevice::DeviceType::SYSTEM) && (!value || !strlen(value))) {
|
||||
if (!cf || !cf->cmdfunction_json_) {
|
||||
#if defined(EMSESP_DEBUG)
|
||||
LOG_DEBUG(F("[DEBUG] Calling %s command '%s' to retrieve attributes"), dname.c_str(), cmd);
|
||||
LOG_DEBUG("[DEBUG] Calling %s command '%s' to retrieve attributes", dname.c_str(), cmd);
|
||||
#endif
|
||||
return EMSESP::get_device_value_info(output, cmd, id, device_type) ? CommandRet::OK : CommandRet::ERROR; // entity = cmd
|
||||
}
|
||||
@@ -264,15 +264,15 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char *
|
||||
|
||||
if ((value == nullptr) || (strlen(value) == 0)) {
|
||||
if (EMSESP::system_.readonly_mode()) {
|
||||
LOG_INFO(F("[readonly] Calling command '%s/%s' (%s)"), dname.c_str(), cmd, read_flash_string(cf->description_).c_str());
|
||||
LOG_INFO(("[readonly] Calling command '%s/%s' (%s)"), dname.c_str(), cmd, cf->description_);
|
||||
} else {
|
||||
LOG_DEBUG(F("Calling command '%s/%s' (%s)"), dname.c_str(), cmd, read_flash_string(cf->description_).c_str());
|
||||
LOG_DEBUG(("Calling command '%s/%s' (%s)"), dname.c_str(), cmd, (cf->description_));
|
||||
}
|
||||
} else {
|
||||
if (EMSESP::system_.readonly_mode()) {
|
||||
LOG_INFO(F("[readonly] Calling command '%s/%s' (%s) with value %s"), dname.c_str(), cmd, read_flash_string(cf->description_).c_str(), value);
|
||||
LOG_INFO(("[readonly] Calling command '%s/%s' (%s) with value %s"), dname.c_str(), cmd, cf->description_, value);
|
||||
} else {
|
||||
LOG_DEBUG(F("Calling command '%s/%s' (%s) with value %s"), dname.c_str(), cmd, read_flash_string(cf->description_).c_str(), value);
|
||||
LOG_DEBUG(("Calling command '%s/%s' (%s) with value %s"), dname.c_str(), cmd, (cf->description_), value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,14 +294,14 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char *
|
||||
}
|
||||
|
||||
// we didn't find the command and its not an endpoint, report error
|
||||
LOG_DEBUG(F("Command failed: invalid command '%s'"), cmd);
|
||||
LOG_DEBUG("Command failed: invalid command '%s'", cmd);
|
||||
return message(CommandRet::NOT_FOUND, "invalid command", output);
|
||||
}
|
||||
|
||||
// add a command to the list, which does not return json
|
||||
void Command::add(const uint8_t device_type, const __FlashStringHelper * cmd, const cmd_function_p cb, const __FlashStringHelper * description, uint8_t flags) {
|
||||
void Command::add(const uint8_t device_type, const char * cmd, const cmd_function_p cb, const char * description, uint8_t flags) {
|
||||
// if the command already exists for that device type don't add it
|
||||
if (find_command(device_type, read_flash_string(cmd).c_str()) != nullptr) {
|
||||
if (find_command(device_type, cmd) != nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -314,9 +314,9 @@ void Command::add(const uint8_t device_type, const __FlashStringHelper * cmd, co
|
||||
}
|
||||
|
||||
// add a command to the list, which does return a json object as output
|
||||
void Command::add(const uint8_t device_type, const __FlashStringHelper * cmd, const cmd_json_function_p cb, const __FlashStringHelper * description, uint8_t flags) {
|
||||
void Command::add(const uint8_t device_type, const char * cmd, const cmd_json_function_p cb, const char * description, uint8_t flags) {
|
||||
// if the command already exists for that device type don't add it
|
||||
if (find_command(device_type, read_flash_string(cmd).c_str()) != nullptr) {
|
||||
if (find_command(device_type, cmd) != nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -338,7 +338,7 @@ Command::CmdFunction * Command::find_command(const uint8_t device_type, const ch
|
||||
}
|
||||
|
||||
for (auto & cf : cmdfunctions_) {
|
||||
if (!strcmp(lowerCmd, Helpers::toLower(read_flash_string(cf.cmd_)).c_str()) && (cf.device_type_ == device_type)) {
|
||||
if (!strcmp(lowerCmd, cf.cmd_) && (cf.device_type_ == device_type)) {
|
||||
return &cf;
|
||||
}
|
||||
}
|
||||
@@ -357,14 +357,14 @@ bool Command::list(const uint8_t device_type, JsonObject & output) {
|
||||
std::list<std::string> sorted_cmds;
|
||||
for (const auto & cf : cmdfunctions_) {
|
||||
if ((cf.device_type_ == device_type) && !cf.has_flags(CommandFlag::HIDDEN)) {
|
||||
sorted_cmds.push_back(read_flash_string(cf.cmd_));
|
||||
sorted_cmds.push_back((cf.cmd_));
|
||||
}
|
||||
}
|
||||
sorted_cmds.sort();
|
||||
|
||||
for (const auto & cl : sorted_cmds) {
|
||||
for (const auto & cf : cmdfunctions_) {
|
||||
if ((cf.device_type_ == device_type) && !cf.has_flags(CommandFlag::HIDDEN) && cf.description_ && (cl == read_flash_string(cf.cmd_))) {
|
||||
if ((cf.device_type_ == device_type) && !cf.has_flags(CommandFlag::HIDDEN) && cf.description_ && (cl == std::string(cf.cmd_))) {
|
||||
output[cl] = cf.description_;
|
||||
}
|
||||
}
|
||||
@@ -376,7 +376,7 @@ bool Command::list(const uint8_t device_type, JsonObject & output) {
|
||||
// output list of all commands to console for a specific DeviceType
|
||||
void Command::show(uuid::console::Shell & shell, uint8_t device_type, bool verbose) {
|
||||
if (cmdfunctions_.empty()) {
|
||||
shell.println(F("No commands available"));
|
||||
shell.println("No commands available");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -384,7 +384,7 @@ void Command::show(uuid::console::Shell & shell, uint8_t device_type, bool verbo
|
||||
std::list<std::string> sorted_cmds;
|
||||
for (const auto & cf : cmdfunctions_) {
|
||||
if ((cf.device_type_ == device_type) && !cf.has_flags(CommandFlag::HIDDEN)) {
|
||||
sorted_cmds.push_back(read_flash_string(cf.cmd_));
|
||||
sorted_cmds.push_back((cf.cmd_));
|
||||
}
|
||||
}
|
||||
sorted_cmds.sort();
|
||||
@@ -404,7 +404,7 @@ void Command::show(uuid::console::Shell & shell, uint8_t device_type, bool verbo
|
||||
for (const auto & cl : sorted_cmds) {
|
||||
// find and print the description
|
||||
for (const auto & cf : cmdfunctions_) {
|
||||
if ((cf.device_type_ == device_type) && !cf.has_flags(CommandFlag::HIDDEN) && cf.description_ && (cl == read_flash_string(cf.cmd_))) {
|
||||
if ((cf.device_type_ == device_type) && !cf.has_flags(CommandFlag::HIDDEN) && cf.description_ && (cl == std::string(cf.cmd_))) {
|
||||
uint8_t i = cl.length();
|
||||
shell.print(" ");
|
||||
if (cf.has_flags(MQTT_SUB_FLAG_HC)) {
|
||||
@@ -424,7 +424,7 @@ void Command::show(uuid::console::Shell & shell, uint8_t device_type, bool verbo
|
||||
shell.print(EMSdevice::tag_to_string(DeviceValueTAG::TAG_DEVICE_DATA_WW));
|
||||
shell.print(' ');
|
||||
}
|
||||
shell.print(read_flash_string(cf.description_).c_str());
|
||||
shell.print((cf.description_));
|
||||
if (!cf.has_flags(CommandFlag::ADMIN_ONLY)) {
|
||||
shell.print(' ');
|
||||
shell.print(COLOR_BRIGHT_RED);
|
||||
@@ -497,7 +497,7 @@ void Command::show_devices(uuid::console::Shell & shell) {
|
||||
// output list of all commands to console
|
||||
// calls show with verbose mode set
|
||||
void Command::show_all(uuid::console::Shell & shell) {
|
||||
shell.println(F("Available commands (*=do not need authorization): "));
|
||||
shell.println(("Available commands (*=do not need authorization): "));
|
||||
|
||||
// show system first
|
||||
shell.print(COLOR_BOLD_ON);
|
||||
|
||||
@@ -54,19 +54,19 @@ using cmd_json_function_p = std::function<bool(const char * data, const int8_t i
|
||||
class Command {
|
||||
public:
|
||||
struct CmdFunction {
|
||||
uint8_t device_type_; // DeviceType::
|
||||
uint8_t flags_; // mqtt flags for command subscriptions
|
||||
const __FlashStringHelper * cmd_;
|
||||
const cmd_function_p cmdfunction_;
|
||||
const cmd_json_function_p cmdfunction_json_;
|
||||
const __FlashStringHelper * description_;
|
||||
uint8_t device_type_; // DeviceType::
|
||||
uint8_t flags_; // mqtt flags for command subscriptions
|
||||
const char * cmd_;
|
||||
const cmd_function_p cmdfunction_;
|
||||
const cmd_json_function_p cmdfunction_json_;
|
||||
const char * description_;
|
||||
|
||||
CmdFunction(const uint8_t device_type,
|
||||
const uint8_t flags,
|
||||
const __FlashStringHelper * cmd,
|
||||
const cmd_function_p cmdfunction,
|
||||
const cmd_json_function_p cmdfunction_json,
|
||||
const __FlashStringHelper * description)
|
||||
CmdFunction(const uint8_t device_type,
|
||||
const uint8_t flags,
|
||||
const char * cmd,
|
||||
const cmd_function_p cmdfunction,
|
||||
const cmd_json_function_p cmdfunction_json,
|
||||
const char * description)
|
||||
: device_type_(device_type)
|
||||
, flags_(flags)
|
||||
, cmd_(cmd)
|
||||
@@ -99,18 +99,12 @@ class Command {
|
||||
static uint8_t call(const uint8_t device_type, const char * cmd, const char * value);
|
||||
|
||||
// with normal call back function taking a value and id
|
||||
static void add(const uint8_t device_type,
|
||||
const __FlashStringHelper * cmd,
|
||||
const cmd_function_p cb,
|
||||
const __FlashStringHelper * description,
|
||||
uint8_t flags = CommandFlag::MQTT_SUB_FLAG_DEFAULT);
|
||||
static void
|
||||
add(const uint8_t device_type, const char * cmd, const cmd_function_p cb, const char * description, uint8_t flags = CommandFlag::MQTT_SUB_FLAG_DEFAULT);
|
||||
|
||||
// callback function taking value, id and a json object for its output
|
||||
static void add(const uint8_t device_type,
|
||||
const __FlashStringHelper * cmd,
|
||||
const cmd_json_function_p cb,
|
||||
const __FlashStringHelper * description,
|
||||
uint8_t flags = CommandFlag::MQTT_SUB_FLAG_DEFAULT);
|
||||
static void
|
||||
add(const uint8_t device_type, const char * cmd, const cmd_json_function_p cb, const char * description, uint8_t flags = CommandFlag::MQTT_SUB_FLAG_DEFAULT);
|
||||
|
||||
static void show_all(uuid::console::Shell & shell);
|
||||
static Command::CmdFunction * find_command(const uint8_t device_type, const char * cmd);
|
||||
|
||||
20
src/common.h
20
src/common.h
@@ -31,29 +31,23 @@ using uuid::log::Level;
|
||||
#define LOG_ERROR(...) logger_.err(__VA_ARGS__)
|
||||
|
||||
// flash strings
|
||||
using uuid::flash_string_vector;
|
||||
using uuid::read_flash_string;
|
||||
using uuid::string_vector;
|
||||
using string_vector = std::vector<const char *>;
|
||||
|
||||
#ifdef FPSTR
|
||||
#undef FPSTR
|
||||
#endif
|
||||
|
||||
#define FJSON(x) x
|
||||
// #define FJSON(x) F(x)
|
||||
|
||||
// clang-format off
|
||||
|
||||
#define MAKE_STR(string_name, string_literal) static constexpr const char * __str__##string_name = string_literal;
|
||||
|
||||
#define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer))
|
||||
#define F_(string_name) FPSTR(__pstr__##string_name)
|
||||
|
||||
#define MAKE_PSTR(string_name, string_literal) static const char __pstr__##string_name[] __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = string_literal;
|
||||
#define FPSTR(pstr_pointer) pstr_pointer
|
||||
#define MAKE_PSTR(string_name, string_literal) static const char __pstr__##string_name[] = string_literal;
|
||||
#define MAKE_PSTR_WORD(string_name) MAKE_PSTR(string_name, #string_name)
|
||||
|
||||
#define F_(string_name) (__pstr__##string_name)
|
||||
#define FL_(list_name) (__pstr__L_##list_name)
|
||||
#define MAKE_PSTR_LIST(list_name, ...) static const __FlashStringHelper * const __pstr__L_##list_name[] PROGMEM = {__VA_ARGS__, nullptr};
|
||||
#define MAKE_PSTR_ENUM(enum_name, ...) static const __FlashStringHelper * const * __pstr__L_##enum_name[] PROGMEM = {__VA_ARGS__, nullptr};
|
||||
#define MAKE_PSTR_LIST(list_name, ...) static const char * const __pstr__L_##list_name[] = {__VA_ARGS__, nullptr};
|
||||
#define MAKE_PSTR_ENUM(enum_name, ...) static const char * const * __pstr__L_##enum_name[] = {__VA_ARGS__, nullptr};
|
||||
|
||||
// clang-format on
|
||||
|
||||
|
||||
194
src/console.cpp
194
src/console.cpp
@@ -45,26 +45,26 @@ EMSESPShell::EMSESPShell()
|
||||
}
|
||||
|
||||
void EMSESPShell::started() {
|
||||
logger().log(LogLevel::DEBUG, LogFacility::CONSOLE, F("User session opened on console %s"), console_name().c_str());
|
||||
logger().log(LogLevel::DEBUG, LogFacility::CONSOLE, ("User session opened on console %s"), console_name().c_str());
|
||||
}
|
||||
|
||||
void EMSESPShell::stopped() {
|
||||
if (has_flags(CommandFlags::ADMIN)) {
|
||||
logger().log(LogLevel::DEBUG, LogFacility::AUTH, F("su session closed on console %s"), console_name().c_str());
|
||||
logger().log(LogLevel::DEBUG, LogFacility::AUTH, ("su session closed on console %s"), console_name().c_str());
|
||||
}
|
||||
logger().log(LogLevel::DEBUG, LogFacility::CONSOLE, F("User session closed on console %s"), console_name().c_str());
|
||||
logger().log(LogLevel::DEBUG, LogFacility::CONSOLE, ("User session closed on console %s"), console_name().c_str());
|
||||
}
|
||||
|
||||
// show welcome banner
|
||||
// this is one of the first functions called when the shell is started
|
||||
void EMSESPShell::display_banner() {
|
||||
println();
|
||||
printfln(F("┌──────────────────────────────────────┐"));
|
||||
printfln(F("│ %sEMS-ESP version %-10s%s │"), COLOR_BOLD_ON, EMSESP_APP_VERSION, COLOR_BOLD_OFF);
|
||||
printfln(F("│ %s%shttps://github.com/emsesp/EMS-ESP32%s │"), COLOR_BRIGHT_GREEN, COLOR_UNDERLINE, COLOR_RESET);
|
||||
printfln(F("│ │"));
|
||||
printfln(F("│ type %shelp%s to show available commands │"), COLOR_UNDERLINE, COLOR_RESET);
|
||||
printfln(F("└──────────────────────────────────────┘"));
|
||||
printfln("┌──────────────────────────────────────┐");
|
||||
printfln("│ %sEMS-ESP version %-10s%s │", COLOR_BOLD_ON, EMSESP_APP_VERSION, COLOR_BOLD_OFF);
|
||||
printfln("│ %s%shttps://github.com/emsesp/EMS-ESP32%s │", COLOR_BRIGHT_GREEN, COLOR_UNDERLINE, COLOR_RESET);
|
||||
printfln("│ │");
|
||||
printfln("│ type %shelp%s to show available commands │", COLOR_UNDERLINE, COLOR_RESET);
|
||||
printfln("└──────────────────────────────────────┘");
|
||||
println();
|
||||
|
||||
// set console name
|
||||
@@ -100,9 +100,9 @@ void EMSESPShell::add_console_commands() {
|
||||
|
||||
commands->add_command(ShellContext::MAIN,
|
||||
CommandFlags::USER,
|
||||
flash_string_vector{F_(show)},
|
||||
string_vector{F_(show)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) {
|
||||
shell.printfln(F("%s%sEMS-ESP version %s%s"), COLOR_BRIGHT_GREEN, COLOR_BOLD_ON, EMSESP_APP_VERSION, COLOR_RESET);
|
||||
shell.printfln("%s%sEMS-ESP version %s%s", COLOR_BRIGHT_GREEN, COLOR_BOLD_ON, EMSESP_APP_VERSION, COLOR_RESET);
|
||||
shell.println();
|
||||
EMSESP::show_device_values(shell);
|
||||
EMSESP::show_sensor_values(shell);
|
||||
@@ -110,36 +110,36 @@ void EMSESPShell::add_console_commands() {
|
||||
|
||||
commands->add_command(ShellContext::MAIN,
|
||||
CommandFlags::USER,
|
||||
flash_string_vector{F_(show), F_(devices)},
|
||||
string_vector{F_(show), F_(devices)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) { EMSESP::show_devices(shell); });
|
||||
|
||||
|
||||
commands->add_command(ShellContext::MAIN,
|
||||
CommandFlags::USER,
|
||||
flash_string_vector{F_(show), F_(ems)},
|
||||
string_vector{F_(show), F_(ems)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) { EMSESP::show_ems(shell); });
|
||||
|
||||
commands->add_command(ShellContext::MAIN,
|
||||
CommandFlags::USER,
|
||||
flash_string_vector{F_(show), F_(values)},
|
||||
string_vector{F_(show), F_(values)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) { EMSESP::show_device_values(shell); });
|
||||
|
||||
commands->add_command(ShellContext::MAIN,
|
||||
CommandFlags::USER,
|
||||
flash_string_vector{F_(show), F_(mqtt)},
|
||||
string_vector{F_(show), F_(mqtt)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) { Mqtt::show_mqtt(shell); });
|
||||
|
||||
|
||||
commands->add_command(ShellContext::MAIN,
|
||||
CommandFlags::USER,
|
||||
flash_string_vector{F_(show), F_(commands)},
|
||||
string_vector{F_(show), F_(commands)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) { Command::show_all(shell); });
|
||||
|
||||
commands->add_command(
|
||||
ShellContext::MAIN,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(set), F_(bus_id)},
|
||||
flash_string_vector{F_(deviceid_mandatory)},
|
||||
string_vector{F_(set), F_(bus_id)},
|
||||
string_vector{F_(deviceid_mandatory)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments) {
|
||||
uint8_t device_id = Helpers::hextoint(arguments.front().c_str());
|
||||
if ((device_id == 0x0B) || (device_id == 0x0D) || (device_id == 0x0A) || (device_id == 0x0F) || (device_id == 0x12)) {
|
||||
@@ -151,24 +151,24 @@ void EMSESPShell::add_console_commands() {
|
||||
},
|
||||
"local");
|
||||
} else {
|
||||
shell.println(F("Must be 0B, 0D, 0A, 0F or 12"));
|
||||
shell.println("Must be 0B, 0D, 0A, 0F or 12");
|
||||
}
|
||||
},
|
||||
[](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments __attribute__((unused))) -> const std::vector<std::string> {
|
||||
return std::vector<std::string>{
|
||||
read_flash_string(F("0B")),
|
||||
read_flash_string(F("0D")),
|
||||
read_flash_string(F("0A")),
|
||||
read_flash_string(F("0F")),
|
||||
read_flash_string(F("12")),
|
||||
("0B"),
|
||||
("0D"),
|
||||
("0A"),
|
||||
("0F"),
|
||||
("12"),
|
||||
|
||||
};
|
||||
});
|
||||
|
||||
commands->add_command(ShellContext::MAIN,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(set), F_(tx_mode)},
|
||||
flash_string_vector{F_(n_mandatory)},
|
||||
string_vector{F_(set), F_(tx_mode)},
|
||||
string_vector{F_(n_mandatory)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments) {
|
||||
uint8_t tx_mode = std::strtol(arguments[0].c_str(), nullptr, 10);
|
||||
// save the tx_mode
|
||||
@@ -183,13 +183,13 @@ void EMSESPShell::add_console_commands() {
|
||||
|
||||
commands->add_command(ShellContext::MAIN,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(scan), F_(devices)},
|
||||
flash_string_vector{F_(deep_optional)},
|
||||
string_vector{F_(scan), F_(devices)},
|
||||
string_vector{F_(deep_optional)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments) {
|
||||
if (arguments.size() == 0) {
|
||||
EMSESP::scan_devices();
|
||||
} else {
|
||||
shell.printfln(F("Performing a deep scan..."));
|
||||
shell.printfln("Performing a deep scan...");
|
||||
EMSESP::clear_all_devices();
|
||||
std::vector<uint8_t> Device_Ids;
|
||||
|
||||
@@ -222,10 +222,10 @@ void EMSESPShell::add_console_commands() {
|
||||
|
||||
commands->add_command(ShellContext::MAIN,
|
||||
CommandFlags::USER,
|
||||
flash_string_vector{F_(set)},
|
||||
string_vector{F_(set)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) {
|
||||
EMSESP::webSettingsService.read([&](WebSettings & settings) {
|
||||
shell.printfln(F("Language: %s"), settings.locale.c_str());
|
||||
shell.printfln("Language: %s", settings.locale.c_str());
|
||||
shell.printfln(F_(tx_mode_fmt), settings.tx_mode);
|
||||
shell.printfln(F_(bus_id_fmt), settings.ems_bus_id);
|
||||
shell.printfln(F_(board_profile_fmt), settings.board_profile.c_str());
|
||||
@@ -234,13 +234,13 @@ void EMSESPShell::add_console_commands() {
|
||||
|
||||
commands->add_command(ShellContext::MAIN,
|
||||
CommandFlags::USER,
|
||||
flash_string_vector{F_(read)},
|
||||
flash_string_vector{F_(deviceid_mandatory), F_(typeid_mandatory), F_(offset_optional), F_(length_optional)},
|
||||
string_vector{F_(read)},
|
||||
string_vector{F_(deviceid_mandatory), F_(typeid_mandatory), F_(offset_optional), F_(length_optional)},
|
||||
[=](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments) {
|
||||
uint8_t device_id = Helpers::hextoint(arguments.front().c_str());
|
||||
|
||||
if (!EMSESP::valid_device(device_id)) {
|
||||
shell.printfln(F("Invalid deviceID"));
|
||||
shell.printfln("Invalid deviceID");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -261,31 +261,31 @@ void EMSESPShell::add_console_commands() {
|
||||
#ifndef EMSESP_STANDALONE
|
||||
commands->add_command(ShellContext::MAIN,
|
||||
CommandFlags::USER,
|
||||
flash_string_vector{F_(set), F_(timeout)},
|
||||
flash_string_vector{F_(n_mandatory)},
|
||||
string_vector{F_(set), F_(timeout)},
|
||||
string_vector{F_(n_mandatory)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments) {
|
||||
uint16_t value = Helpers::atoint(arguments.front().c_str());
|
||||
telnet_.initial_idle_timeout(value * 60);
|
||||
shell.printfln(F("Telnet timeout set to %d minutes"), value);
|
||||
shell.printfln("Telnet timeout set to %d minutes", value);
|
||||
});
|
||||
#endif
|
||||
|
||||
commands->add_command(ShellContext::MAIN,
|
||||
CommandFlags::USER,
|
||||
flash_string_vector{F_(watch)},
|
||||
flash_string_vector{F_(watch_format_optional), F_(watchid_optional)},
|
||||
string_vector{F_(watch)},
|
||||
string_vector{F_(watch_format_optional), F_(watchid_optional)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments) {
|
||||
uint16_t watch_id = WATCH_ID_NONE;
|
||||
|
||||
if (!arguments.empty()) {
|
||||
// get raw/pretty
|
||||
if (arguments[0] == read_flash_string(F_(raw))) {
|
||||
if (arguments[0] == (F_(raw))) {
|
||||
EMSESP::watch(EMSESP::WATCH_RAW); // raw
|
||||
} else if (arguments[0] == Helpers::translated_word(FL_(on), true) || arguments[0] == read_flash_string(FL_(on)[0])) {
|
||||
} else if (arguments[0] == Helpers::translated_word(FL_(on), true) || arguments[0] == (FL_(on)[0])) {
|
||||
EMSESP::watch(EMSESP::WATCH_ON); // on
|
||||
} else if (arguments[0] == Helpers::translated_word(FL_(off), true) || arguments[0] == read_flash_string(FL_(off)[0])) {
|
||||
} else if (arguments[0] == Helpers::translated_word(FL_(off), true) || arguments[0] == (FL_(off)[0])) {
|
||||
EMSESP::watch(EMSESP::WATCH_OFF); // off
|
||||
} else if (arguments[0] == Helpers::translated_word(FL_(unknown), true) || arguments[0] == read_flash_string(FL_(unknown)[0])) {
|
||||
} else if (arguments[0] == Helpers::translated_word(FL_(unknown), true) || arguments[0] == (FL_(unknown)[0])) {
|
||||
EMSESP::watch(EMSESP::WATCH_UNKNOWN); // unknown
|
||||
watch_id = WATCH_ID_NONE;
|
||||
} else {
|
||||
@@ -305,43 +305,43 @@ void EMSESPShell::add_console_commands() {
|
||||
|
||||
EMSESP::watch_id(watch_id);
|
||||
} else {
|
||||
shell.printfln(F("Invalid: use watch raw|on|off|unknown|id [id]"));
|
||||
shell.printfln("Invalid: use watch raw|on|off|unknown|id [id]");
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t watch = EMSESP::watch();
|
||||
if (watch == EMSESP::WATCH_OFF) {
|
||||
shell.printfln(F("Watching telegrams is off"));
|
||||
shell.printfln("Watching telegrams is off");
|
||||
return;
|
||||
}
|
||||
|
||||
// if logging is off, the watch won't show anything, show force it back to NOTICE
|
||||
if (shell.log_level() < Level::NOTICE) {
|
||||
shell.log_level(Level::NOTICE);
|
||||
shell.printfln(F("Setting log level to Notice"));
|
||||
shell.printfln("Setting log level to Notice");
|
||||
}
|
||||
|
||||
if (watch == EMSESP::WATCH_ON) {
|
||||
shell.printfln(F("Watching incoming telegrams, displayed in decoded format"));
|
||||
shell.printfln("Watching incoming telegrams, displayed in decoded format");
|
||||
} else if (watch == EMSESP::WATCH_RAW) {
|
||||
shell.printfln(F("Watching incoming telegrams, displayed as raw bytes")); // WATCH_RAW
|
||||
shell.printfln("Watching incoming telegrams, displayed as raw bytes"); // WATCH_RAW
|
||||
} else {
|
||||
shell.printfln(F("Watching unknown telegrams")); // WATCH_UNKNOWN
|
||||
shell.printfln("Watching unknown telegrams"); // WATCH_UNKNOWN
|
||||
}
|
||||
|
||||
watch_id = EMSESP::watch_id();
|
||||
if (watch_id > 0x80) {
|
||||
shell.printfln(F("Filtering only telegrams that match a telegram type of 0x%02X"), watch_id);
|
||||
shell.printfln("Filtering only telegrams that match a telegram type of 0x%02X", watch_id);
|
||||
} else if (watch_id != WATCH_ID_NONE) {
|
||||
shell.printfln(F("Filtering only telegrams that match a deviceID or telegram type of 0x%02X"), watch_id);
|
||||
shell.printfln("Filtering only telegrams that match a deviceID or telegram type of 0x%02X", watch_id);
|
||||
}
|
||||
});
|
||||
|
||||
commands->add_command(
|
||||
ShellContext::MAIN,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(call)},
|
||||
flash_string_vector{F_(device_type_optional), F_(cmd_optional), F_(data_optional), F_(id_optional)},
|
||||
string_vector{F_(call)},
|
||||
string_vector{F_(device_type_optional), F_(cmd_optional), F_(data_optional), F_(id_optional)},
|
||||
[&](Shell & shell, const std::vector<std::string> & arguments) {
|
||||
if (arguments.empty()) {
|
||||
Command::show_all(shell); // list options
|
||||
@@ -351,7 +351,7 @@ void EMSESPShell::add_console_commands() {
|
||||
// validate the device_type
|
||||
uint8_t device_type = EMSdevice::device_name_2_device_type(arguments[0].c_str());
|
||||
if (!Command::device_has_commands(device_type)) {
|
||||
shell.print(F("Invalid device. Available devices are: "));
|
||||
shell.print("Invalid device. Available devices are: ");
|
||||
Command::show_devices(shell);
|
||||
return;
|
||||
}
|
||||
@@ -359,7 +359,7 @@ void EMSESPShell::add_console_commands() {
|
||||
|
||||
// validate that a command is present
|
||||
if (arguments.size() < 2) {
|
||||
shell.print(F("Missing command. Available commands are: "));
|
||||
shell.print("Missing command. Available commands are: ");
|
||||
Command::show(shell, device_type, false); // non-verbose mode
|
||||
return;
|
||||
}
|
||||
@@ -399,11 +399,11 @@ void EMSESPShell::add_console_commands() {
|
||||
}
|
||||
|
||||
if (return_code == CommandRet::NOT_FOUND) {
|
||||
shell.println(F("Unknown command"));
|
||||
shell.print(F("Available commands are: "));
|
||||
shell.println("Unknown command");
|
||||
shell.print("Available commands are: ");
|
||||
Command::show(shell, device_type, false); // non-verbose mode
|
||||
} else if (return_code != CommandRet::OK) {
|
||||
shell.printfln(F("Bad syntax (error code %d)"), return_code);
|
||||
shell.printfln(("Bad syntax (error code %d)"), return_code);
|
||||
}
|
||||
},
|
||||
[&](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments) -> std::vector<std::string> {
|
||||
@@ -424,7 +424,7 @@ void EMSESPShell::add_console_commands() {
|
||||
if (Command::device_has_commands(device_type)) {
|
||||
for (const auto & cf : Command::commands()) {
|
||||
if (cf.device_type_ == device_type) {
|
||||
command_list.emplace_back(read_flash_string(cf.cmd_));
|
||||
command_list.emplace_back((cf.cmd_));
|
||||
}
|
||||
}
|
||||
return command_list;
|
||||
@@ -448,8 +448,8 @@ void Console::load_standard_commands(unsigned int context) {
|
||||
// create commands test and t
|
||||
EMSESPShell::commands->add_command(context,
|
||||
CommandFlags::USER,
|
||||
flash_string_vector{F("test")},
|
||||
flash_string_vector{F_(name_optional), F_(data_optional)},
|
||||
string_vector{("test")},
|
||||
string_vector{F_(name_optional), F_(data_optional)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments) {
|
||||
if (arguments.empty()) {
|
||||
Test::run_test(shell, "default");
|
||||
@@ -460,7 +460,7 @@ void Console::load_standard_commands(unsigned int context) {
|
||||
}
|
||||
});
|
||||
|
||||
EMSESPShell::commands->add_command(context, CommandFlags::USER, flash_string_vector{F("t")}, [](Shell & shell, const std::vector<std::string> & arguments) {
|
||||
EMSESPShell::commands->add_command(context, CommandFlags::USER, string_vector{("t")}, [](Shell & shell, const std::vector<std::string> & arguments) {
|
||||
Test::run_test(shell, "default");
|
||||
});
|
||||
#endif
|
||||
@@ -468,8 +468,8 @@ void Console::load_standard_commands(unsigned int context) {
|
||||
#if defined(EMSESP_DEBUG)
|
||||
EMSESPShell::commands->add_command(context,
|
||||
CommandFlags::USER,
|
||||
flash_string_vector{F_(debug)},
|
||||
flash_string_vector{F_(name_optional)},
|
||||
string_vector{F_(debug)},
|
||||
string_vector{F_(name_optional)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments) {
|
||||
if (arguments.empty()) {
|
||||
Test::debug(shell, "default");
|
||||
@@ -482,8 +482,8 @@ void Console::load_standard_commands(unsigned int context) {
|
||||
EMSESPShell::commands->add_command(
|
||||
context,
|
||||
CommandFlags::USER,
|
||||
flash_string_vector{F_(log)},
|
||||
flash_string_vector{F_(log_level_optional)},
|
||||
string_vector{F_(log)},
|
||||
string_vector{F_(log_level_optional)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments) {
|
||||
if (!arguments.empty()) {
|
||||
uuid::log::Level level;
|
||||
@@ -494,7 +494,7 @@ void Console::load_standard_commands(unsigned int context) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
shell.print(F("levels: "));
|
||||
shell.print("levels: ");
|
||||
std::vector<std::string> v = uuid::log::levels_lowercase();
|
||||
size_t i = v.size();
|
||||
while (i--) {
|
||||
@@ -511,22 +511,22 @@ void Console::load_standard_commands(unsigned int context) {
|
||||
|
||||
EMSESPShell::commands->add_command(context,
|
||||
CommandFlags::USER,
|
||||
flash_string_vector{F_(help)},
|
||||
string_vector{F_(help)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) {
|
||||
shell.print_all_available_commands();
|
||||
});
|
||||
|
||||
EMSESPShell::commands->add_command(context,
|
||||
CommandFlags::USER,
|
||||
flash_string_vector{F_(exit)},
|
||||
string_vector{F_(exit)},
|
||||
[=](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) { shell.stop(); });
|
||||
|
||||
EMSESPShell::commands->add_command(context,
|
||||
CommandFlags::USER,
|
||||
flash_string_vector{F_(su)},
|
||||
string_vector{F_(su)},
|
||||
[=](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) {
|
||||
auto become_admin = [](Shell & shell) {
|
||||
shell.logger().log(LogLevel::NOTICE, LogFacility::AUTH, F("su session opened on console"));
|
||||
shell.logger().log(LogLevel::NOTICE, LogFacility::AUTH, ("su session opened on console"));
|
||||
shell.add_flags(CommandFlags::ADMIN);
|
||||
};
|
||||
|
||||
@@ -542,8 +542,8 @@ void Console::load_standard_commands(unsigned int context) {
|
||||
become_admin(shell);
|
||||
} else {
|
||||
shell.delay_until(now + INVALID_PASSWORD_DELAY_MS, [](Shell & shell) {
|
||||
shell.logger().log(LogLevel::NOTICE, LogFacility::AUTH, F("Invalid su password on console"));
|
||||
shell.println(F("su: incorrect password"));
|
||||
shell.logger().log(LogLevel::NOTICE, LogFacility::AUTH, ("Invalid su password on console"));
|
||||
shell.println("su: incorrect password");
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -557,21 +557,21 @@ void Console::load_standard_commands(unsigned int context) {
|
||||
void Console::load_system_commands(unsigned int context) {
|
||||
EMSESPShell::commands->add_command(context,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(restart)},
|
||||
string_vector{F_(restart)},
|
||||
[](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments __attribute__((unused))) {
|
||||
EMSESP::system_.system_restart();
|
||||
});
|
||||
|
||||
EMSESPShell::commands->add_command(context,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(wifi), F_(reconnect)},
|
||||
string_vector{F_(wifi), F_(reconnect)},
|
||||
[](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments __attribute__((unused))) {
|
||||
EMSESP::system_.wifi_reconnect();
|
||||
});
|
||||
|
||||
EMSESPShell::commands->add_command(ShellContext::MAIN,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(format)},
|
||||
string_vector{F_(format)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) {
|
||||
shell.enter_password(F_(password_prompt), [=](Shell & shell, bool completed, const std::string & password) {
|
||||
if (completed) {
|
||||
@@ -579,7 +579,7 @@ void Console::load_system_commands(unsigned int context) {
|
||||
if (securitySettings.jwtSecret.equals(password.c_str())) {
|
||||
EMSESP::system_.format(shell);
|
||||
} else {
|
||||
shell.println(F("incorrect password"));
|
||||
shell.println("incorrect password");
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -588,7 +588,7 @@ void Console::load_system_commands(unsigned int context) {
|
||||
|
||||
EMSESPShell::commands->add_command(context,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(passwd)},
|
||||
string_vector{F_(passwd)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) {
|
||||
shell.enter_password(F_(new_password_prompt1), [](Shell & shell, bool completed, const std::string & password1) {
|
||||
if (completed) {
|
||||
@@ -602,9 +602,9 @@ void Console::load_system_commands(unsigned int context) {
|
||||
return StateUpdateResult::CHANGED;
|
||||
},
|
||||
"local");
|
||||
shell.println(F("su password updated"));
|
||||
shell.println("su password updated");
|
||||
} else {
|
||||
shell.println(F("Passwords do not match"));
|
||||
shell.println("Passwords do not match");
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -614,7 +614,7 @@ void Console::load_system_commands(unsigned int context) {
|
||||
|
||||
EMSESPShell::commands->add_command(context,
|
||||
CommandFlags::USER,
|
||||
flash_string_vector{F_(show), F_(system)},
|
||||
string_vector{F_(show), F_(system)},
|
||||
[=](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) {
|
||||
EMSESP::system_.show_system(shell);
|
||||
shell.println();
|
||||
@@ -622,8 +622,8 @@ void Console::load_system_commands(unsigned int context) {
|
||||
|
||||
EMSESPShell::commands->add_command(context,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(set), F_(hostname)},
|
||||
flash_string_vector{F_(name_mandatory)},
|
||||
string_vector{F_(set), F_(hostname)},
|
||||
string_vector{F_(name_mandatory)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments) {
|
||||
shell.println("The network connection will be reset...");
|
||||
Shell::loop_all();
|
||||
@@ -638,8 +638,8 @@ void Console::load_system_commands(unsigned int context) {
|
||||
|
||||
EMSESPShell::commands->add_command(context,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(set), F_(wifi), F_(ssid)},
|
||||
flash_string_vector{F_(name_mandatory)},
|
||||
string_vector{F_(set), F_(wifi), F_(ssid)},
|
||||
string_vector{F_(name_mandatory)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments) {
|
||||
EMSESP::esp8266React.getNetworkSettingsService()->updateWithoutPropagation([&](NetworkSettings & networkSettings) {
|
||||
networkSettings.ssid = arguments.front().c_str();
|
||||
@@ -651,8 +651,8 @@ void Console::load_system_commands(unsigned int context) {
|
||||
// added by mvdp
|
||||
EMSESPShell::commands->add_command(context,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F("mqtt"), F("subscribe")},
|
||||
flash_string_vector{F("<topic>")},
|
||||
string_vector{("mqtt"), ("subscribe")},
|
||||
string_vector{("<topic>")},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments) {
|
||||
Mqtt::subscribe(arguments.front());
|
||||
shell.println("subscribing");
|
||||
@@ -660,7 +660,7 @@ void Console::load_system_commands(unsigned int context) {
|
||||
|
||||
EMSESPShell::commands->add_command(context,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(set), F_(wifi), F_(password)},
|
||||
string_vector{F_(set), F_(wifi), F_(password)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) {
|
||||
shell.enter_password(F_(new_password_prompt1), [](Shell & shell, bool completed, const std::string & password1) {
|
||||
if (completed) {
|
||||
@@ -675,7 +675,7 @@ void Console::load_system_commands(unsigned int context) {
|
||||
});
|
||||
shell.println("Use `wifi reconnect` to save and apply the new settings");
|
||||
} else {
|
||||
shell.println(F("Passwords do not match"));
|
||||
shell.println("Passwords do not match");
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -685,13 +685,13 @@ void Console::load_system_commands(unsigned int context) {
|
||||
|
||||
EMSESPShell::commands->add_command(context,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(set), F_(board_profile)},
|
||||
flash_string_vector{F_(name_mandatory)},
|
||||
string_vector{F_(set), F_(board_profile)},
|
||||
string_vector{F_(name_mandatory)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments) {
|
||||
std::vector<int8_t> data; // led, dallas, rx, tx, button, phy_type, eth_power, eth_phy_addr, eth_clock_mode
|
||||
std::string board_profile = Helpers::toUpper(arguments.front());
|
||||
if (!EMSESP::system_.load_board_profile(data, board_profile)) {
|
||||
shell.println(F("Invalid board profile (S32, E32, MH-ET, NODEMCU, OLIMEX, OLIMEXPOE, C3MINI, CUSTOM)"));
|
||||
shell.println(("Invalid board profile (S32, E32, MH-ET, NODEMCU, OLIMEX, OLIMEXPOE, C3MINI, CUSTOM)"));
|
||||
return;
|
||||
}
|
||||
EMSESP::webSettingsService.update(
|
||||
@@ -714,7 +714,7 @@ void Console::load_system_commands(unsigned int context) {
|
||||
});
|
||||
EMSESPShell::commands->add_command(context,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(show), F_(users)},
|
||||
string_vector{F_(show), F_(users)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) {
|
||||
EMSESP::system_.show_users(shell);
|
||||
});
|
||||
@@ -730,14 +730,14 @@ std::string EMSESPShell::prompt_suffix() {
|
||||
}
|
||||
|
||||
void EMSESPShell::end_of_transmission() {
|
||||
invoke_command(read_flash_string(F_(exit)));
|
||||
invoke_command((F_(exit)));
|
||||
}
|
||||
|
||||
EMSESPStreamConsole::EMSESPStreamConsole(Stream & stream, bool local)
|
||||
: uuid::console::Shell(commands, ShellContext::MAIN, local ? (CommandFlags::USER | CommandFlags::LOCAL) : CommandFlags::USER)
|
||||
, uuid::console::StreamConsole(stream)
|
||||
, EMSESPShell()
|
||||
, name_(read_flash_string(F("Serial")))
|
||||
, name_("Serial")
|
||||
, pty_(SIZE_MAX)
|
||||
, addr_()
|
||||
, port_(0) {
|
||||
@@ -763,14 +763,14 @@ EMSESPStreamConsole::EMSESPStreamConsole(Stream & stream, const IPAddress & addr
|
||||
snprintf(text.data(), text.size(), "pty%u", (uint16_t)pty_);
|
||||
name_ = text.data();
|
||||
#ifndef EMSESP_STANDALONE
|
||||
logger().info(F("Allocated console %s for connection from [%s]:%u"), name_.c_str(), uuid::printable_to_string(addr_).c_str(), port_);
|
||||
logger().info("Allocated console %s for connection from [%s]:%u", name_.c_str(), uuid::printable_to_string(addr_).c_str(), port_);
|
||||
#endif
|
||||
}
|
||||
|
||||
EMSESPStreamConsole::~EMSESPStreamConsole() {
|
||||
if (pty_ != SIZE_MAX) {
|
||||
#ifndef EMSESP_STANDALONE
|
||||
logger().info(F("Shutdown console %s for connection from [%s]:%u"), name_.c_str(), uuid::printable_to_string(addr_).c_str(), port_);
|
||||
logger().info("Shutdown console %s for connection from [%s]:%u", name_.c_str(), uuid::printable_to_string(addr_).c_str(), port_);
|
||||
#endif
|
||||
ptys_[pty_] = false;
|
||||
ptys_.shrink_to_fit();
|
||||
|
||||
@@ -42,7 +42,7 @@ void DallasSensor::start() {
|
||||
|
||||
#ifndef EMSESP_STANDALONE
|
||||
bus_.begin(dallas_gpio_);
|
||||
LOG_INFO(F("Starting Dallas sensor service"));
|
||||
LOG_INFO("Starting Dallas sensor service");
|
||||
#endif
|
||||
|
||||
// Add API calls
|
||||
@@ -84,7 +84,7 @@ void DallasSensor::loop() {
|
||||
if (state_ == State::IDLE) {
|
||||
if (time_now - last_activity_ >= READ_INTERVAL_MS) {
|
||||
#ifdef EMSESP_DEBUG_SENSOR
|
||||
LOG_DEBUG(F("[DEBUG] Read sensor temperature"));
|
||||
LOG_DEBUG("[DEBUG] Read sensor temperature");
|
||||
#endif
|
||||
if (bus_.reset() || parasite_) {
|
||||
YIELD;
|
||||
@@ -99,7 +99,7 @@ void DallasSensor::loop() {
|
||||
if (++scanretry_ > SCAN_MAX) { // every 30 sec
|
||||
scanretry_ = 0;
|
||||
#ifdef EMSESP_DEBUG_SENSOR
|
||||
LOG_ERROR(F("Bus reset failed"));
|
||||
LOG_ERROR("Bus reset failed");
|
||||
#endif
|
||||
for (auto & sensor : sensors_) {
|
||||
sensor.temperature_c = EMS_VALUE_SHORT_NOTSET;
|
||||
@@ -112,13 +112,13 @@ void DallasSensor::loop() {
|
||||
} else if (state_ == State::READING) {
|
||||
if (temperature_convert_complete() && (time_now - last_activity_ > CONVERSION_MS)) {
|
||||
#ifdef EMSESP_DEBUG_SENSOR
|
||||
LOG_DEBUG(F("Scanning for sensors"));
|
||||
LOG_DEBUG("Scanning for sensors");
|
||||
#endif
|
||||
bus_.reset_search();
|
||||
state_ = State::SCANNING;
|
||||
} else if (time_now - last_activity_ > READ_TIMEOUT_MS) {
|
||||
#ifdef EMSESP_DEBUG_SENSOR
|
||||
LOG_WARNING(F("Dallas sensor read timeout"));
|
||||
LOG_WARNING("Dallas sensor read timeout");
|
||||
#endif
|
||||
state_ = State::IDLE;
|
||||
sensorfails_++;
|
||||
@@ -126,7 +126,7 @@ void DallasSensor::loop() {
|
||||
} else if (state_ == State::SCANNING) {
|
||||
if (time_now - last_activity_ > SCAN_TIMEOUT_MS) {
|
||||
#ifdef EMSESP_DEBUG_SENSOR
|
||||
LOG_ERROR(F("Dallas sensor scan timeout"));
|
||||
LOG_ERROR("Dallas sensor scan timeout");
|
||||
#endif
|
||||
state_ = State::IDLE;
|
||||
sensorfails_++;
|
||||
@@ -181,12 +181,12 @@ void DallasSensor::loop() {
|
||||
|
||||
default:
|
||||
sensorfails_++;
|
||||
LOG_ERROR(F("Unknown dallas sensor %s"), Sensor(addr).id().c_str());
|
||||
LOG_ERROR("Unknown dallas sensor %s", Sensor(addr).id().c_str());
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
sensorfails_++;
|
||||
LOG_ERROR(F("Invalid dallas sensor %s"), Sensor(addr).id().c_str());
|
||||
LOG_ERROR("Invalid dallas sensor %s", Sensor(addr).id().c_str());
|
||||
}
|
||||
} else {
|
||||
if (!parasite_) {
|
||||
@@ -204,7 +204,7 @@ void DallasSensor::loop() {
|
||||
scancnt_ = 0;
|
||||
} else if (scancnt_ == SCAN_START + 1) { // startup
|
||||
firstscan_ = sensors_.size();
|
||||
// LOG_DEBUG(F("Adding %d dallas sensor(s) from first scan"), firstscan_);
|
||||
// LOG_DEBUG(("Adding %d dallas sensor(s) from first scan"), firstscan_);
|
||||
} else if ((scancnt_ <= 0) && (firstscan_ != sensors_.size())) { // check 2 times for no change of sensor #
|
||||
scancnt_ = SCAN_START;
|
||||
sensors_.clear(); // restart scaning and clear to get correct numbering
|
||||
@@ -230,7 +230,7 @@ bool DallasSensor::temperature_convert_complete() {
|
||||
int16_t DallasSensor::get_temperature_c(const uint8_t addr[]) {
|
||||
#ifndef EMSESP_STANDALONE
|
||||
if (!bus_.reset()) {
|
||||
LOG_ERROR(F("Bus reset failed before reading scratchpad from %s"), Sensor(addr).id().c_str());
|
||||
LOG_ERROR("Bus reset failed before reading scratchpad from %s", Sensor(addr).id().c_str());
|
||||
return EMS_VALUE_SHORT_NOTSET;
|
||||
}
|
||||
YIELD;
|
||||
@@ -242,13 +242,13 @@ int16_t DallasSensor::get_temperature_c(const uint8_t addr[]) {
|
||||
YIELD;
|
||||
|
||||
if (!bus_.reset()) {
|
||||
LOG_ERROR(F("Bus reset failed after reading scratchpad from %s"), Sensor(addr).id().c_str());
|
||||
LOG_ERROR("Bus reset failed after reading scratchpad from %s", Sensor(addr).id().c_str());
|
||||
return EMS_VALUE_SHORT_NOTSET;
|
||||
}
|
||||
YIELD;
|
||||
|
||||
if (bus_.crc8(scratchpad, SCRATCHPAD_LEN - 1) != scratchpad[SCRATCHPAD_LEN - 1]) {
|
||||
LOG_WARNING(F("Invalid scratchpad CRC: %02X%02X%02X%02X%02X%02X%02X%02X%02X from sensor %s"),
|
||||
LOG_WARNING("Invalid scratchpad CRC: %02X%02X%02X%02X%02X%02X%02X%02X%02X from sensor %s",
|
||||
scratchpad[0],
|
||||
scratchpad[1],
|
||||
scratchpad[2],
|
||||
@@ -315,7 +315,7 @@ bool DallasSensor::update(const std::string & id, const std::string & name, int1
|
||||
SensorCustomization.name = name;
|
||||
SensorCustomization.offset = offset;
|
||||
found = true;
|
||||
LOG_DEBUG(F("Customizing existing sensor ID %s"), id.c_str());
|
||||
LOG_DEBUG("Customizing existing sensor ID %s", id.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -325,7 +325,7 @@ bool DallasSensor::update(const std::string & id, const std::string & name, int1
|
||||
newSensor.name = name;
|
||||
newSensor.offset = offset;
|
||||
settings.sensorCustomizations.push_back(newSensor);
|
||||
LOG_DEBUG(F("Adding new customization for sensor ID %s"), id.c_str());
|
||||
LOG_DEBUG("Adding new customization for sensor ID %s", id.c_str());
|
||||
}
|
||||
sensor.ha_registered = false; // it's changed so we may need to recreate the HA config
|
||||
return StateUpdateResult::CHANGED;
|
||||
@@ -397,11 +397,13 @@ bool DallasSensor::get_value_info(JsonObject & output, const char * cmd, const i
|
||||
if (Helpers::hasValue(sensor.temperature_c)) {
|
||||
output["value"] = serialized(Helpers::render_value(val, sensor.temperature_c, 10, EMSESP::system_.fahrenheit() ? 2 : 0));
|
||||
}
|
||||
|
||||
output["type"] = F_(number);
|
||||
output["min"] = serialized(Helpers::render_value(val, -55, 0, EMSESP::system_.fahrenheit() ? 2 : 0));
|
||||
output["max"] = serialized(Helpers::render_value(val, 125, 0, EMSESP::system_.fahrenheit() ? 2 : 0));
|
||||
output["uom"] = EMSdevice::uom_to_string(DeviceValueUOM::DEGREES);
|
||||
output["writeable"] = false;
|
||||
|
||||
// if we're filtering on an attribute, go find it
|
||||
if (attribute_s) {
|
||||
if (output.containsKey(attribute_s)) {
|
||||
@@ -428,9 +430,9 @@ void DallasSensor::publish_sensor(const Sensor & sensor) {
|
||||
if (Mqtt::publish_single()) {
|
||||
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||
if (Mqtt::publish_single2cmd()) {
|
||||
snprintf(topic, sizeof(topic), "%s/%s", read_flash_string(F_(dallassensor)).c_str(), sensor.name().c_str());
|
||||
snprintf(topic, sizeof(topic), "%s/%s", (F_(dallassensor)), sensor.name().c_str());
|
||||
} else {
|
||||
snprintf(topic, sizeof(topic), "%s%s/%s", read_flash_string(F_(dallassensor)).c_str(), "_data", sensor.name().c_str());
|
||||
snprintf(topic, sizeof(topic), "%s%s/%s", (F_(dallassensor)), "_data", sensor.name().c_str());
|
||||
}
|
||||
char payload[10];
|
||||
Mqtt::publish(topic, Helpers::render_value(payload, sensor.temperature_c, 10, EMSESP::system_.fahrenheit() ? 2 : 0));
|
||||
@@ -443,7 +445,7 @@ void DallasSensor::remove_ha_topic(const std::string & id) {
|
||||
return;
|
||||
}
|
||||
#ifdef EMSESP_DEBUG
|
||||
LOG_DEBUG(F("Removing HA config for temperature sensor ID %s"), id.c_str());
|
||||
LOG_DEBUG("Removing HA config for temperature sensor ID %s", id.c_str());
|
||||
#endif
|
||||
// use '_' as HA doesn't like '-' in the topic name
|
||||
std::string sensorid = id;
|
||||
@@ -486,10 +488,10 @@ void DallasSensor::publish_values(const bool force) {
|
||||
// to e.g. homeassistant/sensor/ems-esp/dallassensor_28-233D-9497-0C03/config
|
||||
if (Mqtt::ha_enabled()) {
|
||||
if (!sensor.ha_registered || force) {
|
||||
LOG_DEBUG(F("Recreating HA config for sensor ID %s"), sensor.id().c_str());
|
||||
LOG_DEBUG("Recreating HA config for sensor ID %s", sensor.id().c_str());
|
||||
|
||||
StaticJsonDocument<EMSESP_JSON_SIZE_MEDIUM> config;
|
||||
config["dev_cla"] = FJSON("temperature");
|
||||
config["dev_cla"] = "temperature";
|
||||
|
||||
char stat_t[50];
|
||||
snprintf(stat_t, sizeof(stat_t), "%s/dallassensor_data", Mqtt::base().c_str());
|
||||
@@ -533,7 +535,7 @@ void DallasSensor::publish_values(const bool force) {
|
||||
}
|
||||
}
|
||||
|
||||
Mqtt::publish(F("dallassensor_data"), doc.as<JsonObject>());
|
||||
Mqtt::publish("dallassensor_data", doc.as<JsonObject>());
|
||||
}
|
||||
|
||||
|
||||
@@ -577,7 +579,7 @@ bool DallasSensor::Sensor::apply_customization() {
|
||||
if (!sensors.empty()) {
|
||||
for (const auto & sensor : sensors) {
|
||||
#if defined(EMSESP_DEBUG)
|
||||
LOG_DEBUG(F("Loading customization for dallas sensor %s"), sensor.id.c_str());
|
||||
LOG_DEBUG("Loading customization for dallas sensor %s", sensor.id.c_str());
|
||||
#endif
|
||||
if (id_ == sensor.id) {
|
||||
set_name(sensor.name);
|
||||
|
||||
@@ -24,142 +24,142 @@
|
||||
*/
|
||||
|
||||
// Boilers - 0x08
|
||||
{ 64, DeviceType::BOILER, F("BK13/BK15/Smartline/GB1x2"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{ 72, DeviceType::BOILER, F("GB125/MC10"), DeviceFlags::EMS_DEVICE_FLAG_EMS},
|
||||
{ 81, DeviceType::BOILER, F("Cascade CM10"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{ 84, DeviceType::BOILER, F("Logamax Plus GB022"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{ 95, DeviceType::BOILER, F("Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3"), DeviceFlags::EMS_DEVICE_FLAG_HT3},
|
||||
{115, DeviceType::BOILER, F("Topline/GB162"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{122, DeviceType::BOILER, F("Proline"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{123, DeviceType::BOILER, F("GBx72/Trendline/Cerapur/Greenstar Si/27i"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{131, DeviceType::BOILER, F("GB212"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{132, DeviceType::BOILER, F("GC7000F"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{133, DeviceType::BOILER, F("Logano GB125/KB195i/Logamatic MC110"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{154, DeviceType::BOILER, F("Greenstar 30Ri Compact"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{167, DeviceType::BOILER, F("Cerapur Aero"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{168, DeviceType::BOILER, F("Hybrid Heatpump"), DeviceFlags::EMS_DEVICE_FLAG_HYBRID},
|
||||
{170, DeviceType::BOILER, F("Logano GB212"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{172, DeviceType::BOILER, F("Enviline/Compress 6000AW/Hybrid 7000iAW/SupraEco/Geo 5xx"), DeviceFlags::EMS_DEVICE_FLAG_HEATPUMP},
|
||||
{173, DeviceType::BOILER, F("Geo 5xx"), DeviceFlags::EMS_DEVICE_FLAG_HEATPUMP},
|
||||
{195, DeviceType::BOILER, F("Condens 5000i/Greenstar 8000"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{203, DeviceType::BOILER, F("Logamax U122/Cerapur"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{206, DeviceType::BOILER, F("Ecomline Excellent"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{208, DeviceType::BOILER, F("Logamax Plus/GB192/Condens GC9000"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{210, DeviceType::BOILER, F("Cascade MC400"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{211, DeviceType::BOILER, F("EasyControl Adapter"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{228, DeviceType::BOILER, F("Alternative Heatsource"), DeviceFlags::EMS_DEVICE_FLAG_AM200},
|
||||
{234, DeviceType::BOILER, F("Logamax Plus GB122/Condense 2300"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{ 64, DeviceType::BOILER, "BK13/BK15/Smartline/GB1x2", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{ 72, DeviceType::BOILER, "GB125/MC10", DeviceFlags::EMS_DEVICE_FLAG_EMS},
|
||||
{ 81, DeviceType::BOILER, "Cascade CM10", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{ 84, DeviceType::BOILER, "Logamax Plus GB022", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{ 95, DeviceType::BOILER, "Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3", DeviceFlags::EMS_DEVICE_FLAG_HT3},
|
||||
{115, DeviceType::BOILER, "Topline/GB162", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{122, DeviceType::BOILER, "Proline", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{123, DeviceType::BOILER, "GBx72/Trendline/Cerapur/Greenstar Si/27i", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{131, DeviceType::BOILER, "GB212", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{132, DeviceType::BOILER, "GC7000F", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{133, DeviceType::BOILER, "Logano GB125/KB195i/Logamatic MC110", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{154, DeviceType::BOILER, "Greenstar 30Ri Compact", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{167, DeviceType::BOILER, "Cerapur Aero", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{168, DeviceType::BOILER, "Hybrid Heatpump", DeviceFlags::EMS_DEVICE_FLAG_HYBRID},
|
||||
{170, DeviceType::BOILER, "Logano GB212", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{172, DeviceType::BOILER, "Enviline/Compress 6000AW/Hybrid 7000iAW/SupraEco/Geo 5xx", DeviceFlags::EMS_DEVICE_FLAG_HEATPUMP},
|
||||
{173, DeviceType::BOILER, "Geo 5xx", DeviceFlags::EMS_DEVICE_FLAG_HEATPUMP},
|
||||
{195, DeviceType::BOILER, "Condens 5000i/Greenstar 8000", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{203, DeviceType::BOILER, "Logamax U122/Cerapur", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{206, DeviceType::BOILER, "Ecomline Excellent", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{208, DeviceType::BOILER, "Logamax Plus/GB192/Condens GC9000", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{210, DeviceType::BOILER, "Cascade MC400", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{211, DeviceType::BOILER, "EasyControl Adapter", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{228, DeviceType::BOILER, "Alternative Heatsource", DeviceFlags::EMS_DEVICE_FLAG_AM200},
|
||||
{234, DeviceType::BOILER, "Logamax Plus GB122/Condense 2300", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
|
||||
// Controllers - 0x09 / 0x10 / 0x50
|
||||
{ 68, DeviceType::CONTROLLER, F("BC10/RFM20"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{ 81, DeviceType::CONTROLLER, F("CM10"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{ 84, DeviceType::CONTROLLER, F("GB022"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{ 89, DeviceType::CONTROLLER, F("BC10 GB142"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{ 95, DeviceType::CONTROLLER, F("HT3"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{114, DeviceType::CONTROLLER, F("BC10"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{125, DeviceType::CONTROLLER, F("BC25"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{152, DeviceType::CONTROLLER, F("Controller"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{168, DeviceType::CONTROLLER, F("Hybrid Heatpump"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{169, DeviceType::CONTROLLER, F("BC40"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{190, DeviceType::CONTROLLER, F("BC10"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{194, DeviceType::CONTROLLER, F("BC10"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{206, DeviceType::CONTROLLER, F("Ecomline"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{207, DeviceType::CONTROLLER, F("Sense II/CS200"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x10
|
||||
{209, DeviceType::CONTROLLER, F("ErP"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{218, DeviceType::CONTROLLER, F("M200/RFM200"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x50
|
||||
{220, DeviceType::CONTROLLER, F("BC30"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x16
|
||||
{224, DeviceType::CONTROLLER, F("9000i"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{229, DeviceType::CONTROLLER, F("8700i"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{230, DeviceType::CONTROLLER, F("BC Base"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{240, DeviceType::CONTROLLER, F("Rego 3000"), DeviceFlags::EMS_DEVICE_FLAG_IVT}, // 0x09
|
||||
{241, DeviceType::CONTROLLER, F("Condens 5000i"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{ 68, DeviceType::CONTROLLER, "BC10/RFM20", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{ 81, DeviceType::CONTROLLER, "CM10", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{ 84, DeviceType::CONTROLLER, "GB022", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{ 89, DeviceType::CONTROLLER, "BC10 GB142", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{ 95, DeviceType::CONTROLLER, "HT3", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{114, DeviceType::CONTROLLER, "BC10", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{125, DeviceType::CONTROLLER, "BC25", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{152, DeviceType::CONTROLLER, "Controller", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{168, DeviceType::CONTROLLER, "Hybrid Heatpump", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{169, DeviceType::CONTROLLER, "BC40", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{190, DeviceType::CONTROLLER, "BC10", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{194, DeviceType::CONTROLLER, "BC10", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{206, DeviceType::CONTROLLER, "Ecomline", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{207, DeviceType::CONTROLLER, "Sense II/CS200", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x10
|
||||
{209, DeviceType::CONTROLLER, "ErP", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{218, DeviceType::CONTROLLER, "M200/RFM200", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x50
|
||||
{220, DeviceType::CONTROLLER, "BC30", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x16
|
||||
{224, DeviceType::CONTROLLER, "9000i", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{229, DeviceType::CONTROLLER, "8700i", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{230, DeviceType::CONTROLLER, "BC Base", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
{240, DeviceType::CONTROLLER, "Rego 3000", DeviceFlags::EMS_DEVICE_FLAG_IVT}, // 0x09
|
||||
{241, DeviceType::CONTROLLER, "Condens 5000i", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||
|
||||
// Thermostat - not currently supporting write operations, like the Easy/100 types - 0x18
|
||||
{202, DeviceType::THERMOSTAT, F("Logamatic TC100/Moduline Easy"), DeviceFlags::EMS_DEVICE_FLAG_EASY | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18, cannot write
|
||||
{203, DeviceType::THERMOSTAT, F("EasyControl CT200"), DeviceFlags::EMS_DEVICE_FLAG_EASY | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18, cannot write
|
||||
{202, DeviceType::THERMOSTAT, "Logamatic TC100/Moduline Easy", DeviceFlags::EMS_DEVICE_FLAG_EASY | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18, cannot write
|
||||
{203, DeviceType::THERMOSTAT, "EasyControl CT200", DeviceFlags::EMS_DEVICE_FLAG_EASY | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18, cannot write
|
||||
|
||||
// Thermostat - Buderus/Nefit/Bosch specific - 0x17 / 0x10 / 0x18 / 0x19-0x1B for hc2-4 / 0x38
|
||||
{ 65, DeviceType::THERMOSTAT, F("RC10"), DeviceFlags::EMS_DEVICE_FLAG_RC20_N},// 0x17
|
||||
{ 67, DeviceType::THERMOSTAT, F("RC30"), DeviceFlags::EMS_DEVICE_FLAG_RC30_N},// 0x10 - based on RC35
|
||||
{ 77, DeviceType::THERMOSTAT, F("RC20/Moduline 300"), DeviceFlags::EMS_DEVICE_FLAG_RC20},// 0x17
|
||||
{ 78, DeviceType::THERMOSTAT, F("Moduline 400"), DeviceFlags::EMS_DEVICE_FLAG_RC30}, // 0x10
|
||||
{ 79, DeviceType::THERMOSTAT, F("RC10/Moduline 100"), DeviceFlags::EMS_DEVICE_FLAG_RC10},// 0x17
|
||||
{ 80, DeviceType::THERMOSTAT, F("Moduline 200"), DeviceFlags::EMS_DEVICE_FLAG_RC10}, // 0x17
|
||||
{ 86, DeviceType::THERMOSTAT, F("RC35"), DeviceFlags::EMS_DEVICE_FLAG_RC35}, // 0x10
|
||||
{ 90, DeviceType::THERMOSTAT, F("RC10/Moduline 100"), DeviceFlags::EMS_DEVICE_FLAG_RC20_N}, // 0x17
|
||||
{ 93, DeviceType::THERMOSTAT, F("RC20RF"), DeviceFlags::EMS_DEVICE_FLAG_RC20}, // 0x19
|
||||
{ 94, DeviceType::THERMOSTAT, F("RFM20 Remote"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x18
|
||||
{151, DeviceType::THERMOSTAT, F("RC25"), DeviceFlags::EMS_DEVICE_FLAG_RC25}, // 0x17
|
||||
{157, DeviceType::THERMOSTAT, F("RC200/CW100"), DeviceFlags::EMS_DEVICE_FLAG_RC100}, // 0x18
|
||||
{158, DeviceType::THERMOSTAT, F("RC300/RC310/Moduline 3000/1010H/CW400/Sense II"), DeviceFlags::EMS_DEVICE_FLAG_RC300}, // 0x10
|
||||
{165, DeviceType::THERMOSTAT, F("RC100/Moduline 1000/1010"), DeviceFlags::EMS_DEVICE_FLAG_RC100}, // 0x18, 0x38
|
||||
{172, DeviceType::THERMOSTAT, F("Rego 2000/3000"), DeviceFlags::EMS_DEVICE_FLAG_RC300}, // 0x10
|
||||
{216, DeviceType::THERMOSTAT, F("CRF200S"), DeviceFlags::EMS_DEVICE_FLAG_CRF | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18
|
||||
{246, DeviceType::THERMOSTAT, F("Comfort+2RF"), DeviceFlags::EMS_DEVICE_FLAG_CRF | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18
|
||||
{ 65, DeviceType::THERMOSTAT, "RC10", DeviceFlags::EMS_DEVICE_FLAG_RC20_N},// 0x17
|
||||
{ 67, DeviceType::THERMOSTAT, "RC30", DeviceFlags::EMS_DEVICE_FLAG_RC30_N},// 0x10 - based on RC35
|
||||
{ 77, DeviceType::THERMOSTAT, "RC20/Moduline 300", DeviceFlags::EMS_DEVICE_FLAG_RC20},// 0x17
|
||||
{ 78, DeviceType::THERMOSTAT, "Moduline 400", DeviceFlags::EMS_DEVICE_FLAG_RC30}, // 0x10
|
||||
{ 79, DeviceType::THERMOSTAT, "RC10/Moduline 100", DeviceFlags::EMS_DEVICE_FLAG_RC10},// 0x17
|
||||
{ 80, DeviceType::THERMOSTAT, "Moduline 200", DeviceFlags::EMS_DEVICE_FLAG_RC10}, // 0x17
|
||||
{ 86, DeviceType::THERMOSTAT, "RC35", DeviceFlags::EMS_DEVICE_FLAG_RC35}, // 0x10
|
||||
{ 90, DeviceType::THERMOSTAT, "RC10/Moduline 100", DeviceFlags::EMS_DEVICE_FLAG_RC20_N}, // 0x17
|
||||
{ 93, DeviceType::THERMOSTAT, "RC20RF", DeviceFlags::EMS_DEVICE_FLAG_RC20}, // 0x19
|
||||
{ 94, DeviceType::THERMOSTAT, "RFM20 Remote", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x18
|
||||
{151, DeviceType::THERMOSTAT, "RC25", DeviceFlags::EMS_DEVICE_FLAG_RC25}, // 0x17
|
||||
{157, DeviceType::THERMOSTAT, "RC200/CW100", DeviceFlags::EMS_DEVICE_FLAG_RC100}, // 0x18
|
||||
{158, DeviceType::THERMOSTAT, "RC300/RC310/Moduline 3000/1010H/CW400/Sense II", DeviceFlags::EMS_DEVICE_FLAG_RC300}, // 0x10
|
||||
{165, DeviceType::THERMOSTAT, "RC100/Moduline 1000/1010", DeviceFlags::EMS_DEVICE_FLAG_RC100}, // 0x18, 0x38
|
||||
{172, DeviceType::THERMOSTAT, "Rego 2000/3000", DeviceFlags::EMS_DEVICE_FLAG_RC300}, // 0x10
|
||||
{216, DeviceType::THERMOSTAT, "CRF200S", DeviceFlags::EMS_DEVICE_FLAG_CRF | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18
|
||||
{246, DeviceType::THERMOSTAT, "Comfort+2RF", DeviceFlags::EMS_DEVICE_FLAG_CRF | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18
|
||||
|
||||
// Thermostat - Sieger - 0x10 / 0x17
|
||||
{ 66, DeviceType::THERMOSTAT, F("ES72/RC20"), DeviceFlags::EMS_DEVICE_FLAG_RC20_N}, // 0x17 or remote
|
||||
{ 76, DeviceType::THERMOSTAT, F("ES73"), DeviceFlags::EMS_DEVICE_FLAG_RC30_N}, // 0x10
|
||||
{113, DeviceType::THERMOSTAT, F("ES72/RC20"), DeviceFlags::EMS_DEVICE_FLAG_RC20_N}, // 0x17
|
||||
{ 66, DeviceType::THERMOSTAT, "ES72/RC20", DeviceFlags::EMS_DEVICE_FLAG_RC20_N}, // 0x17 or remote
|
||||
{ 76, DeviceType::THERMOSTAT, "ES73", DeviceFlags::EMS_DEVICE_FLAG_RC30_N}, // 0x10
|
||||
{113, DeviceType::THERMOSTAT, "ES72/RC20", DeviceFlags::EMS_DEVICE_FLAG_RC20_N}, // 0x17
|
||||
|
||||
// Thermostat - Junkers - 0x10
|
||||
{105, DeviceType::THERMOSTAT, F("FW100"), DeviceFlags::EMS_DEVICE_FLAG_JUNKERS},
|
||||
{106, DeviceType::THERMOSTAT, F("FW200"), DeviceFlags::EMS_DEVICE_FLAG_JUNKERS},
|
||||
{107, DeviceType::THERMOSTAT, F("FR100"), DeviceFlags::EMS_DEVICE_FLAG_JUNKERS | DeviceFlags::EMS_DEVICE_FLAG_JUNKERS_OLD}, // older model
|
||||
{108, DeviceType::THERMOSTAT, F("FR110"), DeviceFlags::EMS_DEVICE_FLAG_JUNKERS | DeviceFlags::EMS_DEVICE_FLAG_JUNKERS_OLD}, // older model
|
||||
{109, DeviceType::THERMOSTAT, F("FB10"), DeviceFlags::EMS_DEVICE_FLAG_JUNKERS},
|
||||
{110, DeviceType::THERMOSTAT, F("FB100"), DeviceFlags::EMS_DEVICE_FLAG_JUNKERS},
|
||||
{111, DeviceType::THERMOSTAT, F("FR10"), DeviceFlags::EMS_DEVICE_FLAG_JUNKERS | DeviceFlags::EMS_DEVICE_FLAG_JUNKERS_OLD}, // older model
|
||||
{116, DeviceType::THERMOSTAT, F("FW500"), DeviceFlags::EMS_DEVICE_FLAG_JUNKERS},
|
||||
{147, DeviceType::THERMOSTAT, F("FR50"), DeviceFlags::EMS_DEVICE_FLAG_JUNKERS | DeviceFlags::EMS_DEVICE_FLAG_JUNKERS_OLD},
|
||||
{191, DeviceType::THERMOSTAT, F("FR120"), DeviceFlags::EMS_DEVICE_FLAG_JUNKERS | DeviceFlags::EMS_DEVICE_FLAG_JUNKERS_OLD}, // older model
|
||||
{192, DeviceType::THERMOSTAT, F("FW120"), DeviceFlags::EMS_DEVICE_FLAG_JUNKERS},
|
||||
{105, DeviceType::THERMOSTAT, "FW100", DeviceFlags::EMS_DEVICE_FLAG_JUNKERS},
|
||||
{106, DeviceType::THERMOSTAT, "FW200", DeviceFlags::EMS_DEVICE_FLAG_JUNKERS},
|
||||
{107, DeviceType::THERMOSTAT, "FR100", DeviceFlags::EMS_DEVICE_FLAG_JUNKERS | DeviceFlags::EMS_DEVICE_FLAG_JUNKERS_OLD}, // older model
|
||||
{108, DeviceType::THERMOSTAT, "FR110", DeviceFlags::EMS_DEVICE_FLAG_JUNKERS | DeviceFlags::EMS_DEVICE_FLAG_JUNKERS_OLD}, // older model
|
||||
{109, DeviceType::THERMOSTAT, "FB10", DeviceFlags::EMS_DEVICE_FLAG_JUNKERS},
|
||||
{110, DeviceType::THERMOSTAT, "FB100", DeviceFlags::EMS_DEVICE_FLAG_JUNKERS},
|
||||
{111, DeviceType::THERMOSTAT, "FR10", DeviceFlags::EMS_DEVICE_FLAG_JUNKERS | DeviceFlags::EMS_DEVICE_FLAG_JUNKERS_OLD}, // older model
|
||||
{116, DeviceType::THERMOSTAT, "FW500", DeviceFlags::EMS_DEVICE_FLAG_JUNKERS},
|
||||
{147, DeviceType::THERMOSTAT, "FR50", DeviceFlags::EMS_DEVICE_FLAG_JUNKERS | DeviceFlags::EMS_DEVICE_FLAG_JUNKERS_OLD},
|
||||
{191, DeviceType::THERMOSTAT, "FR120", DeviceFlags::EMS_DEVICE_FLAG_JUNKERS | DeviceFlags::EMS_DEVICE_FLAG_JUNKERS_OLD}, // older model
|
||||
{192, DeviceType::THERMOSTAT, "FW120", DeviceFlags::EMS_DEVICE_FLAG_JUNKERS},
|
||||
|
||||
// Thermostat remote - 0x38
|
||||
{200, DeviceType::THERMOSTAT, F("RC100H"), DeviceFlags::EMS_DEVICE_FLAG_RC100H},
|
||||
{200, DeviceType::THERMOSTAT, "RC100H", DeviceFlags::EMS_DEVICE_FLAG_RC100H},
|
||||
|
||||
// Solar Modules - 0x30 (for solar), 0x2A, 0x41 (for ww)
|
||||
{ 73, DeviceType::SOLAR, F("SM10"), DeviceFlags::EMS_DEVICE_FLAG_SM10},
|
||||
{101, DeviceType::SOLAR, F("ISM1"), DeviceFlags::EMS_DEVICE_FLAG_ISM},
|
||||
{103, DeviceType::SOLAR, F("ISM2"), DeviceFlags::EMS_DEVICE_FLAG_ISM},
|
||||
{162, DeviceType::SOLAR, F("SM50"), DeviceFlags::EMS_DEVICE_FLAG_SM100},
|
||||
{163, DeviceType::SOLAR, F("SM100/MS100"), DeviceFlags::EMS_DEVICE_FLAG_SM100},
|
||||
{164, DeviceType::SOLAR, F("SM200/MS200"), DeviceFlags::EMS_DEVICE_FLAG_SM100},
|
||||
{ 73, DeviceType::SOLAR, "SM10", DeviceFlags::EMS_DEVICE_FLAG_SM10},
|
||||
{101, DeviceType::SOLAR, "ISM1", DeviceFlags::EMS_DEVICE_FLAG_ISM},
|
||||
{103, DeviceType::SOLAR, "ISM2", DeviceFlags::EMS_DEVICE_FLAG_ISM},
|
||||
{162, DeviceType::SOLAR, "SM50", DeviceFlags::EMS_DEVICE_FLAG_SM100},
|
||||
{163, DeviceType::SOLAR, "SM100/MS100", DeviceFlags::EMS_DEVICE_FLAG_SM100},
|
||||
{164, DeviceType::SOLAR, "SM200/MS200", DeviceFlags::EMS_DEVICE_FLAG_SM100},
|
||||
|
||||
// Mixer Modules - 0x20-0x27 for HC, 0x28-0x29 for WWC and 0x11 for the MP100
|
||||
{ 69, DeviceType::MIXER, F("MM10"), DeviceFlags::EMS_DEVICE_FLAG_MM10},
|
||||
{100, DeviceType::MIXER, F("IPM"), DeviceFlags::EMS_DEVICE_FLAG_IPM},
|
||||
{102, DeviceType::MIXER, F("IPM"), DeviceFlags::EMS_DEVICE_FLAG_IPM},
|
||||
{159, DeviceType::MIXER, F("MM50"), DeviceFlags::EMS_DEVICE_FLAG_MMPLUS},
|
||||
{160, DeviceType::MIXER, F("MM100"), DeviceFlags::EMS_DEVICE_FLAG_MMPLUS},
|
||||
{161, DeviceType::MIXER, F("MM200"), DeviceFlags::EMS_DEVICE_FLAG_MMPLUS},
|
||||
{204, DeviceType::MIXER, F("MP100"), DeviceFlags::EMS_DEVICE_FLAG_MP}, // pool
|
||||
{ 69, DeviceType::MIXER, "MM10", DeviceFlags::EMS_DEVICE_FLAG_MM10},
|
||||
{100, DeviceType::MIXER, "IPM", DeviceFlags::EMS_DEVICE_FLAG_IPM},
|
||||
{102, DeviceType::MIXER, "IPM", DeviceFlags::EMS_DEVICE_FLAG_IPM},
|
||||
{159, DeviceType::MIXER, "MM50", DeviceFlags::EMS_DEVICE_FLAG_MMPLUS},
|
||||
{160, DeviceType::MIXER, "MM100", DeviceFlags::EMS_DEVICE_FLAG_MMPLUS},
|
||||
{161, DeviceType::MIXER, "MM200", DeviceFlags::EMS_DEVICE_FLAG_MMPLUS},
|
||||
{204, DeviceType::MIXER, "MP100", DeviceFlags::EMS_DEVICE_FLAG_MP}, // pool
|
||||
|
||||
// Heat Pumps - 0x38?
|
||||
{252, DeviceType::HEATPUMP, F("HP Module"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{252, DeviceType::HEATPUMP, "HP Module", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
|
||||
// Heat Pumps - 0x53
|
||||
{248, DeviceType::HEATPUMP, F("Hybrid Manager HM200"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{248, DeviceType::HEATPUMP, "Hybrid Manager HM200", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
|
||||
// Connect devices - 0x02
|
||||
{171, DeviceType::CONNECT, F("OpenTherm Converter"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{205, DeviceType::CONNECT, F("Moduline Easy Connect"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{206, DeviceType::CONNECT, F("Easy Connect"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{171, DeviceType::CONNECT, "OpenTherm Converter", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{205, DeviceType::CONNECT, "Moduline Easy Connect", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{206, DeviceType::CONNECT, "Easy Connect", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
|
||||
// Wireless sensor base - 0x50
|
||||
{236, DeviceType::CONNECT, F("Wireless sensor base"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{238, DeviceType::CONNECT, F("Wireless sensor base"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{236, DeviceType::CONNECT, "Wireless sensor base", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{238, DeviceType::CONNECT, "Wireless sensor base", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
|
||||
// Switches - 0x11
|
||||
{ 71, DeviceType::SWITCH, F("WM10"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{ 71, DeviceType::SWITCH, "WM10", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
|
||||
// EM10 error contact and analog flowtemp control- 0x12
|
||||
{ 74, DeviceType::GATEWAY, F("Error Module EM10"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{ 74, DeviceType::GATEWAY, "Error Module EM10", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
|
||||
// Gateways - 0x48
|
||||
{189, DeviceType::GATEWAY, F("KM200/MB LAN 2"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{189, DeviceType::GATEWAY, "KM200/MB LAN 2", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
|
||||
// Generic - 0x40 or other with no product-id and no version
|
||||
{0, DeviceType::GENERIC, F("unknown"), DeviceFlags::EMS_DEVICE_FLAG_NONE}
|
||||
{0, DeviceType::GENERIC, "unknown", DeviceFlags::EMS_DEVICE_FLAG_NONE}
|
||||
|
||||
// clang-format on
|
||||
|
||||
@@ -24,16 +24,16 @@ REGISTER_FACTORY(Boiler, EMSdevice::DeviceType::BOILER)
|
||||
|
||||
uuid::log::Logger Boiler::logger_{F_(boiler), uuid::log::Facility::CONSOLE};
|
||||
|
||||
Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
// alternative heatsource special messages
|
||||
|
||||
if (device_id == EMSdevice::EMS_DEVICE_ID_AM200) {
|
||||
register_telegram_type(0x54D, F("AmTemperatures"), false, MAKE_PF_CB(process_amTempMessage));
|
||||
register_telegram_type(0x54E, F("AmStatus"), false, MAKE_PF_CB(process_amStatusMessage));
|
||||
register_telegram_type(0x54F, F("AmCommand"), false, MAKE_PF_CB(process_amCommandMessage)); // not broadcasted, but actually not used
|
||||
register_telegram_type(0x550, F("AmExtra"), false, MAKE_PF_CB(process_amExtraMessage));
|
||||
register_telegram_type(0x54C, F("AmSettings"), true, MAKE_PF_CB(process_amSettingMessage)); // not broadcasted
|
||||
register_telegram_type(0x54D, "AmTemperatures", false, MAKE_PF_CB(process_amTempMessage));
|
||||
register_telegram_type(0x54E, "AmStatus", false, MAKE_PF_CB(process_amStatusMessage));
|
||||
register_telegram_type(0x54F, "AmCommand", false, MAKE_PF_CB(process_amCommandMessage)); // not broadcasted, but actually not used
|
||||
register_telegram_type(0x550, "AmExtra", false, MAKE_PF_CB(process_amExtraMessage));
|
||||
register_telegram_type(0x54C, "AmSettings", true, MAKE_PF_CB(process_amSettingMessage)); // not broadcasted
|
||||
|
||||
register_device_value(DeviceValueTAG::TAG_AHS,
|
||||
&curFlowTemp_,
|
||||
@@ -113,12 +113,12 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
||||
if (device_id >= EMSdevice::EMS_DEVICE_ID_BOILER_1) {
|
||||
uint8_t hs = device_id - EMSdevice::EMS_DEVICE_ID_BOILER_1; // heating source id, count from 0
|
||||
// Runtime of each heatingsource in 0x06DC, ff
|
||||
register_telegram_type(0x6DC + hs, F("CascadeMessage"), false, MAKE_PF_CB(process_CascadeMessage));
|
||||
register_telegram_type(0x6DC + hs, "CascadeMessage", false, MAKE_PF_CB(process_CascadeMessage));
|
||||
register_device_value(DeviceValueTAG::TAG_HS1 + hs, &burnWorkMin_, DeviceValueType::TIME, FL_(burnWorkMin), DeviceValueUOM::MINUTES);
|
||||
// selBurnpower in D2 and E4
|
||||
// register_telegram_type(0xD2, F("CascadePowerMessage"), false, MAKE_PF_CB(process_CascadePowerMessage));
|
||||
// register_telegram_type(0xD2, "CascadePowerMessage", false, MAKE_PF_CB(process_CascadePowerMessage));
|
||||
// individual Flowtemps and powervalues for each heatingsource in E4
|
||||
register_telegram_type(0xE4, F("UBAMonitorFastPlus"), false, MAKE_PF_CB(process_UBAMonitorFastPlus));
|
||||
register_telegram_type(0xE4, "UBAMonitorFastPlus", false, MAKE_PF_CB(process_UBAMonitorFastPlus));
|
||||
register_device_value(DeviceValueTAG::TAG_HS1 + hs, &selFlowTemp_, DeviceValueType::UINT, FL_(selFlowTemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(DeviceValueTAG::TAG_HS1 + hs, &selBurnPow_, DeviceValueType::UINT, FL_(selBurnPow), DeviceValueUOM::PERCENT);
|
||||
register_device_value(DeviceValueTAG::TAG_HS1 + hs,
|
||||
@@ -136,51 +136,51 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
||||
|
||||
// the telegram handlers...
|
||||
// common for all boilers
|
||||
register_telegram_type(0xBF, F("ErrorMessage"), false, MAKE_PF_CB(process_ErrorMessage));
|
||||
register_telegram_type(0x10, F("UBAErrorMessage1"), false, MAKE_PF_CB(process_UBAErrorMessage));
|
||||
register_telegram_type(0x11, F("UBAErrorMessage2"), false, MAKE_PF_CB(process_UBAErrorMessage));
|
||||
register_telegram_type(0xC2, F("UBAErrorMessage3"), false, MAKE_PF_CB(process_UBAErrorMessage2));
|
||||
register_telegram_type(0x14, F("UBATotalUptime"), true, MAKE_PF_CB(process_UBATotalUptime));
|
||||
register_telegram_type(0x15, F("UBAMaintenanceData"), false, MAKE_PF_CB(process_UBAMaintenanceData));
|
||||
register_telegram_type(0x1C, F("UBAMaintenanceStatus"), false, MAKE_PF_CB(process_UBAMaintenanceStatus));
|
||||
register_telegram_type(0xBF, "ErrorMessage", false, MAKE_PF_CB(process_ErrorMessage));
|
||||
register_telegram_type(0x10, "UBAErrorMessage1", false, MAKE_PF_CB(process_UBAErrorMessage));
|
||||
register_telegram_type(0x11, "UBAErrorMessage2", false, MAKE_PF_CB(process_UBAErrorMessage));
|
||||
register_telegram_type(0xC2, "UBAErrorMessage3", false, MAKE_PF_CB(process_UBAErrorMessage2));
|
||||
register_telegram_type(0x14, "UBATotalUptime", true, MAKE_PF_CB(process_UBATotalUptime));
|
||||
register_telegram_type(0x15, "UBAMaintenanceData", false, MAKE_PF_CB(process_UBAMaintenanceData));
|
||||
register_telegram_type(0x1C, "UBAMaintenanceStatus", false, MAKE_PF_CB(process_UBAMaintenanceStatus));
|
||||
|
||||
// EMS1.0 and maybe EMS+?
|
||||
register_telegram_type(0x18, F("UBAMonitorFast"), false, MAKE_PF_CB(process_UBAMonitorFast));
|
||||
register_telegram_type(0x19, F("UBAMonitorSlow"), false, MAKE_PF_CB(process_UBAMonitorSlow));
|
||||
register_telegram_type(0x1A, F("UBASetPoints"), false, MAKE_PF_CB(process_UBASetPoints));
|
||||
register_telegram_type(0x35, F("UBAFlags"), false, MAKE_PF_CB(process_UBAFlags));
|
||||
register_telegram_type(0x18, "UBAMonitorFast", false, MAKE_PF_CB(process_UBAMonitorFast));
|
||||
register_telegram_type(0x19, "UBAMonitorSlow", false, MAKE_PF_CB(process_UBAMonitorSlow));
|
||||
register_telegram_type(0x1A, "UBASetPoints", false, MAKE_PF_CB(process_UBASetPoints));
|
||||
register_telegram_type(0x35, "UBAFlags", false, MAKE_PF_CB(process_UBAFlags));
|
||||
|
||||
// only EMS 1.0
|
||||
register_telegram_type(0x16, F("UBAParameters"), true, MAKE_PF_CB(process_UBAParameters));
|
||||
register_telegram_type(0x33, F("UBAParameterWW"), true, MAKE_PF_CB(process_UBAParameterWW));
|
||||
register_telegram_type(0x34, F("UBAMonitorWW"), false, MAKE_PF_CB(process_UBAMonitorWW));
|
||||
register_telegram_type(0x16, "UBAParameters", true, MAKE_PF_CB(process_UBAParameters));
|
||||
register_telegram_type(0x33, "UBAParameterWW", true, MAKE_PF_CB(process_UBAParameterWW));
|
||||
register_telegram_type(0x34, "UBAMonitorWW", false, MAKE_PF_CB(process_UBAMonitorWW));
|
||||
|
||||
// not ems1.0, but HT3
|
||||
if (model() != EMSdevice::EMS_DEVICE_FLAG_EMS) {
|
||||
register_telegram_type(0x26, F("UBASettingsWW"), true, MAKE_PF_CB(process_UBASettingsWW));
|
||||
register_telegram_type(0x2A, F("MC110Status"), false, MAKE_PF_CB(process_MC110Status));
|
||||
register_telegram_type(0x26, "UBASettingsWW", true, MAKE_PF_CB(process_UBASettingsWW));
|
||||
register_telegram_type(0x2A, "MC110Status", false, MAKE_PF_CB(process_MC110Status));
|
||||
}
|
||||
|
||||
// only EMS+
|
||||
if (model() != EMSdevice::EMS_DEVICE_FLAG_EMS && model() != EMSdevice::EMS_DEVICE_FLAG_HT3 && model() != EMSdevice::EMS_DEVICE_FLAG_HYBRID) {
|
||||
register_telegram_type(0xD1, F("UBAOutdoorTemp"), false, MAKE_PF_CB(process_UBAOutdoorTemp));
|
||||
register_telegram_type(0xE3, F("UBAMonitorSlowPlus2"), false, MAKE_PF_CB(process_UBAMonitorSlowPlus2));
|
||||
register_telegram_type(0xE4, F("UBAMonitorFastPlus"), false, MAKE_PF_CB(process_UBAMonitorFastPlus));
|
||||
register_telegram_type(0xE5, F("UBAMonitorSlowPlus"), false, MAKE_PF_CB(process_UBAMonitorSlowPlus));
|
||||
register_telegram_type(0xE6, F("UBAParametersPlus"), true, MAKE_PF_CB(process_UBAParametersPlus));
|
||||
register_telegram_type(0xE9, F("UBAMonitorWWPlus"), false, MAKE_PF_CB(process_UBAMonitorWWPlus));
|
||||
register_telegram_type(0xEA, F("UBAParameterWWPlus"), true, MAKE_PF_CB(process_UBAParameterWWPlus));
|
||||
register_telegram_type(0xD1, "UBAOutdoorTemp", false, MAKE_PF_CB(process_UBAOutdoorTemp));
|
||||
register_telegram_type(0xE3, "UBAMonitorSlowPlus2", false, MAKE_PF_CB(process_UBAMonitorSlowPlus2));
|
||||
register_telegram_type(0xE4, "UBAMonitorFastPlus", false, MAKE_PF_CB(process_UBAMonitorFastPlus));
|
||||
register_telegram_type(0xE5, "UBAMonitorSlowPlus", false, MAKE_PF_CB(process_UBAMonitorSlowPlus));
|
||||
register_telegram_type(0xE6, "UBAParametersPlus", true, MAKE_PF_CB(process_UBAParametersPlus));
|
||||
register_telegram_type(0xE9, "UBAMonitorWWPlus", false, MAKE_PF_CB(process_UBAMonitorWWPlus));
|
||||
register_telegram_type(0xEA, "UBAParameterWWPlus", true, MAKE_PF_CB(process_UBAParameterWWPlus));
|
||||
}
|
||||
|
||||
if (model() == EMSdevice::EMS_DEVICE_FLAG_HEATPUMP) {
|
||||
register_telegram_type(0x494, F("UBAEnergySupplied"), false, MAKE_PF_CB(process_UBAEnergySupplied));
|
||||
register_telegram_type(0x495, F("UBAInformation"), false, MAKE_PF_CB(process_UBAInformation));
|
||||
register_telegram_type(0x48D, F("HpPower"), true, MAKE_PF_CB(process_HpPower));
|
||||
register_telegram_type(0x48F, F("HpOutdoor"), false, MAKE_PF_CB(process_HpOutdoor));
|
||||
register_telegram_type(0x48A, F("HpPool"), true, MAKE_PF_CB(process_HpPool));
|
||||
register_telegram_type(0x4A2, F("HpInput"), false, MAKE_PF_CB(process_HpInput));
|
||||
register_telegram_type(0x486, F("HpInConfig"), false, MAKE_PF_CB(process_HpInConfig));
|
||||
register_telegram_type(0x492, F("HpHeaterConfig"), false, MAKE_PF_CB(process_HpHeaterConfig));
|
||||
register_telegram_type(0x494, "UBAEnergySupplied", false, MAKE_PF_CB(process_UBAEnergySupplied));
|
||||
register_telegram_type(0x495, "UBAInformation", false, MAKE_PF_CB(process_UBAInformation));
|
||||
register_telegram_type(0x48D, "HpPower", true, MAKE_PF_CB(process_HpPower));
|
||||
register_telegram_type(0x48F, "HpOutdoor", false, MAKE_PF_CB(process_HpOutdoor));
|
||||
register_telegram_type(0x48A, "HpPool", true, MAKE_PF_CB(process_HpPool));
|
||||
register_telegram_type(0x4A2, "HpInput", false, MAKE_PF_CB(process_HpInput));
|
||||
register_telegram_type(0x486, "HpInConfig", false, MAKE_PF_CB(process_HpInConfig));
|
||||
register_telegram_type(0x492, "HpHeaterConfig", false, MAKE_PF_CB(process_HpHeaterConfig));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -189,7 +189,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
||||
* enable settings here if no thermostat is used in system
|
||||
*
|
||||
if (model() == EMSdevice::EMS_DEVICE_FLAG_HYBRID) {
|
||||
register_telegram_type(0xBB, F("HybridHp"), true, MAKE_PF_CB(process_HybridHp));
|
||||
register_telegram_type(0xBB, "HybridHp", true, MAKE_PF_CB(process_HybridHp));
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -2178,11 +2178,11 @@ bool Boiler::set_ww_circulation_mode(const char * value, const int8_t id) {
|
||||
}
|
||||
|
||||
if (v < 7) {
|
||||
// LOG_INFO(F("Setting dhw circulation mode %dx3min"), v);
|
||||
// LOG_INFO("Setting dhw circulation mode %dx3min", v);
|
||||
} else if (v == 7) {
|
||||
// LOG_INFO(F("Setting dhw circulation mode continuous"));
|
||||
// LOG_INFO("Setting dhw circulation mode continuous");
|
||||
} else {
|
||||
// LOG_WARNING(F("Set dhw circulation mode: Invalid value"));
|
||||
// LOG_WARNING("Set dhw circulation mode: Invalid value");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2206,12 +2206,12 @@ bool Boiler::set_reset(const char * value, const int8_t id) {
|
||||
}
|
||||
|
||||
if (num == 1) {
|
||||
// LOG_INFO(F("Reset boiler maintenance message"));
|
||||
// LOG_INFO("Reset boiler maintenance message");
|
||||
write_command(0x05, 0x08, 0xFF, 0x1C);
|
||||
has_update(&reset_);
|
||||
return true;
|
||||
} else if (num == 2) {
|
||||
// LOG_INFO(F("Reset boiler error message"));
|
||||
// LOG_INFO("Reset boiler error message");
|
||||
write_command(0x05, 0x00, 0x5A); // error reset
|
||||
has_update(&reset_);
|
||||
return true;
|
||||
@@ -2228,7 +2228,7 @@ bool Boiler::set_maintenance(const char * value, const int8_t id) {
|
||||
std::string s;
|
||||
if (Helpers::value2string(value, s)) {
|
||||
if (s == Helpers::translated_word(FL_(reset))) {
|
||||
// LOG_INFO(F("Reset boiler maintenance message"));
|
||||
// LOG_INFO("Reset boiler maintenance message");
|
||||
write_command(0x05, 0x08, 0xFF, 0x1C);
|
||||
return true;
|
||||
}
|
||||
@@ -2239,11 +2239,11 @@ bool Boiler::set_maintenance(const char * value, const int8_t id) {
|
||||
uint8_t month = (value[3] - '0') * 10 + (value[4] - '0');
|
||||
uint8_t year = (uint8_t)(Helpers::atoint(&value[6]) - 2000);
|
||||
if (day > 0 && day < 32 && month > 0 && month < 13) {
|
||||
LOG_INFO(F("Setting maintenance date to %02d.%02d.%04d"), day, month, year + 2000);
|
||||
LOG_INFO("Setting maintenance date to %02d.%02d.%04d", day, month, year + 2000);
|
||||
uint8_t data[5] = {2, (uint8_t)(maintenanceTime_ / 100), day, month, year};
|
||||
write_command(0x15, 0, data, 5, 0x15);
|
||||
} else {
|
||||
LOG_WARNING(F("Setting maintenance: wrong format %d.%d.%d"), day, month, year + 2000);
|
||||
LOG_WARNING("Setting maintenance: wrong format %d.%d.%d", day, month, year + 2000);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -2252,7 +2252,7 @@ bool Boiler::set_maintenance(const char * value, const int8_t id) {
|
||||
int hrs;
|
||||
if (Helpers::value2number(value, hrs)) {
|
||||
if (hrs > 99 && hrs < 25600) {
|
||||
LOG_INFO(F("Setting maintenance time %d hours"), hrs);
|
||||
LOG_INFO("Setting maintenance time %d hours", hrs);
|
||||
uint8_t data[2] = {1, (uint8_t)(hrs / 100)};
|
||||
write_command(0x15, 0, data, 2, 0x15);
|
||||
return true;
|
||||
@@ -2261,12 +2261,12 @@ bool Boiler::set_maintenance(const char * value, const int8_t id) {
|
||||
|
||||
uint8_t num;
|
||||
if (Helpers::value2enum(value, num, FL_(enum_off_time_date_manual))) {
|
||||
LOG_INFO(F("Setting maintenance type to %s"), value);
|
||||
LOG_INFO("Setting maintenance type to %s", value);
|
||||
write_command(0x15, 0, num, 0x15);
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG_WARNING(F("Setting maintenance: wrong format"));
|
||||
LOG_WARNING("Setting maintenance: wrong format");
|
||||
return false;
|
||||
}
|
||||
//maintenance
|
||||
@@ -2274,13 +2274,13 @@ bool Boiler::set_maintenancetime(const char * value, const int8_t id) {
|
||||
int hrs;
|
||||
if (Helpers::value2number(value, hrs)) {
|
||||
if (hrs > 99 && hrs < 25600) {
|
||||
LOG_INFO(F("Setting maintenance time %d hours"), hrs);
|
||||
LOG_INFO("Setting maintenance time %d hours", hrs);
|
||||
uint8_t data[2] = {1, (uint8_t)(hrs / 100)};
|
||||
write_command(0x15, 0, data, 2, 0x15);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
LOG_WARNING(F("Setting maintenance: wrong format"));
|
||||
LOG_WARNING("Setting maintenance: wrong format");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2291,17 +2291,17 @@ bool Boiler::set_maintenancedate(const char * value, const int8_t id) {
|
||||
uint8_t month = (value[3] - '0') * 10 + (value[4] - '0');
|
||||
uint8_t year = (uint8_t)(Helpers::atoint(&value[6]) - 2000);
|
||||
if (day > 0 && day < 32 && month > 0 && month < 13) {
|
||||
LOG_INFO(F("Setting maintenance date to %02d.%02d.%04d"), day, month, year + 2000);
|
||||
LOG_INFO("Setting maintenance date to %02d.%02d.%04d", day, month, year + 2000);
|
||||
uint8_t data[5] = {2, (uint8_t)(maintenanceTime_ / 100), day, month, year};
|
||||
write_command(0x15, 0, data, 5, 0x15);
|
||||
} else {
|
||||
LOG_WARNING(F("Setting maintenance: wrong format %d.%d.%d"), day, month, year + 2000);
|
||||
LOG_WARNING("Setting maintenance: wrong format %d.%d.%d", day, month, year + 2000);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG_WARNING(F("Setting maintenance: wrong format"));
|
||||
LOG_WARNING("Setting maintenance: wrong format");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2312,7 +2312,7 @@ bool Boiler::set_pool_temp(const char * value, const int8_t id) {
|
||||
return false;
|
||||
}
|
||||
uint8_t v2 = ((v * 2) + 0.5);
|
||||
// LOG_INFO(F("Setting pool temperature to %d.%d C"), v2 >> 1, (v2 & 0x01) * 5);
|
||||
// LOG_INFO("Setting pool temperature to %d.%d C", v2 >> 1, (v2 & 0x01) * 5);
|
||||
write_command(0x48A, 1, v2, 0x48A);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace emsesp {
|
||||
|
||||
class Boiler : public EMSdevice {
|
||||
public:
|
||||
Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand);
|
||||
|
||||
private:
|
||||
static uuid::log::Logger logger_;
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace emsesp {
|
||||
|
||||
REGISTER_FACTORY(Connect, EMSdevice::DeviceType::CONNECT);
|
||||
|
||||
Connect::Connect(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
Connect::Connect(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace emsesp {
|
||||
|
||||
class Connect : public EMSdevice {
|
||||
public:
|
||||
Connect(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
Connect(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand);
|
||||
};
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
@@ -22,11 +22,11 @@ namespace emsesp {
|
||||
|
||||
REGISTER_FACTORY(Controller, EMSdevice::DeviceType::CONTROLLER);
|
||||
|
||||
Controller::Controller(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
Controller::Controller(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
// IVT broadcasts Thermostat time from controller (0x09) if display is off.
|
||||
if ((flags & 0x0F) == EMS_DEVICE_FLAG_IVT) {
|
||||
register_telegram_type(0x06, F("RCTime"), false, MAKE_PF_CB(process_dateTime));
|
||||
register_telegram_type(0x06, "RCTime", false, MAKE_PF_CB(process_dateTime));
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace emsesp {
|
||||
|
||||
class Controller : public EMSdevice {
|
||||
public:
|
||||
Controller(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
Controller(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand);
|
||||
|
||||
void process_dateTime(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace emsesp {
|
||||
|
||||
REGISTER_FACTORY(Gateway, EMSdevice::DeviceType::GATEWAY);
|
||||
|
||||
Gateway::Gateway(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
Gateway::Gateway(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace emsesp {
|
||||
|
||||
class Gateway : public EMSdevice {
|
||||
public:
|
||||
Gateway(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
Gateway(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand);
|
||||
};
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
@@ -24,7 +24,7 @@ REGISTER_FACTORY(Generic, EMSdevice::DeviceType::GENERIC);
|
||||
|
||||
uuid::log::Logger Generic::logger_{F_(generic), uuid::log::Facility::CONSOLE};
|
||||
|
||||
Generic::Generic(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
Generic::Generic(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace emsesp {
|
||||
|
||||
class Generic : public EMSdevice {
|
||||
public:
|
||||
Generic(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
Generic(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand);
|
||||
|
||||
private:
|
||||
static uuid::log::Logger logger_;
|
||||
|
||||
@@ -22,11 +22,11 @@ namespace emsesp {
|
||||
|
||||
REGISTER_FACTORY(Heatpump, EMSdevice::DeviceType::HEATPUMP);
|
||||
|
||||
Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
// telegram handlers
|
||||
register_telegram_type(0x042B, F("HP1"), false, MAKE_PF_CB(process_HPMonitor1));
|
||||
register_telegram_type(0x047B, F("HP2"), false, MAKE_PF_CB(process_HPMonitor2));
|
||||
register_telegram_type(0x042B, "HP1", false, MAKE_PF_CB(process_HPMonitor1));
|
||||
register_telegram_type(0x047B, "HP2", false, MAKE_PF_CB(process_HPMonitor2));
|
||||
|
||||
// device values
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &airHumidity_, DeviceValueType::UINT, FL_(airHumidity), DeviceValueUOM::PERCENT);
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace emsesp {
|
||||
|
||||
class Heatpump : public EMSdevice {
|
||||
public:
|
||||
Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand);
|
||||
|
||||
private:
|
||||
uint8_t airHumidity_;
|
||||
|
||||
@@ -24,11 +24,11 @@ REGISTER_FACTORY(Mixer, EMSdevice::DeviceType::MIXER);
|
||||
|
||||
uuid::log::Logger Mixer::logger_{F_(mixer), uuid::log::Facility::CONSOLE};
|
||||
|
||||
Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
// Pool module
|
||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_MP) {
|
||||
register_telegram_type(0x5BA, F("HpPoolStatus"), true, MAKE_PF_CB(process_HpPoolStatus));
|
||||
register_telegram_type(0x5BA, "HpPoolStatus", true, MAKE_PF_CB(process_HpPoolStatus));
|
||||
type_ = Type::MP;
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
&poolTemp_,
|
||||
@@ -43,8 +43,8 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
|
||||
// EMS+
|
||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) {
|
||||
if (device_id >= 0x20 && device_id <= 0x27) {
|
||||
register_telegram_type(device_id - 0x20 + 0x02D7, F("MMPLUSStatusMessage_HC"), false, MAKE_PF_CB(process_MMPLUSStatusMessage_HC));
|
||||
// register_telegram_type(device_id - 0x20 + 0x02E1, F("MMPLUSStetMessage_HC"), true, MAKE_PF_CB(process_MMPLUSSetMessage_HC));
|
||||
register_telegram_type(device_id - 0x20 + 0x02D7, "MMPLUSStatusMessage_HC", false, MAKE_PF_CB(process_MMPLUSStatusMessage_HC));
|
||||
// register_telegram_type(device_id - 0x20 + 0x02E1, "MMPLUSStetMessage_HC", true, MAKE_PF_CB(process_MMPLUSSetMessage_HC));
|
||||
type_ = Type::HC;
|
||||
hc_ = device_id - 0x20 + 1;
|
||||
uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1;
|
||||
@@ -53,9 +53,9 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
|
||||
register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp));
|
||||
register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, FL_(pumpStatus), DeviceValueUOM::NONE, MAKE_CF_CB(set_pump));
|
||||
} else if (device_id >= 0x28 && device_id <= 0x29) {
|
||||
register_telegram_type(device_id - 0x28 + 0x0331, F("MMPLUSStatusMessage_WWC"), false, MAKE_PF_CB(process_MMPLUSStatusMessage_WWC));
|
||||
register_telegram_type(device_id - 0x28 + 0x0313, F("MMPLUSConfigMessage_WWC"), true, MAKE_PF_CB(process_MMPLUSConfigMessage_WWC));
|
||||
// register_telegram_type(device_id - 0x28 + 0x033B, F("MMPLUSSetMessage_WWC"), true, MAKE_PF_CB(process_MMPLUSSetMessage_WWC));
|
||||
register_telegram_type(device_id - 0x28 + 0x0331, "MMPLUSStatusMessage_WWC", false, MAKE_PF_CB(process_MMPLUSStatusMessage_WWC));
|
||||
register_telegram_type(device_id - 0x28 + 0x0313, "MMPLUSConfigMessage_WWC", true, MAKE_PF_CB(process_MMPLUSConfigMessage_WWC));
|
||||
// register_telegram_type(device_id - 0x28 + 0x033B, "MMPLUSSetMessage_WWC", true, MAKE_PF_CB(process_MMPLUSSetMessage_WWC));
|
||||
type_ = Type::WWC;
|
||||
hc_ = device_id - 0x28 + 1;
|
||||
uint8_t tag = DeviceValueTAG::TAG_WWC1 + hc_ - 1;
|
||||
@@ -85,9 +85,9 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
|
||||
|
||||
// EMS 1.0
|
||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_MM10) {
|
||||
register_telegram_type(0x00AA, F("MMConfigMessage"), true, MAKE_PF_CB(process_MMConfigMessage));
|
||||
register_telegram_type(0x00AB, F("MMStatusMessage"), false, MAKE_PF_CB(process_MMStatusMessage));
|
||||
register_telegram_type(0x00AC, F("MMSetMessage"), false, MAKE_PF_CB(process_MMSetMessage));
|
||||
register_telegram_type(0x00AA, "MMConfigMessage", true, MAKE_PF_CB(process_MMConfigMessage));
|
||||
register_telegram_type(0x00AB, "MMStatusMessage", false, MAKE_PF_CB(process_MMStatusMessage));
|
||||
register_telegram_type(0x00AC, "MMSetMessage", false, MAKE_PF_CB(process_MMSetMessage));
|
||||
type_ = Type::HC;
|
||||
hc_ = device_id - 0x20 + 1;
|
||||
uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1;
|
||||
@@ -110,10 +110,10 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
|
||||
// HT3
|
||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_IPM) {
|
||||
if (device_id >= 0x40) { // special DHW pos 10
|
||||
register_telegram_type(0x34, F("UBAMonitorWW"), false, MAKE_PF_CB(process_IPMMonitorWW));
|
||||
register_telegram_type(0x1E, F("HydrTemp"), false, MAKE_PF_CB(process_IPMHydrTemp));
|
||||
register_telegram_type(0x33, F("UBAParameterWW"), true, MAKE_PF_CB(process_IPMParameterWW));
|
||||
// register_telegram_type(0x10D, F("wwNTCStatus"), false, MAKE_PF_CB(process_wwNTCStatus));
|
||||
register_telegram_type(0x34, "UBAMonitorWW", false, MAKE_PF_CB(process_IPMMonitorWW));
|
||||
register_telegram_type(0x1E, "HydrTemp", false, MAKE_PF_CB(process_IPMHydrTemp));
|
||||
register_telegram_type(0x33, "UBAParameterWW", true, MAKE_PF_CB(process_IPMParameterWW));
|
||||
// register_telegram_type(0x10D, "wwNTCStatus", false, MAKE_PF_CB(process_wwNTCStatus));
|
||||
type_ = Type::WWC;
|
||||
hc_ = device_id - 0x40 + 1;
|
||||
uint8_t tag = DeviceValueTAG::TAG_WWC9 + hc_ - 1;
|
||||
@@ -139,9 +139,9 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
|
||||
MAKE_CF_CB(set_wwCircPump));
|
||||
register_device_value(tag, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircMode));
|
||||
} else {
|
||||
register_telegram_type(0x010C, F("IPMStatusMessage"), false, MAKE_PF_CB(process_IPMStatusMessage));
|
||||
register_telegram_type(0x011E, F("IPMTempMessage"), false, MAKE_PF_CB(process_IPMTempMessage));
|
||||
// register_telegram_type(0x0123, F("IPMSetMessage"), false, MAKE_PF_CB(process_IPMSetMessage));
|
||||
register_telegram_type(0x010C, "IPMStatusMessage", false, MAKE_PF_CB(process_IPMStatusMessage));
|
||||
register_telegram_type(0x011E, "IPMTempMessage", false, MAKE_PF_CB(process_IPMTempMessage));
|
||||
// register_telegram_type(0x0123, "IPMSetMessage", false, MAKE_PF_CB(process_IPMSetMessage));
|
||||
type_ = Type::HC;
|
||||
hc_ = device_id - 0x20 + 1;
|
||||
uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1;
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace emsesp {
|
||||
|
||||
class Mixer : public EMSdevice {
|
||||
public:
|
||||
Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand);
|
||||
|
||||
private:
|
||||
static uuid::log::Logger logger_;
|
||||
|
||||
@@ -24,48 +24,48 @@ REGISTER_FACTORY(Solar, EMSdevice::DeviceType::SOLAR);
|
||||
|
||||
uuid::log::Logger Solar::logger_{F_(solar), uuid::log::Facility::CONSOLE};
|
||||
|
||||
Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
// telegram handlers
|
||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_SM10) {
|
||||
register_telegram_type(0x97, F("SM10Monitor"), false, MAKE_PF_CB(process_SM10Monitor));
|
||||
register_telegram_type(0x96, F("SM10Config"), true, MAKE_PF_CB(process_SM10Config));
|
||||
register_telegram_type(0x97, "SM10Monitor", false, MAKE_PF_CB(process_SM10Monitor));
|
||||
register_telegram_type(0x96, "SM10Config", true, MAKE_PF_CB(process_SM10Config));
|
||||
EMSESP::send_read_request(0x97, device_id);
|
||||
}
|
||||
|
||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_SM100) {
|
||||
if (device_id == 0x2A) { // SM100 DHW
|
||||
register_telegram_type(0x07D6, F("SM100wwTemperature"), false, MAKE_PF_CB(process_SM100wwTemperature));
|
||||
register_telegram_type(0x07AA, F("SM100wwStatus"), false, MAKE_PF_CB(process_SM100wwStatus));
|
||||
register_telegram_type(0x07AB, F("SM100wwCommand"), false, MAKE_PF_CB(process_SM100wwCommand));
|
||||
register_telegram_type(0x07A5, F("SM100wwCirc"), true, MAKE_PF_CB(process_SM100wwCirc));
|
||||
register_telegram_type(0x07A6, F("SM100wwParam"), true, MAKE_PF_CB(process_SM100wwParam));
|
||||
register_telegram_type(0x07AE, F("SM100wwKeepWarm"), true, MAKE_PF_CB(process_SM100wwKeepWarm));
|
||||
register_telegram_type(0x07E0, F("SM100wwStatus2"), true, MAKE_PF_CB(process_SM100wwStatus2));
|
||||
register_telegram_type(0x07D6, "SM100wwTemperature", false, MAKE_PF_CB(process_SM100wwTemperature));
|
||||
register_telegram_type(0x07AA, "SM100wwStatus", false, MAKE_PF_CB(process_SM100wwStatus));
|
||||
register_telegram_type(0x07AB, "SM100wwCommand", false, MAKE_PF_CB(process_SM100wwCommand));
|
||||
register_telegram_type(0x07A5, "SM100wwCirc", true, MAKE_PF_CB(process_SM100wwCirc));
|
||||
register_telegram_type(0x07A6, "SM100wwParam", true, MAKE_PF_CB(process_SM100wwParam));
|
||||
register_telegram_type(0x07AE, "SM100wwKeepWarm", true, MAKE_PF_CB(process_SM100wwKeepWarm));
|
||||
register_telegram_type(0x07E0, "SM100wwStatus2", true, MAKE_PF_CB(process_SM100wwStatus2));
|
||||
} else {
|
||||
// F9 is not a telegram type, it's a flag for configure
|
||||
// register_telegram_type(0xF9, F("ParamCfg"), false, MAKE_PF_CB(process_SM100ParamCfg));
|
||||
register_telegram_type(0x0358, F("SM100SystemConfig"), true, MAKE_PF_CB(process_SM100SystemConfig));
|
||||
register_telegram_type(0x035A, F("SM100CircuitConfig"), true, MAKE_PF_CB(process_SM100CircuitConfig));
|
||||
register_telegram_type(0x035D, F("SM100Circuit2Config"), true, MAKE_PF_CB(process_SM100Circuit2Config));
|
||||
register_telegram_type(0x0362, F("SM100Monitor"), false, MAKE_PF_CB(process_SM100Monitor));
|
||||
register_telegram_type(0x0363, F("SM100Monitor2"), false, MAKE_PF_CB(process_SM100Monitor2));
|
||||
register_telegram_type(0x0366, F("SM100Config"), false, MAKE_PF_CB(process_SM100Config));
|
||||
register_telegram_type(0x0364, F("SM100Status"), false, MAKE_PF_CB(process_SM100Status));
|
||||
register_telegram_type(0x036A, F("SM100Status2"), false, MAKE_PF_CB(process_SM100Status2));
|
||||
register_telegram_type(0x0380, F("SM100CollectorConfig"), true, MAKE_PF_CB(process_SM100CollectorConfig));
|
||||
register_telegram_type(0x038E, F("SM100Energy"), true, MAKE_PF_CB(process_SM100Energy));
|
||||
register_telegram_type(0x0391, F("SM100Time"), true, MAKE_PF_CB(process_SM100Time));
|
||||
register_telegram_type(0x035F, F("SM100Config1"), true, MAKE_PF_CB(process_SM100Config1));
|
||||
register_telegram_type(0x035C, F("SM100HeatAssist"), true, MAKE_PF_CB(process_SM100HeatAssist));
|
||||
register_telegram_type(0x0361, F("SM100Differential"), true, MAKE_PF_CB(process_SM100Differential));
|
||||
// register_telegram_type(0xF9, "ParamCfg", false, MAKE_PF_CB(process_SM100ParamCfg));
|
||||
register_telegram_type(0x0358, "SM100SystemConfig", true, MAKE_PF_CB(process_SM100SystemConfig));
|
||||
register_telegram_type(0x035A, "SM100CircuitConfig", true, MAKE_PF_CB(process_SM100CircuitConfig));
|
||||
register_telegram_type(0x035D, "SM100Circuit2Config", true, MAKE_PF_CB(process_SM100Circuit2Config));
|
||||
register_telegram_type(0x0362, "SM100Monitor", false, MAKE_PF_CB(process_SM100Monitor));
|
||||
register_telegram_type(0x0363, "SM100Monitor2", false, MAKE_PF_CB(process_SM100Monitor2));
|
||||
register_telegram_type(0x0366, "SM100Config", false, MAKE_PF_CB(process_SM100Config));
|
||||
register_telegram_type(0x0364, "SM100Status", false, MAKE_PF_CB(process_SM100Status));
|
||||
register_telegram_type(0x036A, "SM100Status2", false, MAKE_PF_CB(process_SM100Status2));
|
||||
register_telegram_type(0x0380, "SM100CollectorConfig", true, MAKE_PF_CB(process_SM100CollectorConfig));
|
||||
register_telegram_type(0x038E, "SM100Energy", true, MAKE_PF_CB(process_SM100Energy));
|
||||
register_telegram_type(0x0391, "SM100Time", true, MAKE_PF_CB(process_SM100Time));
|
||||
register_telegram_type(0x035F, "SM100Config1", true, MAKE_PF_CB(process_SM100Config1));
|
||||
register_telegram_type(0x035C, "SM100HeatAssist", true, MAKE_PF_CB(process_SM100HeatAssist));
|
||||
register_telegram_type(0x0361, "SM100Differential", true, MAKE_PF_CB(process_SM100Differential));
|
||||
}
|
||||
}
|
||||
|
||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_ISM) {
|
||||
register_telegram_type(0x0103, F("ISM1StatusMessage"), true, MAKE_PF_CB(process_ISM1StatusMessage));
|
||||
register_telegram_type(0x0101, F("ISM1Set"), true, MAKE_PF_CB(process_ISM1Set));
|
||||
register_telegram_type(0x0104, F("ISM2StatusMessage"), false, MAKE_PF_CB(process_ISM2StatusMessage));
|
||||
register_telegram_type(0x0103, "ISM1StatusMessage", true, MAKE_PF_CB(process_ISM1StatusMessage));
|
||||
register_telegram_type(0x0101, "ISM1Set", true, MAKE_PF_CB(process_ISM1Set));
|
||||
register_telegram_type(0x0104, "ISM2StatusMessage", false, MAKE_PF_CB(process_ISM2StatusMessage));
|
||||
}
|
||||
|
||||
// device values...
|
||||
@@ -664,7 +664,7 @@ void Solar::process_SM100ParamCfg(std::shared_ptr<const Telegram> telegram) {
|
||||
telegram->read_value(max, 13);
|
||||
telegram->read_value(cur, 17);
|
||||
|
||||
// LOG_DEBUG(F("SM100ParamCfg param=0x%04X, offset=%d, min=%d, default=%d, max=%d, current=%d"), t_id, of, min, def, max, cur));
|
||||
// LOG_DEBUG("SM100ParamCfg param=0x%04X, offset=%d, min=%d, default=%d, max=%d, current=%d", t_id, of, min, def, max, cur));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace emsesp {
|
||||
|
||||
class Solar : public EMSdevice {
|
||||
public:
|
||||
Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand);
|
||||
|
||||
private:
|
||||
static uuid::log::Logger logger_;
|
||||
|
||||
@@ -22,12 +22,12 @@ namespace emsesp {
|
||||
|
||||
REGISTER_FACTORY(Switch, EMSdevice::DeviceType::SWITCH);
|
||||
|
||||
Switch::Switch(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
Switch::Switch(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
// WM10 module, device_id 0x11
|
||||
register_telegram_type(0x9C, F("WM10MonitorMessage"), false, MAKE_PF_CB(process_WM10MonitorMessage));
|
||||
register_telegram_type(0x9D, F("WM10SetMessage"), false, MAKE_PF_CB(process_WM10SetMessage));
|
||||
register_telegram_type(0x1E, F("WM10TempMessage"), false, MAKE_PF_CB(process_WM10TempMessage));
|
||||
register_telegram_type(0x9C, "WM10MonitorMessage", false, MAKE_PF_CB(process_WM10MonitorMessage));
|
||||
register_telegram_type(0x9D, "WM10SetMessage", false, MAKE_PF_CB(process_WM10SetMessage));
|
||||
register_telegram_type(0x1E, "WM10TempMessage", false, MAKE_PF_CB(process_WM10TempMessage));
|
||||
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &activated_, DeviceValueType::BOOL, FL_(activated), DeviceValueUOM::NONE);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace emsesp {
|
||||
|
||||
class Switch : public EMSdevice {
|
||||
public:
|
||||
Switch(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
Switch(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand);
|
||||
|
||||
private:
|
||||
void process_WM10SetMessage(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
@@ -24,37 +24,37 @@ REGISTER_FACTORY(Thermostat, EMSdevice::DeviceType::THERMOSTAT);
|
||||
|
||||
uuid::log::Logger Thermostat::logger_{F_(thermostat), uuid::log::Facility::CONSOLE};
|
||||
|
||||
Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
uint8_t model = this->model();
|
||||
|
||||
// RF remote sensor seen at 0x40, maybe this is also for different hc with id 0x40 - 0x47? emsesp.cpp maps only 0x40
|
||||
if (device_id >= 0x40 && device_id <= 0x47) {
|
||||
register_telegram_type(0x0435, F("RFTemp"), false, MAKE_PF_CB(process_RemoteTemp));
|
||||
register_telegram_type(0x0435, "RFTemp", false, MAKE_PF_CB(process_RemoteTemp));
|
||||
return;
|
||||
}
|
||||
// remote thermostats with humidity: RC100H remote
|
||||
if (device_id >= 0x38 && device_id <= 0x3F) {
|
||||
register_telegram_type(0x042B, F("RemoteTemp"), false, MAKE_PF_CB(process_RemoteTemp));
|
||||
register_telegram_type(0x047B, F("RemoteHumidity"), false, MAKE_PF_CB(process_RemoteHumidity));
|
||||
register_telegram_type(0x0273, F("RemoteCorrection"), true, MAKE_PF_CB(process_RemoteCorrection));
|
||||
register_telegram_type(0x042B, "RemoteTemp", false, MAKE_PF_CB(process_RemoteTemp));
|
||||
register_telegram_type(0x047B, "RemoteHumidity", false, MAKE_PF_CB(process_RemoteHumidity));
|
||||
register_telegram_type(0x0273, "RemoteCorrection", true, MAKE_PF_CB(process_RemoteCorrection));
|
||||
register_device_values(); // register device values for common values (not heating circuit)
|
||||
return; // no values to add
|
||||
}
|
||||
|
||||
// common telegram handlers
|
||||
register_telegram_type(EMS_TYPE_RCOutdoorTemp, F("RCOutdoorTemp"), false, MAKE_PF_CB(process_RCOutdoorTemp));
|
||||
register_telegram_type(EMS_TYPE_RCTime, F("RCTime"), false, MAKE_PF_CB(process_RCTime));
|
||||
register_telegram_type(0xA2, F("RCError"), false, MAKE_PF_CB(process_RCError));
|
||||
register_telegram_type(0x12, F("RCErrorMessage"), false, MAKE_PF_CB(process_RCErrorMessage));
|
||||
register_telegram_type(0x13, F("RCErrorMessage2"), false, MAKE_PF_CB(process_RCErrorMessage));
|
||||
register_telegram_type(EMS_TYPE_RCOutdoorTemp, "RCOutdoorTemp", false, MAKE_PF_CB(process_RCOutdoorTemp));
|
||||
register_telegram_type(EMS_TYPE_RCTime, "RCTime", false, MAKE_PF_CB(process_RCTime));
|
||||
register_telegram_type(0xA2, "RCError", false, MAKE_PF_CB(process_RCError));
|
||||
register_telegram_type(0x12, "RCErrorMessage", false, MAKE_PF_CB(process_RCErrorMessage));
|
||||
register_telegram_type(0x13, "RCErrorMessage2", false, MAKE_PF_CB(process_RCErrorMessage));
|
||||
// RC10
|
||||
if (model == EMSdevice::EMS_DEVICE_FLAG_RC10) {
|
||||
monitor_typeids = {0xB1};
|
||||
set_typeids = {0xB0};
|
||||
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
||||
register_telegram_type(monitor_typeids[i], F("RC10Monitor"), false, MAKE_PF_CB(process_RC10Monitor));
|
||||
register_telegram_type(set_typeids[i], F("RC10Set"), false, MAKE_PF_CB(process_RC10Set));
|
||||
register_telegram_type(monitor_typeids[i], "RC10Monitor", false, MAKE_PF_CB(process_RC10Monitor));
|
||||
register_telegram_type(set_typeids[i], "RC10Set", false, MAKE_PF_CB(process_RC10Set));
|
||||
}
|
||||
|
||||
// RC35
|
||||
@@ -64,15 +64,15 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
|
||||
timer_typeids = {0x3F, 0x49, 0x53, 0x5D};
|
||||
timer2_typeids = {0x42, 0x4C, 0x56, 0x60};
|
||||
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
||||
register_telegram_type(monitor_typeids[i], F("RC35Monitor"), false, MAKE_PF_CB(process_RC35Monitor));
|
||||
register_telegram_type(set_typeids[i], F("RC35Set"), false, MAKE_PF_CB(process_RC35Set));
|
||||
register_telegram_type(timer_typeids[i], F("RC35Timer"), false, MAKE_PF_CB(process_RC35Timer));
|
||||
register_telegram_type(timer2_typeids[i], F("RC35Timer2"), false, MAKE_PF_CB(process_RC35Timer));
|
||||
register_telegram_type(monitor_typeids[i], "RC35Monitor", false, MAKE_PF_CB(process_RC35Monitor));
|
||||
register_telegram_type(set_typeids[i], "RC35Set", false, MAKE_PF_CB(process_RC35Set));
|
||||
register_telegram_type(timer_typeids[i], "RC35Timer", false, MAKE_PF_CB(process_RC35Timer));
|
||||
register_telegram_type(timer2_typeids[i], "RC35Timer2", false, MAKE_PF_CB(process_RC35Timer));
|
||||
}
|
||||
register_telegram_type(EMS_TYPE_IBASettings, F("IBASettings"), true, MAKE_PF_CB(process_IBASettings));
|
||||
register_telegram_type(EMS_TYPE_wwSettings, F("WWSettings"), true, MAKE_PF_CB(process_RC35wwSettings));
|
||||
register_telegram_type(0x38, F("WWTimer"), true, MAKE_PF_CB(process_RC35wwTimer));
|
||||
register_telegram_type(0x39, F("WWCircTimer"), true, MAKE_PF_CB(process_RC35wwTimer));
|
||||
register_telegram_type(EMS_TYPE_IBASettings, "IBASettings", true, MAKE_PF_CB(process_IBASettings));
|
||||
register_telegram_type(EMS_TYPE_wwSettings, "WWSettings", true, MAKE_PF_CB(process_RC35wwSettings));
|
||||
register_telegram_type(0x38, "WWTimer", true, MAKE_PF_CB(process_RC35wwTimer));
|
||||
register_telegram_type(0x39, "WWCircTimer", true, MAKE_PF_CB(process_RC35wwTimer));
|
||||
|
||||
// RC20
|
||||
} else if (model == EMSdevice::EMS_DEVICE_FLAG_RC20) {
|
||||
@@ -81,22 +81,22 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
|
||||
curve_typeids = {0x90};
|
||||
timer_typeids = {0x8F};
|
||||
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
||||
register_telegram_type(monitor_typeids[i], F("RC20Monitor"), false, MAKE_PF_CB(process_RC20Monitor));
|
||||
register_telegram_type(set_typeids[i], F("RC20Set"), false, MAKE_PF_CB(process_RC20Set));
|
||||
register_telegram_type(curve_typeids[i], F("RC20Temp"), false, MAKE_PF_CB(process_RC20Temp));
|
||||
register_telegram_type(timer_typeids[i], F("RC20Timer"), false, MAKE_PF_CB(process_RC20Timer));
|
||||
register_telegram_type(monitor_typeids[i], "RC20Monitor", false, MAKE_PF_CB(process_RC20Monitor));
|
||||
register_telegram_type(set_typeids[i], "RC20Set", false, MAKE_PF_CB(process_RC20Set));
|
||||
register_telegram_type(curve_typeids[i], "RC20Temp", false, MAKE_PF_CB(process_RC20Temp));
|
||||
register_telegram_type(timer_typeids[i], "RC20Timer", false, MAKE_PF_CB(process_RC20Timer));
|
||||
}
|
||||
// remote thermostat uses only 0xAF
|
||||
register_telegram_type(0xAF, F("RC20Remote"), false, MAKE_PF_CB(process_RC20Remote));
|
||||
register_telegram_type(0xAF, "RC20Remote", false, MAKE_PF_CB(process_RC20Remote));
|
||||
// RC20 newer
|
||||
} else if ((model == EMSdevice::EMS_DEVICE_FLAG_RC20_N) || (model == EMSdevice::EMS_DEVICE_FLAG_RC25)) {
|
||||
monitor_typeids = {0xAE};
|
||||
set_typeids = {0xAD};
|
||||
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
||||
register_telegram_type(monitor_typeids[i], F("RC20Monitor"), false, MAKE_PF_CB(process_RC20Monitor_2));
|
||||
register_telegram_type(set_typeids[i], F("RC20Set"), false, MAKE_PF_CB(process_RC20Set_2));
|
||||
register_telegram_type(monitor_typeids[i], "RC20Monitor", false, MAKE_PF_CB(process_RC20Monitor_2));
|
||||
register_telegram_type(set_typeids[i], "RC20Set", false, MAKE_PF_CB(process_RC20Set_2));
|
||||
}
|
||||
register_telegram_type(0xAF, F("RC20Remote"), false, MAKE_PF_CB(process_RC20Remote));
|
||||
register_telegram_type(0xAF, "RC20Remote", false, MAKE_PF_CB(process_RC20Remote));
|
||||
// RC30
|
||||
} else if (model == EMSdevice::EMS_DEVICE_FLAG_RC30) {
|
||||
monitor_typeids = {0x41};
|
||||
@@ -104,27 +104,27 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
|
||||
curve_typeids = {0x40};
|
||||
timer_typeids = {0x3F};
|
||||
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
||||
register_telegram_type(monitor_typeids[i], F("RC30Monitor"), false, MAKE_PF_CB(process_RC30Monitor));
|
||||
register_telegram_type(set_typeids[i], F("RC30Set"), false, MAKE_PF_CB(process_RC30Set));
|
||||
register_telegram_type(curve_typeids[i], F("RC30Temp"), false, MAKE_PF_CB(process_RC30Temp));
|
||||
register_telegram_type(timer_typeids[i], F("RC30Timer"), false, MAKE_PF_CB(process_RC35Timer));
|
||||
register_telegram_type(monitor_typeids[i], "RC30Monitor", false, MAKE_PF_CB(process_RC30Monitor));
|
||||
register_telegram_type(set_typeids[i], "RC30Set", false, MAKE_PF_CB(process_RC30Set));
|
||||
register_telegram_type(curve_typeids[i], "RC30Temp", false, MAKE_PF_CB(process_RC30Temp));
|
||||
register_telegram_type(timer_typeids[i], "RC30Timer", false, MAKE_PF_CB(process_RC35Timer));
|
||||
}
|
||||
register_telegram_type(EMS_TYPE_RC30wwSettings, F("RC30WWSettings"), true, MAKE_PF_CB(process_RC30wwSettings));
|
||||
register_telegram_type(0x38, F("WWTimer"), true, MAKE_PF_CB(process_RC35wwTimer));
|
||||
register_telegram_type(0x39, F("WWCircTimer"), true, MAKE_PF_CB(process_RC35wwTimer));
|
||||
register_telegram_type(EMS_TYPE_RC30wwSettings, "RC30WWSettings", true, MAKE_PF_CB(process_RC30wwSettings));
|
||||
register_telegram_type(0x38, "WWTimer", true, MAKE_PF_CB(process_RC35wwTimer));
|
||||
register_telegram_type(0x39, "WWCircTimer", true, MAKE_PF_CB(process_RC35wwTimer));
|
||||
|
||||
// EASY
|
||||
} else if (model == EMSdevice::EMS_DEVICE_FLAG_EASY) {
|
||||
monitor_typeids = {0x0A};
|
||||
set_typeids = {};
|
||||
register_telegram_type(monitor_typeids[0], F("EasyMonitor"), true, MAKE_PF_CB(process_EasyMonitor));
|
||||
register_telegram_type(monitor_typeids[0], "EasyMonitor", true, MAKE_PF_CB(process_EasyMonitor));
|
||||
|
||||
// CRF
|
||||
} else if (model == EMSdevice::EMS_DEVICE_FLAG_CRF) {
|
||||
monitor_typeids = {0x02A5, 0x02A6, 0x02A7, 0x02A8};
|
||||
set_typeids = {};
|
||||
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
||||
register_telegram_type(monitor_typeids[i], F("CRFMonitor"), false, MAKE_PF_CB(process_CRFMonitor));
|
||||
register_telegram_type(monitor_typeids[i], "CRFMonitor", false, MAKE_PF_CB(process_CRFMonitor));
|
||||
}
|
||||
|
||||
// RC300/RC100
|
||||
@@ -136,46 +136,46 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
|
||||
curve_typeids = {0x029B, 0x029C, 0x029D, 0x029E, 0x029F, 0x02A0, 0x02A1, 0x02A2};
|
||||
summer2_typeids = {0x0471, 0x0472, 0x0473, 0x0474, 0x0475, 0x0476, 0x0477, 0x0478};
|
||||
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
||||
register_telegram_type(monitor_typeids[i], F("RC300Monitor"), false, MAKE_PF_CB(process_RC300Monitor));
|
||||
register_telegram_type(set_typeids[i], F("RC300Set"), false, MAKE_PF_CB(process_RC300Set));
|
||||
register_telegram_type(summer_typeids[i], F("RC300Summer"), false, MAKE_PF_CB(process_RC300Summer));
|
||||
register_telegram_type(curve_typeids[i], F("RC300Curves"), false, MAKE_PF_CB(process_RC300Curve));
|
||||
register_telegram_type(summer2_typeids[i], F("RC300Summer2"), false, MAKE_PF_CB(process_RC300Summer2));
|
||||
register_telegram_type(monitor_typeids[i], "RC300Monitor", false, MAKE_PF_CB(process_RC300Monitor));
|
||||
register_telegram_type(set_typeids[i], "RC300Set", false, MAKE_PF_CB(process_RC300Set));
|
||||
register_telegram_type(summer_typeids[i], "RC300Summer", false, MAKE_PF_CB(process_RC300Summer));
|
||||
register_telegram_type(curve_typeids[i], "RC300Curves", false, MAKE_PF_CB(process_RC300Curve));
|
||||
register_telegram_type(summer2_typeids[i], "RC300Summer2", false, MAKE_PF_CB(process_RC300Summer2));
|
||||
}
|
||||
for (uint8_t i = 0; i < set2_typeids.size(); i++) {
|
||||
register_telegram_type(set2_typeids[i], F("RC300Set2"), false, MAKE_PF_CB(process_RC300Set2));
|
||||
register_telegram_type(set2_typeids[i], "RC300Set2", false, MAKE_PF_CB(process_RC300Set2));
|
||||
}
|
||||
register_telegram_type(0x2F5, F("RC300WWmode"), true, MAKE_PF_CB(process_RC300WWmode));
|
||||
register_telegram_type(0x31B, F("RC300WWtemp"), true, MAKE_PF_CB(process_RC300WWtemp));
|
||||
register_telegram_type(0x31D, F("RC300WWmode2"), false, MAKE_PF_CB(process_RC300WWmode2));
|
||||
register_telegram_type(0x31E, F("RC300WWmode2"), false, MAKE_PF_CB(process_RC300WWmode2));
|
||||
register_telegram_type(0x23A, F("RC300OutdoorTemp"), true, MAKE_PF_CB(process_RC300OutdoorTemp));
|
||||
register_telegram_type(0x267, F("RC300Floordry"), false, MAKE_PF_CB(process_RC300Floordry));
|
||||
register_telegram_type(0x240, F("RC300Settings"), true, MAKE_PF_CB(process_RC300Settings));
|
||||
register_telegram_type(0x2F5, "RC300WWmode", true, MAKE_PF_CB(process_RC300WWmode));
|
||||
register_telegram_type(0x31B, "RC300WWtemp", true, MAKE_PF_CB(process_RC300WWtemp));
|
||||
register_telegram_type(0x31D, "RC300WWmode2", false, MAKE_PF_CB(process_RC300WWmode2));
|
||||
register_telegram_type(0x31E, "RC300WWmode2", false, MAKE_PF_CB(process_RC300WWmode2));
|
||||
register_telegram_type(0x23A, "RC300OutdoorTemp", true, MAKE_PF_CB(process_RC300OutdoorTemp));
|
||||
register_telegram_type(0x267, "RC300Floordry", false, MAKE_PF_CB(process_RC300Floordry));
|
||||
register_telegram_type(0x240, "RC300Settings", true, MAKE_PF_CB(process_RC300Settings));
|
||||
|
||||
// JUNKERS/HT3
|
||||
} else if (model == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) {
|
||||
monitor_typeids = {0x016F, 0x0170, 0x0171, 0x0172};
|
||||
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
||||
register_telegram_type(monitor_typeids[i], F("JunkersMonitor"), false, MAKE_PF_CB(process_JunkersMonitor));
|
||||
register_telegram_type(monitor_typeids[i], "JunkersMonitor", false, MAKE_PF_CB(process_JunkersMonitor));
|
||||
}
|
||||
|
||||
if (has_flags(EMS_DEVICE_FLAG_JUNKERS_OLD)) {
|
||||
// FR120, FR100
|
||||
set_typeids = {0x0179, 0x017A, 0x017B, 0x017C};
|
||||
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
||||
register_telegram_type(set_typeids[i], F("JunkersSet"), false, MAKE_PF_CB(process_JunkersSet2));
|
||||
register_telegram_type(set_typeids[i], "JunkersSet", false, MAKE_PF_CB(process_JunkersSet2));
|
||||
}
|
||||
} else {
|
||||
set_typeids = {0x0165, 0x0166, 0x0167, 0x0168};
|
||||
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
||||
register_telegram_type(set_typeids[i], F("JunkersSet"), false, MAKE_PF_CB(process_JunkersSet));
|
||||
register_telegram_type(set_typeids[i], "JunkersSet", false, MAKE_PF_CB(process_JunkersSet));
|
||||
}
|
||||
}
|
||||
register_telegram_type(0xBB, F("HybridSettings"), true, MAKE_PF_CB(process_JunkersHybridSettings));
|
||||
register_telegram_type(0x23, F("JunkersSetMixer"), true, MAKE_PF_CB(process_JunkersSetMixer));
|
||||
register_telegram_type(0x123, F("JunkersRemote"), false, MAKE_PF_CB(process_JunkersRemoteMonitor));
|
||||
register_telegram_type(0x1D3, F("JunkersDhw"), true, MAKE_PF_CB(process_JunkersWW));
|
||||
register_telegram_type(0xBB, "HybridSettings", true, MAKE_PF_CB(process_JunkersHybridSettings));
|
||||
register_telegram_type(0x23, "JunkersSetMixer", true, MAKE_PF_CB(process_JunkersSetMixer));
|
||||
register_telegram_type(0x123, "JunkersRemote", false, MAKE_PF_CB(process_JunkersRemoteMonitor));
|
||||
register_telegram_type(0x1D3, "JunkersDhw", true, MAKE_PF_CB(process_JunkersWW));
|
||||
}
|
||||
|
||||
// register device values for common values (not heating circuit)
|
||||
@@ -593,7 +593,7 @@ void Thermostat::process_RC20Timer(std::shared_ptr<const Telegram> telegram) {
|
||||
uint8_t time = telegram->message_data[1];
|
||||
|
||||
// we use EN settings for the day abbreviation
|
||||
std::string sday = read_flash_string(FL_(enum_dayOfWeek)[day][0]);
|
||||
std::string sday = (FL_(enum_dayOfWeek)[day][0]);
|
||||
// std::string sday = Helpers::translated_word(FL_(enum_dayOfWeek)[day]);
|
||||
|
||||
if (day == 7) {
|
||||
@@ -680,6 +680,12 @@ void Thermostat::process_JunkersSet(std::shared_ptr<const Telegram> telegram) {
|
||||
return;
|
||||
}
|
||||
|
||||
has_update(telegram, hc->daytemp, 17); // is * 2
|
||||
has_update(telegram, hc->nighttemp, 16); // is * 2
|
||||
has_update(telegram, hc->nofrosttemp, 15); // is * 2
|
||||
has_update(telegram, hc->control, 1); // remote: 0-off, 1-FB10, 2-FB100
|
||||
has_enumupdate(telegram, hc->program, 13, 1); // 1-6: 1 = A, 2 = B,...
|
||||
has_enumupdate(telegram, hc->mode, 14, 1); // 0 = nofrost, 1 = eco, 2 = heat, 3 = auto
|
||||
has_update(telegram, hc->daytemp, 17); // is * 2
|
||||
has_update(telegram, hc->nighttemp, 16); // is * 2
|
||||
has_update(telegram, hc->nofrosttemp, 15); // is * 2
|
||||
@@ -795,7 +801,7 @@ void Thermostat::process_RC35wwTimer(std::shared_ptr<const Telegram> telegram) {
|
||||
|
||||
char data[sizeof(wwSwitchTime_)];
|
||||
// we use EN settings for the day abbreviation
|
||||
std::string sday = read_flash_string(FL_(enum_dayOfWeek)[day][0]);
|
||||
std::string sday = (FL_(enum_dayOfWeek)[day][0]);
|
||||
// std::string sday = Helpers::translated_word(FL_(enum_dayOfWeek)[day]);
|
||||
if (day == 7) {
|
||||
snprintf(data, sizeof(data), "%02d not_set", no);
|
||||
@@ -1274,7 +1280,7 @@ void Thermostat::process_RC35Timer(std::shared_ptr<const Telegram> telegram) {
|
||||
uint8_t time = telegram->message_data[1];
|
||||
|
||||
// we use EN settings for the day abbreviation
|
||||
std::string sday = read_flash_string(FL_(enum_dayOfWeek)[day][0]);
|
||||
std::string sday = (FL_(enum_dayOfWeek)[day][0]);
|
||||
// std::string sday = Helpers::translated_word(FL_(enum_dayOfWeek)[day]);
|
||||
if (day == 7) {
|
||||
snprintf(data, sizeof(data), "%02d not_set", no);
|
||||
@@ -1372,7 +1378,7 @@ void Thermostat::process_RCTime(std::shared_ptr<const Telegram> telegram) {
|
||||
double difference = difftime(now, ttime);
|
||||
if (difference > 15 || difference < -15) {
|
||||
set_datetime("ntp", -1); // set from NTP
|
||||
LOG_INFO(F("thermostat time correction from ntp"));
|
||||
LOG_INFO("thermostat time correction from ntp");
|
||||
}
|
||||
}
|
||||
#ifndef EMSESP_STANDALONE
|
||||
@@ -1383,7 +1389,7 @@ void Thermostat::process_RCTime(std::shared_ptr<const Telegram> telegram) {
|
||||
}
|
||||
struct timeval newnow = {.tv_sec = ttime};
|
||||
settimeofday(&newnow, nullptr);
|
||||
LOG_INFO(F("ems-esp time set from thermostat"));
|
||||
LOG_INFO("ems-esp time set from thermostat");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1551,7 +1557,7 @@ bool Thermostat::set_calinttemp(const char * value, const int8_t id) {
|
||||
}
|
||||
|
||||
auto t = (int8_t)(ct * 10);
|
||||
LOG_DEBUG(F("Calibrating internal temperature to %d.%d C"), t / 10, t < 0 ? -t % 10 : t % 10);
|
||||
LOG_DEBUG("Calibrating internal temperature to %d.%d C", t / 10, t < 0 ? -t % 10 : t % 10);
|
||||
|
||||
if (model() == EMS_DEVICE_FLAG_RC10) {
|
||||
write_command(0xB0, 0, t, 0xB0);
|
||||
@@ -2155,7 +2161,7 @@ bool Thermostat::set_datetime(const char * value, const int8_t id) {
|
||||
return false;
|
||||
}
|
||||
if (!EMSESP::system_.ntp_connected()) {
|
||||
LOG_WARNING(F("Set date: no valid NTP data, setting from ESP Clock"));
|
||||
LOG_WARNING("Set date: no valid NTP data, setting from ESP Clock");
|
||||
}
|
||||
|
||||
data[0] = tm_->tm_year - 100; // Bosch counts from 2000
|
||||
@@ -2183,15 +2189,15 @@ bool Thermostat::set_datetime(const char * value, const int8_t id) {
|
||||
data[7] = 0;
|
||||
}
|
||||
} else {
|
||||
LOG_WARNING(F("Set date: invalid data, wrong length"));
|
||||
LOG_WARNING("Set date: invalid data, wrong length");
|
||||
return false;
|
||||
}
|
||||
if (data[1] == 0 || data[1] > 12 || data[2] > 23 || data[3] == 0 || data[3] > 31 || data[4] > 59 || data[5] > 59 || data[6] > 6 || data[7] > 3) {
|
||||
LOG_WARNING(F("Invalid date/time: %02d.%02d.2%03d-%02d:%02d:%02d-%d-%d"), data[3], data[1], data[0], data[2], data[4], data[5], data[6], data[7]);
|
||||
LOG_WARNING("Invalid date/time: %02d.%02d.2%03d-%02d:%02d:%02d-%d-%d", data[3], data[1], data[0], data[2], data[4], data[5], data[6], data[7]);
|
||||
return false;
|
||||
}
|
||||
|
||||
// LOG_INFO(F("Setting date and time: %02d.%02d.2%03d-%02d:%02d:%02d-%d-%d"), data[3], data[1], data[0], data[2], data[4], data[5], data[6], data[7]);
|
||||
// LOG_INFO("Setting date and time: %02d.%02d.2%03d-%02d:%02d:%02d-%d-%d", data[3], data[1], data[0], data[2], data[4], data[5], data[6], data[7]);
|
||||
write_command(EMS_TYPE_time, 0, data, 8, EMS_TYPE_time);
|
||||
|
||||
return true;
|
||||
@@ -2664,7 +2670,7 @@ bool Thermostat::set_switchtime(const char * value, const uint16_t type_id, char
|
||||
day = 7;
|
||||
on = 7;
|
||||
time = 0x90;
|
||||
// LOG_INFO(F("switchtime %02d cleared"), no);
|
||||
// LOG_INFO("switchtime %02d cleared", no);
|
||||
}
|
||||
} else {
|
||||
if (strlen(value) > 1) {
|
||||
@@ -2681,7 +2687,7 @@ bool Thermostat::set_switchtime(const char * value, const uint16_t type_id, char
|
||||
if (strlen(value) > 4) {
|
||||
for (uint8_t i = 0; i < 7; i++) {
|
||||
// we use EN settings for the day abbreviation
|
||||
if (!strncmp(&value[3], read_flash_string(FL_(enum_dayOfWeek)[i][0]).c_str(), 2)) {
|
||||
if (!strncmp(&value[3], (FL_(enum_dayOfWeek)[i][0]), 2)) {
|
||||
day = i;
|
||||
}
|
||||
|
||||
@@ -2705,7 +2711,7 @@ bool Thermostat::set_switchtime(const char * value, const uint16_t type_id, char
|
||||
day = 7;
|
||||
on = 7;
|
||||
time = 0x90;
|
||||
// LOG_INFO(F("switchtime %02d cleared"), no);
|
||||
// LOG_INFO("switchtime %02d cleared", no);
|
||||
}
|
||||
}
|
||||
uint8_t data[2] = {0xE7, 0x90}; // unset switchtime
|
||||
@@ -2721,20 +2727,20 @@ bool Thermostat::set_switchtime(const char * value, const uint16_t type_id, char
|
||||
max_on = 1;
|
||||
}
|
||||
if (no > 41 || time > 0x90 || ((on < min_on || on > max_on) && on != 7)) {
|
||||
// LOG_WARNING(F("Setting switchtime: Invalid data: %s"), value);
|
||||
// LOG_WARNING(F("Setting switchtime: Invalid data: %02d.%1d.0x%02X.%1d"), no, day, time, on);
|
||||
// LOG_WARNING("Setting switchtime: Invalid data: %s", value);
|
||||
// LOG_WARNING("Setting switchtime: Invalid data: %02d.%1d.0x%02X.%1d", no, day, time, on);
|
||||
return false;
|
||||
}
|
||||
if (data[0] != 0xE7) {
|
||||
// we use EN settings for the day abbreviation
|
||||
std::string sday = read_flash_string(FL_(enum_dayOfWeek)[day][0]);
|
||||
std::string sday = (FL_(enum_dayOfWeek)[day][0]);
|
||||
// std::string sday = Helpers::translated_word(FL_(enum_dayOfWeek)[day]);
|
||||
if (model() == EMS_DEVICE_FLAG_RC35 || model() == EMS_DEVICE_FLAG_RC30_N) {
|
||||
snprintf(out, len, "%02d %s %02d:%02d %s", no, sday.c_str(), time / 6, 10 * (time % 6), on ? "on" : "off");
|
||||
} else if ((model() == EMS_DEVICE_FLAG_RC20) || (model() == EMS_DEVICE_FLAG_RC30)) {
|
||||
snprintf(out, len, "%02d %s %02d:%02d T%d", no, sday.c_str(), time / 6, 10 * (time % 6), on);
|
||||
} else {
|
||||
std::string son = read_flash_string(FL_(enum_switchmode)[on][0]);
|
||||
std::string son = (FL_(enum_switchmode)[on][0]);
|
||||
// std::string son = Helpers::translated_word(FL_(enum_switchmode)[on]);
|
||||
snprintf(out, len, "%02d %s %02d:%02d %s", no, sday.c_str(), time / 6, 10 * (time % 6), son.c_str());
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace emsesp {
|
||||
|
||||
class Thermostat : public EMSdevice {
|
||||
public:
|
||||
Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand);
|
||||
class HeatingCircuit {
|
||||
public:
|
||||
HeatingCircuit(const uint8_t hc_num, const uint8_t model)
|
||||
|
||||
@@ -44,39 +44,39 @@ bool EMSdevice::has_entities() const {
|
||||
}
|
||||
|
||||
std::string EMSdevice::tag_to_string(uint8_t tag) {
|
||||
return read_flash_string(DeviceValue::DeviceValueTAG_s[tag]);
|
||||
return (DeviceValue::DeviceValueTAG_s[tag]);
|
||||
}
|
||||
|
||||
std::string EMSdevice::tag_to_mqtt(uint8_t tag) {
|
||||
return read_flash_string(DeviceValue::DeviceValueTAG_mqtt[tag]);
|
||||
return (DeviceValue::DeviceValueTAG_mqtt[tag]);
|
||||
}
|
||||
|
||||
// convert UOM to a string - these don't need translating
|
||||
std::string EMSdevice::uom_to_string(uint8_t uom) {
|
||||
if (EMSESP::system_.fahrenheit() && (uom == DeviceValueUOM::DEGREES || uom == DeviceValueUOM::DEGREES_R)) {
|
||||
return read_flash_string(DeviceValue::DeviceValueUOM_s[DeviceValueUOM::FAHRENHEIT]);
|
||||
return (DeviceValue::DeviceValueUOM_s[DeviceValueUOM::FAHRENHEIT]);
|
||||
}
|
||||
return read_flash_string(DeviceValue::DeviceValueUOM_s[uom]);
|
||||
return (DeviceValue::DeviceValueUOM_s[uom]);
|
||||
}
|
||||
|
||||
std::string EMSdevice::brand_to_string() const {
|
||||
switch (brand_) {
|
||||
case EMSdevice::Brand::BOSCH:
|
||||
return read_flash_string(F("Bosch"));
|
||||
return ("Bosch");
|
||||
case EMSdevice::Brand::JUNKERS:
|
||||
return read_flash_string(F("Junkers"));
|
||||
return ("Junkers");
|
||||
case EMSdevice::Brand::BUDERUS:
|
||||
return read_flash_string(F("Buderus"));
|
||||
return ("Buderus");
|
||||
case EMSdevice::Brand::NEFIT:
|
||||
return read_flash_string(F("Nefit"));
|
||||
return ("Nefit");
|
||||
case EMSdevice::Brand::SIEGER:
|
||||
return read_flash_string(F("Sieger"));
|
||||
return ("Sieger");
|
||||
case EMSdevice::Brand::WORCESTER:
|
||||
return read_flash_string(F("Worcester"));
|
||||
return ("Worcester");
|
||||
case EMSdevice::Brand::IVT:
|
||||
return read_flash_string(F("IVT"));
|
||||
return ("IVT");
|
||||
default:
|
||||
return read_flash_string(F(""));
|
||||
return ("");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,29 +84,29 @@ std::string EMSdevice::brand_to_string() const {
|
||||
std::string EMSdevice::device_type_2_device_name(const uint8_t device_type) {
|
||||
switch (device_type) {
|
||||
case DeviceType::SYSTEM:
|
||||
return read_flash_string(F_(system));
|
||||
return (F_(system));
|
||||
case DeviceType::BOILER:
|
||||
return read_flash_string(F_(boiler));
|
||||
return (F_(boiler));
|
||||
case DeviceType::THERMOSTAT:
|
||||
return read_flash_string(F_(thermostat));
|
||||
return (F_(thermostat));
|
||||
case DeviceType::HEATPUMP:
|
||||
return read_flash_string(F_(heatpump));
|
||||
return (F_(heatpump));
|
||||
case DeviceType::SOLAR:
|
||||
return read_flash_string(F_(solar));
|
||||
return (F_(solar));
|
||||
case DeviceType::CONNECT:
|
||||
return read_flash_string(F_(connect));
|
||||
return (F_(connect));
|
||||
case DeviceType::MIXER:
|
||||
return read_flash_string(F_(mixer));
|
||||
return (F_(mixer));
|
||||
case DeviceType::DALLASSENSOR:
|
||||
return read_flash_string(F_(dallassensor));
|
||||
return (F_(dallassensor));
|
||||
case DeviceType::ANALOGSENSOR:
|
||||
return read_flash_string(F_(analogsensor));
|
||||
return (F_(analogsensor));
|
||||
case DeviceType::CONTROLLER:
|
||||
return read_flash_string(F_(controller));
|
||||
return (F_(controller));
|
||||
case DeviceType::SWITCH:
|
||||
return read_flash_string(F_(switch));
|
||||
return (F_(switch));
|
||||
case DeviceType::GATEWAY:
|
||||
return read_flash_string(F_(gateway));
|
||||
return (F_(gateway));
|
||||
default:
|
||||
return Helpers::translated_word(FL_(unknown));
|
||||
}
|
||||
@@ -193,11 +193,11 @@ uint8_t EMSdevice::decode_brand(uint8_t value) {
|
||||
std::string EMSdevice::to_string() const {
|
||||
// for devices that haven't been lookup yet, don't show all details
|
||||
if (product_id_ == 0) {
|
||||
return name_ + " (DeviceID:" + Helpers::hextoa(device_id_) + ")";
|
||||
return std::string(name_) + " (DeviceID:" + Helpers::hextoa(device_id_) + ")";
|
||||
}
|
||||
|
||||
if (brand_ == Brand::NO_BRAND) {
|
||||
return name_ + " (DeviceID:" + Helpers::hextoa(device_id_) + ", ProductID:" + Helpers::itoa(product_id_) + ", Version:" + version_ + ")";
|
||||
return std::string(name_) + " (DeviceID:" + Helpers::hextoa(device_id_) + ", ProductID:" + Helpers::itoa(product_id_) + ", Version:" + version_ + ")";
|
||||
}
|
||||
|
||||
return brand_to_string() + " " + name_ + " (DeviceID:" + Helpers::hextoa(device_id_) + ", ProductID:" + Helpers::itoa(product_id_) + ", Version:" + version_
|
||||
@@ -215,7 +215,7 @@ std::string EMSdevice::to_string_short() const {
|
||||
|
||||
// for each telegram that has the fetch value set (true) do a read request
|
||||
void EMSdevice::fetch_values() {
|
||||
EMSESP::logger().debug(F("Fetching values for deviceID 0x%02X"), device_id());
|
||||
EMSESP::logger().debug("Fetching values for deviceID 0x%02X", device_id());
|
||||
|
||||
for (const auto & tf : telegram_functions_) {
|
||||
if (tf.fetch_) {
|
||||
@@ -226,7 +226,7 @@ void EMSdevice::fetch_values() {
|
||||
|
||||
// toggle on/off automatic fetch for a telegramID
|
||||
void EMSdevice::toggle_fetch(uint16_t telegram_id, bool toggle) {
|
||||
EMSESP::logger().debug(F("Toggling fetch for deviceID 0x%02X, telegramID 0x%02X to %d"), device_id(), telegram_id, toggle);
|
||||
EMSESP::logger().debug("Toggling fetch for deviceID 0x%02X, telegramID 0x%02X to %d", device_id(), telegram_id, toggle);
|
||||
|
||||
for (auto & tf : telegram_functions_) {
|
||||
if (tf.telegram_type_id_ == telegram_id) {
|
||||
@@ -264,9 +264,9 @@ void EMSdevice::list_device_entries(JsonObject & output) const {
|
||||
// if we have a tag prefix it
|
||||
char key[50];
|
||||
if (!EMSdevice::tag_to_mqtt(dv.tag).empty()) {
|
||||
snprintf(key, sizeof(key), "%s.%s", EMSdevice::tag_to_mqtt(dv.tag).c_str(), read_flash_string(dv.short_name).c_str());
|
||||
snprintf(key, sizeof(key), "%s.%s", EMSdevice::tag_to_mqtt(dv.tag).c_str(), (dv.short_name));
|
||||
} else {
|
||||
snprintf(key, sizeof(key), "%s", read_flash_string(dv.short_name).c_str());
|
||||
snprintf(key, sizeof(key), "%s", (dv.short_name));
|
||||
}
|
||||
|
||||
JsonArray details = output.createNestedArray(key);
|
||||
@@ -289,7 +289,7 @@ void EMSdevice::show_telegram_handlers(uuid::console::Shell & shell) const {
|
||||
}
|
||||
/*
|
||||
// colored list of type-ids
|
||||
shell.printf(F(" This %s will listen to telegram type IDs: "), device_type_name().c_str());
|
||||
shell.printf(" This %s will listen to telegram type IDs: ", device_type_name().c_str());
|
||||
for (const auto & tf : telegram_functions_) {
|
||||
if (tf.received_ && !tf.fetch_) {
|
||||
shell.printf(COLOR_BRIGHT_GREEN);
|
||||
@@ -298,34 +298,34 @@ void EMSdevice::show_telegram_handlers(uuid::console::Shell & shell) const {
|
||||
} else {
|
||||
shell.printf(COLOR_BRIGHT_RED);
|
||||
}
|
||||
shell.printf(F("0x%02X "), tf.telegram_type_id_);
|
||||
shell.printf("0x%02X ", tf.telegram_type_id_);
|
||||
}
|
||||
shell.printf(COLOR_RESET);
|
||||
*/
|
||||
shell.printf(F(" Received telegram type IDs: "));
|
||||
shell.printf(" Received telegram type IDs: ");
|
||||
for (const auto & tf : telegram_functions_) {
|
||||
if (tf.received_ && !tf.fetch_) {
|
||||
shell.printf(F("0x%02X "), tf.telegram_type_id_);
|
||||
shell.printf("0x%02X ", tf.telegram_type_id_);
|
||||
}
|
||||
}
|
||||
shell.println();
|
||||
shell.printf(F(" Fetched telegram type IDs: "));
|
||||
shell.printf(" Fetched telegram type IDs: ");
|
||||
for (const auto & tf : telegram_functions_) {
|
||||
if (tf.fetch_) {
|
||||
shell.printf(F("0x%02X "), tf.telegram_type_id_);
|
||||
shell.printf("0x%02X ", tf.telegram_type_id_);
|
||||
}
|
||||
}
|
||||
shell.println();
|
||||
shell.printf(F(" Pending telegram type IDs: "));
|
||||
shell.printf(" Pending telegram type IDs: ");
|
||||
for (const auto & tf : telegram_functions_) {
|
||||
if (!tf.received_ && !tf.fetch_) {
|
||||
shell.printf(F("0x%02X "), tf.telegram_type_id_);
|
||||
shell.printf("0x%02X ", tf.telegram_type_id_);
|
||||
}
|
||||
}
|
||||
shell.println();
|
||||
shell.printf(F(" Ignored telegram type IDs: "));
|
||||
shell.printf(" Ignored telegram type IDs: ");
|
||||
for (auto handlers : handlers_ignored_) {
|
||||
shell.printf(F("0x%02X "), handlers);
|
||||
shell.printf("0x%02X ", handlers);
|
||||
}
|
||||
shell.println();
|
||||
}
|
||||
@@ -379,7 +379,7 @@ void EMSdevice::show_mqtt_handlers(uuid::console::Shell & shell) const {
|
||||
}
|
||||
|
||||
// register a callback function for a specific telegram type
|
||||
void EMSdevice::register_telegram_type(const uint16_t telegram_type_id, const __FlashStringHelper * telegram_type_name, bool fetch, const process_function_p f) {
|
||||
void EMSdevice::register_telegram_type(const uint16_t telegram_type_id, const char * telegram_type_name, bool fetch, const process_function_p f) {
|
||||
telegram_functions_.emplace_back(telegram_type_id, telegram_type_name, fetch, false, f);
|
||||
}
|
||||
|
||||
@@ -390,28 +390,34 @@ void EMSdevice::register_telegram_type(const uint16_t telegram_type_id, const __
|
||||
// type: one of DeviceValueType
|
||||
// options: options for enum, which are translated as a list of lists
|
||||
// options_single: list of names
|
||||
// numeric_operatpr: to divide or multiply, see DeviceValueNumOps::
|
||||
// short_name: used in Mqtt as keys
|
||||
// numeric_operator: to divide or multiply, see DeviceValueNumOps::
|
||||
// short_name: used in MQTT as keys
|
||||
// fullname: used in Web and Console unless empty (nullptr) - can be translated
|
||||
// uom: unit of measure from DeviceValueUOM
|
||||
// has_cmd: true if this is an associated command
|
||||
// min: min allowed value
|
||||
// max: max allowed value
|
||||
void EMSdevice::add_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const __FlashStringHelper * const ** options,
|
||||
const __FlashStringHelper * const * options_single,
|
||||
int8_t numeric_operator,
|
||||
const __FlashStringHelper * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max) {
|
||||
void EMSdevice::add_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const char * const ** options,
|
||||
const char * const * options_single,
|
||||
int8_t numeric_operator,
|
||||
const char * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max) {
|
||||
bool has_cmd = (f != nullptr);
|
||||
|
||||
auto short_name = name[0];
|
||||
const class __FlashStringHelper * const * fullname = &name[1]; // translations start at index 1
|
||||
auto short_name = name[0];
|
||||
|
||||
const char * const * fullname;
|
||||
if (Helpers::count_items(name) == 1) {
|
||||
fullname = nullptr; // no translations available, use empty to prevent crash
|
||||
} else {
|
||||
fullname = &name[1]; // translations start at index 1
|
||||
}
|
||||
|
||||
// initialize the device value depending on it's type
|
||||
if (type == DeviceValueType::STRING) {
|
||||
@@ -440,7 +446,7 @@ void EMSdevice::add_device_value(uint8_t tag,
|
||||
EMSESP::webCustomizationService.read([&](WebCustomization & settings) {
|
||||
for (EntityCustomization entityCustomization : settings.entityCustomizations) {
|
||||
if ((entityCustomization.product_id == product_id()) && (entityCustomization.device_id == device_id())) {
|
||||
std::string entity = tag < DeviceValueTAG::TAG_HC1 ? read_flash_string(short_name) : tag_to_string(tag) + "/" + read_flash_string(short_name);
|
||||
std::string entity = tag < DeviceValueTAG::TAG_HC1 ? (short_name) : tag_to_string(tag) + "/" + (short_name);
|
||||
for (std::string entity_id : entityCustomization.entity_ids) {
|
||||
// if there is an appended custom name, strip it to get the true entity name
|
||||
// and extract the new custom name
|
||||
@@ -472,7 +478,6 @@ void EMSdevice::add_device_value(uint8_t tag,
|
||||
// add the device entity
|
||||
devicevalues_.emplace_back(
|
||||
device_type_, tag, value_p, type, options, options_single, numeric_operator, short_name, fullname, custom_fullname, uom, has_cmd, min, max, state);
|
||||
devicevalues_.back().set_custom_minmax();
|
||||
|
||||
// add a new command if it has a function attached
|
||||
if (!has_cmd) {
|
||||
@@ -491,107 +496,102 @@ void EMSdevice::add_device_value(uint8_t tag,
|
||||
|
||||
// add the command to our library
|
||||
// cmd is the short_name and the description is the fullname (not the custom fullname)
|
||||
Command::add(device_type_, short_name, f, Helpers::translated_fword(fullname), flags);
|
||||
Command::add(device_type_, short_name, f, Helpers::translated_word(fullname).c_str(), flags);
|
||||
}
|
||||
|
||||
// single list of options
|
||||
void EMSdevice::register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const __FlashStringHelper * const * options_single,
|
||||
const __FlashStringHelper * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f) {
|
||||
void EMSdevice::register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const char * const * options_single,
|
||||
const char * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f) {
|
||||
// create a multi-list from the options
|
||||
add_device_value(tag, value_p, type, nullptr, options_single, 0, name, uom, f, 0, 0);
|
||||
};
|
||||
|
||||
// single list of options, with no translations, with min and max
|
||||
void EMSdevice::register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const __FlashStringHelper * const * options_single,
|
||||
const __FlashStringHelper * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max) {
|
||||
void EMSdevice::register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const char * const * options_single,
|
||||
const char * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max) {
|
||||
// create a multi-list from the options
|
||||
add_device_value(tag, value_p, type, nullptr, options_single, 0, name, uom, f, min, max);
|
||||
};
|
||||
|
||||
void EMSdevice::register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
int8_t numeric_operator,
|
||||
const __FlashStringHelper * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f) {
|
||||
void EMSdevice::register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
int8_t numeric_operator,
|
||||
const char * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f) {
|
||||
add_device_value(tag, value_p, type, nullptr, nullptr, numeric_operator, name, uom, f, 0, 0);
|
||||
}
|
||||
|
||||
void EMSdevice::register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
int8_t numeric_operator,
|
||||
const __FlashStringHelper * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max) {
|
||||
void EMSdevice::register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
int8_t numeric_operator,
|
||||
const char * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max) {
|
||||
add_device_value(tag, value_p, type, nullptr, nullptr, numeric_operator, name, uom, f, min, max);
|
||||
}
|
||||
|
||||
// no options, no function
|
||||
void EMSdevice::register_device_value(uint8_t tag, void * value_p, uint8_t type, const __FlashStringHelper * const * name, uint8_t uom, const cmd_function_p f) {
|
||||
void EMSdevice::register_device_value(uint8_t tag, void * value_p, uint8_t type, const char * const * name, uint8_t uom, const cmd_function_p f) {
|
||||
add_device_value(tag, value_p, type, nullptr, nullptr, 0, name, uom, f, 0, 0);
|
||||
};
|
||||
|
||||
// no options, with min/max
|
||||
void EMSdevice::register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const __FlashStringHelper * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max) {
|
||||
void EMSdevice::register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const char * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max) {
|
||||
add_device_value(tag, value_p, type, nullptr, nullptr, 0, name, uom, f, min, max);
|
||||
};
|
||||
|
||||
// function with min and max values
|
||||
// adds a new command to the command list
|
||||
// in this function we separate out the short and long names and take any translations
|
||||
void EMSdevice::register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const __FlashStringHelper * const ** options,
|
||||
const __FlashStringHelper * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max) {
|
||||
void EMSdevice::register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const char * const ** options,
|
||||
const char * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max) {
|
||||
add_device_value(tag, value_p, type, options, nullptr, 0, name, uom, f, min, max);
|
||||
}
|
||||
|
||||
// function with no min and max values (set to 0)
|
||||
void EMSdevice::register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const __FlashStringHelper * const ** options,
|
||||
const __FlashStringHelper * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f) {
|
||||
void EMSdevice::register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const char * const ** options,
|
||||
const char * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f) {
|
||||
add_device_value(tag, value_p, type, options, nullptr, 0, name, uom, f, 0, 0);
|
||||
}
|
||||
|
||||
// no associated command function, or min/max values
|
||||
void EMSdevice::register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const __FlashStringHelper * const ** options,
|
||||
const __FlashStringHelper * const * name,
|
||||
uint8_t uom) {
|
||||
void EMSdevice::register_device_value(uint8_t tag, void * value_p, uint8_t type, const char * const ** options, const char * const * name, uint8_t uom) {
|
||||
add_device_value(tag, value_p, type, options, nullptr, 0, name, uom, nullptr, 0, 0);
|
||||
}
|
||||
|
||||
@@ -610,7 +610,7 @@ bool EMSdevice::is_readonly(const std::string & cmd, const int8_t id) const {
|
||||
uint8_t tag = id > 0 ? DeviceValueTAG::TAG_HC1 + id - 1 : DeviceValueTAG::TAG_NONE;
|
||||
for (const auto & dv : devicevalues_) {
|
||||
// check command name and tag, id -1 is default hc and only checks name
|
||||
if (dv.has_cmd && read_flash_string(dv.short_name) == cmd && (dv.tag < DeviceValueTAG::TAG_HC1 || dv.tag == tag || id == -1)) {
|
||||
if (dv.has_cmd && std::string(dv.short_name) == cmd && (dv.tag < DeviceValueTAG::TAG_HC1 || dv.tag == tag || id == -1)) {
|
||||
return dv.has_state(DeviceValueState::DV_READONLY);
|
||||
}
|
||||
}
|
||||
@@ -638,24 +638,14 @@ void EMSdevice::publish_value(void * value_p) const {
|
||||
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||
if (Mqtt::publish_single2cmd()) {
|
||||
if (dv.tag >= DeviceValueTAG::TAG_HC1) {
|
||||
snprintf(topic,
|
||||
sizeof(topic),
|
||||
"%s/%s/%s",
|
||||
device_type_2_device_name(device_type_).c_str(),
|
||||
tag_to_mqtt(dv.tag).c_str(),
|
||||
read_flash_string(dv.short_name).c_str());
|
||||
snprintf(topic, sizeof(topic), "%s/%s/%s", device_type_2_device_name(device_type_).c_str(), tag_to_mqtt(dv.tag).c_str(), (dv.short_name));
|
||||
} else {
|
||||
snprintf(topic, sizeof(topic), "%s/%s", device_type_2_device_name(device_type_).c_str(), read_flash_string(dv.short_name).c_str());
|
||||
snprintf(topic, sizeof(topic), "%s/%s", device_type_2_device_name(device_type_).c_str(), (dv.short_name));
|
||||
}
|
||||
} else if (Mqtt::is_nested() && dv.tag >= DeviceValueTAG::TAG_HC1) {
|
||||
snprintf(topic,
|
||||
sizeof(topic),
|
||||
"%s/%s/%s",
|
||||
Mqtt::tag_to_topic(device_type_, dv.tag).c_str(),
|
||||
tag_to_mqtt(dv.tag).c_str(),
|
||||
read_flash_string(dv.short_name).c_str());
|
||||
snprintf(topic, sizeof(topic), "%s/%s/%s", Mqtt::tag_to_topic(device_type_, dv.tag).c_str(), tag_to_mqtt(dv.tag).c_str(), (dv.short_name));
|
||||
} else {
|
||||
snprintf(topic, sizeof(topic), "%s/%s", Mqtt::tag_to_topic(device_type_, dv.tag).c_str(), read_flash_string(dv.short_name).c_str());
|
||||
snprintf(topic, sizeof(topic), "%s/%s", Mqtt::tag_to_topic(device_type_, dv.tag).c_str(), (dv.short_name));
|
||||
}
|
||||
|
||||
int8_t num_op = dv.numeric_operator;
|
||||
@@ -717,7 +707,6 @@ void EMSdevice::publish_value(void * value_p) const {
|
||||
|
||||
// looks up the UOM for a given key from the device value table
|
||||
// key is the fullname
|
||||
// TODO really should be using the shortname as the identifier
|
||||
std::string EMSdevice::get_value_uom(const char * key) const {
|
||||
// the key may have a TAG string prefixed at the beginning. If so, remove it
|
||||
char new_key[80];
|
||||
@@ -725,11 +714,12 @@ std::string EMSdevice::get_value_uom(const char * key) const {
|
||||
char * key_p = new_key;
|
||||
|
||||
for (uint8_t i = 0; i < DeviceValue::tag_count; i++) {
|
||||
auto tag = read_flash_string(DeviceValue::DeviceValueTAG_s[i]);
|
||||
if (!tag.empty()) {
|
||||
std::string key2 = key; // copy char to a std::string
|
||||
if ((key2.find(tag) != std::string::npos) && (key[tag.length()] == ' ')) {
|
||||
key_p += tag.length() + 1; // remove the tag
|
||||
auto tag = (DeviceValue::DeviceValueTAG_s[i]);
|
||||
if (tag) {
|
||||
std::string key2 = key; // copy string to a std::string so we can use the find function
|
||||
uint8_t length = strlen(tag);
|
||||
if ((key2.find(tag) != std::string::npos) && (key[length] == ' ')) {
|
||||
key_p += length + 1; // remove the tag
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -824,7 +814,7 @@ void EMSdevice::generate_values_web(JsonObject & output) {
|
||||
if (dv.has_cmd && !dv.has_state(DeviceValueState::DV_READONLY)) {
|
||||
// add the name of the Command function
|
||||
if (dv.tag >= DeviceValueTAG::TAG_HC1) {
|
||||
obj["c"] = tag_to_mqtt(dv.tag) + "/" + read_flash_string(dv.short_name);
|
||||
obj["c"] = tag_to_mqtt(dv.tag) + "/" + (dv.short_name);
|
||||
} else {
|
||||
obj["c"] = dv.short_name;
|
||||
}
|
||||
@@ -912,7 +902,6 @@ void EMSdevice::generate_values_web_customization(JsonArray & output) {
|
||||
} else if (dv.type == DeviceValueType::ULONG) {
|
||||
obj["v"] = Helpers::transformNumFloat(*(uint32_t *)(dv.value_p), dv.numeric_operator);
|
||||
} else if (dv.type == DeviceValueType::TIME) {
|
||||
// sometimes we need to divide by 60
|
||||
obj["v"] = Helpers::transformNumFloat(*(uint32_t *)(dv.value_p), dv.numeric_operator);
|
||||
}
|
||||
}
|
||||
@@ -920,9 +909,9 @@ void EMSdevice::generate_values_web_customization(JsonArray & output) {
|
||||
|
||||
// id holds the shortname and must always have a value for the WebUI table to work
|
||||
if (dv.tag >= DeviceValueTAG::TAG_HC1) {
|
||||
obj["id"] = tag_to_string(dv.tag) + "/" + read_flash_string(dv.short_name);
|
||||
obj["id"] = tag_to_string(dv.tag) + "/" + (dv.short_name);
|
||||
} else {
|
||||
obj["id"] = read_flash_string(dv.short_name);
|
||||
obj["id"] = (dv.short_name);
|
||||
}
|
||||
|
||||
// n is the fullname, and can be optional
|
||||
@@ -945,8 +934,12 @@ void EMSdevice::generate_values_web_customization(JsonArray & output) {
|
||||
obj["cn"] = custom_fullname;
|
||||
}
|
||||
} else {
|
||||
// it's a command
|
||||
obj["n"] = "!" + fullname; // prefix ! to fullname for commands
|
||||
obj["n"] = "!" + fullname; // prefix commands with a !
|
||||
}
|
||||
|
||||
// add the custom name, is optional
|
||||
if (!dv.custom_fullname.empty()) {
|
||||
obj["cn"] = dv.custom_fullname;
|
||||
}
|
||||
|
||||
obj["m"] = dv.state >> 4; // send back the mask state. We're only interested in the high nibble
|
||||
@@ -984,8 +977,7 @@ void EMSdevice::set_climate_minmax(uint8_t tag, int16_t min, uint16_t max) {
|
||||
// returns true if the entity has a mask set (not 0 the default)
|
||||
void EMSdevice::setCustomEntity(const std::string & entity_id) {
|
||||
for (auto & dv : devicevalues_) {
|
||||
std::string entity_name =
|
||||
dv.tag < DeviceValueTAG::TAG_HC1 ? read_flash_string(dv.short_name) : tag_to_string(dv.tag) + "/" + read_flash_string(dv.short_name);
|
||||
std::string entity_name = dv.tag < DeviceValueTAG::TAG_HC1 ? (dv.short_name) : tag_to_string(dv.tag) + "/" + (dv.short_name);
|
||||
|
||||
// extra shortname
|
||||
std::string shortname;
|
||||
@@ -1021,10 +1013,14 @@ void EMSdevice::setCustomEntity(const std::string & entity_id) {
|
||||
|
||||
auto min = dv.min;
|
||||
auto max = dv.max;
|
||||
|
||||
// set the min / max
|
||||
dv.set_custom_minmax();
|
||||
|
||||
if (Mqtt::ha_enabled() && dv.short_name == FL_(seltemp)[0] && (min != dv.min || max != dv.max)) {
|
||||
set_climate_minmax(dv.tag, dv.min, dv.max);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1033,9 +1029,8 @@ void EMSdevice::setCustomEntity(const std::string & entity_id) {
|
||||
// populate a string vector with entities that have masks set or have a custom name
|
||||
void EMSdevice::getCustomEntities(std::vector<std::string> & entity_ids) {
|
||||
for (const auto & dv : devicevalues_) {
|
||||
std::string entity_name =
|
||||
dv.tag < DeviceValueTAG::TAG_HC1 ? read_flash_string(dv.short_name) : tag_to_string(dv.tag) + "/" + read_flash_string(dv.short_name);
|
||||
uint8_t mask = dv.state >> 4;
|
||||
std::string entity_name = dv.tag < DeviceValueTAG::TAG_HC1 ? (dv.short_name) : tag_to_string(dv.tag) + "/" + (dv.short_name);
|
||||
uint8_t mask = dv.state >> 4;
|
||||
|
||||
if (mask || !dv.custom_fullname.empty()) {
|
||||
if (dv.custom_fullname.empty()) {
|
||||
@@ -1073,7 +1068,7 @@ bool EMSdevice::get_value_info(JsonObject & output, const char * cmd, const int8
|
||||
|
||||
// search device value with this tag
|
||||
for (auto & dv : devicevalues_) {
|
||||
if (strcmp(command_s, Helpers::toLower(read_flash_string(dv.short_name)).c_str()) == 0 && (tag <= 0 || tag == dv.tag)) {
|
||||
if (!strcmp(command_s, dv.short_name) && (tag <= 0 || tag == dv.tag)) {
|
||||
uint8_t fahrenheit = !EMSESP::system_.fahrenheit() ? 0 : (dv.uom == DeviceValueUOM::DEGREES) ? 2 : (dv.uom == DeviceValueUOM::DEGREES_R) ? 1 : 0;
|
||||
|
||||
const char * type = "type";
|
||||
@@ -1159,7 +1154,7 @@ bool EMSdevice::get_value_info(JsonObject & output, const char * cmd, const int8
|
||||
json[value] = Helpers::render_boolean(s, value_b);
|
||||
}
|
||||
}
|
||||
json[type] = F("boolean");
|
||||
json[type] = ("boolean");
|
||||
break;
|
||||
|
||||
case DeviceValueType::TIME:
|
||||
@@ -1173,7 +1168,7 @@ bool EMSdevice::get_value_info(JsonObject & output, const char * cmd, const int8
|
||||
if (Helpers::hasValue((char *)(dv.value_p))) {
|
||||
json[value] = (char *)(dv.value_p);
|
||||
}
|
||||
json[type] = F("string");
|
||||
json[type] = ("string");
|
||||
break;
|
||||
|
||||
case DeviceValueType::CMD:
|
||||
@@ -1218,7 +1213,7 @@ bool EMSdevice::get_value_info(JsonObject & output, const char * cmd, const int8
|
||||
// if we're filtering on an attribute, go find it
|
||||
if (attribute_s) {
|
||||
#if defined(EMSESP_DEBUG)
|
||||
EMSESP::logger().debug(F("[DEBUG] Attribute '%s'"), attribute_s);
|
||||
EMSESP::logger().debug("[DEBUG] Attribute '%s'", attribute_s);
|
||||
#endif
|
||||
if (json.containsKey(attribute_s)) {
|
||||
JsonVariant data = json[attribute_s];
|
||||
@@ -1293,7 +1288,7 @@ bool EMSdevice::generate_values(JsonObject & output, const uint8_t tag_filter, c
|
||||
strlcpy(name, fullname.c_str(), sizeof(name)); // use full name
|
||||
}
|
||||
} else {
|
||||
strlcpy(name, read_flash_string(dv.short_name).c_str(), sizeof(name)); // use short name
|
||||
strlcpy(name, (dv.short_name), sizeof(name)); // use short name
|
||||
|
||||
// if we have a tag, and its different to the last one create a nested object. only for hc, wwc and hs
|
||||
if (dv.tag != old_tag) {
|
||||
@@ -1360,8 +1355,7 @@ bool EMSdevice::generate_values(JsonObject & output, const uint8_t tag_filter, c
|
||||
} else if ((dv.type == DeviceValueType::TIME) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
|
||||
uint32_t time_value = *(uint32_t *)(dv.value_p);
|
||||
if (dv.numeric_operator == DeviceValueNumOp::DV_NUMOP_DIV60) {
|
||||
// sometimes we need to divide by 60
|
||||
time_value /= 60;
|
||||
time_value /= 60; // sometimes we need to divide by 60
|
||||
}
|
||||
if (output_target == OUTPUT_TARGET::API_VERBOSE || output_target == OUTPUT_TARGET::CONSOLE) {
|
||||
char time_s[60];
|
||||
@@ -1480,14 +1474,14 @@ bool EMSdevice::has_telegram_id(uint16_t id) const {
|
||||
std::string EMSdevice::telegram_type_name(std::shared_ptr<const Telegram> telegram) const {
|
||||
// see if it's one of the common ones, like Version
|
||||
if (telegram->type_id == EMS_TYPE_VERSION) {
|
||||
return read_flash_string(F("Version"));
|
||||
return ("Version");
|
||||
} else if (telegram->type_id == EMS_TYPE_UBADevices) {
|
||||
return read_flash_string(F("UBADevices"));
|
||||
return ("UBADevices");
|
||||
}
|
||||
|
||||
for (const auto & tf : telegram_functions_) {
|
||||
if ((tf.telegram_type_id_ == telegram->type_id) && (telegram->type_id != 0xFF)) {
|
||||
return read_flash_string(tf.telegram_type_name_);
|
||||
return (tf.telegram_type_name_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1502,7 +1496,7 @@ bool EMSdevice::handle_telegram(std::shared_ptr<const Telegram> telegram) {
|
||||
// if the data block is empty and we have not received data before, assume that this telegram
|
||||
// is not recognized by the bus master. So remove it from the automatic fetch list
|
||||
if (telegram->message_length == 0 && telegram->offset == 0 && !tf.received_) {
|
||||
EMSESP::logger().debug(F("This telegram (%s) is not recognized by the EMS bus"), read_flash_string(tf.telegram_type_name_).c_str());
|
||||
EMSESP::logger().debug(("This telegram (%s) is not recognized by the EMS bus"), (tf.telegram_type_name_));
|
||||
tf.fetch_ = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
168
src/emsdevice.h
168
src/emsdevice.h
@@ -34,7 +34,7 @@ class EMSdevice {
|
||||
static constexpr uint8_t EMS_DEVICES_MAX_TELEGRAMS = 20;
|
||||
|
||||
// device_type defines which derived class to use, e.g. BOILER, THERMOSTAT etc..
|
||||
EMSdevice(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
EMSdevice(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand)
|
||||
: device_type_(device_type)
|
||||
, device_id_(device_id)
|
||||
, product_id_(product_id)
|
||||
@@ -104,11 +104,11 @@ class EMSdevice {
|
||||
return brand_;
|
||||
}
|
||||
|
||||
inline void name(const std::string & name) {
|
||||
inline void name(const char * name) {
|
||||
name_ = name;
|
||||
}
|
||||
|
||||
inline std::string name() const {
|
||||
inline const char * name() const {
|
||||
return name_;
|
||||
}
|
||||
|
||||
@@ -193,7 +193,7 @@ class EMSdevice {
|
||||
|
||||
using process_function_p = std::function<void(std::shared_ptr<const Telegram>)>;
|
||||
|
||||
void register_telegram_type(const uint16_t telegram_type_id, const __FlashStringHelper * telegram_type_name, bool fetch, const process_function_p cb);
|
||||
void register_telegram_type(const uint16_t telegram_type_id, const char * telegram_type_name, bool fetch, const process_function_p cb);
|
||||
bool handle_telegram(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
std::string get_value_uom(const char * key) const;
|
||||
@@ -205,93 +205,77 @@ class EMSdevice {
|
||||
void generate_values_web(JsonObject & output);
|
||||
void generate_values_web_customization(JsonArray & output);
|
||||
|
||||
void add_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const __FlashStringHelper * const ** options,
|
||||
const __FlashStringHelper * const * options_single,
|
||||
int8_t numeric_operator,
|
||||
const __FlashStringHelper * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max);
|
||||
void add_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const char * const ** options,
|
||||
const char * const * options_single,
|
||||
int8_t numeric_operator,
|
||||
const char * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max);
|
||||
|
||||
void register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const __FlashStringHelper * const ** options,
|
||||
const __FlashStringHelper * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max);
|
||||
void register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const char * const ** options,
|
||||
const char * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max);
|
||||
|
||||
void register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const __FlashStringHelper * const ** options,
|
||||
const __FlashStringHelper * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f);
|
||||
void
|
||||
register_device_value(uint8_t tag, void * value_p, uint8_t type, const char * const ** options, const char * const * name, uint8_t uom, const cmd_function_p f);
|
||||
|
||||
void register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const __FlashStringHelper * const ** options,
|
||||
const __FlashStringHelper * const * name,
|
||||
uint8_t uom);
|
||||
void register_device_value(uint8_t tag, void * value_p, uint8_t type, const char * const ** options, const char * const * name, uint8_t uom);
|
||||
|
||||
void register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
int8_t numeric_operator,
|
||||
const __FlashStringHelper * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f = nullptr);
|
||||
void register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
int8_t numeric_operator,
|
||||
const char * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f = nullptr);
|
||||
|
||||
void register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
int8_t numeric_operator,
|
||||
const __FlashStringHelper * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max);
|
||||
void register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
int8_t numeric_operator,
|
||||
const char * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max);
|
||||
|
||||
// single list of options
|
||||
void register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const __FlashStringHelper * const * options_single,
|
||||
const __FlashStringHelper * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f = nullptr);
|
||||
void register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const char * const * options_single,
|
||||
const char * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f = nullptr);
|
||||
|
||||
// single list of options, with no translations, with min and max
|
||||
void register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const __FlashStringHelper * const * options_single,
|
||||
const __FlashStringHelper * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max);
|
||||
void register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const char * const * options_single,
|
||||
const char * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max);
|
||||
|
||||
// no options, optional function f
|
||||
void register_device_value(uint8_t tag, void * value_p, uint8_t type, const __FlashStringHelper * const * name, uint8_t uom, const cmd_function_p f = nullptr);
|
||||
void register_device_value(uint8_t tag, void * value_p, uint8_t type, const char * const * name, uint8_t uom, const cmd_function_p f = nullptr);
|
||||
|
||||
// no options, with min/max
|
||||
void register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const __FlashStringHelper * const * name,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max);
|
||||
void
|
||||
register_device_value(uint8_t tag, void * value_p, uint8_t type, const char * const * name, uint8_t uom, const cmd_function_p f, int16_t min, uint16_t max);
|
||||
|
||||
void write_command(const uint16_t type_id, const uint8_t offset, uint8_t * message_data, const uint8_t message_length, const uint16_t validate_typeid) const;
|
||||
void write_command(const uint16_t type_id, const uint8_t offset, const uint8_t value, const uint16_t validate_typeid) const;
|
||||
@@ -425,27 +409,27 @@ class EMSdevice {
|
||||
bool has_entities() const;
|
||||
|
||||
private:
|
||||
uint8_t unique_id_;
|
||||
uint8_t device_type_ = DeviceType::SYSTEM;
|
||||
uint8_t device_id_ = 0;
|
||||
uint8_t product_id_ = 0;
|
||||
char version_[6];
|
||||
std::string name_; // the long name for the EMS model
|
||||
uint8_t flags_ = 0;
|
||||
uint8_t brand_ = Brand::NO_BRAND;
|
||||
uint8_t unique_id_;
|
||||
uint8_t device_type_ = DeviceType::SYSTEM;
|
||||
uint8_t device_id_ = 0;
|
||||
uint8_t product_id_ = 0;
|
||||
char version_[6];
|
||||
const char * name_; // the long name for the EMS model
|
||||
uint8_t flags_ = 0;
|
||||
uint8_t brand_ = Brand::NO_BRAND;
|
||||
|
||||
bool ha_config_done_ = false;
|
||||
bool has_update_ = false;
|
||||
bool ha_config_firstrun_ = true; // this means a first setup of HA is needed after a restart
|
||||
|
||||
struct TelegramFunction {
|
||||
uint16_t telegram_type_id_; // it's type_id
|
||||
const __FlashStringHelper * telegram_type_name_; // e.g. RC20Message
|
||||
bool fetch_; // if this type_id be queried automatically
|
||||
bool received_;
|
||||
process_function_p process_function_;
|
||||
uint16_t telegram_type_id_; // it's type_id
|
||||
const char * telegram_type_name_; // e.g. RC20Message
|
||||
bool fetch_; // if this type_id be queried automatically
|
||||
bool received_;
|
||||
process_function_p process_function_;
|
||||
|
||||
TelegramFunction(uint16_t telegram_type_id, const __FlashStringHelper * telegram_type_name, bool fetch, bool received, const process_function_p process_function)
|
||||
TelegramFunction(uint16_t telegram_type_id, const char * telegram_type_name, bool fetch, bool received, const process_function_p process_function)
|
||||
: telegram_type_id_(telegram_type_id)
|
||||
, telegram_type_name_(telegram_type_name)
|
||||
, fetch_(fetch)
|
||||
|
||||
@@ -23,21 +23,21 @@
|
||||
namespace emsesp {
|
||||
|
||||
// constructor
|
||||
DeviceValue::DeviceValue(uint8_t device_type,
|
||||
uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const __FlashStringHelper * const ** options,
|
||||
const __FlashStringHelper * const * options_single,
|
||||
int8_t numeric_operator,
|
||||
const __FlashStringHelper * const short_name,
|
||||
const __FlashStringHelper * const * fullname,
|
||||
std::string & custom_fullname,
|
||||
uint8_t uom,
|
||||
bool has_cmd,
|
||||
int16_t min,
|
||||
uint16_t max,
|
||||
uint8_t state)
|
||||
DeviceValue::DeviceValue(uint8_t device_type,
|
||||
uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const char * const ** options,
|
||||
const char * const * options_single,
|
||||
int8_t numeric_operator,
|
||||
const char * const short_name,
|
||||
const char * const * fullname,
|
||||
std::string & custom_fullname,
|
||||
uint8_t uom,
|
||||
bool has_cmd,
|
||||
int16_t min,
|
||||
uint16_t max,
|
||||
uint8_t state)
|
||||
: device_type(device_type)
|
||||
, tag(tag)
|
||||
, value_p(value_p)
|
||||
@@ -60,10 +60,14 @@ DeviceValue::DeviceValue(uint8_t device_type,
|
||||
options_size = Helpers::count_items(options);
|
||||
}
|
||||
|
||||
// set the min/max
|
||||
set_custom_minmax();
|
||||
|
||||
#ifdef EMSESP_STANDALONE
|
||||
// only added for debugging
|
||||
Serial.print("registering entity: ");
|
||||
Serial.print(read_flash_string(short_name).c_str());
|
||||
Serial.print(COLOR_BRIGHT_RED_BACKGROUND);
|
||||
Serial.print(" registering entity: ");
|
||||
Serial.print((short_name));
|
||||
Serial.print("/");
|
||||
if (!custom_fullname.empty()) {
|
||||
Serial.print(COLOR_BRIGHT_CYAN);
|
||||
@@ -83,23 +87,23 @@ DeviceValue::DeviceValue(uint8_t device_type,
|
||||
Serial.print(" option");
|
||||
Serial.print(i + 1);
|
||||
Serial.print(":");
|
||||
auto str = Helpers::translated_fword(options[i]);
|
||||
Serial.print(read_flash_string(str).c_str());
|
||||
auto str = Helpers::translated_word(options[i]);
|
||||
Serial.print((str.c_str()));
|
||||
i++;
|
||||
}
|
||||
} else if (options_single != nullptr) {
|
||||
Serial.print("option1:!");
|
||||
Serial.print(read_flash_string(options_single[0]).c_str());
|
||||
Serial.print((options_single[0]));
|
||||
Serial.print("!");
|
||||
}
|
||||
Serial.println("");
|
||||
Serial.println(COLOR_RESET);
|
||||
#endif
|
||||
}
|
||||
|
||||
// mapping of UOM, to match order in DeviceValueUOM enum emsdevice.h
|
||||
// also maps to DeviceValueUOM in interface/src/project/types.ts for the Web UI
|
||||
// must be an int of 4 bytes, 32bit aligned
|
||||
const __FlashStringHelper * DeviceValue::DeviceValueUOM_s[] __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = {
|
||||
const char * DeviceValue::DeviceValueUOM_s[] = {
|
||||
|
||||
F_(uom_blank),
|
||||
F_(uom_degrees),
|
||||
@@ -125,7 +129,7 @@ const __FlashStringHelper * DeviceValue::DeviceValueUOM_s[] __attribute__((__ali
|
||||
|
||||
// mapping of TAGs, to match order in DeviceValueTAG enum in emsdevice.h
|
||||
// must be an int of 4 bytes, 32bit aligned
|
||||
const __FlashStringHelper * const DeviceValue::DeviceValueTAG_s[] PROGMEM = {
|
||||
const char * const DeviceValue::DeviceValueTAG_s[] = {
|
||||
|
||||
F_(tag_none), // ""
|
||||
F_(tag_heartbeat), // ""
|
||||
@@ -171,7 +175,7 @@ const __FlashStringHelper * const DeviceValue::DeviceValueTAG_s[] PROGMEM = {
|
||||
};
|
||||
|
||||
// MQTT topics derived from tags
|
||||
const __FlashStringHelper * const DeviceValue::DeviceValueTAG_mqtt[] PROGMEM = {
|
||||
const char * const DeviceValue::DeviceValueTAG_mqtt[] = {
|
||||
|
||||
F_(tag_none), // ""
|
||||
F_(heartbeat), // "heartbeat"
|
||||
@@ -217,7 +221,7 @@ const __FlashStringHelper * const DeviceValue::DeviceValueTAG_mqtt[] PROGMEM = {
|
||||
};
|
||||
|
||||
// count #tags once at compile time
|
||||
size_t DeviceValue::tag_count = sizeof(DeviceValue::DeviceValueTAG_s) / sizeof(__FlashStringHelper *);
|
||||
size_t DeviceValue::tag_count = sizeof(DeviceValue::DeviceValueTAG_s) / sizeof(char *);
|
||||
|
||||
// checks whether the device value has an actual value
|
||||
// returns true if its valid
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
#include "helpers.h" // for conversions
|
||||
#include "default_settings.h" // for enum types
|
||||
#include <uuid/common.h> // for read_flash_string
|
||||
|
||||
namespace emsesp {
|
||||
|
||||
@@ -143,38 +142,38 @@ class DeviceValue {
|
||||
DV_NUMOP_MUL15 = -15
|
||||
};
|
||||
|
||||
uint8_t device_type; // EMSdevice::DeviceType
|
||||
uint8_t tag; // DeviceValueTAG::*
|
||||
void * value_p; // pointer to variable of any type
|
||||
uint8_t type; // DeviceValueType::*
|
||||
const __FlashStringHelper * const ** options; // options as a flash char array
|
||||
const __FlashStringHelper * const * options_single; // options are not translated
|
||||
int8_t numeric_operator;
|
||||
uint8_t options_size; // number of options in the char array, calculated
|
||||
const __FlashStringHelper * const short_name; // used in MQTT and API
|
||||
const __FlashStringHelper * const * fullname; // used in Web and Console, is translated
|
||||
std::string custom_fullname; // optional, from customization
|
||||
uint8_t uom; // DeviceValueUOM::*
|
||||
bool has_cmd; // true if there is a Console/MQTT command which matches the short_name
|
||||
int16_t min; // min range
|
||||
uint16_t max; // max range
|
||||
uint8_t state; // DeviceValueState::*
|
||||
uint8_t device_type; // EMSdevice::DeviceType
|
||||
uint8_t tag; // DeviceValueTAG::*
|
||||
void * value_p; // pointer to variable of any type
|
||||
uint8_t type; // DeviceValueType::*
|
||||
const char * const ** options; // options as a flash char array
|
||||
const char * const * options_single; // options are not translated
|
||||
int8_t numeric_operator;
|
||||
uint8_t options_size; // number of options in the char array, calculated
|
||||
const char * const short_name; // used in MQTT and API
|
||||
const char * const * fullname; // used in Web and Console, is translated
|
||||
std::string custom_fullname; // optional, from customization
|
||||
uint8_t uom; // DeviceValueUOM::*
|
||||
bool has_cmd; // true if there is a Console/MQTT command which matches the short_name
|
||||
int16_t min; // min range
|
||||
uint16_t max; // max range
|
||||
uint8_t state; // DeviceValueState::*
|
||||
|
||||
DeviceValue(uint8_t device_type,
|
||||
uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const __FlashStringHelper * const ** options,
|
||||
const __FlashStringHelper * const * options_single,
|
||||
int8_t numeric_operator,
|
||||
const __FlashStringHelper * const short_name,
|
||||
const __FlashStringHelper * const * fullname,
|
||||
std::string & custom_fullname,
|
||||
uint8_t uom,
|
||||
bool has_cmd,
|
||||
int16_t min,
|
||||
uint16_t max,
|
||||
uint8_t state);
|
||||
DeviceValue(uint8_t device_type,
|
||||
uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const char * const ** options,
|
||||
const char * const * options_single,
|
||||
int8_t numeric_operator,
|
||||
const char * const short_name,
|
||||
const char * const * fullname,
|
||||
std::string & custom_fullname,
|
||||
uint8_t uom,
|
||||
bool has_cmd,
|
||||
int16_t min,
|
||||
uint16_t max,
|
||||
uint8_t state);
|
||||
|
||||
bool hasValue() const;
|
||||
bool get_min_max(int16_t & dv_set_min, uint16_t & dv_set_max);
|
||||
@@ -199,10 +198,10 @@ class DeviceValue {
|
||||
return state;
|
||||
}
|
||||
|
||||
static const __FlashStringHelper * DeviceValueUOM_s[];
|
||||
static const __FlashStringHelper * const DeviceValueTAG_s[];
|
||||
static const __FlashStringHelper * const DeviceValueTAG_mqtt[];
|
||||
static size_t tag_count; // # tags
|
||||
static const char * DeviceValueUOM_s[];
|
||||
static const char * const DeviceValueTAG_s[];
|
||||
static const char * const DeviceValueTAG_mqtt[];
|
||||
static size_t tag_count; // # tags
|
||||
};
|
||||
|
||||
}; // namespace emsesp
|
||||
|
||||
149
src/emsesp.cpp
149
src/emsesp.cpp
@@ -190,7 +190,7 @@ void EMSESP::uart_init() {
|
||||
if (System::is_valid_gpio(rx_gpio) && System::is_valid_gpio(tx_gpio)) {
|
||||
EMSuart::start(tx_mode, rx_gpio, tx_gpio); // start UART
|
||||
} else {
|
||||
LOG_WARNING(F("Invalid UART Rx/Tx GPIOs. Check config."));
|
||||
LOG_WARNING("Invalid UART Rx/Tx GPIOs. Check config.");
|
||||
}
|
||||
|
||||
txservice_.start(); // sends out request to EMS bus for all devices
|
||||
@@ -234,42 +234,42 @@ void EMSESP::show_ems(uuid::console::Shell & shell) {
|
||||
// EMS bus information
|
||||
switch (bus_status()) {
|
||||
case BUS_STATUS_OFFLINE:
|
||||
shell.printfln(F("EMS Bus is disconnected."));
|
||||
shell.printfln("EMS Bus is disconnected.");
|
||||
break;
|
||||
case BUS_STATUS_TX_ERRORS:
|
||||
shell.printfln(F("EMS Bus is connected, but Tx is not stable."));
|
||||
shell.printfln("EMS Bus is connected, but Tx is not stable.");
|
||||
break;
|
||||
default:
|
||||
shell.printfln(F("EMS Bus is connected."));
|
||||
shell.printfln("EMS Bus is connected.");
|
||||
break;
|
||||
}
|
||||
|
||||
shell.println();
|
||||
|
||||
if (bus_status() != BUS_STATUS_OFFLINE) {
|
||||
shell.printfln(F("EMS Bus info:"));
|
||||
EMSESP::webSettingsService.read([&](WebSettings & settings) { shell.printfln(F(" Tx mode: %d"), settings.tx_mode); });
|
||||
shell.printfln(F(" Bus protocol: %s"), EMSbus::is_ht3() ? F("HT3") : F("Buderus"));
|
||||
shell.printfln(F(" #recognized EMS devices: %d"), EMSESP::emsdevices.size());
|
||||
shell.printfln(F(" #telegrams received: %d"), rxservice_.telegram_count());
|
||||
shell.printfln(F(" #read requests sent: %d"), txservice_.telegram_read_count());
|
||||
shell.printfln(F(" #write requests sent: %d"), txservice_.telegram_write_count());
|
||||
shell.printfln(F(" #incomplete telegrams: %d"), rxservice_.telegram_error_count());
|
||||
shell.printfln(F(" #read fails (after %d retries): %d"), TxService::MAXIMUM_TX_RETRIES, txservice_.telegram_read_fail_count());
|
||||
shell.printfln(F(" #write fails (after %d retries): %d"), TxService::MAXIMUM_TX_RETRIES, txservice_.telegram_write_fail_count());
|
||||
shell.printfln(F(" Rx line quality: %d%%"), rxservice_.quality());
|
||||
shell.printfln(F(" Tx line quality: %d%%"), (txservice_.read_quality() + txservice_.read_quality()) / 2);
|
||||
shell.printfln("EMS Bus info:");
|
||||
EMSESP::webSettingsService.read([&](WebSettings & settings) { shell.printfln(" Tx mode: %d", settings.tx_mode); });
|
||||
shell.printfln(" Bus protocol: %s", EMSbus::is_ht3() ? ("HT3") : ("Buderus"));
|
||||
shell.printfln(" #recognized EMS devices: %d", EMSESP::emsdevices.size());
|
||||
shell.printfln(" #telegrams received: %d", rxservice_.telegram_count());
|
||||
shell.printfln(" #read requests sent: %d", txservice_.telegram_read_count());
|
||||
shell.printfln(" #write requests sent: %d", txservice_.telegram_write_count());
|
||||
shell.printfln(" #incomplete telegrams: %d", rxservice_.telegram_error_count());
|
||||
shell.printfln((" #read fails (after %d retries): %d"), TxService::MAXIMUM_TX_RETRIES, txservice_.telegram_read_fail_count());
|
||||
shell.printfln((" #write fails (after %d retries): %d"), TxService::MAXIMUM_TX_RETRIES, txservice_.telegram_write_fail_count());
|
||||
shell.printfln(" Rx line quality: %d%%", rxservice_.quality());
|
||||
shell.printfln(" Tx line quality: %d%%", (txservice_.read_quality() + txservice_.read_quality()) / 2);
|
||||
shell.println();
|
||||
}
|
||||
|
||||
// Rx queue
|
||||
auto rx_telegrams = rxservice_.queue();
|
||||
if (rx_telegrams.empty()) {
|
||||
shell.printfln(F("Rx Queue is empty"));
|
||||
shell.printfln("Rx Queue is empty");
|
||||
} else {
|
||||
shell.printfln(F("Rx Queue (%ld telegram%s):"), rx_telegrams.size(), rx_telegrams.size() == 1 ? "" : "s");
|
||||
shell.printfln(("Rx Queue (%ld telegram%s):"), rx_telegrams.size(), rx_telegrams.size() == 1 ? "" : "s");
|
||||
for (const auto & it : rx_telegrams) {
|
||||
shell.printfln(F(" [%02d] %s"), it.id_, pretty_telegram(it.telegram_).c_str());
|
||||
shell.printfln(" [%02d] %s", it.id_, pretty_telegram(it.telegram_).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,20 +278,20 @@ void EMSESP::show_ems(uuid::console::Shell & shell) {
|
||||
// Tx queue
|
||||
auto tx_telegrams = txservice_.queue();
|
||||
if (tx_telegrams.empty()) {
|
||||
shell.printfln(F("Tx Queue is empty"));
|
||||
shell.printfln("Tx Queue is empty");
|
||||
} else {
|
||||
shell.printfln(F("Tx Queue (%ld telegram%s):"), tx_telegrams.size(), tx_telegrams.size() == 1 ? "" : "s");
|
||||
shell.printfln(("Tx Queue (%ld telegram%s):"), tx_telegrams.size(), tx_telegrams.size() == 1 ? "" : "s");
|
||||
|
||||
std::string op;
|
||||
for (const auto & it : tx_telegrams) {
|
||||
if ((it.telegram_->operation) == Telegram::Operation::TX_RAW) {
|
||||
op = read_flash_string(F("RAW "));
|
||||
op = "RAW ";
|
||||
} else if ((it.telegram_->operation) == Telegram::Operation::TX_READ) {
|
||||
op = read_flash_string(F("READ "));
|
||||
op = "READ ";
|
||||
} else if ((it.telegram_->operation) == Telegram::Operation::TX_WRITE) {
|
||||
op = read_flash_string(F("WRITE"));
|
||||
op = "WRITE";
|
||||
}
|
||||
shell.printfln(F(" [%02d%c] %s %s"), it.id_, ((it.retry_) ? '*' : ' '), op.c_str(), pretty_telegram(it.telegram_).c_str());
|
||||
shell.printfln(" [%02d%c] %s %s", it.id_, ((it.retry_) ? '*' : ' '), op.c_str(), pretty_telegram(it.telegram_).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,7 +301,7 @@ void EMSESP::show_ems(uuid::console::Shell & shell) {
|
||||
// show EMS device values to the shell console
|
||||
void EMSESP::show_device_values(uuid::console::Shell & shell) {
|
||||
if (emsdevices.empty()) {
|
||||
shell.printfln(F("No EMS devices detected."));
|
||||
shell.printfln("No EMS devices detected.");
|
||||
shell.println();
|
||||
return;
|
||||
}
|
||||
@@ -311,7 +311,7 @@ void EMSESP::show_device_values(uuid::console::Shell & shell) {
|
||||
for (const auto & emsdevice : emsdevices) {
|
||||
if (emsdevice && (emsdevice->device_type() == device_class.first)) {
|
||||
// print header
|
||||
shell.printfln(F("%s: %s (%d)"), emsdevice->device_type_name().c_str(), emsdevice->to_string().c_str(), emsdevice->count_entities());
|
||||
shell.printfln(("%s: %s (%d)"), emsdevice->device_type_name().c_str(), emsdevice->to_string().c_str(), emsdevice->count_entities());
|
||||
|
||||
DynamicJsonDocument doc(EMSESP_JSON_SIZE_XXLARGE_DYN); // use max size
|
||||
JsonObject json = doc.to<JsonObject>();
|
||||
@@ -359,14 +359,14 @@ void EMSESP::show_device_values(uuid::console::Shell & shell) {
|
||||
// show Dallas temperature sensors and Analog sensors
|
||||
void EMSESP::show_sensor_values(uuid::console::Shell & shell) {
|
||||
if (dallassensor_.have_sensors()) {
|
||||
shell.printfln(F("Temperature sensors:"));
|
||||
shell.printfln("Temperature sensors:");
|
||||
char s[10];
|
||||
char s2[10];
|
||||
uint8_t fahrenheit = EMSESP::system_.fahrenheit() ? 2 : 0;
|
||||
|
||||
for (const auto & sensor : dallassensor_.sensors()) {
|
||||
if (Helpers::hasValue(sensor.temperature_c)) {
|
||||
shell.printfln(F(" %s: %s%s °%c%s (offset %s, ID: %s)"),
|
||||
shell.printfln((" %s: %s%s °%c%s (offset %s, ID: %s)"),
|
||||
sensor.name().c_str(),
|
||||
COLOR_BRIGHT_GREEN,
|
||||
Helpers::render_value(s, sensor.temperature_c, 10, fahrenheit),
|
||||
@@ -375,10 +375,7 @@ void EMSESP::show_sensor_values(uuid::console::Shell & shell) {
|
||||
Helpers::render_value(s2, sensor.offset(), 10, fahrenheit),
|
||||
sensor.id().c_str());
|
||||
} else {
|
||||
shell.printfln(F(" %s (offset %s, ID: %s)"),
|
||||
sensor.name().c_str(),
|
||||
Helpers::render_value(s, sensor.offset(), 10, fahrenheit),
|
||||
sensor.id().c_str());
|
||||
shell.printfln((" %s (offset %s, ID: %s)"), sensor.name().c_str(), Helpers::render_value(s, sensor.offset(), 10, fahrenheit), sensor.id().c_str());
|
||||
}
|
||||
}
|
||||
shell.println();
|
||||
@@ -387,11 +384,11 @@ void EMSESP::show_sensor_values(uuid::console::Shell & shell) {
|
||||
if (analogsensor_.have_sensors()) {
|
||||
char s[10];
|
||||
char s2[10];
|
||||
shell.printfln(F("Analog sensors:"));
|
||||
shell.printfln("Analog sensors:");
|
||||
for (const auto & sensor : analogsensor_.sensors()) {
|
||||
switch (sensor.type()) {
|
||||
case AnalogSensor::AnalogType::ADC:
|
||||
shell.printfln(F(" %s: %s%s %s%s (Type: ADC, Factor: %s, Offset: %d)"),
|
||||
shell.printfln((" %s: %s%s %s%s (Type: ADC, Factor: %s, Offset: %d)"),
|
||||
sensor.name().c_str(),
|
||||
COLOR_BRIGHT_GREEN,
|
||||
Helpers::render_value(s, sensor.value(), 2),
|
||||
@@ -403,7 +400,7 @@ void EMSESP::show_sensor_values(uuid::console::Shell & shell) {
|
||||
default:
|
||||
// case AnalogSensor::AnalogType::DIGITAL_IN:
|
||||
// case AnalogSensor::AnalogType::COUNTER:
|
||||
shell.printfln(F(" %s: %s%d%s (Type: %s)"),
|
||||
shell.printfln((" %s: %s%d%s (Type: %s)"),
|
||||
sensor.name().c_str(),
|
||||
COLOR_BRIGHT_GREEN,
|
||||
(uint16_t)sensor.value(), // as int
|
||||
@@ -540,7 +537,7 @@ void EMSESP::publish_device_values(uint8_t device_type) {
|
||||
}
|
||||
if (need_publish) {
|
||||
if (doc.overflowed()) {
|
||||
LOG_WARNING(F("MQTT buffer overflow, please use individual topics"));
|
||||
LOG_WARNING("MQTT buffer overflow, please use individual topics");
|
||||
}
|
||||
Mqtt::publish(Mqtt::tag_to_topic(device_type, DeviceValueTAG::TAG_NONE), json);
|
||||
}
|
||||
@@ -625,9 +622,9 @@ bool EMSESP::get_device_value_info(JsonObject & root, const char * cmd, const in
|
||||
// search for recognized device_ids : Me, All, otherwise print hex value
|
||||
std::string EMSESP::device_tostring(const uint8_t device_id) {
|
||||
if ((device_id & 0x7F) == rxservice_.ems_bus_id()) {
|
||||
return read_flash_string(F("Me"));
|
||||
return "Me";
|
||||
} else if (device_id == 0x00) {
|
||||
return read_flash_string(F("All"));
|
||||
return "All";
|
||||
} else {
|
||||
char buffer[5];
|
||||
return Helpers::hextoa(buffer, device_id);
|
||||
@@ -672,14 +669,14 @@ std::string EMSESP::pretty_telegram(std::shared_ptr<const Telegram> telegram) {
|
||||
|
||||
// check for global/common types like Version & UBADevices
|
||||
if (telegram->type_id == EMSdevice::EMS_TYPE_VERSION) {
|
||||
type_name = read_flash_string(F("Version"));
|
||||
type_name = "Version";
|
||||
} else if (telegram->type_id == EMSdevice::EMS_TYPE_UBADevices) {
|
||||
type_name = read_flash_string(F("UBADevices"));
|
||||
type_name = "UBADevices";
|
||||
}
|
||||
|
||||
// if we don't know the type show
|
||||
if (type_name.empty()) {
|
||||
type_name = read_flash_string(F("?"));
|
||||
type_name = "?";
|
||||
}
|
||||
|
||||
std::string str;
|
||||
@@ -728,7 +725,7 @@ void EMSESP::process_UBADevices(std::shared_ptr<const Telegram> telegram) {
|
||||
// if we haven't already detected this device, request it's version details, unless its us (EMS-ESP)
|
||||
// when the version info is received, it will automagically add the device
|
||||
if ((device_id != EMSbus::ems_bus_id()) && !(EMSESP::device_exists(device_id))) {
|
||||
LOG_DEBUG(F("New EMS device detected with ID 0x%02X. Requesting version information."), device_id);
|
||||
LOG_DEBUG("New EMS device detected with ID 0x%02X. Requesting version information.", device_id);
|
||||
send_read_request(EMSdevice::EMS_TYPE_VERSION, device_id);
|
||||
}
|
||||
}
|
||||
@@ -788,7 +785,7 @@ void EMSESP::process_version(std::shared_ptr<const Telegram> telegram) {
|
||||
bool EMSESP::process_telegram(std::shared_ptr<const Telegram> telegram) {
|
||||
// if watching or reading...
|
||||
if ((telegram->type_id == read_id_) && (telegram->dest == txservice_.ems_bus_id())) {
|
||||
LOG_INFO(F("%s"), pretty_telegram(telegram).c_str());
|
||||
LOG_INFO("%s", pretty_telegram(telegram).c_str());
|
||||
if (Mqtt::send_response()) {
|
||||
publish_response(telegram);
|
||||
}
|
||||
@@ -800,18 +797,18 @@ bool EMSESP::process_telegram(std::shared_ptr<const Telegram> telegram) {
|
||||
} else if (watch() == WATCH_ON) {
|
||||
if ((watch_id_ == WATCH_ID_NONE) || (telegram->type_id == watch_id_)
|
||||
|| ((watch_id_ < 0x80) && ((telegram->src == watch_id_) || (telegram->dest == watch_id_)))) {
|
||||
LOG_NOTICE(F("%s"), pretty_telegram(telegram).c_str());
|
||||
LOG_NOTICE("%s", pretty_telegram(telegram).c_str());
|
||||
} else if (!trace_raw_) {
|
||||
LOG_TRACE(F("%s"), pretty_telegram(telegram).c_str());
|
||||
LOG_TRACE("%s", pretty_telegram(telegram).c_str());
|
||||
}
|
||||
} else if (!trace_raw_) {
|
||||
LOG_TRACE(F("%s"), pretty_telegram(telegram).c_str());
|
||||
LOG_TRACE("%s", pretty_telegram(telegram).c_str());
|
||||
}
|
||||
|
||||
// only process broadcast telegrams or ones sent to us on request
|
||||
// if ((telegram->dest != 0x00) && (telegram->dest != rxservice_.ems_bus_id())) {
|
||||
if (telegram->operation == Telegram::Operation::RX_READ) {
|
||||
// LOG_DEBUG(F("read telegram received, not processing"));
|
||||
// LOG_DEBUG("read telegram received, not processing");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -861,9 +858,9 @@ bool EMSESP::process_telegram(std::shared_ptr<const Telegram> telegram) {
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
LOG_DEBUG(F("No telegram type handler found for ID 0x%02X (src 0x%02X)"), telegram->type_id, telegram->src);
|
||||
LOG_DEBUG(("No telegram type handler found for ID 0x%02X (src 0x%02X)"), telegram->type_id, telegram->src);
|
||||
if (watch() == WATCH_UNKNOWN) {
|
||||
LOG_NOTICE(F("%s"), pretty_telegram(telegram).c_str());
|
||||
LOG_NOTICE("%s", pretty_telegram(telegram).c_str());
|
||||
}
|
||||
if (!wait_km_ && !knowndevice && (telegram->src != EMSbus::ems_bus_id()) && (telegram->message_length > 0)) {
|
||||
send_read_request(EMSdevice::EMS_TYPE_VERSION, telegram->src);
|
||||
@@ -887,12 +884,12 @@ bool EMSESP::device_exists(const uint8_t device_id) {
|
||||
// for each associated EMS device go and get its system information
|
||||
void EMSESP::show_devices(uuid::console::Shell & shell) {
|
||||
if (emsdevices.empty()) {
|
||||
shell.printfln(F("No EMS devices detected. Try using 'scan devices' from the ems menu."));
|
||||
shell.printfln("No EMS devices detected. Try using 'scan devices' from the ems menu.");
|
||||
shell.println();
|
||||
return;
|
||||
}
|
||||
|
||||
shell.printfln(F("These EMS devices are currently active:"));
|
||||
shell.printfln("These EMS devices are currently active:");
|
||||
shell.println();
|
||||
|
||||
// count the number of thermostats
|
||||
@@ -908,7 +905,7 @@ void EMSESP::show_devices(uuid::console::Shell & shell) {
|
||||
for (const auto & device_class : EMSFactory::device_handlers()) {
|
||||
for (const auto & emsdevice : emsdevices) {
|
||||
if (emsdevice && (emsdevice->device_type() == device_class.first)) {
|
||||
shell.printf(F("%s: %s"), emsdevice->device_type_name().c_str(), emsdevice->to_string().c_str());
|
||||
shell.printf("%s: %s", emsdevice->device_type_name().c_str(), emsdevice->to_string().c_str());
|
||||
shell.println();
|
||||
emsdevice->show_telegram_handlers(shell);
|
||||
|
||||
@@ -935,7 +932,7 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const
|
||||
if (product_id == 0) { // update only with valid product_id
|
||||
return true;
|
||||
}
|
||||
LOG_DEBUG(F("Updating details for already active deviceID 0x%02X"), device_id);
|
||||
LOG_DEBUG("Updating details for already active deviceID 0x%02X", device_id);
|
||||
emsdevice->product_id(product_id);
|
||||
emsdevice->version(version);
|
||||
// only set brand if it doesn't already exist
|
||||
@@ -945,7 +942,7 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const
|
||||
// find the name and flags in our database
|
||||
for (const auto & device : device_library_) {
|
||||
if (device.product_id == product_id && device.device_type == emsdevice->device_type()) {
|
||||
emsdevice->name(std::move(read_flash_string(device.name)));
|
||||
emsdevice->name(device.name);
|
||||
emsdevice->add_flags(device.flags);
|
||||
}
|
||||
}
|
||||
@@ -976,14 +973,13 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const
|
||||
|
||||
// if we don't recognize the productID report it and add as a generic device
|
||||
if (device_p == nullptr) {
|
||||
LOG_NOTICE(F("Unrecognized EMS device (deviceID 0x%02X, productID %d). Please report on GitHub."), device_id, product_id);
|
||||
std::string name("unknown");
|
||||
LOG_NOTICE(("Unrecognized EMS device (deviceID 0x%02X, productID %d). Please report on GitHub."), device_id, product_id);
|
||||
emsdevices.push_back(
|
||||
EMSFactory::add(DeviceType::GENERIC, device_id, product_id, version, name, DeviceFlags::EMS_DEVICE_FLAG_NONE, EMSdevice::Brand::NO_BRAND));
|
||||
EMSFactory::add(DeviceType::GENERIC, device_id, product_id, version, "unknown", DeviceFlags::EMS_DEVICE_FLAG_NONE, EMSdevice::Brand::NO_BRAND));
|
||||
return false; // not found
|
||||
}
|
||||
|
||||
auto name = read_flash_string(device_p->name);
|
||||
auto name = device_p->name;
|
||||
auto device_type = device_p->device_type;
|
||||
auto flags = device_p->flags;
|
||||
|
||||
@@ -1022,14 +1018,14 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const
|
||||
name = "generic boiler";
|
||||
device_type = DeviceType::BOILER;
|
||||
flags = DeviceFlags::EMS_DEVICE_FLAG_HEATPUMP;
|
||||
LOG_WARNING(F("Unknown EMS boiler. Using generic profile. Please report on GitHub."));
|
||||
LOG_WARNING("Unknown EMS boiler. Using generic profile. Please report on GitHub.");
|
||||
} else {
|
||||
LOG_WARNING(F("Unrecognized EMS device (device ID 0x%02X, no product ID). Please report on GitHub."), device_id);
|
||||
LOG_WARNING(("Unrecognized EMS device (device ID 0x%02X, no product ID). Please report on GitHub."), device_id);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_DEBUG(F("Adding new device %s (deviceID 0x%02X, productID %d, version %s)"), name.c_str(), device_id, product_id, version);
|
||||
LOG_DEBUG(("Adding new device %s (deviceID 0x%02X, productID %d, version %s)"), name, device_id, product_id, version);
|
||||
emsdevices.push_back(EMSFactory::add(device_type, device_id, product_id, version, name, flags, brand));
|
||||
|
||||
// assign a unique ID. Note that this is not actual unique after a restart as it's dependent on the order that devices are found
|
||||
@@ -1043,7 +1039,7 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const
|
||||
fetch_device_values(device_id); // go and fetch its data
|
||||
|
||||
// Print to LOG showing we've added a new device
|
||||
LOG_INFO(F("Recognized new %s with deviceID 0x%02X"), EMSdevice::device_type_2_device_name(device_type).c_str(), device_id);
|
||||
LOG_INFO("Recognized new %s with deviceID 0x%02X", EMSdevice::device_type_2_device_name(device_type).c_str(), device_id);
|
||||
|
||||
// add command commands for all devices, except for connect, controller and gateway
|
||||
if ((device_type == DeviceType::CONNECT) || (device_type == DeviceType::CONTROLLER) || (device_type == DeviceType::GATEWAY)) {
|
||||
@@ -1059,7 +1055,7 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const
|
||||
F_(info_cmd));
|
||||
Command::add(
|
||||
device_type,
|
||||
F("values"),
|
||||
("values"),
|
||||
[device_type](const char * value, const int8_t id, JsonObject & output) {
|
||||
return command_info(device_type, output, id, EMSdevice::OUTPUT_TARGET::API_SHORTNAMES); // HIDDEN command showing short names, used in e.g. /api/boiler
|
||||
},
|
||||
@@ -1178,7 +1174,7 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) {
|
||||
Roomctrl::check((data[1] ^ 0x80 ^ rxservice_.ems_mask()), data);
|
||||
#ifdef EMSESP_UART_DEBUG
|
||||
// get_uptime is only updated once per loop, does not give the right time
|
||||
LOG_TRACE(F("[UART_DEBUG] Echo after %d ms: %s"), ::millis() - rx_time_, Helpers::data_to_hex(data, length).c_str());
|
||||
LOG_TRACE("[UART_DEBUG] Echo after %d ms: %s", ::millis() - rx_time_, Helpers::data_to_hex(data, length).c_str());
|
||||
#endif
|
||||
// add to RxQueue for log/watch
|
||||
rxservice_.add(data, length);
|
||||
@@ -1194,14 +1190,14 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) {
|
||||
// if we're waiting on a Write operation, we want a single byte 1 or 4
|
||||
if ((tx_state == Telegram::Operation::TX_WRITE) && (length == 1)) {
|
||||
if (first_value == TxService::TX_WRITE_SUCCESS) {
|
||||
LOG_DEBUG(F("Last Tx write successful"));
|
||||
LOG_DEBUG("Last Tx write successful");
|
||||
txservice_.increment_telegram_write_count(); // last tx/write was confirmed ok
|
||||
txservice_.send_poll(); // close the bus
|
||||
publish_id_ = txservice_.post_send_query(); // follow up with any post-read if set
|
||||
txservice_.reset_retry_count();
|
||||
tx_successful = true;
|
||||
} else if (first_value == TxService::TX_WRITE_FAIL) {
|
||||
LOG_ERROR(F("Last Tx write rejected by host"));
|
||||
LOG_ERROR("Last Tx write rejected by host");
|
||||
txservice_.send_poll(); // close the bus
|
||||
txservice_.reset_retry_count();
|
||||
}
|
||||
@@ -1210,7 +1206,7 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) {
|
||||
uint8_t src = data[0];
|
||||
uint8_t dest = data[1];
|
||||
if (txservice_.is_last_tx(src, dest)) {
|
||||
LOG_DEBUG(F("Last Tx read successful"));
|
||||
LOG_DEBUG("Last Tx read successful");
|
||||
txservice_.increment_telegram_read_count();
|
||||
txservice_.send_poll(); // close the bus
|
||||
txservice_.reset_retry_count();
|
||||
@@ -1252,11 +1248,11 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) {
|
||||
#ifdef EMSESP_UART_DEBUG
|
||||
char s[4];
|
||||
if (first_value & 0x80) {
|
||||
LOG_TRACE(F("[UART_DEBUG] next Poll %s after %d ms"), Helpers::hextoa(s, first_value), ::millis() - rx_time_);
|
||||
LOG_TRACE("[UART_DEBUG] next Poll %s after %d ms", Helpers::hextoa(s, first_value), ::millis() - rx_time_);
|
||||
// time measurement starts here, use millis because get_uptime is only updated once per loop
|
||||
rx_time_ = ::millis();
|
||||
} else {
|
||||
LOG_TRACE(F("[UART_DEBUG] Poll ack %s after %d ms"), Helpers::hextoa(s, first_value), ::millis() - rx_time_);
|
||||
LOG_TRACE("[UART_DEBUG] Poll ack %s after %d ms", Helpers::hextoa(s, first_value), ::millis() - rx_time_);
|
||||
}
|
||||
#endif
|
||||
// check for poll to us, if so send top message from Tx queue immediately and quit
|
||||
@@ -1268,7 +1264,7 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) {
|
||||
return;
|
||||
} else {
|
||||
#ifdef EMSESP_UART_DEBUG
|
||||
LOG_TRACE(F("[UART_DEBUG] Reply after %d ms: %s"), ::millis() - rx_time_, Helpers::data_to_hex(data, length).c_str());
|
||||
LOG_TRACE("[UART_DEBUG] Reply after %d ms: %s", ::millis() - rx_time_, Helpers::data_to_hex(data, length).c_str());
|
||||
#endif
|
||||
Roomctrl::check((data[1] ^ 0x80 ^ rxservice_.ems_mask()), data); // check if there is a message for the roomcontroller
|
||||
|
||||
@@ -1293,14 +1289,14 @@ void EMSESP::start() {
|
||||
webLogService.begin(); // start web log service. now we can start capturing logs to the web log
|
||||
|
||||
#ifdef EMSESP_DEBUG
|
||||
LOG_NOTICE(F("System is running in Debug mode"));
|
||||
LOG_NOTICE("System is running in Debug mode");
|
||||
#endif
|
||||
|
||||
LOG_INFO(F("Last system reset reason Core0: %s, Core1: %s"), system_.reset_reason(0).c_str(), system_.reset_reason(1).c_str());
|
||||
LOG_INFO("Last system reset reason Core0: %s, Core1: %s", system_.reset_reason(0).c_str(), system_.reset_reason(1).c_str());
|
||||
|
||||
// do any system upgrades
|
||||
if (system_.check_upgrade()) {
|
||||
LOG_INFO(F("System needs a restart to apply new settings. Please wait."));
|
||||
LOG_INFO("System needs a restart to apply new settings. Please wait.");
|
||||
system_.system_restart();
|
||||
};
|
||||
|
||||
@@ -1316,7 +1312,7 @@ void EMSESP::start() {
|
||||
// start all the EMS-ESP services
|
||||
mqtt_.start(); // mqtt init
|
||||
system_.start(); // starts commands, led, adc, button, network, syslog & uart
|
||||
LOG_INFO(F("Starting EMS-ESP version %s (hostname: %s)"), EMSESP_APP_VERSION, system_.hostname().c_str()); // welcome message
|
||||
LOG_INFO(("Starting EMS-ESP version %s (hostname: %s)"), EMSESP_APP_VERSION, system_.hostname().c_str()); // welcome message
|
||||
|
||||
shower_.start(); // initialize shower timer and shower alert
|
||||
dallassensor_.start(); // Dallas external sensors
|
||||
@@ -1327,7 +1323,7 @@ void EMSESP::start() {
|
||||
device_library_ = {
|
||||
#include "device_library.h"
|
||||
};
|
||||
LOG_INFO(F("Loaded EMS device library (%d records)"), device_library_.size());
|
||||
LOG_INFO(("Loaded EMS device library (%d records)"), device_library_.size());
|
||||
|
||||
#if defined(EMSESP_STANDALONE)
|
||||
Mqtt::on_connect(); // simulate an MQTT connection
|
||||
@@ -1344,6 +1340,7 @@ void EMSESP::scheduled_fetch_values() {
|
||||
last_fetch_ = uuid::get_uptime();
|
||||
no = 1;
|
||||
}
|
||||
|
||||
if (txservice_.tx_queue_empty()) {
|
||||
uint8_t i = 0;
|
||||
for (const auto & emsdevice : emsdevices) {
|
||||
|
||||
@@ -251,10 +251,10 @@ class EMSESP {
|
||||
static constexpr uint8_t EMS_WAIT_KM_TIMEOUT = 60; // wait one minute
|
||||
|
||||
struct Device_record {
|
||||
uint8_t product_id;
|
||||
EMSdevice::DeviceType device_type;
|
||||
const __FlashStringHelper * name;
|
||||
uint8_t flags;
|
||||
uint8_t product_id;
|
||||
EMSdevice::DeviceType device_type;
|
||||
const char * name;
|
||||
uint8_t flags;
|
||||
};
|
||||
static std::vector<Device_record> device_library_;
|
||||
|
||||
|
||||
@@ -55,12 +55,12 @@ class EMSFactory {
|
||||
}
|
||||
|
||||
// Construct derived class returning an unique ptr
|
||||
static auto add(const uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, std::string & name, uint8_t flags, uint8_t brand)
|
||||
static auto add(const uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand)
|
||||
-> std::unique_ptr<EMSdevice> {
|
||||
return std::unique_ptr<EMSdevice>(EMSFactory::makeRaw(device_type, device_id, product_id, version, name, flags, brand));
|
||||
}
|
||||
|
||||
virtual auto construct(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, std::string & name, uint8_t flags, uint8_t brand) const
|
||||
virtual auto construct(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand) const
|
||||
-> EMSdevice * = 0;
|
||||
|
||||
private:
|
||||
@@ -72,7 +72,7 @@ class EMSFactory {
|
||||
|
||||
// Construct derived class returning a raw pointer
|
||||
// find which EMS device it is and use that class
|
||||
static auto makeRaw(const uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, std::string & name, uint8_t flags, uint8_t brand)
|
||||
static auto makeRaw(const uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand)
|
||||
-> EMSdevice * {
|
||||
auto it = EMSFactory::getRegister().find(device_type);
|
||||
if (it != EMSFactory::getRegister().end()) {
|
||||
@@ -90,7 +90,7 @@ class ConcreteEMSFactory : EMSFactory {
|
||||
EMSFactory::registerFactory(device_type, this);
|
||||
}
|
||||
|
||||
auto construct(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, std::string & name, uint8_t flags, uint8_t brand) const
|
||||
auto construct(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand) const
|
||||
-> EMSdevice * {
|
||||
return new DerivedClass(device_type, device_id, product_id, version, name, flags, brand);
|
||||
}
|
||||
|
||||
@@ -608,7 +608,7 @@ bool Helpers::value2bool(const char * value, bool & value_b) {
|
||||
|
||||
// checks to see if a string is member of a vector and return the index, also allow true/false for on/off
|
||||
// this for a list of lists, when using translated strings
|
||||
bool Helpers::value2enum(const char * value, uint8_t & value_ui, const __FlashStringHelper * const ** strs) {
|
||||
bool Helpers::value2enum(const char * value, uint8_t & value_ui, const char * const ** strs) {
|
||||
if ((value == nullptr) || (strlen(value) == 0)) {
|
||||
return false;
|
||||
}
|
||||
@@ -616,7 +616,7 @@ bool Helpers::value2enum(const char * value, uint8_t & value_ui, const __FlashSt
|
||||
|
||||
for (value_ui = 0; strs[value_ui]; value_ui++) {
|
||||
std::string str1 = toLower(Helpers::translated_word(strs[value_ui]));
|
||||
std::string str2 = toLower(read_flash_string(strs[value_ui][0])); // also check for default language
|
||||
std::string str2 = toLower((strs[value_ui][0])); // also check for default language
|
||||
if ((str1 != "")
|
||||
&& ((str2 == "off" && str == "false") || (str2 == "on" && str == "true") || (str == str1) || (str == str2)
|
||||
|| (value[0] == ('0' + value_ui) && value[1] == '\0'))) {
|
||||
@@ -628,14 +628,14 @@ bool Helpers::value2enum(const char * value, uint8_t & value_ui, const __FlashSt
|
||||
}
|
||||
|
||||
// checks to see if a string is member of a vector and return the index, also allow true/false for on/off
|
||||
bool Helpers::value2enum(const char * value, uint8_t & value_ui, const __FlashStringHelper * const * strs) {
|
||||
bool Helpers::value2enum(const char * value, uint8_t & value_ui, const char * const * strs) {
|
||||
if ((value == nullptr) || (strlen(value) == 0)) {
|
||||
return false;
|
||||
}
|
||||
std::string str = toLower(value);
|
||||
|
||||
for (value_ui = 0; strs[value_ui]; value_ui++) {
|
||||
std::string enum_str = toLower(read_flash_string(strs[value_ui]));
|
||||
std::string enum_str = toLower((strs[value_ui]));
|
||||
|
||||
if ((enum_str != "")
|
||||
&& ((enum_str == "off" && (str == Helpers::translated_word(FL_(off)) || str == "false"))
|
||||
@@ -655,6 +655,10 @@ std::string Helpers::toLower(std::string const & s) {
|
||||
return lc;
|
||||
}
|
||||
|
||||
std::string Helpers::toLower(const char * s) {
|
||||
return toLower(std::string(s));
|
||||
}
|
||||
|
||||
std::string Helpers::toUpper(std::string const & s) {
|
||||
std::string lc = s;
|
||||
std::transform(lc.begin(), lc.end(), lc.begin(), [](unsigned char c) { return std::toupper(c); });
|
||||
@@ -676,7 +680,7 @@ void Helpers::replace_char(char * str, char find, char replace) {
|
||||
|
||||
// count number of items in a list
|
||||
// the end of a list has a nullptr
|
||||
uint8_t Helpers::count_items(const __FlashStringHelper * const * list) {
|
||||
uint8_t Helpers::count_items(const char * const * list) {
|
||||
uint8_t list_size = 0;
|
||||
if (list != nullptr) {
|
||||
while (list[list_size]) {
|
||||
@@ -688,7 +692,7 @@ uint8_t Helpers::count_items(const __FlashStringHelper * const * list) {
|
||||
|
||||
// count number of items in a list of lists
|
||||
// the end of a list has a nullptr
|
||||
uint8_t Helpers::count_items(const __FlashStringHelper * const ** list) {
|
||||
uint8_t Helpers::count_items(const char * const ** list) {
|
||||
uint8_t list_size = 0;
|
||||
if (list != nullptr) {
|
||||
while (list[list_size]) {
|
||||
@@ -699,29 +703,20 @@ uint8_t Helpers::count_items(const __FlashStringHelper * const ** list) {
|
||||
}
|
||||
|
||||
// return translated string as a std::string, optionally converting to lowercase (for console commands)
|
||||
// takes a FL(...)
|
||||
std::string Helpers::translated_word(const __FlashStringHelper * const * strings, bool to_lower) {
|
||||
std::string Helpers::translated_word(const char * const * strings, bool to_lower) {
|
||||
uint8_t language_index = EMSESP::system_.language_index();
|
||||
uint8_t index = 0;
|
||||
|
||||
// see how many translations we have for this entity. if there is no translation for this, revert to EN
|
||||
if (Helpers::count_items(strings) >= language_index + 1 && !read_flash_string(strings[language_index]).empty()) {
|
||||
index = language_index;
|
||||
// check for empty
|
||||
if (!strings) {
|
||||
return ""; // it's a nullptr with no translations, return empty to prevent unwanted crash
|
||||
}
|
||||
return to_lower ? toLower(read_flash_string(strings[index])) : read_flash_string(strings[index]);
|
||||
}
|
||||
|
||||
// return translated string
|
||||
// takes a F(...)
|
||||
const __FlashStringHelper * Helpers::translated_fword(const __FlashStringHelper * const * strings) {
|
||||
uint8_t language_index = EMSESP::system_.language_index();
|
||||
uint8_t index = 0;
|
||||
|
||||
// see how many translations we have for this entity. if there is no translation for this, revert to EN
|
||||
if (Helpers::count_items(strings) >= language_index + 1 && !read_flash_string(strings[language_index]).empty()) {
|
||||
if (Helpers::count_items(strings) >= language_index + 1 && strlen(strings[language_index])) {
|
||||
index = language_index;
|
||||
}
|
||||
return strings[index];
|
||||
return to_lower ? toLower((strings[index])) : (strings[index]);
|
||||
}
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
@@ -54,7 +54,9 @@ class Helpers {
|
||||
|
||||
static std::string toLower(std::string const & s);
|
||||
static std::string toUpper(std::string const & s);
|
||||
static void replace_char(char * str, char find, char replace);
|
||||
static std::string toLower(const char * s);
|
||||
|
||||
static void replace_char(char * str, char find, char replace);
|
||||
|
||||
static bool hasValue(const uint8_t & value, const uint8_t isBool = 0);
|
||||
static bool hasValue(const int8_t & value);
|
||||
@@ -67,16 +69,15 @@ class Helpers {
|
||||
static bool value2float(const char * value, float & value_f);
|
||||
static bool value2bool(const char * value, bool & value_b);
|
||||
static bool value2string(const char * value, std::string & value_s);
|
||||
static bool value2enum(const char * value, uint8_t & value_ui, const __FlashStringHelper * const ** strs);
|
||||
static bool value2enum(const char * value, uint8_t & value_ui, const __FlashStringHelper * const * strs);
|
||||
static bool value2enum(const char * value, uint8_t & value_ui, const char * const ** strs);
|
||||
static bool value2enum(const char * value, uint8_t & value_ui, const char * const * strs);
|
||||
static bool value2temperature(const char * value, float & value_f, bool relative = false);
|
||||
static bool value2temperature(const char * value, int & value_i, const bool relative = false, const int min = -2147483648, const int max = 2147483647);
|
||||
|
||||
static uint8_t count_items(const __FlashStringHelper * const ** list);
|
||||
static uint8_t count_items(const __FlashStringHelper * const * list);
|
||||
static uint8_t count_items(const char * const ** list);
|
||||
static uint8_t count_items(const char * const * list);
|
||||
|
||||
static std::string translated_word(const __FlashStringHelper * const * strings, bool to_lower = false);
|
||||
static const __FlashStringHelper * translated_fword(const __FlashStringHelper * const * strings);
|
||||
static std::string translated_word(const char * const * strings, bool to_lower = false);
|
||||
|
||||
#ifdef EMSESP_STANDALONE
|
||||
static char * ultostr(char * ptr, uint32_t value, const uint8_t base);
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
|
||||
// clang-format off
|
||||
|
||||
/*
|
||||
* THIS FILE CONTAINS STANDARD STRING LITERALS THAT DON'T NEED LANGUAGE TRANSLATIONS
|
||||
*/
|
||||
@@ -144,55 +146,55 @@ MAKE_PSTR(password_prompt, "Password: ")
|
||||
MAKE_PSTR(unset, "<unset>")
|
||||
|
||||
// more common names that don't need translations
|
||||
MAKE_PSTR_LIST(1x3min, F("1x3min"))
|
||||
MAKE_PSTR_LIST(2x3min, F("2x3min"))
|
||||
MAKE_PSTR_LIST(3x3min, F("3x3min"))
|
||||
MAKE_PSTR_LIST(4x3min, F("4x3min"))
|
||||
MAKE_PSTR_LIST(5x3min, F("5x3min"))
|
||||
MAKE_PSTR_LIST(6x3min, F("6x3min"))
|
||||
MAKE_PSTR_LIST(auto, F("auto"))
|
||||
MAKE_PSTR_LIST(na, F("n/a"))
|
||||
MAKE_PSTR_LIST(rc3x, F("rc3x"))
|
||||
MAKE_PSTR_LIST(rc20, F("rc20"))
|
||||
MAKE_PSTR_LIST(fb10, F("fb10"))
|
||||
MAKE_PSTR_LIST(fb100, F("fb100"))
|
||||
MAKE_PSTR_LIST(dash, F("-"))
|
||||
MAKE_PSTR_LIST(error, F("error"))
|
||||
MAKE_PSTR_LIST(BLANK, F(""))
|
||||
MAKE_PSTR_LIST(pwm, F("pwm"))
|
||||
MAKE_PSTR_LIST(pwm_invers, F("pwm inverse"))
|
||||
MAKE_PSTR_LIST(mpc, F("mpc"))
|
||||
MAKE_PSTR_LIST(tempauto, F("temp auto"))
|
||||
MAKE_PSTR_LIST(bypass, F("bypass"))
|
||||
MAKE_PSTR_LIST(mixer, F("mixer"))
|
||||
MAKE_PSTR_LIST(monovalent, F("monovalent"))
|
||||
MAKE_PSTR_LIST(bivalent, F("bivalent"))
|
||||
MAKE_PSTR_LIST(n_o, F("n_o"))
|
||||
MAKE_PSTR_LIST(n_c, F("n_c"))
|
||||
MAKE_PSTR_LIST(prog1, F("prog 1"))
|
||||
MAKE_PSTR_LIST(prog2, F("prog 2"))
|
||||
MAKE_PSTR_LIST(proga, F("prog a"))
|
||||
MAKE_PSTR_LIST(progb, F("prog b"))
|
||||
MAKE_PSTR_LIST(progc, F("prog c"))
|
||||
MAKE_PSTR_LIST(progd, F("prog d"))
|
||||
MAKE_PSTR_LIST(proge, F("prog e"))
|
||||
MAKE_PSTR_LIST(progf, F("prog f"))
|
||||
MAKE_PSTR_LIST(rc35, F("RC35"))
|
||||
MAKE_PSTR_LIST(0kW, F("0 kW"))
|
||||
MAKE_PSTR_LIST(2kW, F("2 kW"))
|
||||
MAKE_PSTR_LIST(3kW, F("3 kW"))
|
||||
MAKE_PSTR_LIST(4kW, F("4 kW"))
|
||||
MAKE_PSTR_LIST(6kW, F("6 kW"))
|
||||
MAKE_PSTR_LIST(9kW, F("9 kW"))
|
||||
MAKE_PSTR_LIST(1x3min, "1x3min")
|
||||
MAKE_PSTR_LIST(2x3min, "2x3min")
|
||||
MAKE_PSTR_LIST(3x3min, "3x3min")
|
||||
MAKE_PSTR_LIST(4x3min, "4x3min")
|
||||
MAKE_PSTR_LIST(5x3min, "5x3min")
|
||||
MAKE_PSTR_LIST(6x3min, "6x3min")
|
||||
MAKE_PSTR_LIST(auto, "auto")
|
||||
MAKE_PSTR_LIST(na, "n/a")
|
||||
MAKE_PSTR_LIST(rc3x, "rc3x")
|
||||
MAKE_PSTR_LIST(rc20, "rc20")
|
||||
MAKE_PSTR_LIST(fb10, "fb10")
|
||||
MAKE_PSTR_LIST(fb100, "fb100")
|
||||
MAKE_PSTR_LIST(dash, "-")
|
||||
MAKE_PSTR_LIST(error, "error")
|
||||
MAKE_PSTR_LIST(BLANK, "")
|
||||
MAKE_PSTR_LIST(pwm, "pwm")
|
||||
MAKE_PSTR_LIST(pwm_invers, "pwm inverse")
|
||||
MAKE_PSTR_LIST(mpc, "mpc")
|
||||
MAKE_PSTR_LIST(tempauto, "temp auto")
|
||||
MAKE_PSTR_LIST(bypass, "bypass")
|
||||
MAKE_PSTR_LIST(mixer, "mixer")
|
||||
MAKE_PSTR_LIST(monovalent, "monovalent")
|
||||
MAKE_PSTR_LIST(bivalent, "bivalent")
|
||||
MAKE_PSTR_LIST(n_o, "n_o")
|
||||
MAKE_PSTR_LIST(n_c, "n_c")
|
||||
MAKE_PSTR_LIST(prog1, "prog 1")
|
||||
MAKE_PSTR_LIST(prog2, "prog 2")
|
||||
MAKE_PSTR_LIST(proga, "prog a")
|
||||
MAKE_PSTR_LIST(progb, "prog b")
|
||||
MAKE_PSTR_LIST(progc, "prog c")
|
||||
MAKE_PSTR_LIST(progd, "prog d")
|
||||
MAKE_PSTR_LIST(proge, "prog e")
|
||||
MAKE_PSTR_LIST(progf, "prog f")
|
||||
MAKE_PSTR_LIST(rc35, "RC35")
|
||||
MAKE_PSTR_LIST(0kW, "0 kW")
|
||||
MAKE_PSTR_LIST(2kW, "2 kW")
|
||||
MAKE_PSTR_LIST(3kW, "3 kW")
|
||||
MAKE_PSTR_LIST(4kW, "4 kW")
|
||||
MAKE_PSTR_LIST(6kW, "6 kW")
|
||||
MAKE_PSTR_LIST(9kW, "9 kW")
|
||||
|
||||
// templates - this are not translated and will be saved under optons_single
|
||||
MAKE_PSTR_LIST(tpl_datetime, F("Format: < NTP | dd.mm.yyyy-hh:mm:ss-day(0-6)-dst(0/1) >"))
|
||||
MAKE_PSTR_LIST(tpl_switchtime, F("Format: <nn> [ not_set | day hh:mm on|off ]"))
|
||||
MAKE_PSTR_LIST(tpl_switchtime1, F("Format: <nn> [ not_set | day hh:mm Tn ]"))
|
||||
MAKE_PSTR_LIST(tpl_holidays, F("Format: < dd.mm.yyyy-dd.mm.yyyy >"))
|
||||
MAKE_PSTR_LIST(tpl_date, F("Format: < dd.mm.yyyy >"))
|
||||
MAKE_PSTR_LIST(tpl_input, F("Format: <inv>[<evu1><evu2><evu3><comp><aux><cool><heat><dhw><pv>]"))
|
||||
MAKE_PSTR_LIST(tpl_input4, F("Format: <inv>[<comp><aux><cool><heat><dhw><pv>]"))
|
||||
// templates - this are not translated and will be saved under options_single
|
||||
MAKE_PSTR_LIST(tpl_datetime, "Format: < NTP | dd.mm.yyyy-hh:mm:ss-day(0-6)-dst(0/1) >")
|
||||
MAKE_PSTR_LIST(tpl_switchtime, "Format: <nn> [ not_set | day hh:mm on|off ]")
|
||||
MAKE_PSTR_LIST(tpl_switchtime1, "Format: <nn> [ not_set | day hh:mm Tn ]")
|
||||
MAKE_PSTR_LIST(tpl_holidays, "Format: < dd.mm.yyyy-dd.mm.yyyy >")
|
||||
MAKE_PSTR_LIST(tpl_date, "Format: < dd.mm.yyyy >")
|
||||
MAKE_PSTR_LIST(tpl_input, "Format: <inv>[<evu1><evu2><evu3><comp><aux><cool><heat><dhw><pv>]")
|
||||
MAKE_PSTR_LIST(tpl_input4, "Format: <inv>[<comp><aux><cool><heat><dhw><pv>]")
|
||||
|
||||
// Unit Of Measurement mapping - maps to DeviceValueUOM_s in emsdevice.cpp
|
||||
// These don't need translating, it will mess up HA and the API
|
||||
@@ -273,16 +275,17 @@ MAKE_PSTR(response, "response")
|
||||
MAKE_PSTR(tag_boiler_data_ww_mqtt, "ww")
|
||||
MAKE_PSTR(tag_device_data_ww_mqtt, "")
|
||||
|
||||
MAKE_PSTR_LIST(climate, F("HA climate config creation"), F("")) // empty fullname
|
||||
// Home Assistant - this is special and has no translations
|
||||
MAKE_PSTR_LIST(climate, "HA climate config creation")
|
||||
|
||||
// syslog
|
||||
MAKE_PSTR_LIST(list_syslog_level, F("off"), F("emerg"), F("alert"), F("crit"), F("error"), F("warn"), F("notice"), F("info"), F("debug"), F("trace"), F("all"))
|
||||
MAKE_PSTR_LIST(list_syslog_level, "off", "emerg", "alert", "crit", "error", "warn", "notice", "info", "debug", "trace", "all")
|
||||
|
||||
// sensors
|
||||
MAKE_PSTR_LIST(list_sensortype, F("none"), F("digital in"), F("counter"), F("adc"), F("timer"), F("rate"), F("digital out"), F("pwm 0"), F("pwm 1"), F("pwm 2"))
|
||||
MAKE_PSTR_LIST(list_sensortype, "none", "digital in", "counter", "adc", "timer", "rate", "digital out", "pwm 0", "pwm 1", "pwm 2")
|
||||
|
||||
// watch
|
||||
MAKE_PSTR_LIST(list_watch, F("off"), F("on"), F("raw"), F("unknown"))
|
||||
MAKE_PSTR_LIST(list_watch, "off", "on", "raw", "unknown")
|
||||
|
||||
/*
|
||||
* The rest below are Enums and generated from translations lists
|
||||
@@ -302,16 +305,7 @@ MAKE_PSTR_ENUM(enum_reset, FL_(dash), FL_(maintenance), FL_(error))
|
||||
MAKE_PSTR_ENUM(enum_maxHeat, FL_(0kW), FL_(2kW), FL_(3kW), FL_(4kW), FL_(6kW), FL_(9kW))
|
||||
|
||||
// thermostat lists
|
||||
MAKE_PSTR_ENUM(enum_ibaMainDisplay,
|
||||
FL_(internal_temperature),
|
||||
FL_(internal_setpoint),
|
||||
FL_(external_temperature),
|
||||
FL_(burner_temperature),
|
||||
FL_(ww_temperature),
|
||||
FL_(functioning_mode),
|
||||
FL_(time),
|
||||
FL_(date),
|
||||
FL_(smoke_temperature))
|
||||
MAKE_PSTR_ENUM(enum_ibaMainDisplay, FL_(internal_temperature), FL_(internal_setpoint), FL_(external_temperature), FL_(burner_temperature), FL_(ww_temperature), FL_(functioning_mode), FL_(time), FL_(date), FL_(smoke_temperature))
|
||||
MAKE_PSTR_ENUM(enum_ibaLanguage, FL_(german), FL_(dutch), FL_(french), FL_(italian))
|
||||
MAKE_PSTR_ENUM(enum_ibaLanguage_RC30, FL_(german), FL_(dutch))
|
||||
MAKE_PSTR_ENUM(enum_floordrystatus, FL_(off), FL_(start), FL_(heat), FL_(hold), FL_(cool), FL_(end))
|
||||
@@ -379,3 +373,5 @@ MAKE_PSTR_ENUM(enum_bufConfig, FL_(monovalent), FL_(bivalent))
|
||||
MAKE_PSTR_ENUM(enum_blockTerm, FL_(n_o), FL_(n_c))
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// clang-format on
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
247
src/mqtt.cpp
247
src/mqtt.cpp
@@ -186,26 +186,26 @@ void Mqtt::loop() {
|
||||
|
||||
// print MQTT log and other stuff to console
|
||||
void Mqtt::show_mqtt(uuid::console::Shell & shell) {
|
||||
shell.printfln(F("MQTT is %s"), connected() ? read_flash_string(F_(connected)).c_str() : read_flash_string(F_(disconnected)).c_str());
|
||||
shell.printfln("MQTT is %s", connected() ? F_(connected) : F_(disconnected));
|
||||
|
||||
shell.printfln(F("MQTT publish errors: %lu"), mqtt_publish_fails_);
|
||||
shell.printfln("MQTT publish errors: %lu", mqtt_publish_fails_);
|
||||
shell.println();
|
||||
|
||||
// show subscriptions
|
||||
shell.printfln(F("MQTT topic subscriptions:"));
|
||||
shell.printfln("MQTT topic subscriptions:");
|
||||
for (const auto & mqtt_subfunction : mqtt_subfunctions_) {
|
||||
shell.printfln(F(" %s/%s"), mqtt_base_.c_str(), mqtt_subfunction.topic_.c_str());
|
||||
shell.printfln(" %s/%s", mqtt_base_.c_str(), mqtt_subfunction.topic_.c_str());
|
||||
}
|
||||
shell.println();
|
||||
|
||||
// show queues
|
||||
if (mqtt_messages_.empty()) {
|
||||
shell.printfln(F("MQTT queue is empty"));
|
||||
shell.printfln("MQTT queue is empty");
|
||||
shell.println();
|
||||
return;
|
||||
}
|
||||
|
||||
shell.printfln(F("MQTT queue (%d/%d messages):"), mqtt_messages_.size(), MAX_MQTT_MESSAGES);
|
||||
shell.printfln(("MQTT queue (%d/%d messages):"), mqtt_messages_.size(), MAX_MQTT_MESSAGES);
|
||||
|
||||
for (const auto & message : mqtt_messages_) {
|
||||
auto content = message.content_;
|
||||
@@ -222,12 +222,12 @@ void Mqtt::show_mqtt(uuid::console::Shell & shell) {
|
||||
// Publish messages
|
||||
if (message.retry_count_ == 0) {
|
||||
if (message.packet_id_ == 0) {
|
||||
shell.printfln(F(" [%02d] (Pub) topic=%s payload=%s"), message.id_, topic, content->payload.c_str());
|
||||
shell.printfln((" [%02d] (Pub) topic=%s payload=%s"), message.id_, topic, content->payload.c_str());
|
||||
} else {
|
||||
shell.printfln(F(" [%02d] (Pub) topic=%s payload=%s (pid %d)"), message.id_, topic, content->payload.c_str(), message.packet_id_);
|
||||
shell.printfln((" [%02d] (Pub) topic=%s payload=%s (pid %d)"), message.id_, topic, content->payload.c_str(), message.packet_id_);
|
||||
}
|
||||
} else {
|
||||
shell.printfln(F(" [%02d] (Pub) topic=%s payload=%s (pid %d, retry #%d)"),
|
||||
shell.printfln((" [%02d] (Pub) topic=%s payload=%s (pid %d, retry #%d)"),
|
||||
message.id_,
|
||||
topic,
|
||||
content->payload.c_str(),
|
||||
@@ -236,7 +236,7 @@ void Mqtt::show_mqtt(uuid::console::Shell & shell) {
|
||||
}
|
||||
} else {
|
||||
// Subscribe messages
|
||||
shell.printfln(F(" [%02d] (Sub) topic=%s"), message.id_, topic);
|
||||
shell.printfln((" [%02d] (Sub) topic=%s"), message.id_, topic);
|
||||
}
|
||||
}
|
||||
shell.println();
|
||||
@@ -264,16 +264,16 @@ void Mqtt::on_message(const char * topic, const char * payload, size_t len) cons
|
||||
|
||||
#if defined(EMSESP_DEBUG)
|
||||
if (len) {
|
||||
LOG_DEBUG(F("Received topic `%s` => payload `%s` (length %d)"), topic, message, len);
|
||||
LOG_DEBUG(("Received topic `%s` => payload `%s` (length %d)"), topic, message, len);
|
||||
} else {
|
||||
LOG_DEBUG(F("Received topic `%s`"), topic);
|
||||
LOG_DEBUG("Received topic `%s`", topic);
|
||||
}
|
||||
#endif
|
||||
// remove HA topics if we don't use discovery
|
||||
if (strncmp(topic, discovery_prefix().c_str(), discovery_prefix().size()) == 0) {
|
||||
if (!ha_enabled_ && len) { // don't ping pong the empty message
|
||||
queue_publish_message(topic, "", true);
|
||||
LOG_DEBUG(F("Remove topic %s"), topic);
|
||||
LOG_DEBUG("Remove topic %s", topic);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -285,7 +285,7 @@ void Mqtt::on_message(const char * topic, const char * payload, size_t len) cons
|
||||
snprintf(full_topic, sizeof(full_topic), "%s/%s", mqtt_base_.c_str(), mf.topic_.c_str());
|
||||
if ((!strcmp(topic, full_topic)) && (mf.mqtt_subfunction_)) {
|
||||
if (!(mf.mqtt_subfunction_)(message)) {
|
||||
LOG_ERROR(F("error: invalid payload %s for this topic %s"), message, topic);
|
||||
LOG_ERROR("error: invalid payload %s for this topic %s", message, topic);
|
||||
if (send_response_) {
|
||||
Mqtt::publish(F_(response), "error: invalid data");
|
||||
}
|
||||
@@ -341,10 +341,10 @@ void Mqtt::show_topic_handlers(uuid::console::Shell & shell, const uint8_t devic
|
||||
return;
|
||||
}
|
||||
|
||||
// shell.print(F(" Subscribed MQTT topics: "));
|
||||
// shell.print(" Subscribed MQTT topics: ");
|
||||
// for (const auto & mqtt_subfunction : mqtt_subfunctions_) {
|
||||
// if (mqtt_subfunction.device_type_ == device_type) {
|
||||
// shell.printf(F("%s "), mqtt_subfunction.topic_.c_str());
|
||||
// shell.printf("%s ", mqtt_subfunction.topic_.c_str());
|
||||
// }
|
||||
// }
|
||||
shell.println();
|
||||
@@ -358,7 +358,7 @@ void Mqtt::on_publish(uint16_t packetId) const {
|
||||
// find the MQTT message in the queue and remove it
|
||||
if (mqtt_messages_.empty()) {
|
||||
#if defined(EMSESP_DEBUG)
|
||||
LOG_DEBUG(F("[DEBUG] No message stored for ACK pid %d"), packetId);
|
||||
LOG_DEBUG("[DEBUG] No message stored for ACK pid %d", packetId);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
@@ -368,18 +368,18 @@ void Mqtt::on_publish(uint16_t packetId) const {
|
||||
// if the last published failed, don't bother checking it. wait for the next retry
|
||||
if (mqtt_message.packet_id_ == 0) {
|
||||
#if defined(EMSESP_DEBUG)
|
||||
LOG_DEBUG(F("[DEBUG] ACK for failed message pid 0"));
|
||||
LOG_DEBUG("[DEBUG] ACK for failed message pid 0");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (mqtt_message.packet_id_ != packetId) {
|
||||
LOG_ERROR(F("Mismatch, expecting PID %d, got %d"), mqtt_message.packet_id_, packetId);
|
||||
LOG_ERROR("Mismatch, expecting PID %d, got %d", mqtt_message.packet_id_, packetId);
|
||||
mqtt_publish_fails_++; // increment error count
|
||||
}
|
||||
|
||||
#if defined(EMSESP_DEBUG)
|
||||
LOG_DEBUG(F("[DEBUG] ACK pid %d"), packetId);
|
||||
LOG_DEBUG("[DEBUG] ACK pid %d", packetId);
|
||||
#endif
|
||||
|
||||
mqtt_messages_.pop_front(); // always remove from queue, regardless if there was a successful ACK
|
||||
@@ -450,17 +450,17 @@ void Mqtt::start() {
|
||||
}
|
||||
connecting_ = false;
|
||||
if (reason == AsyncMqttClientDisconnectReason::TCP_DISCONNECTED) {
|
||||
LOG_WARNING(F("MQTT disconnected: TCP"));
|
||||
LOG_WARNING("MQTT disconnected: TCP");
|
||||
} else if (reason == AsyncMqttClientDisconnectReason::MQTT_IDENTIFIER_REJECTED) {
|
||||
LOG_WARNING(F("MQTT disconnected: Identifier Rejected"));
|
||||
LOG_WARNING("MQTT disconnected: Identifier Rejected");
|
||||
} else if (reason == AsyncMqttClientDisconnectReason::MQTT_SERVER_UNAVAILABLE) {
|
||||
LOG_WARNING(F("MQTT disconnected: Server unavailable"));
|
||||
LOG_WARNING("MQTT disconnected: Server unavailable");
|
||||
} else if (reason == AsyncMqttClientDisconnectReason::MQTT_MALFORMED_CREDENTIALS) {
|
||||
LOG_WARNING(F("MQTT disconnected: Malformed credentials"));
|
||||
LOG_WARNING("MQTT disconnected: Malformed credentials");
|
||||
} else if (reason == AsyncMqttClientDisconnectReason::MQTT_NOT_AUTHORIZED) {
|
||||
LOG_WARNING(F("MQTT disconnected: Not authorized"));
|
||||
LOG_WARNING("MQTT disconnected: Not authorized");
|
||||
} else {
|
||||
LOG_WARNING(F("MQTT disconnected: code %d"), reason);
|
||||
LOG_WARNING("MQTT disconnected: code %d", reason);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -535,7 +535,7 @@ void Mqtt::on_connect() {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO(F("MQTT connected"));
|
||||
LOG_INFO("MQTT connected");
|
||||
|
||||
connecting_ = true;
|
||||
connectcount_++;
|
||||
@@ -546,15 +546,15 @@ void Mqtt::on_connect() {
|
||||
StaticJsonDocument<EMSESP_JSON_SIZE_MEDIUM> doc;
|
||||
// first time to connect
|
||||
if (connectcount_ == 1) {
|
||||
doc["event"] = FJSON("start");
|
||||
doc["event"] = "start";
|
||||
} else {
|
||||
doc["event"] = FJSON("reconnect");
|
||||
doc["event"] = "reconnect";
|
||||
}
|
||||
|
||||
doc["version"] = EMSESP_APP_VERSION;
|
||||
#ifndef EMSESP_STANDALONE
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
doc["connection"] = F("WiFi");
|
||||
doc["connection"] = ("WiFi");
|
||||
doc["hostname"] = WiFi.getHostname();
|
||||
doc["SSID"] = WiFi.SSID();
|
||||
doc["BSSID"] = WiFi.BSSIDstr();
|
||||
@@ -567,7 +567,7 @@ void Mqtt::on_connect() {
|
||||
doc["IPv6 address"] = uuid::printable_to_string(WiFi.localIPv6());
|
||||
}
|
||||
} else if (EMSESP::system_.ethernet_connected()) {
|
||||
doc["connection"] = F("Ethernet");
|
||||
doc["connection"] = ("Ethernet");
|
||||
doc["hostname"] = ETH.getHostname();
|
||||
doc["MAC"] = ETH.macAddress();
|
||||
doc["IPv4 address"] = uuid::printable_to_string(ETH.localIP()) + "/" + uuid::printable_to_string(ETH.subnetMask());
|
||||
@@ -600,7 +600,7 @@ void Mqtt::on_connect() {
|
||||
// re-subscribe to all custom registered MQTT topics
|
||||
resubscribe();
|
||||
|
||||
publish_retain(F("status"), "online", true); // say we're alive to the Last Will topic, with retain on
|
||||
publish_retain("status", "online", true); // say we're alive to the Last Will topic, with retain on
|
||||
|
||||
mqtt_publish_fails_ = 0; // reset fail count to 0
|
||||
|
||||
@@ -609,7 +609,7 @@ void Mqtt::on_connect() {
|
||||
LOG_INFO("Queue size: %d", mqtt_messages_.size());
|
||||
for (const auto & message : mqtt_messages_) {
|
||||
auto content = message.content_;
|
||||
LOG_INFO(F(" [%02d] (%d) topic=%s payload=%s"), message.id_, content->operation, content->topic.c_str(), content->payload.c_str());
|
||||
LOG_INFO((" [%02d] (%d) topic=%s payload=%s"), message.id_, content->operation, content->topic.c_str(), content->payload.c_str());
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -620,21 +620,21 @@ void Mqtt::on_connect() {
|
||||
void Mqtt::ha_status() {
|
||||
StaticJsonDocument<EMSESP_JSON_SIZE_HA_CONFIG> doc;
|
||||
|
||||
doc["uniq_id"] = FJSON("ems-esp-system");
|
||||
doc["uniq_id"] = "ems-esp-system";
|
||||
doc["~"] = mqtt_base_; // default ems-esp
|
||||
// doc["avty_t"] = FJSON("~/status"); // commented out, as it causes errors in HA sometimes
|
||||
// doc["json_attr_t"] = FJSON("~/heartbeat"); // store also as HA attributes
|
||||
doc["stat_t"] = FJSON("~/heartbeat");
|
||||
doc["object_id"] = FJSON("ems_esp_status");
|
||||
doc["name"] = FJSON("EMS-ESP status");
|
||||
// doc["avty_t"] = "~/status"; // commented out, as it causes errors in HA sometimes
|
||||
// doc["json_attr_t"] = "~/heartbeat"; // store also as HA attributes
|
||||
doc["stat_t"] = "~/heartbeat";
|
||||
doc["object_id"] = "ems_esp_status";
|
||||
doc["name"] = "EMS-ESP status";
|
||||
doc["ic"] = F_(icondevice);
|
||||
doc["val_tpl"] = FJSON("{{value_json['bus_status']}}");
|
||||
doc["val_tpl"] = "{{value_json['bus_status']}}";
|
||||
|
||||
JsonObject dev = doc.createNestedObject("dev");
|
||||
dev["name"] = F_(EMSESP); // "EMS-ESP"
|
||||
dev["name"] = "EMS-ESP";
|
||||
dev["sw"] = "v" + std::string(EMSESP_APP_VERSION);
|
||||
dev["mf"] = FJSON("proddy");
|
||||
dev["mdl"] = F_(EMSESP); // "EMS-ESP"
|
||||
dev["mf"] = "proddy";
|
||||
dev["mdl"] = "EMS-ESP";
|
||||
JsonArray ids = dev.createNestedArray("ids");
|
||||
ids.add("ems-esp");
|
||||
|
||||
@@ -644,19 +644,20 @@ void Mqtt::ha_status() {
|
||||
|
||||
// create the sensors - must match the MQTT payload keys
|
||||
if (!EMSESP::system_.ethernet_connected()) {
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT, F("WiFi RSSI"), F("rssi"), DeviceValueUOM::DBM);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT, F("WiFi strength"), F("wifistrength"), DeviceValueUOM::PERCENT);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT, ("WiFi RSSI"), ("rssi"), DeviceValueUOM::DBM);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT, ("WiFi strength"), ("wifistrength"), DeviceValueUOM::PERCENT);
|
||||
}
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT, F("Uptime"), F("uptime"), DeviceValueUOM::NONE);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT, F("Uptime (sec)"), F("uptime_sec"), DeviceValueUOM::SECONDS);
|
||||
publish_system_ha_sensor_config(DeviceValueType::BOOL, F("NTP status"), F("ntp_status"), DeviceValueUOM::NONE);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT, F("Free memory"), F("freemem"), DeviceValueUOM::KB);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT, F("MQTT fails"), F("mqttfails"), DeviceValueUOM::NONE);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT, F("Rx received"), F("rxreceived"), DeviceValueUOM::NONE);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT, F("Rx fails"), F("rxfails"), DeviceValueUOM::NONE);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT, F("Tx reads"), F("txreads"), DeviceValueUOM::NONE);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT, F("Tx writes"), F("txwrites"), DeviceValueUOM::NONE);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT, F("Tx fails"), F("txfails"), DeviceValueUOM::NONE);
|
||||
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT, ("Uptime"), ("uptime"), DeviceValueUOM::NONE);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT, ("Uptime (sec)"), ("uptime_sec"), DeviceValueUOM::SECONDS);
|
||||
publish_system_ha_sensor_config(DeviceValueType::BOOL, ("NTP status"), ("ntp_status"), DeviceValueUOM::NONE);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT, ("Free memory"), ("freemem"), DeviceValueUOM::KB);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT, ("MQTT fails"), ("mqttfails"), DeviceValueUOM::NONE);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT, ("Rx received"), ("rxreceived"), DeviceValueUOM::NONE);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT, ("Rx fails"), ("rxfails"), DeviceValueUOM::NONE);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT, ("Tx reads"), ("txreads"), DeviceValueUOM::NONE);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT, ("Tx writes"), ("txwrites"), DeviceValueUOM::NONE);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT, ("Tx fails"), ("txfails"), DeviceValueUOM::NONE);
|
||||
}
|
||||
|
||||
// add sub or pub task to the queue.
|
||||
@@ -686,7 +687,7 @@ std::shared_ptr<const MqttMessage> Mqtt::queue_message(const uint8_t operation,
|
||||
// if the queue is full, make room but removing the last one
|
||||
if (mqtt_messages_.size() >= MAX_MQTT_MESSAGES) {
|
||||
mqtt_messages_.pop_front();
|
||||
LOG_WARNING(F("Queue overflow, removing one message"));
|
||||
LOG_WARNING("Queue overflow, removing one message");
|
||||
mqtt_publish_fails_++;
|
||||
}
|
||||
mqtt_messages_.emplace_back(mqtt_message_id_++, std::move(message));
|
||||
@@ -718,17 +719,17 @@ void Mqtt::publish(const std::string & topic, const std::string & payload) {
|
||||
}
|
||||
|
||||
// MQTT Publish, using a user's retain flag - except for char * strings
|
||||
void Mqtt::publish(const __FlashStringHelper * topic, const char * payload) {
|
||||
queue_publish_message(read_flash_string(topic), payload, mqtt_retain_);
|
||||
void Mqtt::publish(const char * topic, const char * payload) {
|
||||
queue_publish_message((topic), payload, mqtt_retain_);
|
||||
}
|
||||
|
||||
// MQTT Publish, using a specific retain flag, topic is a flash string
|
||||
void Mqtt::publish(const __FlashStringHelper * topic, const std::string & payload) {
|
||||
queue_publish_message(read_flash_string(topic), payload, mqtt_retain_);
|
||||
void Mqtt::publish(const char * topic, const std::string & payload) {
|
||||
queue_publish_message((topic), payload, mqtt_retain_);
|
||||
}
|
||||
|
||||
void Mqtt::publish(const __FlashStringHelper * topic, const JsonObject & payload) {
|
||||
publish(read_flash_string(topic), payload);
|
||||
void Mqtt::publish(const char * topic, const JsonObject & payload) {
|
||||
publish_retain(topic, payload, mqtt_retain_);
|
||||
}
|
||||
|
||||
// publish json doc, only if its not empty
|
||||
@@ -737,12 +738,16 @@ void Mqtt::publish(const std::string & topic, const JsonObject & payload) {
|
||||
}
|
||||
|
||||
// MQTT Publish, using a specific retain flag, topic is a flash string, forcing retain flag
|
||||
void Mqtt::publish_retain(const __FlashStringHelper * topic, const std::string & payload, bool retain) {
|
||||
queue_publish_message(read_flash_string(topic), payload, retain);
|
||||
void Mqtt::publish_retain(const char * topic, const std::string & payload, bool retain) {
|
||||
queue_publish_message((topic), payload, retain);
|
||||
}
|
||||
|
||||
// publish json doc, only if its not empty, using the retain flag
|
||||
void Mqtt::publish_retain(const std::string & topic, const JsonObject & payload, bool retain) {
|
||||
publish_retain(topic.c_str(), payload, retain);
|
||||
}
|
||||
|
||||
void Mqtt::publish_retain(const char * topic, const JsonObject & payload, bool retain) {
|
||||
if (enabled() && payload.size()) {
|
||||
std::string payload_text;
|
||||
serializeJson(payload, payload_text); // convert json to string
|
||||
@@ -750,30 +755,22 @@ void Mqtt::publish_retain(const std::string & topic, const JsonObject & payload,
|
||||
}
|
||||
}
|
||||
|
||||
void Mqtt::publish_retain(const __FlashStringHelper * topic, const JsonObject & payload, bool retain) {
|
||||
publish_retain(read_flash_string(topic), payload, retain);
|
||||
}
|
||||
|
||||
void Mqtt::publish_ha(const __FlashStringHelper * topic, const JsonObject & payload) {
|
||||
publish_ha(read_flash_string(topic), payload);
|
||||
}
|
||||
|
||||
// publish empty payload to remove the topic
|
||||
void Mqtt::publish_ha(const std::string & topic) {
|
||||
void Mqtt::publish_ha(const char * topic) {
|
||||
if (!enabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string fulltopic = Mqtt::discovery_prefix() + topic;
|
||||
#if defined(EMSESP_DEBUG)
|
||||
LOG_DEBUG(F("[DEBUG] Publishing empty HA topic=%s"), fulltopic.c_str());
|
||||
LOG_DEBUG("[DEBUG] Publishing empty HA topic=%s", fulltopic.c_str());
|
||||
#endif
|
||||
|
||||
queue_publish_message(fulltopic, "", true); // publish with retain to remove from broker
|
||||
}
|
||||
|
||||
// publish a Home Assistant config topic and payload, with retain flag off.
|
||||
void Mqtt::publish_ha(const std::string & topic, const JsonObject & payload) {
|
||||
void Mqtt::publish_ha(const char * topic, const JsonObject & payload) {
|
||||
if (!enabled()) {
|
||||
return;
|
||||
}
|
||||
@@ -784,9 +781,9 @@ void Mqtt::publish_ha(const std::string & topic, const JsonObject & payload) {
|
||||
|
||||
std::string fulltopic = Mqtt::discovery_prefix() + topic;
|
||||
#if defined(EMSESP_STANDALONE)
|
||||
LOG_DEBUG(F("Publishing HA topic=%s, payload=%s"), fulltopic.c_str(), payload_text.c_str());
|
||||
LOG_DEBUG("Publishing HA topic=%s, payload=%s", fulltopic.c_str(), payload_text.c_str());
|
||||
#elif defined(EMSESP_DEBUG)
|
||||
LOG_DEBUG(F("[debug] Publishing HA topic=%s, payload=%s"), fulltopic.c_str(), payload_text.c_str());
|
||||
LOG_DEBUG("[debug] Publishing HA topic=%s, payload=%s", fulltopic.c_str(), payload_text.c_str());
|
||||
#endif
|
||||
|
||||
// queue messages if the MQTT connection is not yet established. to ensure we don't miss messages
|
||||
@@ -815,7 +812,7 @@ void Mqtt::process_queue() {
|
||||
// it will have a real packet ID
|
||||
if (mqtt_message.packet_id_ > 0) {
|
||||
#if defined(EMSESP_DEBUG)
|
||||
LOG_DEBUG(F("[DEBUG] Waiting for QOS-ACK"));
|
||||
LOG_DEBUG("[DEBUG] Waiting for QOS-ACK");
|
||||
#endif
|
||||
// if we don't get the ack within 10 minutes, republish with new packet_id
|
||||
if (uuid::get_uptime_sec() - last_publish_queue_ < 600) {
|
||||
@@ -826,13 +823,13 @@ void Mqtt::process_queue() {
|
||||
|
||||
// if we're subscribing...
|
||||
if (message->operation == Operation::SUBSCRIBE) {
|
||||
LOG_DEBUG(F("Subscribing to topic '%s'"), topic);
|
||||
LOG_DEBUG("Subscribing to topic '%s'", topic);
|
||||
uint16_t packet_id = mqttClient_->subscribe(topic, mqtt_qos_);
|
||||
if (!packet_id) {
|
||||
if (++mqtt_messages_.front().retry_count_ < MQTT_PUBLISH_MAX_RETRY) {
|
||||
return;
|
||||
}
|
||||
LOG_ERROR(F("Error subscribing to topic '%s'"), topic);
|
||||
LOG_ERROR("Error subscribing to topic '%s'", topic);
|
||||
mqtt_publish_fails_++; // increment failure counter
|
||||
}
|
||||
|
||||
@@ -843,13 +840,13 @@ void Mqtt::process_queue() {
|
||||
|
||||
// if we're unsubscribing...
|
||||
if (message->operation == Operation::UNSUBSCRIBE) {
|
||||
LOG_DEBUG(F("Subscribing to topic '%s'"), topic);
|
||||
LOG_DEBUG("Subscribing to topic '%s'", topic);
|
||||
uint16_t packet_id = mqttClient_->unsubscribe(topic);
|
||||
if (!packet_id) {
|
||||
if (++mqtt_messages_.front().retry_count_ < MQTT_PUBLISH_MAX_RETRY) {
|
||||
return;
|
||||
}
|
||||
LOG_ERROR(F("Error unsubscribing to topic '%s'"), topic);
|
||||
LOG_ERROR("Error unsubscribing to topic '%s'", topic);
|
||||
mqtt_publish_fails_++; // increment failure counter
|
||||
}
|
||||
|
||||
@@ -860,7 +857,7 @@ void Mqtt::process_queue() {
|
||||
|
||||
// else try and publish it
|
||||
uint16_t packet_id = mqttClient_->publish(topic, mqtt_qos_, message->retain, message->payload.c_str(), message->payload.size(), false, mqtt_message.id_);
|
||||
LOG_DEBUG(F("Publishing topic %s (#%02d, retain=%d, retry=%d, size=%d, pid=%d)"),
|
||||
LOG_DEBUG(("Publishing topic %s (#%02d, retain=%d, retry=%d, size=%d, pid=%d)"),
|
||||
topic,
|
||||
mqtt_message.id_,
|
||||
message->retain,
|
||||
@@ -871,14 +868,14 @@ void Mqtt::process_queue() {
|
||||
if (packet_id == 0) {
|
||||
// it failed. if we retried n times, give up. remove from queue
|
||||
if (mqtt_message.retry_count_ == (MQTT_PUBLISH_MAX_RETRY - 1)) {
|
||||
LOG_ERROR(F("Failed to publish to %s after %d attempts"), topic, mqtt_message.retry_count_ + 1);
|
||||
LOG_ERROR("Failed to publish to %s after %d attempts", topic, mqtt_message.retry_count_ + 1);
|
||||
mqtt_publish_fails_++; // increment failure counter
|
||||
mqtt_messages_.pop_front(); // delete
|
||||
return;
|
||||
} else {
|
||||
// update the record
|
||||
mqtt_messages_.front().retry_count_++;
|
||||
LOG_DEBUG(F("Failed to publish to %s. Trying again, #%d"), topic, mqtt_message.retry_count_ + 1);
|
||||
LOG_DEBUG("Failed to publish to %s. Trying again, #%d", topic, mqtt_message.retry_count_ + 1);
|
||||
return; // leave on queue for next time so it gets republished
|
||||
}
|
||||
}
|
||||
@@ -888,7 +885,7 @@ void Mqtt::process_queue() {
|
||||
if (mqtt_qos_ != 0) {
|
||||
mqtt_messages_.front().packet_id_ = packet_id;
|
||||
#if defined(EMSESP_DEBUG)
|
||||
LOG_DEBUG(F("[DEBUG] Setting packetID for ACK to %d"), packet_id);
|
||||
LOG_DEBUG("[DEBUG] Setting packetID for ACK to %d", packet_id);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
@@ -927,8 +924,8 @@ void Mqtt::publish_ha_sensor_config(DeviceValue & dv, const std::string & model,
|
||||
|
||||
publish_ha_sensor_config(dv.type,
|
||||
dv.tag,
|
||||
dv.get_fullname(),
|
||||
dv.fullname[0],
|
||||
dv.get_fullname().c_str(),
|
||||
(dv.fullname ? dv.fullname[0] : nullptr), // EN name
|
||||
dv.device_type,
|
||||
dv.short_name,
|
||||
dv.uom,
|
||||
@@ -942,37 +939,35 @@ void Mqtt::publish_ha_sensor_config(DeviceValue & dv, const std::string & model,
|
||||
}
|
||||
|
||||
// publish HA sensor for System using the heartbeat tag
|
||||
void Mqtt::publish_system_ha_sensor_config(uint8_t type, const __FlashStringHelper * name, const __FlashStringHelper * entity, const uint8_t uom) {
|
||||
void Mqtt::publish_system_ha_sensor_config(uint8_t type, const char * name, const char * entity, const uint8_t uom) {
|
||||
StaticJsonDocument<EMSESP_JSON_SIZE_HA_CONFIG> doc;
|
||||
JsonObject dev_json = doc.createNestedObject("dev");
|
||||
|
||||
JsonArray ids = dev_json.createNestedArray("ids");
|
||||
ids.add("ems-esp");
|
||||
|
||||
auto fullname = read_flash_string(name);
|
||||
|
||||
publish_ha_sensor_config(type, DeviceValueTAG::TAG_HEARTBEAT, fullname, name, EMSdevice::DeviceType::SYSTEM, entity, uom, false, false, nullptr, 0, 0, 0, dev_json);
|
||||
publish_ha_sensor_config(type, DeviceValueTAG::TAG_HEARTBEAT, name, name, EMSdevice::DeviceType::SYSTEM, entity, uom, false, false, nullptr, 0, 0, 0, dev_json);
|
||||
}
|
||||
|
||||
// MQTT discovery configs
|
||||
// entity must match the key/value pair in the *_data topic
|
||||
// note: some extra string copying done here, it looks messy but does help with heap fragmentation issues
|
||||
void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdevice::DeviceValueType
|
||||
uint8_t tag, // EMSdevice::DeviceValueTAG
|
||||
const std::string & fullname, // fullname, already translated
|
||||
const __FlashStringHelper * const en_name,
|
||||
const uint8_t device_type, // EMSdevice::DeviceType
|
||||
const __FlashStringHelper * const entity, // same as shortname
|
||||
const uint8_t uom, // EMSdevice::DeviceValueUOM (0=NONE)
|
||||
const bool remove, // true if we want to remove this topic
|
||||
const bool has_cmd,
|
||||
const __FlashStringHelper * const ** options,
|
||||
uint8_t options_size,
|
||||
const int16_t dv_set_min,
|
||||
const int16_t dv_set_max,
|
||||
const JsonObject & dev_json) {
|
||||
void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdevice::DeviceValueType
|
||||
uint8_t tag, // EMSdevice::DeviceValueTAG
|
||||
const char * const fullname, // fullname, already translated
|
||||
const char * const en_name,
|
||||
const uint8_t device_type, // EMSdevice::DeviceType
|
||||
const char * const entity, // same as shortname
|
||||
const uint8_t uom, // EMSdevice::DeviceValueUOM (0=NONE)
|
||||
const bool remove, // true if we want to remove this topic
|
||||
const bool has_cmd,
|
||||
const char * const ** options,
|
||||
uint8_t options_size,
|
||||
const int16_t dv_set_min,
|
||||
const int16_t dv_set_max,
|
||||
const JsonObject & dev_json) {
|
||||
// ignore if name (fullname) is empty
|
||||
if (fullname.empty() || en_name == nullptr) {
|
||||
if (fullname == nullptr || en_name == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -983,9 +978,9 @@ void Mqtt::publish_ha_sensor_config(uint8_t type,
|
||||
// create entity by add the hc/wwc tag if present, separating with a .
|
||||
char new_entity[50];
|
||||
if (tag >= DeviceValueTAG::TAG_HC1) {
|
||||
snprintf(new_entity, sizeof(new_entity), "%s.%s", EMSdevice::tag_to_string(tag).c_str(), read_flash_string(entity).c_str());
|
||||
snprintf(new_entity, sizeof(new_entity), "%s.%s", EMSdevice::tag_to_string(tag).c_str(), (entity));
|
||||
} else {
|
||||
snprintf(new_entity, sizeof(new_entity), "%s", read_flash_string(entity).c_str());
|
||||
snprintf(new_entity, sizeof(new_entity), "%s", (entity));
|
||||
}
|
||||
|
||||
// build unique identifier which will be used in the topic, replacing all . with _ as not to break HA
|
||||
@@ -1037,7 +1032,7 @@ void Mqtt::publish_ha_sensor_config(uint8_t type,
|
||||
// if we're asking to remove this topic, send an empty payload and exit
|
||||
// https://github.com/emsesp/EMS-ESP32/issues/196
|
||||
if (remove) {
|
||||
LOG_DEBUG(F("Removing HA config for %s"), uniq);
|
||||
LOG_DEBUG("Removing HA config for %s", uniq);
|
||||
publish_ha(topic);
|
||||
return;
|
||||
}
|
||||
@@ -1107,7 +1102,7 @@ void Mqtt::publish_ha_sensor_config(uint8_t type,
|
||||
|
||||
// friendly name = <tag> <name>
|
||||
char ha_name[70];
|
||||
char * F_name = strdup(fullname.c_str());
|
||||
char * F_name = strdup(fullname);
|
||||
F_name[0] = toupper(F_name[0]); // capitalize first letter
|
||||
if (have_tag) {
|
||||
snprintf(ha_name, sizeof(ha_name), "%s %s", EMSdevice::tag_to_string(tag).c_str(), F_name);
|
||||
@@ -1120,14 +1115,12 @@ void Mqtt::publish_ha_sensor_config(uint8_t type,
|
||||
// entity id is generated from the name, see https://www.home-assistant.io/docs/mqtt/discovery/#use-object_id-to-influence-the-entity-id
|
||||
// so we override it to make it unique using entity_id
|
||||
// See https://github.com/emsesp/EMS-ESP32/issues/596
|
||||
// keep it compatible to v3.4, use english fullname, no prefix (basename prefix commmented out)
|
||||
// keep it compatible to v3.4, use english fullname, no prefix (basename prefix commented out)
|
||||
char object_id[130];
|
||||
if (have_tag) {
|
||||
// snprintf(object_id, sizeof(object_id), "%s_%s_%s_%s", mqtt_basename_, device_name, EMSdevice::tag_to_string(tag).c_str(), read_flash_string(en_name).c_str());
|
||||
snprintf(object_id, sizeof(object_id), "%s_%s_%s", device_name, EMSdevice::tag_to_string(tag).c_str(), read_flash_string(en_name).c_str());
|
||||
snprintf(object_id, sizeof(object_id), "%s_%s_%s", device_name, EMSdevice::tag_to_string(tag).c_str(), en_name);
|
||||
} else {
|
||||
// snprintf(object_id, sizeof(object_id), "%s_%s_%s", mqtt_basename_, device_name, read_flash_string(en_name).c_str());
|
||||
snprintf(object_id, sizeof(object_id), "%s_%s", device_name, read_flash_string(en_name).c_str());
|
||||
snprintf(object_id, sizeof(object_id), "%s_%s", device_name, en_name);
|
||||
}
|
||||
doc["object_id"] = object_id;
|
||||
|
||||
@@ -1137,7 +1130,7 @@ void Mqtt::publish_ha_sensor_config(uint8_t type,
|
||||
if (is_nested()) {
|
||||
snprintf(val_tpl, sizeof(val_tpl), "{{value_json.%s}}", new_entity);
|
||||
} else {
|
||||
snprintf(val_tpl, sizeof(val_tpl), "{{value_json.%s}}", read_flash_string(entity).c_str());
|
||||
snprintf(val_tpl, sizeof(val_tpl), "{{value_json.%s}}", entity);
|
||||
}
|
||||
doc["val_tpl"] = val_tpl;
|
||||
|
||||
@@ -1147,9 +1140,9 @@ void Mqtt::publish_ha_sensor_config(uint8_t type,
|
||||
// and has no unit of measure or icon
|
||||
if (type == DeviceValueType::BOOL) {
|
||||
char result[10];
|
||||
doc[F("payload_on")] = Helpers::render_boolean(result, true);
|
||||
doc[F("payload_off")] = Helpers::render_boolean(result, false);
|
||||
doc[sc_ha] = F_(measurement);
|
||||
doc[("payload_on")] = Helpers::render_boolean(result, true);
|
||||
doc[("payload_off")] = Helpers::render_boolean(result, false);
|
||||
doc[sc_ha] = F_(measurement);
|
||||
} else {
|
||||
// always set the uom
|
||||
if (uom != DeviceValueUOM::NONE) {
|
||||
@@ -1169,11 +1162,11 @@ void Mqtt::publish_ha_sensor_config(uint8_t type,
|
||||
case DeviceValueUOM::DEGREES:
|
||||
case DeviceValueUOM::DEGREES_R:
|
||||
doc[sc_ha] = F_(measurement);
|
||||
doc[dc_ha] = F("temperature"); // no icon needed
|
||||
doc[dc_ha] = "temperature"; // no icon needed
|
||||
break;
|
||||
case DeviceValueUOM::PERCENT:
|
||||
doc[sc_ha] = F_(measurement);
|
||||
doc[dc_ha] = F("power_factor"); // no icon needed
|
||||
doc[dc_ha] = "power_factor"; // no icon needed
|
||||
break;
|
||||
case DeviceValueUOM::SECONDS:
|
||||
case DeviceValueUOM::MINUTES:
|
||||
@@ -1198,11 +1191,11 @@ void Mqtt::publish_ha_sensor_config(uint8_t type,
|
||||
} else {
|
||||
doc[sc_ha] = F_(measurement);
|
||||
}
|
||||
doc[dc_ha] = F("energy"); // no icon needed
|
||||
doc[dc_ha] = "energy"; // no icon needed
|
||||
break;
|
||||
case DeviceValueUOM::KWH:
|
||||
doc[sc_ha] = F_(total_increasing);
|
||||
doc[dc_ha] = F("energy"); // no icon needed
|
||||
doc[dc_ha] = "energy"; // no icon needed
|
||||
break;
|
||||
case DeviceValueUOM::UA:
|
||||
doc[ic_ha] = F_(iconua);
|
||||
@@ -1210,16 +1203,16 @@ void Mqtt::publish_ha_sensor_config(uint8_t type,
|
||||
break;
|
||||
case DeviceValueUOM::BAR:
|
||||
doc[sc_ha] = F_(measurement);
|
||||
doc[dc_ha] = F("pressure");
|
||||
doc[dc_ha] = "pressure";
|
||||
break;
|
||||
case DeviceValueUOM::W:
|
||||
case DeviceValueUOM::KW:
|
||||
doc[sc_ha] = F_(measurement);
|
||||
doc[dc_ha] = F("power");
|
||||
doc[dc_ha] = "power";
|
||||
break;
|
||||
case DeviceValueUOM::DBM:
|
||||
doc[sc_ha] = F_(measurement);
|
||||
doc[dc_ha] = F("signal_strength");
|
||||
doc[dc_ha] = "signal_strength";
|
||||
break;
|
||||
case DeviceValueUOM::NONE:
|
||||
// for device entities which have numerical values, with no UOM
|
||||
|
||||
45
src/mqtt.h
45
src/mqtt.h
@@ -79,35 +79,34 @@ class Mqtt {
|
||||
static void resubscribe();
|
||||
|
||||
static void publish(const std::string & topic, const std::string & payload);
|
||||
static void publish(const __FlashStringHelper * topic, const char * payload);
|
||||
static void publish(const char * topic, const char * payload);
|
||||
static void publish(const std::string & topic, const JsonObject & payload);
|
||||
static void publish(const __FlashStringHelper * topic, const JsonObject & payload);
|
||||
static void publish(const __FlashStringHelper * topic, const std::string & payload);
|
||||
static void publish(const char * topic, const JsonObject & payload);
|
||||
static void publish(const char * topic, const std::string & payload);
|
||||
static void publish_retain(const std::string & topic, const JsonObject & payload, bool retain);
|
||||
static void publish_retain(const __FlashStringHelper * topic, const std::string & payload, bool retain);
|
||||
static void publish_retain(const __FlashStringHelper * topic, const JsonObject & payload, bool retain);
|
||||
static void publish_ha(const std::string & topic, const JsonObject & payload);
|
||||
static void publish_ha(const __FlashStringHelper * topic, const JsonObject & payload);
|
||||
static void publish_ha(const std::string & topic);
|
||||
static void publish_retain(const char * topic, const std::string & payload, bool retain);
|
||||
static void publish_retain(const char * topic, const JsonObject & payload, bool retain);
|
||||
static void publish_ha(const char * topic, const JsonObject & payload);
|
||||
static void publish_ha(const char * topic);
|
||||
|
||||
static void
|
||||
publish_ha_sensor_config(DeviceValue & dv, const std::string & model, const std::string & brand, const bool remove, const bool create_device_config = false);
|
||||
static void publish_ha_sensor_config(uint8_t type,
|
||||
uint8_t tag,
|
||||
const std::string & fullname,
|
||||
const __FlashStringHelper * const en_name,
|
||||
const uint8_t device_type,
|
||||
const __FlashStringHelper * const entity,
|
||||
const uint8_t uom,
|
||||
const bool remove,
|
||||
const bool has_cmd,
|
||||
const __FlashStringHelper * const ** options,
|
||||
uint8_t options_size,
|
||||
const int16_t dv_set_min,
|
||||
const int16_t dv_set_max,
|
||||
const JsonObject & dev_json);
|
||||
static void publish_ha_sensor_config(uint8_t type,
|
||||
uint8_t tag,
|
||||
const char * const fullname,
|
||||
const char * const en_name,
|
||||
const uint8_t device_type,
|
||||
const char * const entity,
|
||||
const uint8_t uom,
|
||||
const bool remove,
|
||||
const bool has_cmd,
|
||||
const char * const ** options,
|
||||
uint8_t options_size,
|
||||
const int16_t dv_set_min,
|
||||
const int16_t dv_set_max,
|
||||
const JsonObject & dev_json);
|
||||
|
||||
static void publish_system_ha_sensor_config(uint8_t type, const __FlashStringHelper * name, const __FlashStringHelper * entity, const uint8_t uom);
|
||||
static void publish_system_ha_sensor_config(uint8_t type, const char * name, const char * entity, const uint8_t uom);
|
||||
static void publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp, const bool remove = false, const int16_t min = 5, const uint16_t max = 30);
|
||||
|
||||
static void show_topic_handlers(uuid::console::Shell & shell, const uint8_t device_type);
|
||||
|
||||
@@ -57,7 +57,7 @@ void Shower::loop() {
|
||||
// first check to see if hot water has been on long enough to be recognized as a Shower/Bath
|
||||
if (!shower_state_ && (time_now - timer_start_) > SHOWER_MIN_DURATION) {
|
||||
set_shower_state(true);
|
||||
LOG_DEBUG(F("[Shower] hot water still running, starting shower timer"));
|
||||
LOG_DEBUG("[Shower] hot water still running, starting shower timer");
|
||||
}
|
||||
// check if the shower has been on too long
|
||||
else if ((time_now - timer_start_) > shower_alert_trigger_) {
|
||||
@@ -82,8 +82,8 @@ void Shower::loop() {
|
||||
char s[50];
|
||||
snprintf(s, 50, "%d minutes and %d seconds", (uint8_t)(duration_ / 60000), (uint8_t)((duration_ / 1000) % 60));
|
||||
doc["duration"] = s;
|
||||
Mqtt::publish(F("shower_data"), doc.as<JsonObject>());
|
||||
LOG_DEBUG(F("[Shower] finished with duration %d"), duration_);
|
||||
Mqtt::publish("shower_data", doc.as<JsonObject>());
|
||||
LOG_DEBUG("[Shower] finished with duration %d", duration_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ void Shower::loop() {
|
||||
// turn back on the hot water for the shower
|
||||
void Shower::shower_alert_stop() {
|
||||
if (doing_cold_shot_) {
|
||||
LOG_DEBUG(F("Shower Alert stopped"));
|
||||
LOG_DEBUG("Shower Alert stopped");
|
||||
(void)Command::call(EMSdevice::DeviceType::BOILER, "wwtapactivated", "true");
|
||||
doing_cold_shot_ = false;
|
||||
}
|
||||
@@ -117,7 +117,7 @@ void Shower::shower_alert_stop() {
|
||||
// turn off hot water to send a shot of cold
|
||||
void Shower::shower_alert_start() {
|
||||
if (shower_alert_) {
|
||||
LOG_DEBUG(F("Shower Alert started"));
|
||||
LOG_DEBUG("Shower Alert started");
|
||||
(void)Command::call(EMSdevice::DeviceType::BOILER, "wwtapactivated", "false");
|
||||
doing_cold_shot_ = true;
|
||||
alert_timer_start_ = uuid::get_uptime(); // timer starts now
|
||||
@@ -144,22 +144,22 @@ void Shower::set_shower_state(bool state, bool force) {
|
||||
|
||||
// always publish as a string
|
||||
char s[7];
|
||||
Mqtt::publish(F("shower_active"), Helpers::render_boolean(s, shower_state_)); // https://github.com/emsesp/EMS-ESP/issues/369
|
||||
Mqtt::publish("shower_active", Helpers::render_boolean(s, shower_state_)); // https://github.com/emsesp/EMS-ESP/issues/369
|
||||
|
||||
// send out HA MQTT Discovery config topic
|
||||
if ((Mqtt::ha_enabled()) && (!ha_configdone_ || force)) {
|
||||
ha_configdone_ = true;
|
||||
|
||||
StaticJsonDocument<EMSESP_JSON_SIZE_HA_CONFIG> doc;
|
||||
doc["name"] = FJSON("Shower Active");
|
||||
doc["uniq_id"] = FJSON("shower_active");
|
||||
doc["name"] = "Shower Active";
|
||||
doc["uniq_id"] = "shower_active";
|
||||
doc["~"] = Mqtt::base();
|
||||
doc["stat_t"] = FJSON("~/shower_active");
|
||||
doc["stat_t"] = "~/shower_active";
|
||||
|
||||
// always render boolean as strings for HA
|
||||
char result[10];
|
||||
doc[F("payload_on")] = Helpers::render_boolean(result, true);
|
||||
doc[F("payload_off")] = Helpers::render_boolean(result, false);
|
||||
doc[("payload_on")] = Helpers::render_boolean(result, true);
|
||||
doc[("payload_off")] = Helpers::render_boolean(result, false);
|
||||
|
||||
JsonObject dev = doc.createNestedObject("dev");
|
||||
JsonArray ids = dev.createNestedArray("ids");
|
||||
|
||||
219
src/system.cpp
219
src/system.cpp
@@ -77,19 +77,19 @@ bool System::command_fetch(const char * value, const int8_t id) {
|
||||
std::string value_s;
|
||||
if (Helpers::value2string(value, value_s)) {
|
||||
if (value_s == "all") {
|
||||
LOG_INFO(F("Requesting data from EMS devices"));
|
||||
LOG_INFO("Requesting data from EMS devices");
|
||||
EMSESP::fetch_device_values();
|
||||
return true;
|
||||
} else if (value_s == read_flash_string(F_(boiler))) {
|
||||
} else if (value_s == (F_(boiler))) {
|
||||
EMSESP::fetch_device_values_type(EMSdevice::DeviceType::BOILER);
|
||||
return true;
|
||||
} else if (value_s == read_flash_string(F_(thermostat))) {
|
||||
} else if (value_s == (F_(thermostat))) {
|
||||
EMSESP::fetch_device_values_type(EMSdevice::DeviceType::THERMOSTAT);
|
||||
return true;
|
||||
} else if (value_s == read_flash_string(F_(solar))) {
|
||||
} else if (value_s == (F_(solar))) {
|
||||
EMSESP::fetch_device_values_type(EMSdevice::DeviceType::SOLAR);
|
||||
return true;
|
||||
} else if (value_s == read_flash_string(F_(mixer))) {
|
||||
} else if (value_s == (F_(mixer))) {
|
||||
EMSESP::fetch_device_values_type(EMSdevice::DeviceType::MIXER);
|
||||
return true;
|
||||
}
|
||||
@@ -105,31 +105,31 @@ bool System::command_publish(const char * value, const int8_t id) {
|
||||
if (Helpers::value2string(value, value_s)) {
|
||||
if (value_s == "ha") {
|
||||
EMSESP::publish_all(true); // includes HA
|
||||
LOG_INFO(F("Publishing all data to MQTT, including HA configs"));
|
||||
LOG_INFO("Publishing all data to MQTT, including HA configs");
|
||||
return true;
|
||||
} else if (value_s == read_flash_string(F_(boiler))) {
|
||||
} else if (value_s == (F_(boiler))) {
|
||||
EMSESP::publish_device_values(EMSdevice::DeviceType::BOILER);
|
||||
return true;
|
||||
} else if (value_s == read_flash_string(F_(thermostat))) {
|
||||
} else if (value_s == (F_(thermostat))) {
|
||||
EMSESP::publish_device_values(EMSdevice::DeviceType::THERMOSTAT);
|
||||
return true;
|
||||
} else if (value_s == read_flash_string(F_(solar))) {
|
||||
} else if (value_s == (F_(solar))) {
|
||||
EMSESP::publish_device_values(EMSdevice::DeviceType::SOLAR);
|
||||
return true;
|
||||
} else if (value_s == read_flash_string(F_(mixer))) {
|
||||
} else if (value_s == (F_(mixer))) {
|
||||
EMSESP::publish_device_values(EMSdevice::DeviceType::MIXER);
|
||||
return true;
|
||||
} else if (value_s == "other") {
|
||||
EMSESP::publish_other_values(); // switch and heat pump
|
||||
return true;
|
||||
} else if ((value_s == read_flash_string(F_(dallassensor))) || (value_s == read_flash_string(F_(analogsensor)))) {
|
||||
} else if ((value_s == (F_(dallassensor))) || (value_s == (F_(analogsensor)))) {
|
||||
EMSESP::publish_sensor_values(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
EMSESP::publish_all();
|
||||
LOG_INFO(F("Publishing all data to MQTT"));
|
||||
LOG_INFO("Publishing all data to MQTT");
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -166,11 +166,9 @@ bool System::command_watch(const char * value, const int8_t id) {
|
||||
}
|
||||
if (Mqtt::publish_single() && w != EMSESP::watch()) {
|
||||
if (Mqtt::publish_single2cmd()) {
|
||||
Mqtt::publish(F("system/watch"),
|
||||
EMSESP::system_.enum_format() == ENUM_FORMAT_INDEX ? Helpers::itoa(w) : read_flash_string(FL_(list_watch)[w]).c_str());
|
||||
Mqtt::publish("system/watch", EMSESP::system_.enum_format() == ENUM_FORMAT_INDEX ? Helpers::itoa(w) : (FL_(list_watch)[w]));
|
||||
} else {
|
||||
Mqtt::publish(F("system_data/watch"),
|
||||
EMSESP::system_.enum_format() == ENUM_FORMAT_INDEX ? Helpers::itoa(w) : read_flash_string(FL_(list_watch)[w]).c_str());
|
||||
Mqtt::publish("system_data/watch", EMSESP::system_.enum_format() == ENUM_FORMAT_INDEX ? Helpers::itoa(w) : (FL_(list_watch)[w]));
|
||||
}
|
||||
}
|
||||
EMSESP::watch(w);
|
||||
@@ -178,9 +176,9 @@ bool System::command_watch(const char * value, const int8_t id) {
|
||||
} else if (i) {
|
||||
if (Mqtt::publish_single() && i != EMSESP::watch_id()) {
|
||||
if (Mqtt::publish_single2cmd()) {
|
||||
Mqtt::publish(F("system/watch"), Helpers::hextoa(i));
|
||||
Mqtt::publish("system/watch", Helpers::hextoa(i));
|
||||
} else {
|
||||
Mqtt::publish(F("system_data/watch"), Helpers::hextoa(i));
|
||||
Mqtt::publish("system_data/watch", Helpers::hextoa(i));
|
||||
}
|
||||
}
|
||||
EMSESP::watch_id(i);
|
||||
@@ -194,7 +192,7 @@ bool System::command_watch(const char * value, const int8_t id) {
|
||||
|
||||
// restart EMS-ESP
|
||||
void System::system_restart() {
|
||||
LOG_INFO(F("Restarting EMS-ESP..."));
|
||||
LOG_INFO("Restarting EMS-ESP...");
|
||||
Shell::loop_all();
|
||||
delay(1000); // wait a second
|
||||
#ifndef EMSESP_STANDALONE
|
||||
@@ -204,7 +202,7 @@ void System::system_restart() {
|
||||
|
||||
// saves all settings
|
||||
void System::wifi_reconnect() {
|
||||
LOG_INFO(F("WiFi reconnecting..."));
|
||||
LOG_INFO("WiFi reconnecting...");
|
||||
Shell::loop_all();
|
||||
EMSESP::console_.loop();
|
||||
delay(1000); // wait a second
|
||||
@@ -214,7 +212,7 @@ void System::wifi_reconnect() {
|
||||
|
||||
// format the FS. Wipes everything.
|
||||
void System::format(uuid::console::Shell & shell) {
|
||||
auto msg = F("Formatting file system. This will reset all settings to their defaults");
|
||||
auto msg = ("Formatting file system. This will reset all settings to their defaults");
|
||||
shell.logger().warning(msg);
|
||||
shell.flush();
|
||||
|
||||
@@ -243,7 +241,7 @@ void System::syslog_init() {
|
||||
// start & configure syslog
|
||||
if (!was_enabled) {
|
||||
syslog_.start();
|
||||
EMSESP::logger().info(F("Starting Syslog"));
|
||||
EMSESP::logger().info("Starting Syslog");
|
||||
}
|
||||
syslog_.log_level((uuid::log::Level)syslog_level_);
|
||||
syslog_.mark_interval(syslog_mark_interval_);
|
||||
@@ -252,12 +250,12 @@ void System::syslog_init() {
|
||||
|
||||
// register the command
|
||||
// TODO translate this
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(syslog), System::command_syslog_level, F("change the syslog level"), CommandFlag::ADMIN_ONLY);
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(syslog), System::command_syslog_level, ("change the syslog level"), CommandFlag::ADMIN_ONLY);
|
||||
|
||||
} else if (was_enabled) {
|
||||
// in case service is still running, this flushes the queue
|
||||
// https://github.com/emsesp/EMS-ESP/issues/496
|
||||
EMSESP::logger().info(F("Stopping Syslog"));
|
||||
EMSESP::logger().info("Stopping Syslog");
|
||||
syslog_.log_level((uuid::log::Level)-1);
|
||||
syslog_.mark_interval(0);
|
||||
syslog_.destination("");
|
||||
@@ -265,23 +263,21 @@ void System::syslog_init() {
|
||||
|
||||
if (Mqtt::publish_single()) {
|
||||
if (Mqtt::publish_single2cmd()) {
|
||||
Mqtt::publish(F("system/syslog"), syslog_enabled_ ? read_flash_string(FL_(list_syslog_level)[syslog_level_ + 1]).c_str() : "off");
|
||||
Mqtt::publish("system/syslog", syslog_enabled_ ? (FL_(list_syslog_level)[syslog_level_ + 1]) : "off");
|
||||
if (EMSESP::watch_id() == 0 || EMSESP::watch() == 0) {
|
||||
Mqtt::publish(F("system/watch"),
|
||||
EMSESP::system_.enum_format() == ENUM_FORMAT_INDEX ? Helpers::itoa(EMSESP::watch())
|
||||
: read_flash_string(FL_(list_watch)[EMSESP::watch()]).c_str());
|
||||
Mqtt::publish("system/watch",
|
||||
EMSESP::system_.enum_format() == ENUM_FORMAT_INDEX ? Helpers::itoa(EMSESP::watch()) : (FL_(list_watch)[EMSESP::watch()]));
|
||||
} else {
|
||||
Mqtt::publish(F("system/watch"), Helpers::hextoa(EMSESP::watch_id()));
|
||||
Mqtt::publish("system/watch", Helpers::hextoa(EMSESP::watch_id()));
|
||||
}
|
||||
|
||||
} else {
|
||||
Mqtt::publish(F("system_data/syslog"), syslog_enabled_ ? read_flash_string(FL_(list_syslog_level)[syslog_level_ + 1]).c_str() : "off");
|
||||
Mqtt::publish("system_data/syslog", syslog_enabled_ ? (FL_(list_syslog_level)[syslog_level_ + 1]) : "off");
|
||||
if (EMSESP::watch_id() == 0 || EMSESP::watch() == 0) {
|
||||
Mqtt::publish(F("system_data/watch"),
|
||||
EMSESP::system_.enum_format() == ENUM_FORMAT_INDEX ? Helpers::itoa(EMSESP::watch())
|
||||
: read_flash_string(FL_(list_watch)[EMSESP::watch()]).c_str());
|
||||
Mqtt::publish("system_data/watch",
|
||||
EMSESP::system_.enum_format() == ENUM_FORMAT_INDEX ? Helpers::itoa(EMSESP::watch()) : (FL_(list_watch)[EMSESP::watch()]));
|
||||
} else {
|
||||
Mqtt::publish(F("system_data/watch"), Helpers::hextoa(EMSESP::watch_id()));
|
||||
Mqtt::publish("system_data/watch", Helpers::hextoa(EMSESP::watch_id()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -348,7 +344,7 @@ void System::wifi_tweak() {
|
||||
WiFi.setSleep(false); // turn off sleep - WIFI_PS_NONE
|
||||
bool s2 = WiFi.getSleep();
|
||||
#if defined(EMSESP_DEBUG)
|
||||
LOG_DEBUG(F("[DEBUG] Adjusting WiFi - Tx power %d->%d, Sleep %d->%d"), p1, p2, s1, s2);
|
||||
LOG_DEBUG("[DEBUG] Adjusting WiFi - Tx power %d->%d, Sleep %d->%d", p1, p2, s1, s2);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
@@ -403,7 +399,7 @@ void System::start() {
|
||||
|
||||
// button single click
|
||||
void System::button_OnClick(PButton & b) {
|
||||
LOG_DEBUG(F("Button pressed - single click"));
|
||||
LOG_DEBUG("Button pressed - single click");
|
||||
|
||||
#ifdef EMSESP_DEBUG
|
||||
#ifndef EMSESP_STANDALONE
|
||||
@@ -414,20 +410,20 @@ void System::button_OnClick(PButton & b) {
|
||||
|
||||
// button double click
|
||||
void System::button_OnDblClick(PButton & b) {
|
||||
LOG_DEBUG(F("Button pressed - double click - reconnect"));
|
||||
LOG_DEBUG("Button pressed - double click - reconnect");
|
||||
EMSESP::system_.wifi_reconnect();
|
||||
}
|
||||
|
||||
// button long press
|
||||
void System::button_OnLongPress(PButton & b) {
|
||||
LOG_DEBUG(F("Button pressed - long press"));
|
||||
LOG_DEBUG("Button pressed - long press");
|
||||
}
|
||||
|
||||
// button indefinite press
|
||||
void System::button_OnVLongPress(PButton & b) {
|
||||
LOG_DEBUG(F("Button pressed - very long press"));
|
||||
LOG_DEBUG("Button pressed - very long press");
|
||||
#ifndef EMSESP_STANDALONE
|
||||
LOG_WARNING(F("Performing factory reset..."));
|
||||
LOG_WARNING("Performing factory reset...");
|
||||
EMSESP::console_.loop();
|
||||
EMSESP::esp8266React.factoryReset();
|
||||
#endif
|
||||
@@ -441,12 +437,12 @@ void System::button_init(bool refresh) {
|
||||
|
||||
if (is_valid_gpio(pbutton_gpio_)) {
|
||||
if (!myPButton_.init(pbutton_gpio_, HIGH)) {
|
||||
LOG_DEBUG(F("Multi-functional button not detected"));
|
||||
LOG_DEBUG("Multi-functional button not detected");
|
||||
} else {
|
||||
LOG_DEBUG(F("Multi-functional button enabled"));
|
||||
LOG_DEBUG("Multi-functional button enabled");
|
||||
}
|
||||
} else {
|
||||
LOG_WARNING(F("Invalid button GPIO. Check config."));
|
||||
LOG_WARNING("Invalid button GPIO. Check config.");
|
||||
}
|
||||
|
||||
myPButton_.onClick(BUTTON_Debounce, button_OnClick);
|
||||
@@ -528,11 +524,11 @@ void System::loop() {
|
||||
bool System::heartbeat_json(JsonObject & output) {
|
||||
uint8_t bus_status = EMSESP::bus_status();
|
||||
if (bus_status == EMSESP::BUS_STATUS_TX_ERRORS) {
|
||||
output["bus_status"] = FJSON("txerror");
|
||||
output["bus_status"] = "txerror";
|
||||
} else if (bus_status == EMSESP::BUS_STATUS_CONNECTED) {
|
||||
output["bus_status"] = FJSON("connected");
|
||||
output["bus_status"] = "connected";
|
||||
} else {
|
||||
output["bus_status"] = FJSON("disconnected");
|
||||
output["bus_status"] = "disconnected";
|
||||
}
|
||||
|
||||
output["uptime"] = uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3);
|
||||
@@ -668,25 +664,25 @@ void System::system_check() {
|
||||
|
||||
// commands - takes static function pointers
|
||||
void System::commands_init() {
|
||||
// TODO these should be translated too
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(send), System::command_send, F("send a telegram"), CommandFlag::ADMIN_ONLY);
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(fetch), System::command_fetch, F("refresh all EMS values"), CommandFlag::ADMIN_ONLY);
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(restart), System::command_restart, F("restart EMS-ESP"), CommandFlag::ADMIN_ONLY);
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(watch), System::command_watch, F("watch incoming telegrams"));
|
||||
// TODO translate this
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(send), System::command_send, ("send a telegram"), CommandFlag::ADMIN_ONLY);
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(fetch), System::command_fetch, ("refresh all EMS values"), CommandFlag::ADMIN_ONLY);
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(restart), System::command_restart, ("restart EMS-ESP"), CommandFlag::ADMIN_ONLY);
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(watch), System::command_watch, ("watch incoming telegrams"));
|
||||
|
||||
// register syslog command in syslog init
|
||||
// Command::add(EMSdevice::DeviceType::SYSTEM, F_(syslog), System::command_syslog_level, F("set syslog level"), CommandFlag::ADMIN_ONLY);
|
||||
// Command::add(EMSdevice::DeviceType::SYSTEM, F_(syslog), System::command_syslog_level, ("set syslog level"), CommandFlag::ADMIN_ONLY);
|
||||
|
||||
if (Mqtt::enabled()) {
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(publish), System::command_publish, F("force a MQTT publish"));
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(publish), System::command_publish, ("force a MQTT publish"));
|
||||
}
|
||||
|
||||
// these commands will return data in JSON format
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(info), System::command_info, F("show system status"));
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(commands), System::command_commands, F("fetch system commands"));
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(info), System::command_info, ("show system status"));
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(commands), System::command_commands, ("fetch system commands"));
|
||||
|
||||
#if defined(EMSESP_DEBUG)
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F("test"), System::command_test, F("run a specific test"));
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, ("test"), System::command_test, ("run a specific test"));
|
||||
#endif
|
||||
|
||||
// MQTT subscribe "ems-esp/system/#"
|
||||
@@ -776,12 +772,12 @@ int8_t System::wifi_quality(int8_t dBm) {
|
||||
|
||||
// print users to console
|
||||
void System::show_users(uuid::console::Shell & shell) {
|
||||
shell.printfln(F("Users:"));
|
||||
shell.printfln("Users:");
|
||||
|
||||
#ifndef EMSESP_STANDALONE
|
||||
EMSESP::esp8266React.getSecuritySettingsService()->read([&](SecuritySettings & securitySettings) {
|
||||
for (const User & user : securitySettings.users) {
|
||||
shell.printfln(F(" username: %s, password: %s, is_admin: %s"), user.username.c_str(), user.password.c_str(), user.admin ? F("yes") : F("no"));
|
||||
shell.printfln(" username: %s, password: %s, is_admin: %s", user.username.c_str(), user.password.c_str(), user.admin ? ("yes") : ("no"));
|
||||
}
|
||||
});
|
||||
#endif
|
||||
@@ -791,94 +787,94 @@ void System::show_users(uuid::console::Shell & shell) {
|
||||
|
||||
void System::show_system(uuid::console::Shell & shell) {
|
||||
shell.println("System:");
|
||||
shell.printfln(F(" Board profile: %s"), board_profile().c_str());
|
||||
shell.printfln(F(" Uptime: %s"), uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3).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
|
||||
shell.printfln(F(" SDK version: %s"), ESP.getSdkVersion());
|
||||
shell.printfln(F(" CPU frequency: %lu MHz"), ESP.getCpuFreqMHz());
|
||||
shell.printfln(F(" Free heap: %lu KB"), (uint32_t)ESP.getFreeHeap() / 1024);
|
||||
shell.printfln(F(" App used/free: %lu KB / %lu KB"), appUsed(), appFree());
|
||||
shell.printfln(" SDK version: %s", ESP.getSdkVersion());
|
||||
shell.printfln(" CPU frequency: %lu MHz", ESP.getCpuFreqMHz());
|
||||
shell.printfln(" Free heap: %lu KB", (uint32_t)ESP.getFreeHeap() / 1024);
|
||||
shell.printfln(" App used/free: %lu KB / %lu KB", appUsed(), appFree());
|
||||
uint32_t FSused = LittleFS.usedBytes() / 1024;
|
||||
shell.printfln(F(" FS used/free: %lu KB / %lu KB"), FSused, FStotal() - FSused);
|
||||
shell.printfln(" FS used/free: %lu KB / %lu KB", FSused, FStotal() - FSused);
|
||||
shell.println();
|
||||
|
||||
shell.println("Network:");
|
||||
switch (WiFi.status()) {
|
||||
case WL_IDLE_STATUS:
|
||||
shell.printfln(F(" Network: Idle"));
|
||||
shell.printfln(" Network: Idle");
|
||||
break;
|
||||
|
||||
case WL_NO_SSID_AVAIL:
|
||||
shell.printfln(F(" Network: Network not found"));
|
||||
shell.printfln(" Network: Network not found");
|
||||
break;
|
||||
|
||||
case WL_SCAN_COMPLETED:
|
||||
shell.printfln(F(" Network: Network scan complete"));
|
||||
shell.printfln(" Network: Network scan complete");
|
||||
break;
|
||||
|
||||
case WL_CONNECTED:
|
||||
shell.printfln(F(" Network: connected"));
|
||||
shell.printfln(F(" SSID: %s"), WiFi.SSID().c_str());
|
||||
shell.printfln(F(" BSSID: %s"), WiFi.BSSIDstr().c_str());
|
||||
shell.printfln(F(" RSSI: %d dBm (%d %%)"), WiFi.RSSI(), wifi_quality(WiFi.RSSI()));
|
||||
shell.printfln(F(" MAC address: %s"), WiFi.macAddress().c_str());
|
||||
shell.printfln(F(" Hostname: %s"), WiFi.getHostname());
|
||||
shell.printfln(F(" IPv4 address: %s/%s"), uuid::printable_to_string(WiFi.localIP()).c_str(), uuid::printable_to_string(WiFi.subnetMask()).c_str());
|
||||
shell.printfln(F(" IPv4 gateway: %s"), uuid::printable_to_string(WiFi.gatewayIP()).c_str());
|
||||
shell.printfln(F(" IPv4 nameserver: %s"), uuid::printable_to_string(WiFi.dnsIP()).c_str());
|
||||
shell.printfln(" Network: connected");
|
||||
shell.printfln(" SSID: %s", WiFi.SSID().c_str());
|
||||
shell.printfln(" BSSID: %s", WiFi.BSSIDstr().c_str());
|
||||
shell.printfln((" RSSI: %d dBm (%d %%)"), WiFi.RSSI(), wifi_quality(WiFi.RSSI()));
|
||||
shell.printfln(" MAC address: %s", WiFi.macAddress().c_str());
|
||||
shell.printfln(" Hostname: %s", WiFi.getHostname());
|
||||
shell.printfln(" IPv4 address: %s/%s", uuid::printable_to_string(WiFi.localIP()).c_str(), uuid::printable_to_string(WiFi.subnetMask()).c_str());
|
||||
shell.printfln(" IPv4 gateway: %s", uuid::printable_to_string(WiFi.gatewayIP()).c_str());
|
||||
shell.printfln(" IPv4 nameserver: %s", uuid::printable_to_string(WiFi.dnsIP()).c_str());
|
||||
if (WiFi.localIPv6().toString() != "0000:0000:0000:0000:0000:0000:0000:0000") {
|
||||
shell.printfln(F(" IPv6 address: %s"), uuid::printable_to_string(WiFi.localIPv6()).c_str());
|
||||
shell.printfln(" IPv6 address: %s", uuid::printable_to_string(WiFi.localIPv6()).c_str());
|
||||
}
|
||||
break;
|
||||
|
||||
case WL_CONNECT_FAILED:
|
||||
shell.printfln(F(" WiFi Network: Connection failed"));
|
||||
shell.printfln(" WiFi Network: Connection failed");
|
||||
break;
|
||||
|
||||
case WL_CONNECTION_LOST:
|
||||
shell.printfln(F(" WiFi Network: Connection lost"));
|
||||
shell.printfln(" WiFi Network: Connection lost");
|
||||
break;
|
||||
|
||||
case WL_DISCONNECTED:
|
||||
shell.printfln(F(" WiFi Network: Disconnected"));
|
||||
shell.printfln(" WiFi Network: Disconnected");
|
||||
break;
|
||||
|
||||
case WL_NO_SHIELD:
|
||||
default:
|
||||
shell.printfln(F(" WiFi Network: Unknown"));
|
||||
shell.printfln(" WiFi Network: Unknown");
|
||||
break;
|
||||
}
|
||||
|
||||
// show Ethernet if connected
|
||||
if (ethernet_connected_) {
|
||||
shell.println();
|
||||
shell.printfln(F(" Ethernet Network: connected"));
|
||||
shell.printfln(F(" MAC address: %s"), ETH.macAddress().c_str());
|
||||
shell.printfln(F(" Hostname: %s"), ETH.getHostname());
|
||||
shell.printfln(F(" IPv4 address: %s/%s"), uuid::printable_to_string(ETH.localIP()).c_str(), uuid::printable_to_string(ETH.subnetMask()).c_str());
|
||||
shell.printfln(F(" IPv4 gateway: %s"), uuid::printable_to_string(ETH.gatewayIP()).c_str());
|
||||
shell.printfln(F(" IPv4 nameserver: %s"), uuid::printable_to_string(ETH.dnsIP()).c_str());
|
||||
shell.printfln(" Ethernet Network: connected");
|
||||
shell.printfln(" MAC address: %s", ETH.macAddress().c_str());
|
||||
shell.printfln(" Hostname: %s", ETH.getHostname());
|
||||
shell.printfln(" IPv4 address: %s/%s", uuid::printable_to_string(ETH.localIP()).c_str(), uuid::printable_to_string(ETH.subnetMask()).c_str());
|
||||
shell.printfln(" IPv4 gateway: %s", uuid::printable_to_string(ETH.gatewayIP()).c_str());
|
||||
shell.printfln(" IPv4 nameserver: %s", uuid::printable_to_string(ETH.dnsIP()).c_str());
|
||||
if (ETH.localIPv6().toString() != "0000:0000:0000:0000:0000:0000:0000:0000") {
|
||||
shell.printfln(F(" IPv6 address: %s"), uuid::printable_to_string(ETH.localIPv6()).c_str());
|
||||
shell.printfln(" IPv6 address: %s", uuid::printable_to_string(ETH.localIPv6()).c_str());
|
||||
}
|
||||
}
|
||||
shell.println();
|
||||
|
||||
shell.println("Syslog:");
|
||||
if (!syslog_enabled_) {
|
||||
shell.printfln(F(" Syslog: disabled"));
|
||||
shell.printfln(" Syslog: disabled");
|
||||
} else {
|
||||
shell.printfln(F(" Syslog: %s"), syslog_.started() ? "started" : "stopped");
|
||||
shell.print(F(" "));
|
||||
shell.printfln(F_(host_fmt), !syslog_host_.isEmpty() ? syslog_host_.c_str() : read_flash_string(F_(unset)).c_str());
|
||||
shell.printfln(F(" IP: %s"), uuid::printable_to_string(syslog_.ip()).c_str());
|
||||
shell.print(F(" "));
|
||||
shell.printfln(" Syslog: %s", syslog_.started() ? "started" : "stopped");
|
||||
shell.print(" ");
|
||||
shell.printfln(F_(host_fmt), !syslog_host_.isEmpty() ? syslog_host_.c_str() : (F_(unset)));
|
||||
shell.printfln(" IP: %s", uuid::printable_to_string(syslog_.ip()).c_str());
|
||||
shell.print(" ");
|
||||
shell.printfln(F_(port_fmt), syslog_port_);
|
||||
shell.print(F(" "));
|
||||
shell.print(" ");
|
||||
shell.printfln(F_(log_level_fmt), uuid::log::format_level_lowercase(static_cast<uuid::log::Level>(syslog_level_)));
|
||||
shell.print(F(" "));
|
||||
shell.print(" ");
|
||||
shell.printfln(F_(mark_interval_fmt), syslog_mark_interval_);
|
||||
shell.printfln(F(" Queued: %d"), syslog_.queued());
|
||||
shell.printfln(" Queued: %d", syslog_.queued());
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -912,10 +908,10 @@ bool System::check_upgrade() {
|
||||
// it's a customization file, just replace it and there's no need to reboot
|
||||
saveSettings(EMSESP_CUSTOMIZATION_FILE, "Customizations", input);
|
||||
} else {
|
||||
LOG_ERROR(F("Unrecognized file uploaded"));
|
||||
LOG_ERROR("Unrecognized file uploaded");
|
||||
}
|
||||
} else {
|
||||
LOG_ERROR(F("Unrecognized file uploaded, not json"));
|
||||
LOG_ERROR("Unrecognized file uploaded, not json");
|
||||
}
|
||||
|
||||
// close (just in case) and remove the temp file
|
||||
@@ -958,7 +954,7 @@ bool System::saveSettings(const char * filename, const char * section, JsonObjec
|
||||
if (section_json) {
|
||||
File section_file = LittleFS.open(filename, "w");
|
||||
if (section_file) {
|
||||
LOG_INFO(F("Applying new %s settings"), section);
|
||||
LOG_INFO("Applying new %s settings", section);
|
||||
serializeJson(section_json, section_file);
|
||||
section_file.close();
|
||||
return true; // reboot required
|
||||
@@ -988,7 +984,7 @@ bool System::command_info(const char * value, const int8_t id, JsonObject & outp
|
||||
// Network Status
|
||||
node = output.createNestedObject("Network Status");
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
node["connection"] = F("WiFi");
|
||||
node["connection"] = ("WiFi");
|
||||
node["hostname"] = WiFi.getHostname();
|
||||
// node["SSID"] = WiFi.SSID();
|
||||
// node["BSSID"] = WiFi.BSSIDstr();
|
||||
@@ -1001,7 +997,7 @@ bool System::command_info(const char * value, const int8_t id, JsonObject & outp
|
||||
node["IPv6 address"] = uuid::printable_to_string(WiFi.localIPv6());
|
||||
}
|
||||
} else if (EMSESP::system_.ethernet_connected()) {
|
||||
node["connection"] = F("Ethernet");
|
||||
node["connection"] = ("Ethernet");
|
||||
node["hostname"] = ETH.getHostname();
|
||||
node["MAC"] = ETH.macAddress();
|
||||
node["IPv4 address"] = uuid::printable_to_string(ETH.localIP()) + "/" + uuid::printable_to_string(ETH.subnetMask());
|
||||
@@ -1115,20 +1111,20 @@ bool System::command_info(const char * value, const int8_t id, JsonObject & outp
|
||||
node = output.createNestedObject("Bus Status");
|
||||
switch (EMSESP::bus_status()) {
|
||||
case EMSESP::BUS_STATUS_OFFLINE:
|
||||
node["bus status"] = (F("disconnected"));
|
||||
node["bus status"] = ("disconnected");
|
||||
break;
|
||||
case EMSESP::BUS_STATUS_TX_ERRORS:
|
||||
node["bus status"] = (F("connected, tx issues - try a different Tx Mode"));
|
||||
node["bus status"] = ("connected, tx issues - try a different Tx Mode");
|
||||
break;
|
||||
case EMSESP::BUS_STATUS_CONNECTED:
|
||||
node["bus status"] = (F("connected"));
|
||||
node["bus status"] = ("connected");
|
||||
break;
|
||||
default:
|
||||
node["bus status"] = (F("unknown"));
|
||||
node["bus status"] = ("unknown");
|
||||
break;
|
||||
}
|
||||
if (EMSESP::bus_status() != EMSESP::BUS_STATUS_OFFLINE) {
|
||||
node["bus protocol"] = EMSbus::is_ht3() ? F("HT3") : F("Buderus");
|
||||
node["bus protocol"] = EMSbus::is_ht3() ? ("HT3") : ("Buderus");
|
||||
node["bus telegrams received (rx)"] = EMSESP::rxservice_.telegram_count();
|
||||
node["bus reads (tx)"] = EMSESP::txservice_.telegram_read_count();
|
||||
node["bus writes (tx)"] = EMSESP::txservice_.telegram_write_count();
|
||||
@@ -1174,9 +1170,8 @@ bool System::command_info(const char * value, const int8_t id, JsonObject & outp
|
||||
for (const auto & device_class : EMSFactory::device_handlers()) {
|
||||
for (const auto & emsdevice : EMSESP::emsdevices) {
|
||||
if (emsdevice && (emsdevice->device_type() == device_class.first)) {
|
||||
JsonObject obj = devices.createNestedObject();
|
||||
obj["type"] = emsdevice->device_type_name();
|
||||
// obj["name"] = emsdevice->to_string();
|
||||
JsonObject obj = devices.createNestedObject();
|
||||
obj["type"] = emsdevice->device_type_name();
|
||||
obj["name"] = emsdevice->name();
|
||||
obj["device id"] = Helpers::hextoa(emsdevice->device_id());
|
||||
obj["product id"] = emsdevice->product_id();
|
||||
@@ -1321,7 +1316,7 @@ std::string System::reset_reason(uint8_t cpu) const {
|
||||
// set NTP status
|
||||
void System::ntp_connected(bool b) {
|
||||
if (b != ntp_connected_) {
|
||||
LOG_INFO(b ? F("NTP connected") : F("NTP disconnected"));
|
||||
LOG_INFO(b ? ("NTP connected") : ("NTP disconnected"));
|
||||
}
|
||||
ntp_connected_ = b;
|
||||
ntp_last_check_ = b ? uuid::get_uptime_sec() : 0;
|
||||
|
||||
@@ -120,7 +120,7 @@ std::string Telegram::to_string() const {
|
||||
// returns telegram's message body only, in hex
|
||||
std::string Telegram::to_string_message() const {
|
||||
if (this->message_length == 0) {
|
||||
return read_flash_string(F("<empty>"));
|
||||
return ("<empty>");
|
||||
}
|
||||
|
||||
return Helpers::data_to_hex(this->message_data, this->message_length);
|
||||
@@ -150,9 +150,9 @@ void RxService::add(uint8_t * data, uint8_t length) {
|
||||
if (data[length - 1] != crc) {
|
||||
if ((data[0] & 0x7F) != ems_bus_id()) { // do not count echos as errors
|
||||
telegram_error_count_++;
|
||||
LOG_WARNING(F("Incomplete Rx: %s"), Helpers::data_to_hex(data, length - 1).c_str()); // exclude CRC
|
||||
LOG_WARNING("Incomplete Rx: %s", Helpers::data_to_hex(data, length - 1).c_str()); // exclude CRC
|
||||
} else {
|
||||
LOG_TRACE(F("Incomplete Rx: %s"), Helpers::data_to_hex(data, length - 1).c_str()); // exclude CRC
|
||||
LOG_TRACE("Incomplete Rx: %s", Helpers::data_to_hex(data, length - 1).c_str()); // exclude CRC
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -203,16 +203,16 @@ void RxService::add(uint8_t * data, uint8_t length) {
|
||||
uint16_t trace_watch_id = EMSESP::watch_id();
|
||||
if ((trace_watch_id == WATCH_ID_NONE) || (type_id == trace_watch_id)
|
||||
|| ((trace_watch_id < 0x80) && ((src == trace_watch_id) || (dest == trace_watch_id)))) {
|
||||
LOG_NOTICE(F("Rx: %s"), Helpers::data_to_hex(data, length).c_str());
|
||||
LOG_NOTICE("Rx: %s", Helpers::data_to_hex(data, length).c_str());
|
||||
} else if (EMSESP::trace_raw()) {
|
||||
LOG_TRACE(F("Rx: %s"), Helpers::data_to_hex(data, length).c_str());
|
||||
LOG_TRACE("Rx: %s", Helpers::data_to_hex(data, length).c_str());
|
||||
}
|
||||
} else if (EMSESP::trace_raw()) {
|
||||
LOG_TRACE(F("Rx: %s"), Helpers::data_to_hex(data, length).c_str());
|
||||
LOG_TRACE("Rx: %s", Helpers::data_to_hex(data, length).c_str());
|
||||
}
|
||||
|
||||
#ifdef EMSESP_DEBUG
|
||||
LOG_DEBUG(F("[DEBUG] New Rx telegram, message length %d"), message_length);
|
||||
LOG_DEBUG("[DEBUG] New Rx telegram, message length %d", message_length);
|
||||
#endif
|
||||
|
||||
// if we don't have a type_id exit,
|
||||
@@ -262,7 +262,7 @@ void TxService::start() {
|
||||
|
||||
// sends a 1 byte poll which is our own deviceID
|
||||
void TxService::send_poll() const {
|
||||
//LOG_DEBUG(F("Ack %02X"),ems_bus_id() ^ ems_mask());
|
||||
//LOG_DEBUG("Ack %02X",ems_bus_id() ^ ems_mask());
|
||||
if (tx_mode()) {
|
||||
EMSuart::send_poll(ems_bus_id() ^ ems_mask());
|
||||
}
|
||||
@@ -363,13 +363,13 @@ void TxService::send_telegram(const QueuedTxTelegram & tx_telegram) {
|
||||
|
||||
// if we're in simulation mode, don't send anything, just quit
|
||||
if (EMSESP::system_.readonly_mode() && (telegram->operation == Telegram::Operation::TX_WRITE)) {
|
||||
LOG_INFO(F("[readonly] Sending write Tx telegram: %s"), Helpers::data_to_hex(telegram_raw, length - 1).c_str());
|
||||
LOG_INFO("[readonly] Sending write Tx telegram: %s", Helpers::data_to_hex(telegram_raw, length - 1).c_str());
|
||||
tx_state(Telegram::Operation::NONE);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_DEBUG(F("Sending %s Tx [#%d], telegram: %s"),
|
||||
(telegram->operation == Telegram::Operation::TX_WRITE) ? F("write") : F("read"),
|
||||
LOG_DEBUG("Sending %s Tx [#%d], telegram: %s",
|
||||
(telegram->operation == Telegram::Operation::TX_WRITE) ? ("write") : ("read"),
|
||||
tx_telegram.id_,
|
||||
Helpers::data_to_hex(telegram_raw, length - 1).c_str()); // exclude the last CRC byte
|
||||
|
||||
@@ -381,7 +381,7 @@ void TxService::send_telegram(const QueuedTxTelegram & tx_telegram) {
|
||||
uint16_t status = EMSuart::transmit(telegram_raw, length);
|
||||
|
||||
if (status == EMS_TX_STATUS_ERR) {
|
||||
LOG_ERROR(F("Failed to transmit Tx via UART."));
|
||||
LOG_ERROR("Failed to transmit Tx via UART.");
|
||||
if (telegram->operation == Telegram::Operation::TX_READ) {
|
||||
increment_telegram_read_fail_count(); // another Tx fail
|
||||
} else {
|
||||
@@ -412,7 +412,7 @@ void TxService::send_telegram(const uint8_t * data, const uint8_t length) {
|
||||
uint16_t status = EMSuart::transmit(telegram_raw, length);
|
||||
|
||||
if (status == EMS_TX_STATUS_ERR) {
|
||||
LOG_ERROR(F("Failed to transmit Tx via UART."));
|
||||
LOG_ERROR("Failed to transmit Tx via UART.");
|
||||
increment_telegram_fail_count(); // another Tx fail
|
||||
}
|
||||
}
|
||||
@@ -429,10 +429,10 @@ void TxService::add(const uint8_t operation,
|
||||
auto telegram = std::make_shared<Telegram>(operation, ems_bus_id(), dest, type_id, offset, message_data, message_length);
|
||||
|
||||
#ifdef EMSESP_DEBUG
|
||||
LOG_DEBUG(F("[DEBUG] New Tx [#%d] telegram, length %d"), tx_telegram_id_, message_length);
|
||||
LOG_DEBUG("[DEBUG] New Tx [#%d] telegram, length %d", tx_telegram_id_, message_length);
|
||||
#endif
|
||||
|
||||
// if the queue is full, make room but removing the last one
|
||||
// if the queue is full, make room by removing the last one
|
||||
if (tx_telegrams_.size() >= MAX_TX_TELEGRAMS) {
|
||||
if (tx_telegrams_.front().telegram_->operation == Telegram::Operation::TX_WRITE) {
|
||||
telegram_write_fail_count_++;
|
||||
@@ -493,7 +493,7 @@ void TxService::add(uint8_t operation, const uint8_t * data, const uint8_t lengt
|
||||
// if we don't have a type_id or empty data block, exit
|
||||
if ((type_id == 0) || (message_length == 0)) {
|
||||
#ifdef EMSESP_DEBUG
|
||||
LOG_DEBUG(F("[DEBUG] Tx telegram type %d failed, length %d"), type_id, message_length);
|
||||
LOG_DEBUG("[DEBUG] Tx telegram type %d failed, length %d", type_id, message_length);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
@@ -510,7 +510,7 @@ void TxService::add(uint8_t operation, const uint8_t * data, const uint8_t lengt
|
||||
|
||||
auto telegram = std::make_shared<Telegram>(operation, src, dest, type_id, offset, message_data, message_length); // operation is TX_WRITE or TX_READ
|
||||
|
||||
// if the queue is full, make room but removing the last one
|
||||
// if the queue is full, make room by removing the last one
|
||||
if (tx_telegrams_.size() >= MAX_TX_TELEGRAMS) {
|
||||
if (tx_telegrams_.front().telegram_->operation == Telegram::Operation::TX_WRITE) {
|
||||
telegram_write_fail_count_++;
|
||||
@@ -521,7 +521,7 @@ void TxService::add(uint8_t operation, const uint8_t * data, const uint8_t lengt
|
||||
}
|
||||
|
||||
#ifdef EMSESP_DEBUG
|
||||
LOG_DEBUG(F("[DEBUG] New Tx [#%d] telegram, length %d"), tx_telegram_id_, message_length);
|
||||
LOG_DEBUG("[DEBUG] New Tx [#%d] telegram, length %d", tx_telegram_id_, message_length);
|
||||
#endif
|
||||
|
||||
if (front) {
|
||||
@@ -538,7 +538,7 @@ void TxService::add(uint8_t operation, const uint8_t * data, const uint8_t lengt
|
||||
|
||||
// send a Tx telegram to request data from an EMS device
|
||||
void TxService::read_request(const uint16_t type_id, const uint8_t dest, const uint8_t offset, const uint8_t length) {
|
||||
LOG_DEBUG(F("Tx read request to device 0x%02X for type ID 0x%02X"), dest, type_id);
|
||||
LOG_DEBUG("Tx read request to device 0x%02X for type ID 0x%02X", dest, type_id);
|
||||
|
||||
uint8_t message_data = (type_id > 0xFF) ? (EMS_MAX_TELEGRAM_MESSAGE_LENGTH - 2) : EMS_MAX_TELEGRAM_MESSAGE_LENGTH;
|
||||
// if length set, publish result and set telegram to front
|
||||
@@ -603,7 +603,7 @@ void TxService::retry_tx(const uint8_t operation, const uint8_t * data, const ui
|
||||
EMSESP::wait_validate(0); // do not wait for validation
|
||||
if (operation == Telegram::Operation::TX_READ) {
|
||||
if (telegram_last_->offset > 0) { // ignore errors for higher offsets
|
||||
LOG_DEBUG(F("Last Tx Read operation failed after %d retries. Ignoring request: %s"), MAXIMUM_TX_RETRIES, telegram_last_->to_string().c_str());
|
||||
LOG_DEBUG("Last Tx Read operation failed after %d retries. Ignoring request: %s", MAXIMUM_TX_RETRIES, telegram_last_->to_string().c_str());
|
||||
return;
|
||||
}
|
||||
increment_telegram_read_fail_count(); // another Tx fail
|
||||
@@ -611,8 +611,8 @@ void TxService::retry_tx(const uint8_t operation, const uint8_t * data, const ui
|
||||
increment_telegram_write_fail_count(); // another Tx fail
|
||||
}
|
||||
|
||||
LOG_ERROR(F("Last Tx %s operation failed after %d retries. Ignoring request: %s"),
|
||||
(operation == Telegram::Operation::TX_WRITE) ? F("Write") : F("Read"),
|
||||
LOG_ERROR("Last Tx %s operation failed after %d retries. Ignoring request: %s",
|
||||
(operation == Telegram::Operation::TX_WRITE) ? ("Write") : ("Read"),
|
||||
MAXIMUM_TX_RETRIES,
|
||||
telegram_last_->to_string().c_str());
|
||||
|
||||
@@ -623,8 +623,8 @@ void TxService::retry_tx(const uint8_t operation, const uint8_t * data, const ui
|
||||
}
|
||||
|
||||
#ifdef EMSESP_DEBUG
|
||||
LOG_DEBUG(F("[DEBUG] Last Tx %s operation failed. Retry #%d. sent message: %s, received: %s"),
|
||||
(operation == Telegram::Operation::TX_WRITE) ? F("Write") : F("Read"),
|
||||
LOG_DEBUG("[DEBUG] Last Tx %s operation failed. Retry #%d. sent message: %s, received: %s",
|
||||
(operation == Telegram::Operation::TX_WRITE) ? ("Write") : ("Read"),
|
||||
retry_count_,
|
||||
telegram_last_->to_string().c_str(),
|
||||
Helpers::data_to_hex(data, length - 1).c_str());
|
||||
@@ -675,7 +675,7 @@ uint16_t TxService::post_send_query() {
|
||||
(this->telegram_last_->type_id > 0xFF) ? (EMS_MAX_TELEGRAM_MESSAGE_LENGTH - 2) : EMS_MAX_TELEGRAM_MESSAGE_LENGTH; // request all data, 32 bytes
|
||||
this->add(Telegram::Operation::TX_READ, dest, post_typeid, offset, &message_data, 1, 0, true); // add to top/front of queue
|
||||
// read_request(telegram_last_post_send_query_, dest, 0); // no offset
|
||||
LOG_DEBUG(F("Sending post validate read, type ID 0x%02X to dest 0x%02X"), post_typeid, dest);
|
||||
LOG_DEBUG("Sending post validate read, type ID 0x%02X to dest 0x%02X", post_typeid, dest);
|
||||
set_post_send_query(0); // reset
|
||||
// delay the request if we have a different type_id for post_send_query
|
||||
delayed_send_ = (this->telegram_last_->type_id == post_typeid) ? 0 : (uuid::get_uptime() + POST_SEND_DELAY);
|
||||
|
||||
@@ -30,7 +30,7 @@ bool Test::run_test(const char * command, int8_t id) {
|
||||
}
|
||||
|
||||
if (strcmp(command, "general") == 0) {
|
||||
EMSESP::logger().info(F("Testing general. Adding a Boiler and Thermostat"));
|
||||
EMSESP::logger().info("Testing general. Adding a Boiler and Thermostat");
|
||||
|
||||
add_device(0x08, 123); // Nefit Trendline
|
||||
add_device(0x18, 157); // Bosch CR100
|
||||
@@ -54,7 +54,7 @@ bool Test::run_test(const char * command, int8_t id) {
|
||||
}
|
||||
|
||||
if (strcmp(command, "2thermostats") == 0) {
|
||||
EMSESP::logger().info(F("Testing with multiple thermostats..."));
|
||||
EMSESP::logger().info("Testing with multiple thermostats...");
|
||||
|
||||
add_device(0x08, 123); // GB072
|
||||
add_device(0x10, 158); // RC310
|
||||
@@ -86,7 +86,7 @@ bool Test::run_test(const char * command, int8_t id) {
|
||||
}
|
||||
|
||||
if (strcmp(command, "310") == 0) {
|
||||
EMSESP::logger().info(F("Adding a GB072/RC310 combo..."));
|
||||
EMSESP::logger().info("Adding a GB072/RC310 combo...");
|
||||
|
||||
add_device(0x08, 123); // GB072
|
||||
add_device(0x10, 158); // RC310
|
||||
@@ -113,7 +113,7 @@ bool Test::run_test(const char * command, int8_t id) {
|
||||
}
|
||||
|
||||
if (strcmp(command, "gateway") == 0) {
|
||||
EMSESP::logger().info(F("Adding a Gateway..."));
|
||||
EMSESP::logger().info("Adding a Gateway...");
|
||||
|
||||
// add 0x48 KM200, via a version command
|
||||
rx_telegram({0x48, 0x0B, 0x02, 0x00, 0xBD, 0x04, 0x06, 00, 00, 00, 00, 00, 00, 00});
|
||||
@@ -133,7 +133,7 @@ bool Test::run_test(const char * command, int8_t id) {
|
||||
}
|
||||
|
||||
if (strcmp(command, "mixer") == 0) {
|
||||
EMSESP::logger().info(F("Adding a mixer..."));
|
||||
EMSESP::logger().info("Adding a mixer...");
|
||||
|
||||
// add controller
|
||||
add_device(0x09, 114);
|
||||
@@ -155,7 +155,7 @@ bool Test::run_test(const char * command, int8_t id) {
|
||||
}
|
||||
|
||||
if (strcmp(command, "boiler") == 0) {
|
||||
EMSESP::logger().info(F("Adding boiler..."));
|
||||
EMSESP::logger().info("Adding boiler...");
|
||||
add_device(0x08, 123); // Nefit Trendline
|
||||
|
||||
// UBAuptime
|
||||
@@ -172,7 +172,7 @@ bool Test::run_test(const char * command, int8_t id) {
|
||||
}
|
||||
|
||||
if (strcmp(command, "thermostat") == 0) {
|
||||
EMSESP::logger().info(F("Adding thermostat..."));
|
||||
EMSESP::logger().info("Adding thermostat...");
|
||||
|
||||
add_device(0x10, 192); // FW120
|
||||
|
||||
@@ -185,7 +185,7 @@ bool Test::run_test(const char * command, int8_t id) {
|
||||
}
|
||||
|
||||
if (strcmp(command, "solar") == 0) {
|
||||
EMSESP::logger().info(F("Adding solar..."));
|
||||
EMSESP::logger().info("Adding solar...");
|
||||
|
||||
add_device(0x30, 163); // SM100
|
||||
|
||||
@@ -204,7 +204,7 @@ bool Test::run_test(const char * command, int8_t id) {
|
||||
}
|
||||
|
||||
if (strcmp(command, "heatpump") == 0) {
|
||||
EMSESP::logger().info(F("Adding heatpump..."));
|
||||
EMSESP::logger().info("Adding heatpump...");
|
||||
|
||||
add_device(0x38, 200); // Enviline module
|
||||
add_device(0x10, 192); // FW120 thermostat
|
||||
@@ -238,7 +238,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "general") {
|
||||
shell.printfln(F("Testing adding a general boiler & thermostat..."));
|
||||
shell.printfln("Testing adding a general boiler & thermostat...");
|
||||
run_test("general");
|
||||
shell.invoke_command("show devices");
|
||||
shell.invoke_command("show");
|
||||
@@ -247,7 +247,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "render") {
|
||||
shell.printfln(F("Testing render..."));
|
||||
shell.printfln("Testing render...");
|
||||
|
||||
// check read_value to make sure it handles all the data type correctly
|
||||
uint8_t message_data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; // message_length is 9
|
||||
@@ -315,7 +315,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "devices") {
|
||||
shell.printfln(F("Testing devices..."));
|
||||
shell.printfln("Testing devices...");
|
||||
|
||||
// A fake response - UBADevices(0x07)
|
||||
rx_telegram({0x08, 0x00, 0x07, 0x00, 0x0B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
|
||||
@@ -323,7 +323,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
|
||||
// check for boiler and controller on same product_id
|
||||
if (command == "double") {
|
||||
shell.printfln(F("Testing double..."));
|
||||
shell.printfln("Testing double...");
|
||||
|
||||
add_device(0x08, 206); // Nefit Excellent HR30
|
||||
add_device(0x09, 206); // Nefit Excellent HR30 Controller
|
||||
@@ -333,7 +333,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "620") {
|
||||
EMSESP::logger().info(F("Testing 620..."));
|
||||
EMSESP::logger().info("Testing 620...");
|
||||
|
||||
// Version Controller
|
||||
uart_telegram({0x09, 0x0B, 0x02, 0x00, 0x5F, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
|
||||
@@ -344,7 +344,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
|
||||
// unknown device
|
||||
if (command == "unknown") {
|
||||
shell.printfln(F("Testing unknown..."));
|
||||
shell.printfln("Testing unknown...");
|
||||
|
||||
// add boiler
|
||||
add_device(0x08, 84);
|
||||
@@ -361,19 +361,19 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "unknown2") {
|
||||
shell.printfln(F("Testing unknown2..."));
|
||||
shell.printfln("Testing unknown2...");
|
||||
|
||||
// simulate getting version information back from an unknown device
|
||||
rx_telegram({0x09, 0x0B, 0x02, 0x00, 0x5A, 0x01, 0x02}); // productID is 90 which doesn't exist
|
||||
}
|
||||
|
||||
if (command == "gateway") {
|
||||
shell.printfln(F("Testing Gateway..."));
|
||||
shell.printfln("Testing Gateway...");
|
||||
run_test("gateway");
|
||||
}
|
||||
|
||||
if (command == "310") {
|
||||
shell.printfln(F("Testing RC310..."));
|
||||
shell.printfln("Testing RC310...");
|
||||
run_test("310");
|
||||
shell.invoke_command("show devices");
|
||||
shell.invoke_command("show");
|
||||
@@ -382,14 +382,14 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "2thermostats") {
|
||||
shell.printfln(F("Testing multiple thermostats..."));
|
||||
shell.printfln("Testing multiple thermostats...");
|
||||
run_test("2thermostats");
|
||||
shell.invoke_command("show");
|
||||
shell.invoke_command("show devices");
|
||||
}
|
||||
|
||||
if (command == "web") {
|
||||
shell.printfln(F("Testing Web..."));
|
||||
shell.printfln("Testing Web...");
|
||||
|
||||
Mqtt::enabled(false); // turn off mqtt
|
||||
Mqtt::ha_enabled(false); // turn off ha
|
||||
@@ -438,7 +438,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "board_profile") {
|
||||
shell.printfln(F("Testing board profile..."));
|
||||
shell.printfln("Testing board profile...");
|
||||
|
||||
shell.invoke_command("system");
|
||||
shell.invoke_command("set board_profile wemos");
|
||||
@@ -447,7 +447,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "boiler") {
|
||||
shell.printfln(F("Testing boiler..."));
|
||||
shell.printfln("Testing boiler...");
|
||||
// Mqtt::ha_enabled(false);
|
||||
Mqtt::ha_enabled(true);
|
||||
Mqtt::nested_format(1);
|
||||
@@ -475,7 +475,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "shower_alert") {
|
||||
shell.printfln(F("Testing Shower Alert..."));
|
||||
shell.printfln("Testing Shower Alert...");
|
||||
|
||||
run_test("boiler");
|
||||
|
||||
@@ -484,7 +484,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "fr120") {
|
||||
shell.printfln(F("Testing adding a thermostat FR120..."));
|
||||
shell.printfln("Testing adding a thermostat FR120...");
|
||||
|
||||
add_device(0x10, 191); // FR120 thermostat
|
||||
|
||||
@@ -496,7 +496,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "ha") {
|
||||
shell.printfln(F("Testing HA mqtt discovery"));
|
||||
shell.printfln("Testing HA mqtt discovery");
|
||||
Mqtt::ha_enabled(true);
|
||||
// Mqtt::ha_enabled(false);
|
||||
|
||||
@@ -518,7 +518,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "lastcode") {
|
||||
shell.printfln(F("Testing lastcode"));
|
||||
shell.printfln("Testing lastcode");
|
||||
|
||||
Mqtt::ha_enabled(false);
|
||||
Mqtt::nested_format(1);
|
||||
@@ -536,7 +536,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "dv") {
|
||||
shell.printfln(F("Testing device value rendering"));
|
||||
shell.printfln("Testing device value rendering");
|
||||
|
||||
Mqtt::ha_enabled(true);
|
||||
Mqtt::nested_format(1);
|
||||
@@ -550,12 +550,12 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "dallas") {
|
||||
shell.printfln(F("Testing adding Dallas sensor"));
|
||||
shell.printfln("Testing adding Dallas sensor");
|
||||
emsesp::EMSESP::dallassensor_.test();
|
||||
}
|
||||
|
||||
if (command == "dallas_full") {
|
||||
shell.printfln(F("Testing adding and changing Dallas sensor"));
|
||||
shell.printfln("Testing adding and changing Dallas sensor");
|
||||
Mqtt::ha_enabled(true);
|
||||
Mqtt::nested_format(1);
|
||||
// Mqtt::nested_format(0);
|
||||
@@ -571,7 +571,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "analog") {
|
||||
shell.printfln(F("Testing adding Analog sensor"));
|
||||
shell.printfln("Testing adding Analog sensor");
|
||||
Mqtt::ha_enabled(true);
|
||||
// Mqtt::ha_enabled(false);
|
||||
Mqtt::nested_format(1);
|
||||
@@ -597,12 +597,42 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
|
||||
// n=1 = EMSESP::system_.HEALTHCHECK_NO_BUS
|
||||
// n=2 = EMSESP::system_.HEALTHCHECK_NO_NETWORK
|
||||
shell.printfln(F("Testing healthcheck with %d"), n);
|
||||
shell.printfln("Testing healthcheck with %d", n);
|
||||
EMSESP::system_.healthcheck(n);
|
||||
}
|
||||
|
||||
if (command == "custom") {
|
||||
shell.printfln(F("Testing custom entities"));
|
||||
|
||||
Mqtt::ha_enabled(true);
|
||||
Mqtt::send_response(false);
|
||||
|
||||
run_test("thermostat");
|
||||
|
||||
// shell.invoke_command("call thermostat seltemp");
|
||||
// shell.invoke_command("call system publish");
|
||||
|
||||
// toggle mode
|
||||
for (const auto & emsdevice : EMSESP::emsdevices) {
|
||||
Serial.print("Custom: ");
|
||||
Serial.print(emsdevice->device_type_name().c_str());
|
||||
Serial.print(" uniqueid=");
|
||||
Serial.println(emsdevice->unique_id());
|
||||
|
||||
if (emsdevice->unique_id() == 1) { // thermostat
|
||||
std::string a = "00hc1/seltemp|new name>5<52";
|
||||
emsdevice->setCustomEntity(a);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
shell.invoke_command("call thermostat seltemp");
|
||||
shell.invoke_command("call system publish");
|
||||
}
|
||||
|
||||
|
||||
if (command == "masked") {
|
||||
shell.printfln(F("Testing masked entities"));
|
||||
shell.printfln("Testing masked entities");
|
||||
|
||||
Mqtt::ha_enabled(true);
|
||||
Mqtt::send_response(false);
|
||||
@@ -626,7 +656,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "dv2") {
|
||||
shell.printfln(F("Testing device value lost"));
|
||||
shell.printfln("Testing device value lost");
|
||||
|
||||
Mqtt::ha_enabled(true);
|
||||
Mqtt::send_response(false);
|
||||
@@ -647,7 +677,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
|
||||
if (command == "api_values") {
|
||||
#if defined(EMSESP_STANDALONE)
|
||||
shell.printfln(F("Testing API getting values"));
|
||||
shell.printfln("Testing API getting values");
|
||||
Mqtt::ha_enabled(false);
|
||||
Mqtt::nested_format(1);
|
||||
Mqtt::send_response(false);
|
||||
@@ -680,7 +710,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "mqtt_post") {
|
||||
shell.printfln(F("Testing MQTT incoming changes"));
|
||||
shell.printfln("Testing MQTT incoming changes");
|
||||
Mqtt::ha_enabled(false);
|
||||
Mqtt::nested_format(1);
|
||||
Mqtt::send_response(false);
|
||||
@@ -696,7 +726,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
#if defined(EMSESP_STANDALONE)
|
||||
// https://github.com/emsesp/EMS-ESP32/issues/541
|
||||
if (command == "api_wwmode") {
|
||||
shell.printfln(F("Testing API wwmode"));
|
||||
shell.printfln("Testing API wwmode");
|
||||
Mqtt::ha_enabled(false);
|
||||
Mqtt::nested_format(1);
|
||||
run_test("310");
|
||||
@@ -715,7 +745,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
#endif
|
||||
|
||||
if (command == "api") {
|
||||
shell.printfln(F("Testing API with MQTT and REST, standalone"));
|
||||
shell.printfln("Testing API with MQTT and REST, standalone");
|
||||
|
||||
Mqtt::ha_enabled(true);
|
||||
// Mqtt::ha_enabled(false);
|
||||
@@ -990,7 +1020,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "mqtt_nested") {
|
||||
shell.printfln(F("Testing nested MQTT"));
|
||||
shell.printfln("Testing nested MQTT");
|
||||
Mqtt::ha_enabled(false); // turn off HA Discovery to stop the chatter
|
||||
|
||||
run_test("boiler");
|
||||
@@ -1010,7 +1040,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "thermostat") {
|
||||
shell.printfln(F("Testing adding a thermostat FW120..."));
|
||||
shell.printfln("Testing adding a thermostat FW120...");
|
||||
|
||||
run_test("thermostat");
|
||||
shell.invoke_command("show");
|
||||
@@ -1026,7 +1056,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "tc100") {
|
||||
shell.printfln(F("Testing adding a TC100 thermostat to the EMS bus..."));
|
||||
shell.printfln("Testing adding a TC100 thermostat to the EMS bus...");
|
||||
|
||||
// add a thermostat
|
||||
add_device(0x18, 202); // Bosch TC100 - https://github.com/emsesp/EMS-ESP/issues/474
|
||||
@@ -1037,7 +1067,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "solar") {
|
||||
shell.printfln(F("Testing Solar"));
|
||||
shell.printfln("Testing Solar");
|
||||
run_test("solar");
|
||||
|
||||
uart_telegram("30 00 FF 0A 02 6A 04"); // SM100 pump on (1)sh
|
||||
@@ -1050,14 +1080,14 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "heatpump") {
|
||||
shell.printfln(F("Testing Heat Pump"));
|
||||
shell.printfln("Testing Heat Pump");
|
||||
run_test("heatpump");
|
||||
shell.invoke_command("call");
|
||||
shell.invoke_command("call heatpump info");
|
||||
}
|
||||
|
||||
if (command == "solar200") {
|
||||
shell.printfln(F("Testing Solar SM200"));
|
||||
shell.printfln("Testing Solar SM200");
|
||||
|
||||
add_device(0x30, 164); // SM200
|
||||
|
||||
@@ -1082,7 +1112,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "km") {
|
||||
shell.printfln(F("Testing KM200 Gateway"));
|
||||
shell.printfln("Testing KM200 Gateway");
|
||||
|
||||
add_device(0x10, 158); // RC300
|
||||
add_device(0x48, 189); // KM200
|
||||
@@ -1140,7 +1170,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "cr100") {
|
||||
shell.printfln(F("Testing CR100"));
|
||||
shell.printfln("Testing CR100");
|
||||
|
||||
add_device(0x18, 157); // Bosch CR100 - https://github.com/emsesp/EMS-ESP/issues/355
|
||||
|
||||
@@ -1165,14 +1195,14 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "rx2") {
|
||||
shell.printfln(F("Testing Rx2..."));
|
||||
shell.printfln("Testing Rx2...");
|
||||
for (uint8_t i = 0; i < 30; i++) {
|
||||
uart_telegram({0x08, 0x0B, 0x33, 0x00, 0x08, 0xFF, 0x34, 0xFB, 0x00, 0x28, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0x00});
|
||||
}
|
||||
}
|
||||
|
||||
if (command == "rx") {
|
||||
shell.printfln(F("Testing Rx..."));
|
||||
shell.printfln("Testing Rx...");
|
||||
|
||||
// fake telegrams. length includes CRC
|
||||
// Boiler -> Me, UBAMonitorFast(0x18), telegram: 08 00 18 00 00 02 5A 73 3D 0A 10 65 40 02 1A 80 00 01 E1 01 76 0E 3D 48 00 C9 44 02 00 (#data=25)
|
||||
@@ -1229,7 +1259,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "tx") {
|
||||
shell.printfln(F("Testing Tx..."));
|
||||
shell.printfln("Testing Tx...");
|
||||
|
||||
// TX queue example - Me -> Thermostat, (0x91), telegram: 0B 17 91 05 44 45 46 47 (#data=4)
|
||||
uint8_t t11[] = {0x44, 0x45, 0x46, 0x47};
|
||||
@@ -1266,7 +1296,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "poll") {
|
||||
shell.printfln(F("Testing Poll..."));
|
||||
shell.printfln("Testing Poll...");
|
||||
|
||||
// simulate sending a read request
|
||||
// uint8_t t16[] = {0x44, 0x45, 0x46, 0x47}; // Me -> Thermostat, (0x91), telegram: 0B 17 91 05 44 45 46 47 (#data=4)
|
||||
@@ -1291,7 +1321,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "cmd") {
|
||||
shell.printfln(F("Testing Commands..."));
|
||||
shell.printfln("Testing Commands...");
|
||||
|
||||
// add a thermostat with 3 HCs
|
||||
add_device(0x10, 192); // FW120
|
||||
@@ -1318,13 +1348,13 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "pin") {
|
||||
shell.printfln(F("Testing pin..."));
|
||||
shell.printfln("Testing pin...");
|
||||
shell.invoke_command("call system pin");
|
||||
shell.invoke_command("call system pin 1 true");
|
||||
}
|
||||
|
||||
if (command == "mqtt2") {
|
||||
shell.printfln(F("Testing MQTT large payloads..."));
|
||||
shell.printfln("Testing MQTT large payloads...");
|
||||
|
||||
DynamicJsonDocument doc(EMSESP_JSON_SIZE_XXLARGE_DYN);
|
||||
|
||||
@@ -1339,15 +1369,15 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
doc.shrinkToFit();
|
||||
JsonObject jo = doc.as<JsonObject>();
|
||||
shell.printfln(F("Size of JSON payload = %d"), jo.memoryUsage());
|
||||
shell.printfln(F("Length of JSON payload = %d"), measureJson(jo));
|
||||
shell.printfln("Size of JSON payload = %d", jo.memoryUsage());
|
||||
shell.printfln("Length of JSON payload = %d", measureJson(jo));
|
||||
|
||||
Mqtt::publish("test", jo);
|
||||
Mqtt::show_mqtt(shell); // show queue
|
||||
}
|
||||
|
||||
if (command == "mqtt") {
|
||||
shell.printfln(F("Testing MQTT..."));
|
||||
shell.printfln("Testing MQTT...");
|
||||
|
||||
Mqtt::ha_enabled(false);
|
||||
Mqtt::enabled(true);
|
||||
@@ -1422,7 +1452,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "poll2") {
|
||||
shell.printfln(F("Testing Tx Sending last message on queue..."));
|
||||
shell.printfln("Testing Tx Sending last message on queue...");
|
||||
|
||||
EMSESP::show_ems(shell);
|
||||
|
||||
@@ -1433,7 +1463,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "rx2") {
|
||||
shell.printfln(F("Testing rx2..."));
|
||||
shell.printfln("Testing rx2...");
|
||||
|
||||
uart_telegram({0x1B, 0x5B, 0xFD, 0x2D, 0x9E, 0x3A, 0xB6, 0xE5, 0x02, 0x20, 0x33, 0x30, 0x32, 0x3A, 0x20, 0x5B,
|
||||
0x73, 0xFF, 0xFF, 0xCB, 0xDF, 0xB7, 0xA7, 0xB5, 0x67, 0x77, 0x77, 0xE4, 0xFF, 0xFD, 0x77, 0xFF});
|
||||
@@ -1441,14 +1471,14 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
|
||||
// https://github.com/emsesp/EMS-ESP/issues/380#issuecomment-633663007
|
||||
if (command == "rx3") {
|
||||
shell.printfln(F("Testing rx3..."));
|
||||
shell.printfln("Testing rx3...");
|
||||
|
||||
uart_telegram({0x21, 0x0B, 0xFF, 0x00});
|
||||
}
|
||||
|
||||
// testing the UART tx command, without a queue
|
||||
if (command == "tx2") {
|
||||
shell.printfln(F("Testing tx2..."));
|
||||
shell.printfln("Testing tx2...");
|
||||
|
||||
uint8_t t[] = {0x0B, 0x88, 0x18, 0x00, 0x20, 0xD4}; // including CRC
|
||||
EMSuart::transmit(t, sizeof(t));
|
||||
@@ -1456,14 +1486,14 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
|
||||
// send read request with offset
|
||||
if (command == "offset") {
|
||||
shell.printfln(F("Testing offset..."));
|
||||
shell.printfln("Testing offset...");
|
||||
|
||||
// send_read_request(0x18, 0x08);
|
||||
EMSESP::txservice_.read_request(0x18, 0x08, 27); // no offset
|
||||
}
|
||||
|
||||
if (command == "mixer") {
|
||||
shell.printfln(F("Testing Mixer..."));
|
||||
shell.printfln("Testing Mixer...");
|
||||
|
||||
run_test("mixer");
|
||||
|
||||
@@ -1477,13 +1507,13 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "crash") {
|
||||
shell.printfln(F("Forcing a crash..."));
|
||||
shell.printfln("Forcing a crash...");
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdiv-by-zero"
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
uint8_t a = 2 / 0;
|
||||
shell.printfln(F("Testing %s"), a);
|
||||
shell.printfln("Testing %s", a);
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ namespace emsesp {
|
||||
// #define EMSESP_DEBUG_DEFAULT "mixer"
|
||||
// #define EMSESP_DEBUG_DEFAULT "web"
|
||||
// #define EMSESP_DEBUG_DEFAULT "mqtt"
|
||||
// #define EMSESP_DEBUG_DEFAULT "general"
|
||||
#define EMSESP_DEBUG_DEFAULT "boiler"
|
||||
#define EMSESP_DEBUG_DEFAULT "general"
|
||||
// #define EMSESP_DEBUG_DEFAULT "boiler"
|
||||
// #define EMSESP_DEBUG_DEFAULT "mqtt2"
|
||||
// #define EMSESP_DEBUG_DEFAULT "mqtt_nested"
|
||||
// #define EMSESP_DEBUG_DEFAULT "ha"
|
||||
@@ -51,6 +51,7 @@ namespace emsesp {
|
||||
// #define EMSESP_DEBUG_DEFAULT "api_values"
|
||||
// #define EMSESP_DEBUG_DEFAULT "mqtt_post"
|
||||
// #define EMSESP_DEBUG_DEFAULT "api_wwmode"
|
||||
// #define EMSESP_DEBUG_DEFAULT "custom"
|
||||
|
||||
class Test {
|
||||
public:
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#define EMS_MAXBUFFERSIZE 33 // max size of the buffer. EMS packets are max 32 bytes, plus extra for BRK
|
||||
|
||||
#if (defined(ARDUINO_LOLIN_C3_MINI)) || (defined(ARDUINO_LOLIN_S2_MINI))
|
||||
#define EMSUART_NUM UART_NUM_1 // on C3 mini we're using UART1
|
||||
#define EMSUART_NUM UART_NUM_1 // on C3 and S2 we're using UART1
|
||||
#else
|
||||
#define EMSUART_NUM UART_NUM_2 // on the ESP32 we're using UART2
|
||||
#endif
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define EMSESP_APP_VERSION "3.5.0b4"
|
||||
#define EMSESP_APP_VERSION "3.5.0b5"
|
||||
|
||||
@@ -117,7 +117,7 @@ void WebAPIService::parse(AsyncWebServerRequest * request, JsonObject & input) {
|
||||
emsesp::EMSESP::logger().err(error);
|
||||
api_fails_++;
|
||||
} else {
|
||||
// emsesp::EMSESP::logger().debug(F("API command called successfully"));
|
||||
// emsesp::EMSESP::logger().debug("API command called successfully");
|
||||
// if there was no json output from the call, default to the output message 'OK'.
|
||||
if (!output.size()) {
|
||||
output["message"] = "OK";
|
||||
|
||||
@@ -236,9 +236,9 @@ void WebDataService::write_value(AsyncWebServerRequest * request, JsonVariant &
|
||||
|
||||
// write debug
|
||||
if (return_code != CommandRet::OK) {
|
||||
EMSESP::logger().err(F("Write command failed %s (%s)"), (const char *)output["message"], Command::return_code_string(return_code).c_str());
|
||||
EMSESP::logger().err(("Write command failed %s (%s)"), (const char *)output["message"], Command::return_code_string(return_code).c_str());
|
||||
} else {
|
||||
EMSESP::logger().debug(F("Write command successful"));
|
||||
EMSESP::logger().debug("Write command successful");
|
||||
}
|
||||
|
||||
response->setCode((return_code == CommandRet::OK) ? 200 : 204);
|
||||
|
||||
@@ -34,13 +34,13 @@ WebStatusService::WebStatusService(AsyncWebServer * server, SecurityManager * se
|
||||
void WebStatusService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) {
|
||||
switch (event) {
|
||||
case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
|
||||
EMSESP::logger().warning(F("WiFi disconnected. Reason code=%d"), info.wifi_sta_disconnected.reason); // IDF 4.0
|
||||
EMSESP::logger().warning("WiFi disconnected. Reason code=%d", info.wifi_sta_disconnected.reason); // IDF 4.0
|
||||
WiFi.disconnect(true);
|
||||
break;
|
||||
|
||||
case ARDUINO_EVENT_WIFI_STA_GOT_IP:
|
||||
#ifndef EMSESP_STANDALONE
|
||||
EMSESP::logger().info(F("WiFi connected with IP=%s, hostname=%s"), WiFi.localIP().toString().c_str(), WiFi.getHostname());
|
||||
EMSESP::logger().info("WiFi connected with IP=%s, hostname=%s", WiFi.localIP().toString().c_str(), WiFi.getHostname());
|
||||
#endif
|
||||
// EMSESP::system_.send_heartbeat(); // send from mqtt start
|
||||
EMSESP::system_.syslog_init();
|
||||
@@ -48,7 +48,7 @@ void WebStatusService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) {
|
||||
break;
|
||||
|
||||
case ARDUINO_EVENT_ETH_START:
|
||||
// EMSESP::logger().info(F("Ethernet initialized"));
|
||||
// EMSESP::logger().info("Ethernet initialized");
|
||||
ETH.setHostname(EMSESP::system_.hostname().c_str());
|
||||
|
||||
// configure for static IP
|
||||
@@ -64,7 +64,7 @@ void WebStatusService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) {
|
||||
// prevent double calls
|
||||
if (!EMSESP::system_.ethernet_connected()) {
|
||||
#ifndef EMSESP_STANDALONE
|
||||
EMSESP::logger().info(F("Ethernet connected with IP=%s, speed %d Mbps"), ETH.localIP().toString().c_str(), ETH.linkSpeed());
|
||||
EMSESP::logger().info("Ethernet connected with IP=%s, speed %d Mbps", ETH.localIP().toString().c_str(), ETH.linkSpeed());
|
||||
#endif
|
||||
// EMSESP::system_.send_heartbeat();
|
||||
EMSESP::system_.syslog_init();
|
||||
@@ -74,12 +74,12 @@ void WebStatusService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) {
|
||||
break;
|
||||
|
||||
case ARDUINO_EVENT_ETH_DISCONNECTED:
|
||||
EMSESP::logger().warning(F("Ethernet disconnected"));
|
||||
EMSESP::logger().warning("Ethernet disconnected");
|
||||
EMSESP::system_.ethernet_connected(false);
|
||||
break;
|
||||
|
||||
case ARDUINO_EVENT_ETH_STOP:
|
||||
EMSESP::logger().info(F("Ethernet stopped"));
|
||||
EMSESP::logger().info("Ethernet stopped");
|
||||
EMSESP::system_.ethernet_connected(false);
|
||||
break;
|
||||
|
||||
@@ -103,9 +103,9 @@ void WebStatusService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) {
|
||||
case ARDUINO_EVENT_WIFI_STA_GOT_IP6:
|
||||
case ARDUINO_EVENT_ETH_GOT_IP6:
|
||||
if (EMSESP::system_.ethernet_connected()) {
|
||||
EMSESP::logger().info(F("Ethernet connected with IPv6=%s, speed %d Mbps"), ETH.localIPv6().toString().c_str(), ETH.linkSpeed());
|
||||
EMSESP::logger().info("Ethernet connected with IPv6=%s, speed %d Mbps", ETH.localIPv6().toString().c_str(), ETH.linkSpeed());
|
||||
} else {
|
||||
EMSESP::logger().info(F("WiFi connected with IPv6=%s, hostname=%s"), WiFi.localIPv6().toString().c_str(), WiFi.getHostname());
|
||||
EMSESP::logger().info("WiFi connected with IPv6=%s, hostname=%s", WiFi.localIPv6().toString().c_str(), WiFi.getHostname());
|
||||
}
|
||||
// EMSESP::system_.send_heartbeat();
|
||||
EMSESP::system_.syslog_init();
|
||||
@@ -202,7 +202,7 @@ void WebStatusService::mDNS_start() const {
|
||||
EMSESP::esp8266React.getNetworkSettingsService()->read([&](NetworkSettings & networkSettings) {
|
||||
if (networkSettings.enableMDNS) {
|
||||
if (!MDNS.begin(EMSESP::system_.hostname().c_str())) {
|
||||
EMSESP::logger().warning(F("Failed to start mDNS responder service"));
|
||||
EMSESP::logger().warning("Failed to start mDNS responder service");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -214,13 +214,13 @@ void WebStatusService::mDNS_start() const {
|
||||
MDNS.addServiceTxt("http", "tcp", "version", EMSESP_APP_VERSION);
|
||||
MDNS.addServiceTxt("http", "tcp", "address", address_s.c_str());
|
||||
|
||||
EMSESP::logger().info(F("mDNS responder service started"));
|
||||
EMSESP::logger().info("mDNS responder service started");
|
||||
}
|
||||
});
|
||||
#else
|
||||
EMSESP::esp8266React.getNetworkSettingsService()->read([&](NetworkSettings & networkSettings) {
|
||||
if (networkSettings.enableMDNS) {
|
||||
EMSESP::logger().info(F("mDNS responder service started"));
|
||||
EMSESP::logger().info("mDNS responder service started");
|
||||
}
|
||||
});
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user