This commit is contained in:
MichaelDvP
2022-12-30 15:47:41 +01:00
7 changed files with 207 additions and 180 deletions

View File

@@ -37,7 +37,7 @@ extra_scripts =
; options for debugging are: EMSESP_DEBUG EMSESP_UART_DEBUG EMSESP_DEBUG_SENSOR ; options for debugging are: EMSESP_DEBUG EMSESP_UART_DEBUG EMSESP_DEBUG_SENSOR
[env:debug] [env:debug]
board = esp32dev board = esp32dev
platform = espressif32 platform = espressif32@5.2.0
board_build.partitions = esp32_partition_debug.csv board_build.partitions = esp32_partition_debug.csv
upload_protocol = esptool upload_protocol = esptool
build_type = debug build_type = debug

View File

@@ -56,7 +56,7 @@ check_flags =
[env:ci] [env:ci]
extra_scripts = scripts/rename_fw.py extra_scripts = scripts/rename_fw.py
board = esp32dev board = esp32dev
platform = espressif32 platform = espressif32@5.2.0
board_build.partitions = esp32_partition_4M.csv board_build.partitions = esp32_partition_4M.csv
board_build.filesystem = littlefs board_build.filesystem = littlefs
build_flags = ${common.build_flags} build_flags = ${common.build_flags}
@@ -67,7 +67,7 @@ extra_scripts =
pre:scripts/build_interface.py pre:scripts/build_interface.py
scripts/rename_fw.py scripts/rename_fw.py
board = esp32dev board = esp32dev
platform = espressif32 platform = espressif32@5.2.0
board_upload.flash_size = 4MB board_upload.flash_size = 4MB
board_build.partitions = esp32_partition_4M.csv board_build.partitions = esp32_partition_4M.csv
build_flags = ${common.build_flags} build_flags = ${common.build_flags}
@@ -78,7 +78,7 @@ extra_scripts =
pre:scripts/build_interface.py pre:scripts/build_interface.py
scripts/rename_fw.py scripts/rename_fw.py
board = esp32dev board = esp32dev
platform = espressif32 platform = espressif32@5.2.0
board_upload.flash_size = 16MB board_upload.flash_size = 16MB
board_build.partitions = esp32_partition_16M.csv board_build.partitions = esp32_partition_16M.csv
build_flags = ${common.build_flags} build_flags = ${common.build_flags}
@@ -89,7 +89,7 @@ extra_scripts =
pre:scripts/build_interface.py pre:scripts/build_interface.py
scripts/rename_fw.py scripts/rename_fw.py
board = lolin_c3_mini board = lolin_c3_mini
platform = espressif32 platform = espressif32@5.2.0
board_upload.flash_size = 4MB board_upload.flash_size = 4MB
board_build.partitions = esp32_partition_4M.csv board_build.partitions = esp32_partition_4M.csv
build_flags = ${common.build_flags} build_flags = ${common.build_flags}
@@ -102,7 +102,7 @@ extra_scripts =
pre:scripts/build_interface.py pre:scripts/build_interface.py
scripts/rename_fw.py scripts/rename_fw.py
board = lolin_c3_mini board = lolin_c3_mini
platform = espressif32 platform = espressif32@5.2.0
board_upload.flash_size = 4MB board_upload.flash_size = 4MB
board_build.partitions = esp32_partition_4M.csv board_build.partitions = esp32_partition_4M.csv
build_flags = ${common.build_flags} -DBOARD_C3_MINI_V1 build_flags = ${common.build_flags} -DBOARD_C3_MINI_V1
@@ -113,7 +113,7 @@ extra_scripts =
pre:scripts/build_interface.py pre:scripts/build_interface.py
scripts/rename_fw.py scripts/rename_fw.py
board = lolin_s2_mini board = lolin_s2_mini
platform = espressif32 platform = espressif32@5.2.0
board_upload.flash_size = 4MB board_upload.flash_size = 4MB
board_build.partitions = esp32_partition_4M.csv board_build.partitions = esp32_partition_4M.csv
build_flags = ${common.build_flags} build_flags = ${common.build_flags}

View File

@@ -320,6 +320,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
99); 99);
} }
*/ */
// heatpump info // heatpump info
if (model() == EMS_DEVICE_FLAG_HEATPUMP) { if (model() == EMS_DEVICE_FLAG_HEATPUMP) {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,

View File

@@ -26,8 +26,6 @@ uuid::log::Logger Thermostat::logger_{F_(thermostat), uuid::log::Facility::CONSO
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) 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) { : 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 // 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) { if (device_id >= 0x40 && device_id <= 0x47) {
register_telegram_type(0x0435, "RFTemp", false, MAKE_PF_CB(process_RemoteTemp)); register_telegram_type(0x0435, "RFTemp", false, MAKE_PF_CB(process_RemoteTemp));
@@ -48,6 +46,9 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
register_telegram_type(0xA2, "RCError", false, MAKE_PF_CB(process_RCError)); 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(0x12, "RCErrorMessage", false, MAKE_PF_CB(process_RCErrorMessage));
register_telegram_type(0x13, "RCErrorMessage2", false, MAKE_PF_CB(process_RCErrorMessage)); register_telegram_type(0x13, "RCErrorMessage2", false, MAKE_PF_CB(process_RCErrorMessage));
uint8_t model = this->model();
// RC10 // RC10
if (model == EMSdevice::EMS_DEVICE_FLAG_RC10) { if (model == EMSdevice::EMS_DEVICE_FLAG_RC10) {
monitor_typeids = {0xB1}; monitor_typeids = {0xB1};
@@ -3384,6 +3385,7 @@ void Thermostat::register_device_values() {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &errorCode_, DeviceValueType::STRING, FL_(errorCode), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &errorCode_, DeviceValueType::STRING, FL_(errorCode), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &lastCode_, DeviceValueType::STRING, FL_(lastCode), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &lastCode_, DeviceValueType::STRING, FL_(lastCode), DeviceValueUOM::NONE);
switch (this->model()) { switch (this->model()) {
case EMS_DEVICE_FLAG_RC100: case EMS_DEVICE_FLAG_RC100:
case EMS_DEVICE_FLAG_RC300: case EMS_DEVICE_FLAG_RC300:
@@ -4008,6 +4010,11 @@ void Thermostat::register_device_values() {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime
break; break;
} }
#if defined(EMSESP_STANDALONE_DUMP)
// if we're just dumping out values, create a single dummy hc
register_device_values_hc(std::make_shared<emsesp::Thermostat::HeatingCircuit>(1, this->model())); // hc=1
#endif
} }
// registers the values for a heating circuit // registers the values for a heating circuit
@@ -4031,6 +4038,7 @@ void Thermostat::register_device_values_hc(std::shared_ptr<Thermostat::HeatingCi
seltemp_divider = DeviceValueNumOp::DV_NUMOP_DIV2; seltemp_divider = DeviceValueNumOp::DV_NUMOP_DIV2;
roomtemp_divider = DeviceValueNumOp::DV_NUMOP_DIV10; roomtemp_divider = DeviceValueNumOp::DV_NUMOP_DIV10;
} }
if (has_flags(EMS_DEVICE_FLAG_NO_WRITE)) { if (has_flags(EMS_DEVICE_FLAG_NO_WRITE)) {
register_device_value(tag, &hc->selTemp, DeviceValueType::SHORT, seltemp_divider, FL_(selRoomTemp), DeviceValueUOM::DEGREES); register_device_value(tag, &hc->selTemp, DeviceValueType::SHORT, seltemp_divider, FL_(selRoomTemp), DeviceValueUOM::DEGREES);
} else { } else {

View File

@@ -436,17 +436,6 @@ void EMSdevice::add_device_value(uint8_t tag,
const cmd_function_p f, const cmd_function_p f,
int16_t min, int16_t min,
uint16_t max) { uint16_t max) {
bool has_cmd = (f != nullptr);
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 // initialize the device value depending on it's type
// ignoring DeviceValueType::CMD and DeviceValueType::TIME // ignoring DeviceValueType::CMD and DeviceValueType::TIME
if (type == DeviceValueType::STRING) { if (type == DeviceValueType::STRING) {
@@ -467,11 +456,18 @@ void EMSdevice::add_device_value(uint8_t tag,
*(uint8_t *)(value_p) = EMS_VALUE_DEFAULT_ENUM; // enums behave as uint8_t *(uint8_t *)(value_p) = EMS_VALUE_DEFAULT_ENUM; // enums behave as uint8_t
} }
// determine state uint8_t state = DeviceValueState::DV_DEFAULT; // determine state
uint8_t state = DeviceValueState::DV_DEFAULT; std::string custom_fullname = std::string(""); // custom fullname
auto short_name = name[0]; // entity name
bool has_cmd = (f != nullptr); // is it a command?
// custom fullname // get fullname, getting translation if it exists
std::string custom_fullname = std::string(""); 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
}
// scan through customizations to see if it's on the exclusion list by matching the productID and deviceID // scan through customizations to see if it's on the exclusion list by matching the productID and deviceID
EMSESP::webCustomizationService.read([&](WebCustomization & settings) { EMSESP::webCustomizationService.read([&](WebCustomization & settings) {
@@ -511,10 +507,7 @@ void EMSdevice::add_device_value(uint8_t tag,
device_type_, tag, value_p, type, options, options_single, numeric_operator, short_name, fullname, custom_fullname, uom, has_cmd, min, max, state); device_type_, tag, value_p, type, options, options_single, numeric_operator, short_name, fullname, custom_fullname, uom, has_cmd, min, max, state);
// add a new command if it has a function attached // add a new command if it has a function attached
if (!has_cmd) { if (has_cmd) {
return;
}
uint8_t flags = CommandFlag::ADMIN_ONLY; // executing commands require admin privileges uint8_t flags = CommandFlag::ADMIN_ONLY; // executing commands require admin privileges
if (tag >= DeviceValueTAG::TAG_HC1 && tag <= DeviceValueTAG::TAG_HC8) { if (tag >= DeviceValueTAG::TAG_HC1 && tag <= DeviceValueTAG::TAG_HC8) {
@@ -527,6 +520,7 @@ void EMSdevice::add_device_value(uint8_t tag,
// add the command to our library // add the command to our library
Command::add(device_type_, device_id_, short_name, f, fullname, flags); Command::add(device_type_, device_id_, short_name, f, fullname, flags);
}
} }
// single list of options // single list of options
@@ -1069,9 +1063,12 @@ void EMSdevice::getCustomEntities(std::vector<std::string> & entity_ids) {
#if defined(EMSESP_STANDALONE_DUMP) #if defined(EMSESP_STANDALONE_DUMP)
// dumps all entity values in native English // dumps all entity values in native English
// device name,device type,product_id,shortname,fullname,type [(enum values) | (min/max)],uom,writeable,discovery_entityid // the code is intended to run only once standalone, outside the ESP32 so not optimized for memory efficiency
// pipe symbols (|) are escaped so they can be converted to Markdown in the Wiki
// format is: device name,device type,product id,shortname,fullname,type [options...] \\| (min/max),uom,writeable,discovery entityid v3.4, discovery entityid
void EMSdevice::dump_value_info() { void EMSdevice::dump_value_info() {
for (auto & dv : devicevalues_) { for (auto & dv : devicevalues_) {
if (dv.fullname != nullptr) {
Serial.print(name_); Serial.print(name_);
Serial.print(','); Serial.print(',');
Serial.print(device_type_name().c_str()); Serial.print(device_type_name().c_str());
@@ -1086,33 +1083,25 @@ void EMSdevice::dump_value_info() {
Serial.print(dv.fullname[0]); Serial.print(dv.fullname[0]);
Serial.print(','); Serial.print(',');
// type and optional enum values and min/max // per type
switch (dv.type) { switch (dv.type) {
case DeviceValueType::ENUM: { case DeviceValueType::ENUM:
case DeviceValueType::CMD:
if (dv.type == DeviceValueType::ENUM) {
Serial.print("enum"); Serial.print("enum");
Serial.print(" ("); } else {
for (uint8_t i = 0; i < dv.options_size; i++) { Serial.print("cmd");
Serial.print(Helpers::translated_word(dv.options[i]));
if (i < dv.options_size - 1) {
Serial.print('|');
}
}
Serial.print(')');
break;
} }
case DeviceValueType::CMD: { Serial.print(" [");
Serial.print("cmd");
Serial.print(" (");
for (uint8_t i = 0; i < dv.options_size; i++) { for (uint8_t i = 0; i < dv.options_size; i++) {
Serial.print(Helpers::translated_word(dv.options[i])); Serial.print(dv.options[i][0]);
if (i < dv.options_size - 1) { if (i < dv.options_size - 1) {
Serial.print('|'); Serial.print("\\|");
} }
} }
Serial.print(')'); Serial.print(']');
break; break;
}
case DeviceValueType::USHORT: case DeviceValueType::USHORT:
Serial.print("ushort"); Serial.print("ushort");
@@ -1160,7 +1149,6 @@ void EMSdevice::dump_value_info() {
Serial.print(dv_set_max); Serial.print(dv_set_max);
Serial.print(")"); Serial.print(")");
} }
Serial.print(","); Serial.print(",");
// uom // uom
@@ -1175,22 +1163,37 @@ void EMSdevice::dump_value_info() {
Serial.print(dv.has_cmd ? "true" : "false"); Serial.print(dv.has_cmd ? "true" : "false");
Serial.print(","); Serial.print(",");
// MQTT Discovery entity name, assuming we're using the default v3.5 option // MQTT Discovery entity name
char entity_with_tag[50]; // do this twice for the old and new formats
char entity_with_tag[200];
char entityid[500];
char entity_name[100];
for (uint8_t count = 0; count < 2; count++) {
if (count) {
// new name, comes as last
Serial.print(",");
strcpy(entity_name, dv.short_name);
} else {
// old format, comes first
char uniq_s[100];
strlcpy(uniq_s, dv.fullname[0], sizeof(uniq_s));
Helpers::replace_char(uniq_s, ' ', '_');
strcpy(entity_name, uniq_s);
}
if (dv.tag >= DeviceValueTAG::TAG_HC1) { if (dv.tag >= DeviceValueTAG::TAG_HC1) {
snprintf(entity_with_tag, snprintf(entity_with_tag,
sizeof(entity_with_tag), sizeof(entity_with_tag),
"%s_%s_%s", "%s_%s_%s",
device_type_2_device_name(device_type_), device_type_2_device_name(device_type_),
EMSdevice::tag_to_mqtt(dv.tag).c_str(), EMSdevice::tag_to_mqtt(dv.tag).c_str(),
dv.short_name); entity_name);
} else { } else {
// should really test for which device types have tags (like hc, wwc etc) snprintf(entity_with_tag, sizeof(entity_with_tag), "%s_%s", device_type_2_device_name(device_type_), entity_name);
// snprintf(entity_with_tag, sizeof(entity_with_tag), "%s_[<tag>_]%s", device_type_2_device_name(device_type_), dv.short_name);
snprintf(entity_with_tag, sizeof(entity_with_tag), "%s_%s", device_type_2_device_name(device_type_), dv.short_name);
} }
char entityid[150];
if (dv.has_cmd) { if (dv.has_cmd) {
switch (dv.type) { switch (dv.type) {
case DeviceValueType::INT: case DeviceValueType::INT:
@@ -1219,9 +1222,11 @@ void EMSdevice::dump_value_info() {
} }
Serial.print(entityid); Serial.print(entityid);
}
Serial.println(); Serial.println();
} }
}
} }
#endif #endif

View File

@@ -63,7 +63,7 @@ DeviceValue::DeviceValue(uint8_t device_type,
// set the min/max // set the min/max
set_custom_minmax(); set_custom_minmax();
/* /*
#ifdef EMSESP_STANDALONE #ifdef EMSESP_STANDALONE
// only added for debugging // only added for debugging
Serial.print(COLOR_BRIGHT_RED_BACKGROUND); Serial.print(COLOR_BRIGHT_RED_BACKGROUND);

View File

@@ -313,14 +313,27 @@ void EMSESP::show_ems(uuid::console::Shell & shell) {
void EMSESP::dump_all_values(uuid::console::Shell & shell) { void EMSESP::dump_all_values(uuid::console::Shell & shell) {
Serial.println("---- CSV START ----"); // marker use by py script Serial.println("---- CSV START ----"); // marker use by py script
// add header for CSV // add header for CSV
Serial.print("device name,device type,product_id,shortname,fullname,type [(enum values) | (min/max)],uom,writeable,discovery_entityid"); Serial.print(
"device name,device type,product id,shortname,fullname,type [options...] \\| (min/max),uom,writeable,discovery entityid v3.4, discovery entityid");
Serial.println(); Serial.println();
for (const auto & device_class : EMSFactory::device_handlers()) { for (const auto & device_class : EMSFactory::device_handlers()) {
// go through each device type so they are sorted // go through each device type so they are sorted
for (const auto & device : device_library_) { for (const auto & device : device_library_) {
if (device_class.first == device.device_type) { if (device_class.first == device.device_type) {
emsdevices.push_back(EMSFactory::add(device.device_type, 0, device.product_id, "1.0", device.name, device.flags, EMSdevice::Brand::NO_BRAND)); uint8_t device_id = 0;
// Mixer class looks at device_id to determine type, so fixing to 0x28 which will give all the settings except flowSetTemp
if ((device.device_type == DeviceType::MIXER) && (device.flags == EMSdevice::EMS_DEVICE_FLAG_MMPLUS)) {
// pick one as hc and the other as having wwc
if (device.product_id == 160) { // MM100
device_id = 0x28; // wwc
} else {
device_id = 0x20; // hc
}
}
emsdevices.push_back(
EMSFactory::add(device.device_type, device_id, device.product_id, "1.0", device.name, device.flags, EMSdevice::Brand::NO_BRAND));
emsdevices.back()->dump_value_info(); // dump all the entity information emsdevices.back()->dump_value_info(); // dump all the entity information
} }
} }