mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-08 16:59:50 +03:00
Merge branch 'dev' into dev2
This commit is contained in:
@@ -679,7 +679,7 @@ bool AnalogSensor::get_value_info(JsonObject output, const char * cmd, const int
|
||||
// if we're filtering on an attribute, go find it
|
||||
if (attribute_s) {
|
||||
if (output.containsKey(attribute_s)) {
|
||||
JsonVariant data = output[attribute_s];
|
||||
String data = output[attribute_s].as<String>();
|
||||
output.clear();
|
||||
output["api_data"] = data;
|
||||
return true;
|
||||
|
||||
@@ -128,14 +128,16 @@ static void setup_commands(std::shared_ptr<Commands> & commands) {
|
||||
commands->add_command(ShellContext::MAIN,
|
||||
CommandFlags::USER,
|
||||
string_vector{"test"},
|
||||
string_vector{F_(name_optional), F_(data_optional)},
|
||||
string_vector{F_(name_optional), F_(data_optional), F_(id_optional)},
|
||||
[=](Shell & shell, const std::vector<std::string> & arguments) {
|
||||
if (arguments.empty()) {
|
||||
Test::run_test(shell, "default");
|
||||
} else if (arguments.size() == 1) {
|
||||
Test::run_test(shell, arguments.front());
|
||||
} else {
|
||||
} else if (arguments.size() == 2) {
|
||||
Test::run_test(shell, arguments[0].c_str(), arguments[1].c_str());
|
||||
} else {
|
||||
Test::run_test(shell, arguments[0].c_str(), arguments[1].c_str(), arguments[2].c_str());
|
||||
}
|
||||
});
|
||||
commands->add_command(ShellContext::MAIN, CommandFlags::USER, string_vector{"t"}, [=](Shell & shell, const std::vector<std::string> & arguments) {
|
||||
@@ -531,15 +533,8 @@ static void setup_commands(std::shared_ptr<Commands> & commands) {
|
||||
|
||||
if (return_code == CommandRet::OK && json.size()) {
|
||||
if (json.containsKey("api_data")) {
|
||||
JsonVariant data = json["api_data"];
|
||||
if (data.is<int>()) {
|
||||
shell.printfln("%d", data.as<int>());
|
||||
} else if (data.is<float>()) {
|
||||
char s[10];
|
||||
shell.println(Helpers::render_value(s, data.as<float>(), 1));
|
||||
} else {
|
||||
shell.println(data.as<const char *>());
|
||||
}
|
||||
String data = json["api_data"].as<String>();
|
||||
shell.println(data.c_str());
|
||||
return;
|
||||
}
|
||||
serializeJsonPretty(doc, shell);
|
||||
@@ -568,9 +563,9 @@ static void setup_commands(std::shared_ptr<Commands> & commands) {
|
||||
}
|
||||
return devices_list;
|
||||
} else if (current_arguments.size() == 1) {
|
||||
std::vector<std::string> command_list;
|
||||
uint8_t device_type = EMSdevice::device_name_2_device_type(current_arguments[0].c_str());
|
||||
uint8_t device_type = EMSdevice::device_name_2_device_type(current_arguments[0].c_str());
|
||||
if (Command::device_has_commands(device_type)) {
|
||||
std::vector<std::string> command_list;
|
||||
for (const auto & cf : Command::commands()) {
|
||||
if (cf.device_type_ == device_type) {
|
||||
command_list.emplace_back(cf.cmd_);
|
||||
|
||||
@@ -482,6 +482,15 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
||||
FL_(hpMaxPower),
|
||||
DeviceValueUOM::PERCENT,
|
||||
MAKE_CF_CB(set_hpMaxPower));
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
&hpSetDiffPress_,
|
||||
DeviceValueType::UINT,
|
||||
DeviceValueNumOp::DV_NUMOP_MUL50,
|
||||
FL_(hpSetDiffPress),
|
||||
DeviceValueUOM::MBAR,
|
||||
MAKE_CF_CB(set_hpDiffPress),
|
||||
150,
|
||||
750);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpCompOn_, DeviceValueType::BOOL, FL_(hpCompOn), DeviceValueUOM::NONE);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpActivity_, DeviceValueType::ENUM, FL_(enum_hpactivity), FL_(hpActivity), DeviceValueUOM::NONE);
|
||||
// register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpHeatingOn_, DeviceValueType::BOOL, FL_(hpHeatingOn), DeviceValueUOM::NONE);
|
||||
@@ -1935,6 +1944,10 @@ void Boiler::process_HpMeters(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, meterHeat_, 24);
|
||||
}
|
||||
|
||||
void Boiler::process_HpPressure(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, hpSetDiffPress_, 9);
|
||||
}
|
||||
|
||||
// HIU unit
|
||||
|
||||
// boiler(0x08) -B-> All(0x00), ?(0x0779), data: 06 05 01 01 AD 02 EF FF FF 00 00 7F FF
|
||||
@@ -2939,6 +2952,15 @@ bool Boiler::set_hpMaxPower(const char * value, const int8_t id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Boiler::set_hpDiffPress(const char * value, const int8_t id) {
|
||||
int v;
|
||||
if (Helpers::value2number(value, v)) {
|
||||
write_command(0x2CC, 9, (uint8_t)(v / 50), 0x2CC);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Boiler::set_vp_cooling(const char * value, const int8_t id) {
|
||||
bool v;
|
||||
if (Helpers::value2bool(value, v)) {
|
||||
|
||||
@@ -223,6 +223,7 @@ class Boiler : public EMSdevice {
|
||||
uint32_t meterHeat_;
|
||||
uint8_t hpEA0_;
|
||||
uint8_t hpPumpMode_;
|
||||
uint8_t hpSetDiffPress_;
|
||||
|
||||
// Pool unit
|
||||
int8_t poolSetTemp_;
|
||||
@@ -334,6 +335,7 @@ class Boiler : public EMSdevice {
|
||||
void process_HpPool(std::shared_ptr<const Telegram> telegram);
|
||||
void process_HpInput(std::shared_ptr<const Telegram> telegram);
|
||||
void process_HpInConfig(std::shared_ptr<const Telegram> telegram);
|
||||
void process_HpPressure(std::shared_ptr<const Telegram> telegram);
|
||||
void process_HpCooling(std::shared_ptr<const Telegram> telegram);
|
||||
void process_HpHeaterConfig(std::shared_ptr<const Telegram> telegram);
|
||||
void process_HybridHp(std::shared_ptr<const Telegram> telegram);
|
||||
@@ -437,6 +439,7 @@ class Boiler : public EMSdevice {
|
||||
bool set_hpCircPumpWw(const char * value, const int8_t id);
|
||||
bool set_hpPumpMode(const char * value, const int8_t id);
|
||||
bool set_hpMaxPower(const char * value, const int8_t id);
|
||||
bool set_hpDiffPress(const char * value, const int8_t id);
|
||||
|
||||
bool set_auxLimit(const char * value, const int8_t id);
|
||||
inline bool set_auxMaxLimit(const char * value, const int8_t id) {
|
||||
|
||||
@@ -30,7 +30,7 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
|
||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) {
|
||||
register_telegram_type(device_id - 0x20 + 0x02D7, "MMPLUSStatusMessage_HC", false, MAKE_PF_CB(process_MMPLUSStatusMessage_HC));
|
||||
// register_telegram_type(device_id - 0x20 + 0x02E1, "MMPLUSSetMessage_HC", true, MAKE_PF_CB(process_MMPLUSSetMessage_HC));
|
||||
register_telegram_type(device_id - 0x20 + 0x02CD, "MMPLUSSetMessage_HC", false, MAKE_PF_CB(process_MMPLUSSetMessage_HC));
|
||||
register_telegram_type((device_id - 0x20) * 2 + 0x02CC, "MMPLUSSetMessage_HC", false, MAKE_PF_CB(process_MMPLUSSetMessage_HC));
|
||||
hc_ = device_id - 0x20 + 1;
|
||||
uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1;
|
||||
register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES);
|
||||
@@ -151,7 +151,7 @@ void Mixer::process_MMConfigMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, setValveTime_, 1); // valve runtime in 10 sec, max 120 s
|
||||
}
|
||||
|
||||
// Mixer Setting 0x2CD
|
||||
// Mixer Setting 0x2CC
|
||||
void Mixer::process_MMPLUSSetMessage_HC(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, activated_, 0); // on = 0xFF
|
||||
has_update(telegram, setValveTime_, 1); // valve runtime in 10 sec, max 120 s
|
||||
@@ -241,7 +241,7 @@ bool Mixer::set_activated(const char * value, const int8_t id) {
|
||||
}
|
||||
if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) {
|
||||
uint8_t hc = device_id() - 0x20;
|
||||
write_command(0x2CD + hc, 0, b ? 0xFF : 0, 0x2CD + hc);
|
||||
write_command(0x2CC + hc * 2, 0, b ? 0xFF : 0, 0x2CC + hc * 2);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -260,7 +260,7 @@ bool Mixer::set_setValveTime(const char * value, const int8_t id) {
|
||||
if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) {
|
||||
v = (v + 5) / 10;
|
||||
uint8_t hc = device_id() - 0x20;
|
||||
write_command(0x2CD + hc, 1, v, 0x2CD + hc);
|
||||
write_command(0x2CC + hc * 2, 1, v, 0x2CC + hc * 2);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -273,7 +273,7 @@ bool Mixer::set_flowTempOffset(const char * value, const int8_t id) {
|
||||
}
|
||||
if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) {
|
||||
uint8_t hc = device_id() - 0x20;
|
||||
write_command(0x2CD + hc, 2, v, 0x2CD + hc);
|
||||
write_command(0x2CC + hc * 2, 2, v, 0x2CC + hc * 2);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -583,6 +583,7 @@ void EMSdevice::add_device_value(uint8_t tag, // to b
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (ignore) {
|
||||
return;
|
||||
}
|
||||
@@ -943,11 +944,10 @@ void EMSdevice::generate_values_web(JsonObject output) {
|
||||
auto mask = Helpers::hextoa((uint8_t)(dv.state >> 4), false); // create mask to a 2-char string
|
||||
|
||||
// add name, prefixing the tag if it exists. This is the id used in the WebUI table and must be unique
|
||||
if (dv.has_tag()) {
|
||||
obj["id"] = mask + tag_to_string(dv.tag) + " " + fullname;
|
||||
} else {
|
||||
obj["id"] = mask + fullname;
|
||||
}
|
||||
obj["id"] = dv.has_tag() ? mask + tag_to_string(dv.tag) + " " + fullname : mask + fullname; // suffix tag
|
||||
|
||||
// TODO check TAG https://github.com/emsesp/EMS-ESP32/issues/1338
|
||||
// obj["id"] = dv.has_tag() ? mask + fullname + " " + tag_to_string(dv.tag) : mask + fullname; // suffix tag
|
||||
|
||||
// add commands and options
|
||||
if (dv.has_cmd && !dv.has_state(DeviceValueState::DV_READONLY)) {
|
||||
@@ -1001,7 +1001,7 @@ void EMSdevice::generate_values_web(JsonObject output) {
|
||||
|
||||
// as generate_values_web() but stripped down to only show all entities and their state
|
||||
// this is used only for WebCustomizationService::device_entities()
|
||||
void EMSdevice::generate_values_web_customization(JsonArray & output) {
|
||||
void EMSdevice::generate_values_web_customization(JsonArray output) {
|
||||
for (auto & dv : devicevalues_) {
|
||||
// also show commands and entities that have an empty full name
|
||||
JsonObject obj = output.add<JsonObject>();
|
||||
@@ -1058,13 +1058,10 @@ void EMSdevice::generate_values_web_customization(JsonArray & output) {
|
||||
auto fullname = Helpers::translated_word(dv.fullname);
|
||||
if (dv.type != DeviceValueType::CMD) {
|
||||
if (fullname) {
|
||||
if (dv.has_tag()) {
|
||||
char name[50];
|
||||
snprintf(name, sizeof(name), "%s %s", tag_to_string(dv.tag), fullname);
|
||||
obj["n"] = name;
|
||||
} else {
|
||||
obj["n"] = fullname;
|
||||
}
|
||||
obj["n"] = dv.has_tag() ? std::string(tag_to_string(dv.tag)) + " " + fullname : fullname; // prefix tag
|
||||
|
||||
// TODO check TAG https://github.com/emsesp/EMS-ESP32/issues/1338
|
||||
// obj["n"] = (dv.has_tag()) ? fullname + " " + tag_to_string(dv.tag) : fullname; // suffix tag
|
||||
}
|
||||
|
||||
// add the custom name, is optional
|
||||
@@ -1409,13 +1406,10 @@ bool EMSdevice::get_value_info(JsonObject output, const char * cmd, const int8_t
|
||||
|
||||
auto fullname = dv.get_fullname();
|
||||
if (!fullname.empty()) {
|
||||
if (dv.has_tag()) {
|
||||
char name[50];
|
||||
snprintf(name, sizeof(name), "%s %s", tag_to_string(dv.tag), fullname.c_str());
|
||||
json["fullname"] = name;
|
||||
} else {
|
||||
json["fullname"] = fullname;
|
||||
}
|
||||
json["fullname"] = dv.has_tag() ? fullname + " " + tag_to_string(dv.tag) : fullname; // suffix tag
|
||||
|
||||
// TODO check TAG https://github.com/emsesp/EMS-ESP32/issues/1338
|
||||
json["fullname"] = dv.has_tag() ? std::string(tag_to_string(dv.tag)) + " " + fullname.c_str() : fullname; // prefix tag
|
||||
}
|
||||
|
||||
if (dv.tag != DeviceValueTAG::TAG_NONE) {
|
||||
@@ -1549,7 +1543,7 @@ bool EMSdevice::get_value_info(JsonObject output, const char * cmd, const int8_t
|
||||
EMSESP::logger().debug("Attribute '%s'", attribute_s);
|
||||
#endif
|
||||
if (json.containsKey(attribute_s)) {
|
||||
JsonVariant data = json[attribute_s];
|
||||
String data = json[attribute_s].as<String>();
|
||||
output.clear();
|
||||
output["api_data"] = data;
|
||||
return true;
|
||||
@@ -1610,16 +1604,20 @@ bool EMSdevice::generate_values(JsonObject output, const uint8_t tag_filter, con
|
||||
char name[80];
|
||||
|
||||
if (output_target == OUTPUT_TARGET::API_VERBOSE || output_target == OUTPUT_TARGET::CONSOLE) {
|
||||
char short_name[20];
|
||||
if (output_target == OUTPUT_TARGET::CONSOLE) {
|
||||
snprintf(short_name, sizeof(short_name), " (%s)", dv.short_name);
|
||||
} else {
|
||||
strcpy(short_name, "");
|
||||
}
|
||||
// char short_name[20];
|
||||
// if (output_target == OUTPUT_TARGET::CONSOLE) {
|
||||
// snprintf(short_name, sizeof(short_name), "(%s)", dv.short_name);
|
||||
// } else {
|
||||
// strcpy(short_name, "");
|
||||
// }
|
||||
|
||||
// add tag
|
||||
if (have_tag) {
|
||||
snprintf(name, sizeof(name), "%s %s%s", tag_to_string(dv.tag), fullname.c_str(), short_name); // prefix the tag
|
||||
snprintf(name, sizeof(name), "%s %s (%s)", tag_to_string(dv.tag), fullname.c_str(), dv.short_name); // prefix tag
|
||||
// TODO check TAG https://github.com/emsesp/EMS-ESP32/issues/1338
|
||||
// snprintf(name, sizeof(name), "%s %s (%s)", fullname.c_str(), tag_to_string(dv.tag), dv.short_name); // sufix tag
|
||||
} else {
|
||||
snprintf(name, sizeof(name), "%s%s", fullname.c_str(), short_name);
|
||||
snprintf(name, sizeof(name), "%s (%s)", fullname.c_str(), dv.short_name);
|
||||
}
|
||||
} else {
|
||||
strlcpy(name, (dv.short_name), sizeof(name)); // use short name
|
||||
|
||||
@@ -222,7 +222,7 @@ class EMSdevice {
|
||||
enum OUTPUT_TARGET : uint8_t { API_VERBOSE, API_SHORTNAMES, MQTT, CONSOLE };
|
||||
bool generate_values(JsonObject output, const uint8_t tag_filter, const bool nested, const uint8_t output_target);
|
||||
void generate_values_web(JsonObject output);
|
||||
void generate_values_web_customization(JsonArray & output);
|
||||
void generate_values_web_customization(JsonArray output);
|
||||
|
||||
void add_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
|
||||
@@ -110,7 +110,7 @@ const char * DeviceValue::DeviceValueUOM_s[] = {
|
||||
F_(uom_blank), // 0
|
||||
F_(uom_degrees), F_(uom_degrees), F_(uom_percent), F_(uom_lmin), F_(uom_kwh), F_(uom_wh), FL_(hours)[0], FL_(minutes)[0], F_(uom_ua),
|
||||
F_(uom_bar), F_(uom_kw), F_(uom_w), F_(uom_kb), FL_(seconds)[0], F_(uom_dbm), F_(uom_fahrenheit), F_(uom_mv), F_(uom_sqm),
|
||||
F_(uom_m3), F_(uom_l), F_(uom_kmin), F_(uom_k), F_(uom_volts), F_(uom_blank)
|
||||
F_(uom_m3), F_(uom_l), F_(uom_kmin), F_(uom_k), F_(uom_volts), F_(uom_mbar), F_(uom_blank)
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -71,7 +71,8 @@ class DeviceValue {
|
||||
KMIN, // 21 - K*min
|
||||
K, // 22 - K
|
||||
VOLTS, // 23 - V
|
||||
CONNECTIVITY // 24 - used in HA
|
||||
MBAR, // 24 - mbar
|
||||
CONNECTIVITY // 25 - used in HA
|
||||
};
|
||||
|
||||
// TAG mapping - maps to DeviceValueTAG_s in emsdevice.cpp
|
||||
@@ -143,7 +144,8 @@ class DeviceValue {
|
||||
DV_NUMOP_DIV100 = 100,
|
||||
DV_NUMOP_MUL5 = -5,
|
||||
DV_NUMOP_MUL10 = -10,
|
||||
DV_NUMOP_MUL15 = -15
|
||||
DV_NUMOP_MUL15 = -15,
|
||||
DV_NUMOP_MUL50 = -50
|
||||
};
|
||||
|
||||
uint8_t device_type; // EMSdevice::DeviceType
|
||||
|
||||
@@ -392,7 +392,6 @@ void EMSESP::show_device_values(uuid::console::Shell & shell) {
|
||||
// extract the shortname from the key, which is in brackets
|
||||
std::size_t first_bracket = key.find_last_of('(');
|
||||
std::size_t last_bracket = key.find_last_of(')');
|
||||
std::string shortname = key.substr(first_bracket + 1, last_bracket - first_bracket - 1);
|
||||
std::string uom = emsdevice->get_value_uom(key.substr(first_bracket + 1, last_bracket - first_bracket - 1));
|
||||
|
||||
shell.printfln(" %s: %s%s %s%s", key.c_str(), COLOR_BRIGHT_GREEN, p.value().as<std::string>().c_str(), uom.c_str(), COLOR_RESET);
|
||||
@@ -705,7 +704,7 @@ bool EMSESP::get_device_value_info(JsonObject root, const char * cmd, const int8
|
||||
|
||||
// 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()) {
|
||||
if ((device_id & 0x7F) == EMSbus::ems_bus_id()) {
|
||||
return "Me";
|
||||
} else if (device_id == 0x00) {
|
||||
return "All";
|
||||
@@ -734,9 +733,13 @@ std::string EMSESP::pretty_telegram(std::shared_ptr<const Telegram> telegram) {
|
||||
} else if (emsdevice->is_device_id(dest)) {
|
||||
dest_name = emsdevice->device_type_name();
|
||||
}
|
||||
// get the type name, any match will do
|
||||
// get the type name
|
||||
if (type_name.empty()) {
|
||||
type_name = emsdevice->telegram_type_name(telegram);
|
||||
if ((telegram->operation == Telegram::Operation::RX_READ && emsdevice->is_device_id(dest))
|
||||
|| (telegram->operation != Telegram::Operation::RX_READ && dest == 0 && emsdevice->is_device_id(src))
|
||||
|| (telegram->operation != Telegram::Operation::RX_READ && src == EMSbus::ems_bus_id() && emsdevice->is_device_id(dest))) {
|
||||
type_name = emsdevice->telegram_type_name(telegram);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -867,7 +870,7 @@ void EMSESP::process_version(std::shared_ptr<const Telegram> telegram) {
|
||||
// returns false if there are none found
|
||||
bool EMSESP::process_telegram(std::shared_ptr<const Telegram> telegram) {
|
||||
// if watching or reading...
|
||||
if ((telegram->type_id == read_id_ || telegram->type_id == response_id_) && (telegram->dest == txservice_.ems_bus_id())) {
|
||||
if ((telegram->type_id == read_id_ || telegram->type_id == response_id_) && (telegram->dest == EMSbus::ems_bus_id())) {
|
||||
if (telegram->type_id == response_id_) {
|
||||
if (!trace_raw_) {
|
||||
LOG_TRACE("%s", pretty_telegram(telegram).c_str());
|
||||
@@ -896,7 +899,7 @@ bool EMSESP::process_telegram(std::shared_ptr<const Telegram> telegram) {
|
||||
}
|
||||
|
||||
// only process broadcast telegrams or ones sent to us on request
|
||||
// if ((telegram->dest != 0x00) && (telegram->dest != rxservice_.ems_bus_id())) {
|
||||
// if ((telegram->dest != 0x00) && (telegram->dest != EMSbus::ems_bus_id())) {
|
||||
if (telegram->operation == Telegram::Operation::RX_READ) {
|
||||
// LOG_DEBUG("read telegram received, not processing");
|
||||
return false;
|
||||
@@ -924,13 +927,13 @@ bool EMSESP::process_telegram(std::shared_ptr<const Telegram> telegram) {
|
||||
bool found = false;
|
||||
bool knowndevice = false;
|
||||
for (const auto & emsdevice : emsdevices) {
|
||||
if (emsdevice->is_device_id(telegram->src)) {
|
||||
if (emsdevice->is_device_id(telegram->src) && (telegram->dest == 0 || telegram->dest == EMSbus::ems_bus_id())) {
|
||||
knowndevice = true;
|
||||
found = emsdevice->handle_telegram(telegram);
|
||||
// if we correctly processed the telegram then follow up with sending it via MQTT (if enabled)
|
||||
if (found && Mqtt::connected()) {
|
||||
if ((mqtt_.get_publish_onchange(emsdevice->device_type()) && emsdevice->has_update())
|
||||
|| (telegram->type_id == publish_id_ && telegram->dest == txservice_.ems_bus_id())) {
|
||||
|| (telegram->type_id == publish_id_ && telegram->dest == EMSbus::ems_bus_id())) {
|
||||
if (telegram->type_id == publish_id_) {
|
||||
publish_id_ = 0;
|
||||
}
|
||||
@@ -947,7 +950,7 @@ bool EMSESP::process_telegram(std::shared_ptr<const Telegram> telegram) {
|
||||
emsdevice->add_handlers_ignored(telegram->type_id);
|
||||
}
|
||||
break;
|
||||
} else if (emsdevice->is_device_id(telegram->dest)) {
|
||||
} else if (emsdevice->is_device_id(telegram->dest) && telegram->src != EMSbus::ems_bus_id()) {
|
||||
emsdevice->handle_telegram(telegram);
|
||||
}
|
||||
}
|
||||
@@ -1021,7 +1024,7 @@ void EMSESP::show_devices(uuid::console::Shell & shell) {
|
||||
// if its not in our database, we don't add it
|
||||
bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const char * version, const uint8_t brand) {
|
||||
// don't add ourselves!
|
||||
if (device_id == rxservice_.ems_bus_id()) {
|
||||
if (device_id == EMSbus::ems_bus_id()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1062,7 +1065,7 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const
|
||||
device_p = &device;
|
||||
break;
|
||||
}
|
||||
if ((device_id >= EMSdevice::EMS_DEVICE_ID_HS1 && device_id <= EMSdevice::EMS_DEVICE_ID_HS16)) {
|
||||
if (device_id >= EMSdevice::EMS_DEVICE_ID_HS1 && device_id <= EMSdevice::EMS_DEVICE_ID_HS16) {
|
||||
device_p = &device;
|
||||
device_p->device_type = DeviceType::HEATSOURCE;
|
||||
break;
|
||||
@@ -1265,7 +1268,7 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) {
|
||||
#endif
|
||||
// check first for echo
|
||||
uint8_t first_value = data[0];
|
||||
if (((first_value & 0x7F) == txservice_.ems_bus_id()) && (length > 1)) {
|
||||
if (((first_value & 0x7F) == EMSbus::ems_bus_id()) && (length > 1)) {
|
||||
// if we ask ourself at roomcontrol for version e.g. 0B 98 02 00 20
|
||||
Roomctrl::check((data[1] ^ 0x80 ^ rxservice_.ems_mask()), data, length);
|
||||
#ifdef EMSESP_UART_DEBUG
|
||||
@@ -1336,7 +1339,7 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) {
|
||||
wait_km_ = true;
|
||||
connect_time = uuid::get_uptime_sec();
|
||||
}
|
||||
if (poll_id == txservice_.ems_bus_id()) {
|
||||
if (poll_id == EMSbus::ems_bus_id()) {
|
||||
EMSbus::last_bus_activity(uuid::get_uptime()); // set the flag indication the EMS bus is active
|
||||
}
|
||||
if (wait_km_) {
|
||||
|
||||
@@ -249,6 +249,7 @@ MAKE_WORD_CUSTOM(uom_l, "l")
|
||||
MAKE_WORD_CUSTOM(uom_kmin, "K*min")
|
||||
MAKE_WORD_CUSTOM(uom_k, "K")
|
||||
MAKE_WORD_CUSTOM(uom_volts, "V")
|
||||
MAKE_WORD_CUSTOM(uom_mbar, "mbar")
|
||||
|
||||
// MQTT topics and prefixes
|
||||
MAKE_WORD_CUSTOM(heating_active, "heating_active")
|
||||
|
||||
@@ -286,7 +286,7 @@ MAKE_WORD_TRANSLATION(partymode, "party", "Party", "party", "", "impreza", "", "
|
||||
MAKE_WORD_TRANSLATION(fireplace, "fireplace", "Kamin", "haard", "", "kominek", "", "", "şömine", "camino", "krb") // TODO translate
|
||||
|
||||
// MQTT Discovery - this is special device entity for 'climate'
|
||||
MAKE_TRANSLATION(haclimate, "haclimate", "Discovery current room temperature", "Discovery Temperatur", "Discovery huidige kamertemperatuur", "", "termostat w HA", "HA Avlest temp", "", "Güncel osa sıcaklığı", "verifica temperatura ambiente attuale", "Zistiť aktuálnu teplotu v miestnosti") // TODO translate
|
||||
MAKE_TRANSLATION(haclimate, "haclimate", "mqtt discovery current room temperature", "Discovery Temperatur", "Discovery huidige kamertemperatuur", "", "termostat w HA", "HA Avlest temp", "", "Güncel osa sıcaklığı", "verifica temperatura ambiente attuale", "Zistiť aktuálnu teplotu v miestnosti") // TODO translate
|
||||
|
||||
// Entity translations: tag, mqtt, en, de, nl, sv, pl, no, fr, tr, it, sk
|
||||
// Boiler
|
||||
@@ -463,6 +463,7 @@ MAKE_TRANSLATION(hpPumpMode, "hppumpmode", "primary heatpump mode", "Modus Haupt
|
||||
MAKE_TRANSLATION(instantstart, "instantstart", "instant start", "Sofortstart", "", "", "natychmiastowy start", "", "", "", "", "") // TODO translate
|
||||
MAKE_TRANSLATION(heatondelay, "heatondelay", "heat-on delay", "Einschaltverzögerung Heizen", "", "", "opóźnienie włączania ogrzewania", "", "", "", "", "") // TODO translate
|
||||
MAKE_TRANSLATION(heatoffdelay, "heatoffdelay", "heat-off delay", "Ausschaltverzögerung Heizen", "", "", "opóźnienie włączania ogrzewania", "", "", "", "", "") // TODO translate
|
||||
MAKE_TRANSLATION(hpSetDiffPress, "hpsetdiffpress", "set differental pressure", "Pumpensolldruck", "", "", "", "", "", "", "", "") // TODO translate
|
||||
|
||||
// hybrid heatpump
|
||||
MAKE_TRANSLATION(hybridStrategy, "hybridstrategy", "hybrid control strategy", "Hybrid Strategie", "Hybride strategie", "Hybrid kontrollstrategi", "strategia sterowania hybrydowego", "hybrid kontrollstrategi", "stratégie contrôle hybride", "hibrit kontrol stratejisi", "strategia comtrollo ibrido", "hybridná stratégia riadenia")
|
||||
|
||||
12
src/mqtt.cpp
12
src/mqtt.cpp
@@ -683,12 +683,12 @@ bool Mqtt::queue_publish(const char * topic, const std::string & payload) {
|
||||
return queue_publish_message((topic), payload, mqtt_retain_);
|
||||
}
|
||||
|
||||
bool Mqtt::queue_publish(const char * topic, const JsonObjectConst & payload) {
|
||||
bool Mqtt::queue_publish(const char * topic, const JsonObjectConst payload) {
|
||||
return queue_publish_retain(topic, payload, mqtt_retain_);
|
||||
}
|
||||
|
||||
// publish json doc, only if its not empty
|
||||
bool Mqtt::queue_publish(const std::string & topic, const JsonObjectConst & payload) {
|
||||
bool Mqtt::queue_publish(const std::string & topic, const JsonObjectConst payload) {
|
||||
return queue_publish_retain(topic, payload, mqtt_retain_);
|
||||
}
|
||||
|
||||
@@ -698,11 +698,11 @@ bool Mqtt::queue_publish_retain(const char * topic, const std::string & payload,
|
||||
}
|
||||
|
||||
// publish json doc, only if its not empty, using the retain flag
|
||||
bool Mqtt::queue_publish_retain(const std::string & topic, const JsonObjectConst & payload, const bool retain) {
|
||||
bool Mqtt::queue_publish_retain(const std::string & topic, const JsonObjectConst payload, const bool retain) {
|
||||
return queue_publish_retain(topic.c_str(), payload, retain);
|
||||
}
|
||||
|
||||
bool Mqtt::queue_publish_retain(const char * topic, const JsonObjectConst & payload, const bool retain) {
|
||||
bool Mqtt::queue_publish_retain(const char * topic, const JsonObjectConst payload, const bool retain) {
|
||||
if (payload.size()) {
|
||||
std::string payload_text;
|
||||
payload_text.reserve(measureJson(payload) + 1);
|
||||
@@ -722,7 +722,7 @@ bool Mqtt::queue_remove_topic(const char * topic) {
|
||||
}
|
||||
|
||||
// queue a Home Assistant config topic and payload, with retain flag off.
|
||||
bool Mqtt::queue_ha(const char * topic, const JsonObjectConst & payload) {
|
||||
bool Mqtt::queue_ha(const char * topic, const JsonObjectConst payload) {
|
||||
if (!enabled()) {
|
||||
return false;
|
||||
}
|
||||
@@ -817,7 +817,7 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSd
|
||||
const int16_t dv_set_min,
|
||||
const uint32_t dv_set_max,
|
||||
const int8_t num_op,
|
||||
const JsonObjectConst & dev_json) {
|
||||
const JsonObjectConst dev_json) {
|
||||
// ignore if name (fullname) is empty
|
||||
if (!fullname || !en_name) {
|
||||
return false;
|
||||
|
||||
44
src/mqtt.h
44
src/mqtt.h
@@ -68,31 +68,31 @@ class Mqtt {
|
||||
|
||||
static bool queue_publish(const std::string & topic, const std::string & payload);
|
||||
static bool queue_publish(const char * topic, const char * payload);
|
||||
static bool queue_publish(const std::string & topic, const JsonObjectConst & payload);
|
||||
static bool queue_publish(const char * topic, const JsonObjectConst & payload);
|
||||
static bool queue_publish(const std::string & topic, const JsonObjectConst payload);
|
||||
static bool queue_publish(const char * topic, const JsonObjectConst payload);
|
||||
static bool queue_publish(const char * topic, const std::string & payload);
|
||||
static bool queue_publish_retain(const std::string & topic, const JsonObjectConst & payload, const bool retain);
|
||||
static bool queue_publish_retain(const std::string & topic, const JsonObjectConst payload, const bool retain);
|
||||
static bool queue_publish_retain(const char * topic, const std::string & payload, const bool retain);
|
||||
static bool queue_publish_retain(const char * topic, const JsonObjectConst & payload, const bool retain);
|
||||
static bool queue_ha(const char * topic, const JsonObjectConst & payload);
|
||||
static bool queue_publish_retain(const char * topic, const JsonObjectConst payload, const bool retain);
|
||||
static bool queue_ha(const char * topic, const JsonObjectConst payload);
|
||||
static bool queue_remove_topic(const char * topic);
|
||||
|
||||
static bool publish_ha_sensor_config(DeviceValue & dv, const char * model, const char * brand, const bool remove, const bool create_device_config = false);
|
||||
static bool 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 uint32_t dv_set_max,
|
||||
const int8_t num_op,
|
||||
const JsonObjectConst & dev_json);
|
||||
static bool 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 uint32_t dv_set_max,
|
||||
const int8_t num_op,
|
||||
const JsonObjectConst dev_json);
|
||||
|
||||
static bool publish_system_ha_sensor_config(uint8_t type, const char * name, const char * entity, const uint8_t uom);
|
||||
static bool publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp, const bool remove = false, const int16_t min = 5, const uint32_t max = 30);
|
||||
@@ -168,6 +168,10 @@ class Mqtt {
|
||||
return entity_format_;
|
||||
}
|
||||
|
||||
static void entity_format(uint8_t n) {
|
||||
entity_format_ = n;
|
||||
}
|
||||
|
||||
static uint8_t discovery_type() {
|
||||
return discovery_type_;
|
||||
}
|
||||
|
||||
@@ -632,7 +632,7 @@ void System::send_info_mqtt() {
|
||||
}
|
||||
|
||||
// create the json for heartbeat
|
||||
bool System::heartbeat_json(JsonObject output) {
|
||||
void System::heartbeat_json(JsonObject output) {
|
||||
uint8_t bus_status = EMSESP::bus_status();
|
||||
if (bus_status == EMSESP::BUS_STATUS_TX_ERRORS) {
|
||||
output["bus_status"] = "txerror";
|
||||
@@ -684,8 +684,6 @@ bool System::heartbeat_json(JsonObject output) {
|
||||
output["wifistrength"] = wifi_quality(rssi);
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// send periodic MQTT message with system information
|
||||
@@ -700,9 +698,8 @@ void System::send_heartbeat() {
|
||||
JsonDocument doc;
|
||||
JsonObject json = doc.to<JsonObject>();
|
||||
|
||||
if (heartbeat_json(json)) {
|
||||
Mqtt::queue_publish(F_(heartbeat), json); // send to MQTT with retain off. This will add to MQTT queue.
|
||||
}
|
||||
heartbeat_json(json);
|
||||
Mqtt::queue_publish(F_(heartbeat), json); // send to MQTT with retain off. This will add to MQTT queue.
|
||||
}
|
||||
|
||||
// initializes network
|
||||
@@ -1471,7 +1468,7 @@ bool System::command_info(const char * value, const int8_t id, JsonObject output
|
||||
#if defined(EMSESP_TEST)
|
||||
// run a test, e.g. http://ems-esp/api?device=system&cmd=test&data=boiler
|
||||
bool System::command_test(const char * value, const int8_t id) {
|
||||
return Test::run_test(value, id);
|
||||
return Test::test(value, id);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ class System {
|
||||
void syslog_init();
|
||||
bool check_upgrade(bool factory_settings);
|
||||
bool check_restore();
|
||||
bool heartbeat_json(JsonObject output);
|
||||
void heartbeat_json(JsonObject output);
|
||||
void send_heartbeat();
|
||||
void send_info_mqtt();
|
||||
|
||||
|
||||
@@ -414,8 +414,8 @@ bool TemperatureSensor::get_value_info(JsonObject output, const char * cmd, cons
|
||||
if (Helpers::toLower(command_s) == Helpers::toLower(sensor.name().c_str()) || Helpers::toLower(command_s) == Helpers::toLower(sensor.id().c_str())) {
|
||||
output["id"] = sensor.id();
|
||||
output["name"] = sensor.name();
|
||||
char val[10];
|
||||
if (Helpers::hasValue(sensor.temperature_c)) {
|
||||
char val[10];
|
||||
output["value"] = serialized(Helpers::render_value(val, sensor.temperature_c, 10, EMSESP::system_.fahrenheit() ? 2 : 0));
|
||||
}
|
||||
|
||||
@@ -426,7 +426,7 @@ bool TemperatureSensor::get_value_info(JsonObject output, const char * cmd, cons
|
||||
// if we're filtering on an attribute, go find it
|
||||
if (attribute_s) {
|
||||
if (output.containsKey(attribute_s)) {
|
||||
JsonVariant data = output[attribute_s];
|
||||
String data = output[attribute_s].as<String>();
|
||||
output.clear();
|
||||
output["api_data"] = data;
|
||||
return true;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
|
||||
/*
|
||||
* EMS-ESP - https://github.com/emsesp/EMS-ESP
|
||||
* Copyright 2020-2023 Paul Derbyshire
|
||||
* Copyright 2020-2023 Paul Derbyshire
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -25,12 +24,19 @@ namespace emsesp {
|
||||
|
||||
// no shell, called via the API or 'call system test' command
|
||||
// or http://ems-esp/api?device=system&cmd=test&data=boiler
|
||||
bool Test::run_test(const char * command, int8_t id) {
|
||||
if ((command == nullptr) || (strlen(command) == 0)) {
|
||||
bool Test::test(const std::string & cmd, int8_t id1, int8_t id2) {
|
||||
if (cmd.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strcmp(command, "memory") == 0) {
|
||||
if (cmd == "add") {
|
||||
Mqtt::entity_format(Mqtt::entityFormat::SINGLE_LONG); // SINGLE_LONG, SINGLE_SHORT, MULTI_SHORT
|
||||
System::test_set_all_active(true); // include all entities and give them fake values
|
||||
add_device(id1, id2);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cmd == "memory") {
|
||||
EMSESP::logger().notice("Testing memory by adding lots of devices and entities...");
|
||||
|
||||
System::test_set_all_active(true); // include all entities and give them fake values
|
||||
@@ -43,7 +49,7 @@ bool Test::run_test(const char * command, int8_t id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (strcmp(command, "general") == 0) {
|
||||
if (cmd == "general") {
|
||||
EMSESP::logger().info("Testing general. Adding a Boiler and Thermostat");
|
||||
|
||||
// System::test_set_all_active(true); // uncomment if we want to show all entities and give them fake values
|
||||
@@ -77,7 +83,7 @@ bool Test::run_test(const char * command, int8_t id) {
|
||||
//
|
||||
#ifdef EMSESP_STANDALONE
|
||||
|
||||
if (strcmp(command, "heat_exchange") == 0) {
|
||||
if (cmd == "heat_exchange") {
|
||||
EMSESP::logger().info("Testing heating exchange...");
|
||||
|
||||
add_device(0x08, 219); // Greenstar HIU/Logamax kompakt WS170
|
||||
@@ -89,7 +95,7 @@ bool Test::run_test(const char * command, int8_t id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (strcmp(command, "2thermostats") == 0) {
|
||||
if (cmd == "2thermostats") {
|
||||
EMSESP::logger().info("Testing with multiple thermostats...");
|
||||
|
||||
add_device(0x08, 123); // GB072
|
||||
@@ -121,7 +127,7 @@ bool Test::run_test(const char * command, int8_t id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (strcmp(command, "310") == 0) {
|
||||
if (cmd == "310") {
|
||||
EMSESP::logger().info("Adding a GB072/RC310 combo...");
|
||||
|
||||
add_device(0x08, 123); // GB072
|
||||
@@ -148,7 +154,7 @@ bool Test::run_test(const char * command, int8_t id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (strcmp(command, "gateway") == 0) {
|
||||
if (cmd == "gateway") {
|
||||
EMSESP::logger().info("Adding a Gateway...");
|
||||
|
||||
// add 0x48 KM200, via a version command
|
||||
@@ -168,7 +174,7 @@ bool Test::run_test(const char * command, int8_t id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (strcmp(command, "mixer") == 0) {
|
||||
if (cmd == "mixer") {
|
||||
EMSESP::logger().info("Adding a mixer...");
|
||||
|
||||
// add controller
|
||||
@@ -190,7 +196,7 @@ bool Test::run_test(const char * command, int8_t id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (strcmp(command, "boiler") == 0) {
|
||||
if (cmd == "boiler") {
|
||||
EMSESP::logger().info("Adding boiler...");
|
||||
add_device(0x08, 123); // Nefit Trendline
|
||||
|
||||
@@ -207,7 +213,7 @@ bool Test::run_test(const char * command, int8_t id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (strcmp(command, "thermostat") == 0) {
|
||||
if (cmd == "thermostat") {
|
||||
EMSESP::logger().info("Adding thermostat...");
|
||||
|
||||
add_device(0x10, 192); // FW120
|
||||
@@ -220,7 +226,7 @@ bool Test::run_test(const char * command, int8_t id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (strcmp(command, "solar") == 0) {
|
||||
if (cmd == "solar") {
|
||||
EMSESP::logger().info("Adding solar...");
|
||||
|
||||
add_device(0x30, 163); // SM100
|
||||
@@ -239,7 +245,7 @@ bool Test::run_test(const char * command, int8_t id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (strcmp(command, "heatpump") == 0) {
|
||||
if (cmd == "heatpump") {
|
||||
EMSESP::logger().info("Adding heatpump...");
|
||||
|
||||
add_device(0x38, 200); // Enviline module
|
||||
@@ -258,11 +264,13 @@ bool Test::run_test(const char * command, int8_t id) {
|
||||
}
|
||||
|
||||
// These next tests are run from the Consol via the test command, so inherit the Shell
|
||||
void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const std::string & data) {
|
||||
void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const std::string & id1_s, const std::string & id2_s) {
|
||||
shell.add_flags(CommandFlags::ADMIN); // switch to su
|
||||
|
||||
// init stuff
|
||||
Mqtt::ha_enabled(true);
|
||||
Mqtt::entity_format(Mqtt::entityFormat::SINGLE_SHORT); // SINGLE_LONG, SINGLE_SHORT, MULTI_SHORT
|
||||
|
||||
EMSESP::rxservice_.ems_mask(EMSbus::EMS_MASK_BUDERUS);
|
||||
|
||||
// EMSESP::watch(EMSESP::Watch::WATCH_RAW); // raw mode
|
||||
@@ -275,11 +283,32 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
command = cmd;
|
||||
}
|
||||
|
||||
// extract params
|
||||
int8_t id1 = -1;
|
||||
int8_t id2 = -1;
|
||||
if (!id1_s.empty()) {
|
||||
if (id1_s[0] == '0' && id1_s[1] == 'x') {
|
||||
id1 = Helpers::hextoint(id1_s.c_str());
|
||||
} else {
|
||||
id1 = Helpers::atoint(id1_s.c_str());
|
||||
}
|
||||
}
|
||||
if (!id2_s.empty()) {
|
||||
id2 = Helpers::atoint(id2_s.c_str());
|
||||
}
|
||||
|
||||
bool ok = false;
|
||||
|
||||
if (command == "add") {
|
||||
shell.printfln("Testing Adding a device (product_id %d), with all values...", id2);
|
||||
test("add", id1, id2); // e.g. 8 172
|
||||
shell.invoke_command("show values");
|
||||
ok = true;
|
||||
}
|
||||
|
||||
if (command == "general") {
|
||||
shell.printfln("Testing adding a boiler, thermostat and sensors...");
|
||||
run_test("general");
|
||||
test("general");
|
||||
|
||||
// add sensors
|
||||
emsesp::EMSESP::analogsensor_.test();
|
||||
@@ -296,14 +325,14 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
// https://github.com/emsesp/EMS-ESP32/issues/869
|
||||
if (command == "memory") {
|
||||
shell.printfln("Testing memory by adding lots of devices and entities...");
|
||||
run_test("memory");
|
||||
test("memory");
|
||||
shell.invoke_command("show values");
|
||||
ok = true;
|
||||
}
|
||||
|
||||
if (command == "custom_entities") {
|
||||
shell.printfln("custom entities...");
|
||||
run_test("general");
|
||||
test("general");
|
||||
|
||||
#ifdef EMSESP_STANDALONE
|
||||
AsyncWebServerRequest request;
|
||||
@@ -318,7 +347,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
|
||||
if (command == "coldshot") {
|
||||
shell.printfln("Testing coldshot...");
|
||||
run_test("general");
|
||||
test("general");
|
||||
|
||||
#ifdef EMSESP_STANDALONE
|
||||
AsyncWebServerRequest request;
|
||||
@@ -370,7 +399,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
|
||||
if (command == "modes") {
|
||||
shell.printfln("Testing thermostat modes...");
|
||||
run_test("general");
|
||||
test("general");
|
||||
shell.invoke_command("call thermostat mode auto");
|
||||
shell.invoke_command("call thermostat mode Manuell"); // DE
|
||||
shell.invoke_command("call thermostat mode 1");
|
||||
@@ -506,13 +535,13 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
|
||||
if (command == "gateway") {
|
||||
shell.printfln("Testing Gateway...");
|
||||
run_test("gateway");
|
||||
test("gateway");
|
||||
ok = true;
|
||||
}
|
||||
|
||||
if (command == "310") {
|
||||
shell.printfln("Testing RC310...");
|
||||
run_test("310");
|
||||
test("310");
|
||||
shell.invoke_command("show devices");
|
||||
shell.invoke_command("show values");
|
||||
shell.invoke_command("call system publish");
|
||||
@@ -522,7 +551,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
|
||||
if (command == "heat_exchange") {
|
||||
shell.printfln("Testing heat exchange...");
|
||||
run_test("heat_exchange");
|
||||
test("heat_exchange");
|
||||
shell.invoke_command("show devices");
|
||||
shell.invoke_command("show values");
|
||||
ok = true;
|
||||
@@ -530,7 +559,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
|
||||
if (command == "2thermostats") {
|
||||
shell.printfln("Testing multiple thermostats...");
|
||||
run_test("2thermostats");
|
||||
test("2thermostats");
|
||||
shell.invoke_command("show values");
|
||||
shell.invoke_command("show devices");
|
||||
ok = true;
|
||||
@@ -542,8 +571,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
Mqtt::enabled(false); // turn off mqtt
|
||||
Mqtt::ha_enabled(false); // turn off ha
|
||||
|
||||
run_test("boiler");
|
||||
run_test("thermostat");
|
||||
test("boiler");
|
||||
test("thermostat");
|
||||
|
||||
JsonDocument doc; // some absurd high number
|
||||
for (const auto & emsdevice : EMSESP::emsdevices) {
|
||||
@@ -596,7 +625,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
Mqtt::ha_enabled(true);
|
||||
Mqtt::nested_format(1);
|
||||
|
||||
run_test("boiler");
|
||||
test("boiler");
|
||||
shell.invoke_command("show devices");
|
||||
shell.invoke_command("show values");
|
||||
shell.invoke_command("call boiler info");
|
||||
@@ -622,7 +651,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
if (command == "shower_alert") {
|
||||
shell.printfln("Testing Shower Alert...");
|
||||
|
||||
run_test("boiler");
|
||||
test("boiler");
|
||||
|
||||
// device type, command, data
|
||||
Command::call(EMSdevice::DeviceType::BOILER, "wwtapactivated", "false");
|
||||
@@ -650,10 +679,10 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
Mqtt::nested_format(1); // is nested
|
||||
// Mqtt::nested_format(2); // not nested
|
||||
|
||||
run_test("boiler");
|
||||
run_test("thermostat");
|
||||
run_test("solar");
|
||||
run_test("mixer");
|
||||
test("boiler");
|
||||
test("thermostat");
|
||||
test("solar");
|
||||
test("mixer");
|
||||
|
||||
shell.invoke_command("call system publish");
|
||||
shell.invoke_command("show mqtt");
|
||||
@@ -672,8 +701,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
Mqtt::nested_format(1);
|
||||
// Mqtt::send_response(false);
|
||||
|
||||
run_test("boiler");
|
||||
// run_test("thermostat");
|
||||
test("boiler");
|
||||
// test("thermostat");
|
||||
|
||||
// 0xC2
|
||||
// [emsesp] Boiler(0x08) -> Me(0x0B), UBAErrorMessage3(0xC2), data: 08 AC 00 10 31 48 30 31 15 80 95 0B 0E 10 38 00 7F FF FF FF 08 AC 00 10 09 41 30
|
||||
@@ -692,8 +721,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
Mqtt::nested_format(1);
|
||||
// Mqtt::send_response(false);
|
||||
|
||||
run_test("boiler");
|
||||
run_test("thermostat");
|
||||
test("boiler");
|
||||
test("thermostat");
|
||||
|
||||
shell.invoke_command("call boiler wwseltemp");
|
||||
shell.invoke_command("call system publish");
|
||||
@@ -745,15 +774,13 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "healthcheck") {
|
||||
uint8_t n = 0;
|
||||
if (!data.empty()) {
|
||||
n = Helpers::atoint(data.c_str());
|
||||
}
|
||||
|
||||
// n=1 = EMSESP::system_.HEALTHCHECK_NO_BUS
|
||||
// n=2 = EMSESP::system_.HEALTHCHECK_NO_NETWORK
|
||||
shell.printfln("Testing healthcheck with %d", n);
|
||||
EMSESP::system_.healthcheck(n);
|
||||
if (id1 == -1) {
|
||||
id1 = 0;
|
||||
}
|
||||
shell.printfln("Testing healthcheck with %d", id1);
|
||||
EMSESP::system_.healthcheck(id1);
|
||||
ok = true;
|
||||
}
|
||||
|
||||
@@ -763,7 +790,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
Mqtt::ha_enabled(true);
|
||||
// Mqtt::send_response(false);
|
||||
|
||||
run_test("thermostat");
|
||||
test("thermostat");
|
||||
|
||||
// shell.invoke_command("call thermostat seltemp");
|
||||
// shell.invoke_command("call system publish");
|
||||
@@ -794,7 +821,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
Mqtt::ha_enabled(true);
|
||||
// Mqtt::send_response(false);
|
||||
|
||||
run_test("boiler");
|
||||
test("boiler");
|
||||
|
||||
shell.invoke_command("call boiler wwseltemp");
|
||||
shell.invoke_command("call system publish");
|
||||
@@ -819,7 +846,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
Mqtt::ha_enabled(true);
|
||||
// Mqtt::send_response(false);
|
||||
|
||||
run_test("boiler");
|
||||
test("boiler");
|
||||
|
||||
shell.invoke_command("call boiler wwseltemp");
|
||||
shell.invoke_command("call system publish");
|
||||
@@ -842,8 +869,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
// EMSESP::bool_format(BOOL_FORMAT_10); // BOOL_FORMAT_10_STR
|
||||
EMSESP::system_.bool_format(BOOL_FORMAT_TRUEFALSE); // BOOL_FORMAT_TRUEFALSE_STR
|
||||
|
||||
run_test("boiler");
|
||||
run_test("thermostat");
|
||||
test("boiler");
|
||||
test("thermostat");
|
||||
|
||||
AsyncWebServerRequest request;
|
||||
JsonDocument doc;
|
||||
@@ -875,8 +902,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
EMSESP::system_.bool_format(BOOL_FORMAT_10); // BOOL_FORMAT_10_STR
|
||||
// EMSESP::bool_format(BOOL_FORMAT_TRUEFALSE); // BOOL_FORMAT_TRUEFALSE_STR
|
||||
|
||||
run_test("boiler");
|
||||
run_test("thermostat");
|
||||
test("boiler");
|
||||
test("thermostat");
|
||||
|
||||
EMSESP::mqtt_.incoming("ems-esp/boiler/wwseltemp", "59");
|
||||
ok = true;
|
||||
@@ -887,15 +914,15 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
shell.printfln("Testing API wwmode");
|
||||
Mqtt::ha_enabled(false);
|
||||
Mqtt::nested_format(1);
|
||||
run_test("310");
|
||||
test("310");
|
||||
|
||||
AsyncWebServerRequest request;
|
||||
request.method(HTTP_POST);
|
||||
JsonDocument doc;
|
||||
JsonVariant json;
|
||||
|
||||
char data[] = "{\"value\":\"off\"}";
|
||||
deserializeJson(doc, data);
|
||||
char odata[] = "{\"value\":\"off\"}";
|
||||
deserializeJson(doc, odata);
|
||||
json = doc.as<JsonVariant>();
|
||||
request.url("/api/thermostat/wwmode");
|
||||
EMSESP::webAPIService.webAPIService_post(&request, json);
|
||||
@@ -911,8 +938,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
Mqtt::nested_format(1);
|
||||
// Mqtt::send_response(true);
|
||||
|
||||
run_test("boiler");
|
||||
run_test("thermostat");
|
||||
test("boiler");
|
||||
test("thermostat");
|
||||
|
||||
AsyncWebServerRequest requestX;
|
||||
JsonDocument docX;
|
||||
@@ -1181,10 +1208,10 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
shell.printfln("Testing nested MQTT");
|
||||
Mqtt::ha_enabled(false); // turn off HA Discovery to stop the chatter
|
||||
|
||||
run_test("boiler");
|
||||
run_test("thermostat");
|
||||
run_test("solar");
|
||||
run_test("mixer");
|
||||
test("boiler");
|
||||
test("thermostat");
|
||||
test("solar");
|
||||
test("mixer");
|
||||
|
||||
// first with nested
|
||||
Mqtt::nested_format(1);
|
||||
@@ -1201,7 +1228,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
if (command == "thermostat") {
|
||||
shell.printfln("Testing adding a thermostat FW120...");
|
||||
|
||||
run_test("thermostat");
|
||||
test("thermostat");
|
||||
shell.invoke_command("show values");
|
||||
shell.invoke_command("call system publish");
|
||||
|
||||
@@ -1229,7 +1256,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
|
||||
if (command == "solar") {
|
||||
shell.printfln("Testing Solar");
|
||||
run_test("solar");
|
||||
test("solar");
|
||||
|
||||
uart_telegram("30 00 FF 0A 02 6A 04"); // SM100 pump on (1)sh
|
||||
EMSESP::show_device_values(shell);
|
||||
@@ -1243,7 +1270,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
|
||||
if (command == "heatpump") {
|
||||
shell.printfln("Testing Heat Pump");
|
||||
run_test("heatpump");
|
||||
test("heatpump");
|
||||
shell.invoke_command("call");
|
||||
shell.invoke_command("call heatpump info");
|
||||
ok = true;
|
||||
@@ -1698,7 +1725,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
if (command == "mixer") {
|
||||
shell.printfln("Testing Mixer...");
|
||||
|
||||
run_test("mixer");
|
||||
test("mixer");
|
||||
|
||||
// check for error "No telegram type handler found for ID 0x255 (src 0x20)"
|
||||
uart_telegram({0xA0, 0x00, 0xFF, 0x00, 0x01, 0x55, 0x00, 0x1A});
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#define EMSESP_TEST_H
|
||||
|
||||
#include "emsesp.h"
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
|
||||
namespace emsesp {
|
||||
@@ -60,8 +61,8 @@ namespace emsesp {
|
||||
|
||||
class Test {
|
||||
public:
|
||||
static void run_test(uuid::console::Shell & shell, const std::string & command, const std::string & data = "");
|
||||
static bool run_test(const char * command, int8_t id = 0);
|
||||
static void run_test(uuid::console::Shell & shell, const std::string & command, const std::string & id1 = "", const std::string & id2 = "");
|
||||
static bool test(const std::string & command, int8_t id1 = -1, int8_t id2 = -1);
|
||||
static void dummy_mqtt_commands(const char * message);
|
||||
static void rx_telegram(const std::vector<uint8_t> & data);
|
||||
static void uart_telegram(const std::vector<uint8_t> & rx_data);
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define EMSESP_APP_VERSION "3.6.5-test.8"
|
||||
#define EMSESP_APP_VERSION "3.6.5-test.10"
|
||||
|
||||
@@ -53,7 +53,7 @@ void WebAPIService::webAPIService_get(AsyncWebServerRequest * request) {
|
||||
// For HTTP POSTS with an optional JSON body
|
||||
// HTTP_POST | HTTP_PUT | HTTP_PATCH
|
||||
// POST /{device}[/{hc|id}][/{name}]
|
||||
void WebAPIService::webAPIService_post(AsyncWebServerRequest * request, JsonVariant & json) {
|
||||
void WebAPIService::webAPIService_post(AsyncWebServerRequest * request, JsonVariant json) {
|
||||
// if no body then treat it as a secure GET
|
||||
if (!json.is<JsonObject>()) {
|
||||
webAPIService_get(request);
|
||||
@@ -134,8 +134,8 @@ void WebAPIService::parse(AsyncWebServerRequest * request, JsonObject input) {
|
||||
// if we're returning single values, just sent as plain text
|
||||
// https://github.com/emsesp/EMS-ESP32/issues/462#issuecomment-1093877210
|
||||
if (output.containsKey("api_data")) {
|
||||
JsonVariant data = output["api_data"];
|
||||
request->send(200, "text/plain; charset=utf-8", data.as<String>());
|
||||
String data = output["api_data"].as<String>();
|
||||
request->send(200, "text/plain; charset=utf-8", data);
|
||||
api_count_++;
|
||||
delete response;
|
||||
return;
|
||||
|
||||
@@ -31,8 +31,8 @@ class WebAPIService {
|
||||
public:
|
||||
WebAPIService(AsyncWebServer * server, SecurityManager * securityManager);
|
||||
|
||||
void webAPIService_post(AsyncWebServerRequest * request, JsonVariant & json); // for POSTs
|
||||
void webAPIService_get(AsyncWebServerRequest * request); // for GETs
|
||||
void webAPIService_post(AsyncWebServerRequest * request, JsonVariant json); // for POSTs
|
||||
void webAPIService_get(AsyncWebServerRequest * request); // for GETs
|
||||
|
||||
static uint32_t api_count() {
|
||||
return api_count_;
|
||||
|
||||
@@ -48,6 +48,7 @@ void WebCustomEntity::read(WebCustomEntity & webEntity, JsonObject root) {
|
||||
for (const CustomEntityItem & entityItem : webEntity.customEntityItems) {
|
||||
JsonObject ei = entity.add<JsonObject>();
|
||||
ei["id"] = counter++; // id is only used to render the table and must be unique
|
||||
ei["ram"] = entityItem.ram;
|
||||
ei["device_id"] = entityItem.device_id;
|
||||
ei["type_id"] = entityItem.type_id;
|
||||
ei["offset"] = entityItem.offset;
|
||||
@@ -73,7 +74,7 @@ StateUpdateResult WebCustomEntity::update(JsonObject root, WebCustomEntity & web
|
||||
JsonDocument doc;
|
||||
deserializeJson(doc, json);
|
||||
root = doc.as<JsonObject>();
|
||||
Serial.println(COLOR_BRIGHT_MAGENTA);
|
||||
Serial.print(COLOR_BRIGHT_MAGENTA);
|
||||
Serial.print(" Using fake custom entity file: ");
|
||||
serializeJson(root, Serial);
|
||||
Serial.println(COLOR_RESET);
|
||||
@@ -88,6 +89,7 @@ StateUpdateResult WebCustomEntity::update(JsonObject root, WebCustomEntity & web
|
||||
if (root["entities"].is<JsonArray>()) {
|
||||
for (const JsonObject ei : root["entities"].as<JsonArray>()) {
|
||||
auto entityItem = CustomEntityItem();
|
||||
entityItem.ram = ei["ram"] | 0;
|
||||
entityItem.device_id = ei["device_id"]; // send as numeric, will be converted to string in web
|
||||
entityItem.type_id = ei["type_id"];
|
||||
entityItem.offset = ei["offset"];
|
||||
@@ -96,6 +98,14 @@ StateUpdateResult WebCustomEntity::update(JsonObject root, WebCustomEntity & web
|
||||
entityItem.uom = ei["uom"];
|
||||
entityItem.value_type = ei["value_type"];
|
||||
entityItem.writeable = ei["writeable"];
|
||||
entityItem.data = ei["value"].as<std::string>();
|
||||
if (entityItem.ram == 1) {
|
||||
entityItem.device_id = 0;
|
||||
entityItem.type_id = 0;
|
||||
entityItem.uom = 0;
|
||||
entityItem.value_type = DeviceValueType::STRING;
|
||||
entityItem.writeable = true;
|
||||
}
|
||||
|
||||
if (entityItem.value_type == DeviceValueType::BOOL) {
|
||||
entityItem.value = EMS_VALUE_DEFAULT_BOOL;
|
||||
@@ -107,7 +117,7 @@ StateUpdateResult WebCustomEntity::update(JsonObject root, WebCustomEntity & web
|
||||
entityItem.value = EMS_VALUE_DEFAULT_SHORT;
|
||||
} else if (entityItem.value_type == DeviceValueType::USHORT) {
|
||||
entityItem.value = EMS_VALUE_DEFAULT_USHORT;
|
||||
} else { // if (entityItem.value_type == DeviceValueType::ULONG || entityItem.value_type == DeviceValueType::TIME) {
|
||||
} else if (entityItem.value_type == DeviceValueType::ULONG || entityItem.value_type == DeviceValueType::TIME) {
|
||||
entityItem.value = EMS_VALUE_DEFAULT_ULONG;
|
||||
}
|
||||
if (entityItem.factor == 0) {
|
||||
@@ -134,7 +144,9 @@ bool WebCustomEntityService::command_setvalue(const char * value, const std::str
|
||||
EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; });
|
||||
for (CustomEntityItem & entityItem : *customEntityItems) {
|
||||
if (Helpers::toLower(entityItem.name) == Helpers::toLower(name)) {
|
||||
if (entityItem.value_type == DeviceValueType::STRING) {
|
||||
if (entityItem.ram == 1) {
|
||||
entityItem.data = value;
|
||||
} else if (entityItem.value_type == DeviceValueType::STRING) {
|
||||
char telegram[84];
|
||||
strlcpy(telegram, value, sizeof(telegram));
|
||||
uint8_t data[EMS_MAX_TELEGRAM_LENGTH];
|
||||
@@ -274,7 +286,7 @@ bool WebCustomEntityService::get_value_info(JsonObject output, const char * cmd)
|
||||
for (const CustomEntityItem & entity : *customEntityItems) {
|
||||
render_value(output, entity);
|
||||
}
|
||||
return (output.size() != 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
char command_s[30];
|
||||
@@ -297,18 +309,20 @@ bool WebCustomEntityService::get_value_info(JsonObject output, const char * cmd)
|
||||
output["readable"] = true;
|
||||
output["writeable"] = entity.writeable;
|
||||
output["visible"] = true;
|
||||
output["device_id"] = Helpers::hextoa(entity.device_id);
|
||||
output["type_id"] = Helpers::hextoa(entity.type_id);
|
||||
output["offset"] = entity.offset;
|
||||
if (entity.value_type != DeviceValueType::BOOL && entity.value_type != DeviceValueType::STRING) {
|
||||
output["factor"] = entity.factor;
|
||||
} else if (entity.value_type == DeviceValueType::STRING) {
|
||||
output["bytes"] = (uint8_t)entity.factor;
|
||||
if (entity.ram == 0) {
|
||||
output["device_id"] = Helpers::hextoa(entity.device_id);
|
||||
output["type_id"] = Helpers::hextoa(entity.type_id);
|
||||
output["offset"] = entity.offset;
|
||||
if (entity.value_type != DeviceValueType::BOOL && entity.value_type != DeviceValueType::STRING) {
|
||||
output["factor"] = entity.factor;
|
||||
} else if (entity.value_type == DeviceValueType::STRING) {
|
||||
output["bytes"] = (uint8_t)entity.factor;
|
||||
}
|
||||
}
|
||||
render_value(output, entity, true);
|
||||
if (attribute_s) {
|
||||
if (output.containsKey(attribute_s)) {
|
||||
JsonVariant data = output[attribute_s];
|
||||
String data = output[attribute_s].as<String>();
|
||||
output.clear();
|
||||
output["api_data"] = data;
|
||||
return true;
|
||||
@@ -547,10 +561,21 @@ void WebCustomEntityService::fetch() {
|
||||
EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; });
|
||||
const uint8_t len[] = {1, 1, 1, 2, 2, 3, 3};
|
||||
for (auto & entity : *customEntityItems) {
|
||||
EMSESP::send_read_request(entity.type_id,
|
||||
entity.device_id,
|
||||
entity.offset,
|
||||
entity.value_type == DeviceValueType::STRING ? (uint8_t)entity.factor : len[entity.value_type]);
|
||||
if (entity.device_id > 0 && entity.type_id > 0) { // ths excludes also RAM type
|
||||
bool needFetch = true;
|
||||
for (const auto & emsdevice : EMSESP::emsdevices) {
|
||||
if (entity.value_type != DeviceValueType::STRING && emsdevice->is_device_id(entity.device_id) && emsdevice->is_fetch(entity.type_id)) {
|
||||
needFetch = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (needFetch) {
|
||||
EMSESP::send_read_request(entity.type_id,
|
||||
entity.device_id,
|
||||
entity.offset,
|
||||
entity.value_type == DeviceValueType::STRING ? (uint8_t)entity.factor : len[entity.value_type]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// EMSESP::logger().debug("fetch custom entities");
|
||||
}
|
||||
@@ -563,8 +588,8 @@ bool WebCustomEntityService::get_value(std::shared_ptr<const Telegram> telegram)
|
||||
const uint8_t len[] = {1, 1, 1, 2, 2, 3, 3};
|
||||
for (auto & entity : *customEntityItems) {
|
||||
if (entity.value_type == DeviceValueType::STRING && telegram->type_id == entity.type_id && telegram->src == entity.device_id
|
||||
&& telegram->offset == entity.offset) {
|
||||
auto data = Helpers::data_to_hex(telegram->message_data, telegram->message_length);
|
||||
&& telegram->offset <= entity.offset && (telegram->offset + telegram->message_length) >= (entity.offset + (uint8_t)entity.factor)) {
|
||||
auto data = Helpers::data_to_hex(telegram->message_data, (uint8_t)entity.factor);
|
||||
if (entity.data != data) {
|
||||
entity.data = data;
|
||||
if (Mqtt::publish_single()) {
|
||||
@@ -573,9 +598,8 @@ bool WebCustomEntityService::get_value(std::shared_ptr<const Telegram> telegram)
|
||||
has_change = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (entity.value_type != DeviceValueType::STRING && telegram->type_id == entity.type_id && telegram->src == entity.device_id
|
||||
&& telegram->offset <= entity.offset && (telegram->offset + telegram->message_length) >= (entity.offset + len[entity.value_type])) {
|
||||
} else if (entity.value_type != DeviceValueType::STRING && telegram->type_id == entity.type_id && telegram->src == entity.device_id
|
||||
&& telegram->offset <= entity.offset && (telegram->offset + telegram->message_length) >= (entity.offset + len[entity.value_type])) {
|
||||
uint32_t value = 0;
|
||||
for (uint8_t i = 0; i < len[entity.value_type]; i++) {
|
||||
value = (value << 8) + telegram->message_data[i + entity.offset - telegram->offset];
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#define WebCustomEntityService_h
|
||||
|
||||
#define EMSESP_CUSTOMENTITY_FILE "/config/emsespEntity.json"
|
||||
#define EMSESP_CUSTOMENTITY_SERVICE_PATH "/rest/customentities" // GET and POST
|
||||
#define EMSESP_CUSTOMENTITY_SERVICE_PATH "/rest/customEntities" // GET and POST
|
||||
|
||||
namespace emsesp {
|
||||
|
||||
@@ -38,6 +38,7 @@ class CustomEntityItem {
|
||||
bool writeable;
|
||||
uint32_t value;
|
||||
std::string data;
|
||||
uint8_t ram;
|
||||
};
|
||||
|
||||
class WebCustomEntity {
|
||||
|
||||
@@ -25,14 +25,7 @@ using namespace std::placeholders; // for `_1` etc
|
||||
bool WebCustomization::_start = true;
|
||||
|
||||
WebCustomizationService::WebCustomizationService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager)
|
||||
: _httpEndpoint(WebCustomization::read,
|
||||
WebCustomization::update,
|
||||
this,
|
||||
server,
|
||||
EMSESP_CUSTOMIZATION_SERVICE_PATH,
|
||||
securityManager,
|
||||
AuthenticationPredicates::IS_AUTHENTICATED)
|
||||
, _fsPersistence(WebCustomization::read, WebCustomization::update, this, fs, EMSESP_CUSTOMIZATION_FILE)
|
||||
: _fsPersistence(WebCustomization::read, WebCustomization::update, this, fs, EMSESP_CUSTOMIZATION_FILE)
|
||||
, _masked_entities_handler(CUSTOMIZATION_ENTITIES_PATH,
|
||||
securityManager->wrapCallback(std::bind(&WebCustomizationService::customization_entities, this, _1, _2),
|
||||
AuthenticationPredicates::IS_AUTHENTICATED)) {
|
||||
@@ -85,7 +78,7 @@ void WebCustomization::read(WebCustomization & customizations, JsonObject root)
|
||||
entityJson["product_id"] = entityCustomization.product_id;
|
||||
entityJson["device_id"] = entityCustomization.device_id;
|
||||
|
||||
// entries are in the form <XX><shortname>[|optional customname] e.g "08heatingactive|heating is on"
|
||||
// entries are in the form <XX><shortname>[optional customname] e.g "08heatingactive|heating is on"
|
||||
JsonArray masked_entityJson = entityJson["entity_ids"].to<JsonArray>();
|
||||
for (std::string entity_id : entityCustomization.entity_ids) {
|
||||
masked_entityJson.add(entity_id);
|
||||
@@ -103,7 +96,7 @@ StateUpdateResult WebCustomization::update(JsonObject root, WebCustomization & c
|
||||
JsonDocument doc;
|
||||
deserializeJson(doc, json);
|
||||
root = doc.as<JsonObject>();
|
||||
Serial.println(COLOR_BRIGHT_MAGENTA);
|
||||
Serial.print(COLOR_BRIGHT_MAGENTA);
|
||||
Serial.print(" Using fake customization file: ");
|
||||
serializeJson(root, Serial);
|
||||
Serial.println(COLOR_RESET);
|
||||
@@ -239,7 +232,7 @@ void WebCustomizationService::device_entities(AsyncWebServerRequest * request) {
|
||||
// takes a list of updated entities with new masks from the web UI
|
||||
// saves it in the customization service
|
||||
// and updates the entity list real-time
|
||||
void WebCustomizationService::customization_entities(AsyncWebServerRequest * request, JsonVariant & json) {
|
||||
void WebCustomizationService::customization_entities(AsyncWebServerRequest * request, JsonVariant json) {
|
||||
bool need_reboot = false;
|
||||
if (json.is<JsonObject>()) {
|
||||
// find the device using the unique_id
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
// GET
|
||||
#define DEVICES_SERVICE_PATH "/rest/devices"
|
||||
#define EMSESP_CUSTOMIZATION_SERVICE_PATH "/rest/customization"
|
||||
#define DEVICE_ENTITIES_PATH "/rest/deviceEntities"
|
||||
|
||||
// POST
|
||||
@@ -89,7 +88,6 @@ class WebCustomizationService : public StatefulService<WebCustomization> {
|
||||
private:
|
||||
#endif
|
||||
|
||||
HttpEndpoint<WebCustomization> _httpEndpoint;
|
||||
FSPersistence<WebCustomization> _fsPersistence;
|
||||
|
||||
// GET
|
||||
@@ -97,7 +95,7 @@ class WebCustomizationService : public StatefulService<WebCustomization> {
|
||||
void device_entities(AsyncWebServerRequest * request);
|
||||
|
||||
// POST
|
||||
void customization_entities(AsyncWebServerRequest * request, JsonVariant & json);
|
||||
void customization_entities(AsyncWebServerRequest * request, JsonVariant json);
|
||||
void reset_customization(AsyncWebServerRequest * request); // command
|
||||
|
||||
AsyncCallbackJsonWebHandler _masked_entities_handler;
|
||||
|
||||
@@ -227,7 +227,7 @@ void WebDataService::device_data(AsyncWebServerRequest * request) {
|
||||
}
|
||||
|
||||
// assumes the service has been checked for admin authentication
|
||||
void WebDataService::write_device_value(AsyncWebServerRequest * request, JsonVariant & json) {
|
||||
void WebDataService::write_device_value(AsyncWebServerRequest * request, JsonVariant json) {
|
||||
if (json.is<JsonObject>()) {
|
||||
uint8_t unique_id = json["id"]; // unique ID
|
||||
const char * cmd = json["c"]; // the command
|
||||
@@ -323,7 +323,7 @@ void WebDataService::write_device_value(AsyncWebServerRequest * request, JsonVar
|
||||
|
||||
// takes a temperaturesensor name and optional offset from the WebUI and update the customization settings
|
||||
// via the temperaturesensor service
|
||||
void WebDataService::write_temperature_sensor(AsyncWebServerRequest * request, JsonVariant & json) {
|
||||
void WebDataService::write_temperature_sensor(AsyncWebServerRequest * request, JsonVariant json) {
|
||||
bool ok = false;
|
||||
if (json.is<JsonObject>()) {
|
||||
JsonObject sensor = json;
|
||||
@@ -346,7 +346,7 @@ void WebDataService::write_temperature_sensor(AsyncWebServerRequest * request, J
|
||||
}
|
||||
|
||||
// update the analog record, or create a new one
|
||||
void WebDataService::write_analog_sensor(AsyncWebServerRequest * request, JsonVariant & json) {
|
||||
void WebDataService::write_analog_sensor(AsyncWebServerRequest * request, JsonVariant json) {
|
||||
bool ok = false;
|
||||
if (json.is<JsonObject>()) {
|
||||
JsonObject analog = json;
|
||||
|
||||
@@ -47,9 +47,9 @@ class WebDataService {
|
||||
void device_data(AsyncWebServerRequest * request);
|
||||
|
||||
// POST
|
||||
void write_device_value(AsyncWebServerRequest * request, JsonVariant & json);
|
||||
void write_temperature_sensor(AsyncWebServerRequest * request, JsonVariant & json);
|
||||
void write_analog_sensor(AsyncWebServerRequest * request, JsonVariant & json);
|
||||
void write_device_value(AsyncWebServerRequest * request, JsonVariant json);
|
||||
void write_temperature_sensor(AsyncWebServerRequest * request, JsonVariant json);
|
||||
void write_analog_sensor(AsyncWebServerRequest * request, JsonVariant json);
|
||||
void scan_devices(AsyncWebServerRequest * request); // command
|
||||
|
||||
AsyncCallbackJsonWebHandler _write_value_handler, _write_temperature_handler, _write_analog_handler;
|
||||
|
||||
@@ -211,7 +211,7 @@ void WebLogService::fetchLog(AsyncWebServerRequest * request) {
|
||||
}
|
||||
|
||||
// sets the values like level after a POST
|
||||
void WebLogService::setValues(AsyncWebServerRequest * request, JsonVariant & json) {
|
||||
void WebLogService::setValues(AsyncWebServerRequest * request, JsonVariant json) {
|
||||
if (!json.is<JsonObject>()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ class WebLogService : public uuid::log::Handler {
|
||||
|
||||
char * messagetime(char * out, const uint64_t t, const size_t bufsize);
|
||||
|
||||
void setValues(AsyncWebServerRequest * request, JsonVariant & json);
|
||||
void setValues(AsyncWebServerRequest * request, JsonVariant json);
|
||||
|
||||
AsyncCallbackJsonWebHandler setValues_; // for POSTs
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ StateUpdateResult WebScheduler::update(JsonObject root, WebScheduler & webSchedu
|
||||
JsonDocument doc;
|
||||
deserializeJson(doc, json);
|
||||
root = doc.as<JsonObject>();
|
||||
Serial.println(COLOR_BRIGHT_MAGENTA);
|
||||
Serial.print(COLOR_BRIGHT_MAGENTA);
|
||||
Serial.print(" Using fake scheduler file: ");
|
||||
serializeJson(root, Serial);
|
||||
Serial.println(COLOR_RESET);
|
||||
@@ -177,7 +177,6 @@ bool WebSchedulerService::get_value_info(JsonObject output, const char * cmd) {
|
||||
attribute_s = breakp + 1;
|
||||
}
|
||||
|
||||
JsonVariant data;
|
||||
for (const ScheduleItem & scheduleItem : *scheduleItems) {
|
||||
if (Helpers::toLower(scheduleItem.name) == Helpers::toLower(command_s)) {
|
||||
output["name"] = scheduleItem.name;
|
||||
@@ -199,7 +198,7 @@ bool WebSchedulerService::get_value_info(JsonObject output, const char * cmd) {
|
||||
}
|
||||
|
||||
if (attribute_s && output.containsKey(attribute_s)) {
|
||||
data = output[attribute_s];
|
||||
String data = output[attribute_s].as<String>();
|
||||
output.clear();
|
||||
output["api_data"] = data;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user