diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index bcee95903..11de8eaed 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -6,6 +6,7 @@ - new device WATER shows dhw entities from MM100 and SM100 in dhw setting - renamed WWC to DHW, always create DHW nests/topics, remove ww prefix from mqtt names [#1634](https://github.com/emsesp/EMS-ESP32/issues/1634) +- change temperaturesensor id to underscore ## Added @@ -42,5 +43,7 @@ - rename DeviceValueTypes, add UINT32 for custom entities - dynamic register dhw circuits for thermostat - removed OTA feature [#1738](https://github.com/emsesp/EMS-ESP32/issues/1738) -- added shower min duration [[#1801](https://github.com/emsesp/EMS-ESP32/issues/1801)] +- added shower min duration [#1801](https://github.com/emsesp/EMS-ESP32/issues/1801) - Include TXT file along with the generated CSV for Device Data export/download +- thermostat/remotetemp as command [#1835](https://github.com/emsesp/EMS-ESP32/discussions/1835) +- temperaturesensor id notation with underscore [#1794](https://github.com/emsesp/EMS-ESP32/discussions/1794) diff --git a/interface/src/project/validators.ts b/interface/src/project/validators.ts index 168685da6..348a46970 100644 --- a/interface/src/project/validators.ts +++ b/interface/src/project/validators.ts @@ -389,7 +389,13 @@ export const entityItemValidation = (entity: EntityItem[], entityItem: EntityIte export const temperatureSensorItemValidation = () => new Schema({ - n: [{ required: true, message: 'Name is required' }] + n: [ + { + type: 'string', + pattern: /^[a-zA-Z0-9_\\.]{0,15}$/, + message: "Must be <15 characters: alpha numeric, '_' or '.'" + } + ] }); export const isGPIOUniqueValidator = (sensors: AnalogSensor[]) => ({ diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 8ebcef611..2e1ceb0cb 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -720,11 +720,7 @@ void Thermostat::process_RC20Set_2(std::shared_ptr telegram) { // 0xAF - for reading the roomtemperature from the RC20/ES72 thermostat (0x18, 0x19, ..) void Thermostat::process_RC20Remote(std::shared_ptr telegram) { - auto hc = heating_circuit(telegram); - if (hc == nullptr) { - return; - } - has_update(telegram, hc->remotetemp, 0); + has_update(telegram, tempsensor1_, 0); } // 0x42B - for reading the roomtemperature from the RC100H remote thermostat (0x38, 0x39, ..) @@ -2035,6 +2031,22 @@ bool Thermostat::set_control(const char * value, const int8_t id) { write_command(set_typeids[hc->hc()], 1, ctrl); return true; } + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400) { + if (Helpers::value2enum(value, ctrl, FL_(enum_control2))) { + write_command(hpmode_typeids[hc->hc()], 3, ctrl); + hc->control = ctrl; // set in advance, dont wait for verify + if (hc->remotetemp != EMS_VALUE_INT16_NOTSET && ctrl > 0) { + if (ctrl == 2) { + Roomctrl::set_remotetemp(Roomctrl::RC100, hc->hc(), hc->remotetemp); + } else if (ctrl == 3) { + Roomctrl::set_remotetemp(Roomctrl::RC100H, hc->hc(), hc->remotetemp); + } else { + hc->remotetemp = EMS_VALUE_INT16_NOTSET; + Roomctrl::set_remotetemp(0, hc->hc(), hc->remotetemp); + } + } + return true; + } } else if (isRC300() || model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, ctrl, FL_(enum_control1))) { write_command(hpmode_typeids[hc->hc()], 3, ctrl); @@ -4428,10 +4440,14 @@ void Thermostat::register_device_values_hc(std::shared_ptrdewoffset, DeviceValueType::UINT8, FL_(dewoffset), DeviceValueUOM::K, MAKE_CF_CB(set_dewoffset), 2, 10); register_device_value(tag, &hc->roomtempdiff, DeviceValueType::UINT8, FL_(roomtempdiff), DeviceValueUOM::K, MAKE_CF_CB(set_roomtempdiff)); register_device_value(tag, &hc->hpminflowtemp, DeviceValueType::UINT8, FL_(hpminflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_hpminflowtemp)); - register_device_value(tag, &hc->control, DeviceValueType::ENUM, FL_(enum_control1), FL_(control), DeviceValueUOM::NONE, MAKE_CF_CB(set_control)); + if (model == EMSdevice::EMS_DEVICE_FLAG_BC400) { + register_device_value(tag, &hc->control, DeviceValueType::ENUM, FL_(enum_control2), FL_(control), DeviceValueUOM::NONE, MAKE_CF_CB(set_control)); + } else { + register_device_value(tag, &hc->control, DeviceValueType::ENUM, FL_(enum_control1), FL_(control), DeviceValueUOM::NONE, MAKE_CF_CB(set_control)); + } register_device_value(tag, &hc->remotetemp, - DeviceValueType::INT16, + DeviceValueType::CMD, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(remotetemp), DeviceValueUOM::DEGREES, @@ -4504,7 +4520,7 @@ void Thermostat::register_device_values_hc(std::shared_ptrheatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype), FL_(heatingtype), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatingtype)); register_device_value(tag, &hc->summertemp, DeviceValueType::UINT8, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp), 10, 30); register_device_value(tag, &hc->summermode, DeviceValueType::ENUM, FL_(enum_summer), FL_(summermode), DeviceValueUOM::NONE); - register_device_value(tag, &hc->remotetemp, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(remotetemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &tempsensor1_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(remotetemp), DeviceValueUOM::DEGREES); break; case EMSdevice::EMS_DEVICE_FLAG_RC25: register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode3), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); @@ -4655,7 +4671,7 @@ void Thermostat::register_device_values_hc(std::shared_ptrvacreducemode, DeviceValueType::ENUM, FL_(enum_reducemode), FL_(vacreducemode), DeviceValueUOM::NONE, MAKE_CF_CB(set_vacreducemode)); register_device_value(tag, &hc->remotetemp, - DeviceValueType::INT16, + DeviceValueType::CMD, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(remotetemp), DeviceValueUOM::DEGREES, @@ -4692,7 +4708,7 @@ void Thermostat::register_device_values_hc(std::shared_ptrprogram, DeviceValueType::ENUM, FL_(enum_progMode4), FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program)); register_device_value(tag, &hc->remotetemp, - DeviceValueType::INT16, + DeviceValueType::CMD, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(remotetemp), DeviceValueUOM::DEGREES, diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 0175d5bba..3153f94b1 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -155,6 +155,9 @@ const char * EMSdevice::device_type_2_device_name(const uint8_t device_type) { const char * EMSdevice::device_type_2_device_name_translated() { switch (device_type_) { case DeviceType::BOILER: + if (flags_ == EMS_DEVICE_FLAG_HEATPUMP) { + return Helpers::translated_word(FL_(boiler_hp_device)); + } return Helpers::translated_word(FL_(boiler_device)); case DeviceType::THERMOSTAT: return Helpers::translated_word(FL_(thermostat_device)); @@ -534,6 +537,12 @@ void EMSdevice::add_device_value(int8_t tag, // to b *(int8_t *)(value_p) = System::test_set_all_active() ? EMS_VALUE_DEFAULT_BOOL_DUMMY : EMS_VALUE_DEFAULT_BOOL; // bool is uint8_t, but other initial value } else if (type == DeviceValueType::ENUM) { *(uint8_t *)(value_p) = System::test_set_all_active() ? EMS_VALUE_DEFAULT_ENUM_DUMMY : EMS_VALUE_DEFAULT_ENUM; // enums behave as uint8_t + } else if (type == DeviceValueType::CMD) { + if (uom == DeviceValueUOM::NONE) { + *(uint8_t *)(value_p) = System::test_set_all_active() ? EMS_VALUE_DEFAULT_ENUM_DUMMY : EMS_VALUE_DEFAULT_ENUM; // enums behave as uint8_t + } else if (uom == DeviceValueUOM::DEGREES) { + *(int16_t *)(value_p) = System::test_set_all_active() ? EMS_VALUE_DEFAULT_INT16_DUMMY : EMS_VALUE_DEFAULT_INT16; + } } uint8_t state = DeviceValueState::DV_DEFAULT; // determine state @@ -981,7 +990,7 @@ void EMSdevice::generate_values_web(JsonObject output) { l.add(Helpers::render_boolean(result, true, true)); } // add command help template - else if (dv.type == DeviceValueType::STRING || dv.type == DeviceValueType::CMD) { + else if (dv.type == DeviceValueType::STRING || (dv.type == DeviceValueType::CMD && dv.uom == DeviceValueUOM::NONE)) { if (dv.options_size == 1) { obj["h"] = dv.options_single[0]; // NOT translated } diff --git a/src/locale_common.h b/src/locale_common.h index 787272ffd..442d8cc79 100644 --- a/src/locale_common.h +++ b/src/locale_common.h @@ -180,6 +180,9 @@ MAKE_NOTRANSLATION(rc200, "RC200") MAKE_NOTRANSLATION(rc100, "RC100") MAKE_NOTRANSLATION(rc100h, "RC100H") MAKE_NOTRANSLATION(tc100, "TC100") +MAKE_NOTRANSLATION(rc120rf, "RC120RF") +MAKE_NOTRANSLATION(rc220, "RC220") +MAKE_NOTRANSLATION(single, "single") MAKE_NOTRANSLATION(dash, "-") MAKE_NOTRANSLATION(BLANK, "") MAKE_NOTRANSLATION(pwm, "pwm") @@ -342,6 +345,7 @@ MAKE_ENUM(enum_j_control, FL_(off), FL_(fb10), FL_(fb100)) MAKE_ENUM(enum_roomsensor, FL_(extern), FL_(intern), FL_(auto)) MAKE_ENUM(enum_roominfluence, FL_(off), FL_(intern), FL_(extern), FL_(auto)) MAKE_ENUM(enum_control1, FL_(rc310), FL_(rc200), FL_(rc100), FL_(rc100h), FL_(tc100)) +MAKE_ENUM(enum_control2, FL_(off), FL_(dash), FL_(rc100), FL_(rc100h), FL_(dash), FL_(rc120rf), FL_(rc220), FL_(single)) // BC400 MAKE_ENUM(enum_switchmode, FL_(off), FL_(eco), FL_(comfort), FL_(heat)) diff --git a/src/locale_translations.h b/src/locale_translations.h index ca1d8790e..6ee851ee6 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -36,6 +36,7 @@ // if there is no translation, it will default to en // // device types, as display in Web and Console +MAKE_WORD_TRANSLATION(boiler_hp_device, "Boiler/HP", "Kessel/WP", "CV ketel/WP", "Värmepanna/VP", "Kocioł/PC", "Varmekjele/VP", "", "Kazan/IP", "Caldaia/PC", "Bojler/Tč") // TODO translate MAKE_WORD_TRANSLATION(boiler_device, "Boiler", "Kessel", "CV ketel", "Värmepanna", "Kocioł", "Varmekjele", "", "Kazan", "Caldaia", "Bojler") // TODO translate MAKE_WORD_TRANSLATION(thermostat_device, "Thermostat", "Thermostat", "Thermostaat", "Termostat", "Termostat", "Termostat", "", "Termostat", "Termostato", "Termostat") // TODO translate MAKE_WORD_TRANSLATION(heatpump_device, "Heat Pump", "Wärmepumpe", "Warmtepomp", "Värmepump", "Pompa ciepła", "Varmepumpe", "", "Isı Pompası", "Pompa di Calore", "Tepelné čerpadlo") // TODO translate diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 211f8d0b2..e912bcacc 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -959,9 +959,18 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev readonly_sensors = false; break; case DeviceValueType::ENUM: + snprintf(topic, sizeof(topic), "select/%s", config_topic); + readonly_sensors = false; + break; case DeviceValueType::CMD: // hardcoded commands are always ENUMS // select - https://www.home-assistant.io/integrations/select.mqtt - snprintf(topic, sizeof(topic), "select/%s", config_topic); + if (uom == DeviceValueUOM::NONE) { + snprintf(topic, sizeof(topic), "select/%s", config_topic); + } else if (discovery_type() == discoveryType::HOMEASSISTANT || discovery_type() == discoveryType::DOMOTICZ_LATEST) { + snprintf(topic, sizeof(topic), "number/%s", config_topic); + } else { + snprintf(topic, sizeof(topic), "sensor/%s", config_topic); + } readonly_sensors = false; break; case DeviceValueType::STRING: diff --git a/src/temperaturesensor.cpp b/src/temperaturesensor.cpp index 3b0773e34..7766b465c 100644 --- a/src/temperaturesensor.cpp +++ b/src/temperaturesensor.cpp @@ -556,11 +556,7 @@ void TemperatureSensor::publish_values(const bool force) { Mqtt::add_ha_sections_to_doc("temperature", stat_t, config, !is_ha_device_created, val_cond); char topic[Mqtt::MQTT_TOPIC_MAX_SIZE]; - // use '_' as HA doesn't like '-' in the topic name - std::string sensorid = sensor.id(); - std::replace(sensorid.begin(), sensorid.end(), '-', '_'); - - snprintf(topic, sizeof(topic), "sensor/%s/%s_%s/config", Mqtt::basename().c_str(), F_(temperaturesensor), sensorid.c_str()); + snprintf(topic, sizeof(topic), "sensor/%s/%s_%s/config", Mqtt::basename().c_str(), F_(temperaturesensor), sensor.id().c_str()); sensor.ha_registered = Mqtt::queue_ha(topic, config.as()); } @@ -580,7 +576,7 @@ TemperatureSensor::Sensor::Sensor(const uint8_t addr[]) char id_s[20]; snprintf(id_s, sizeof(id_s), - "%02X-%04X-%04X-%04X", + "%02X_%04X_%04X_%04X", (unsigned int)(internal_id_ >> 48) & 0xFF, (unsigned int)(internal_id_ >> 32) & 0xFFFF, (unsigned int)(internal_id_ >> 16) & 0xFFFF, diff --git a/src/test/test.cpp b/src/test/test.cpp index 9ff67b305..3fec354fd 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -793,7 +793,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const EMSESP::webAPIService.webAPIService(&request); request.url("/api/temperaturesensor/info"); EMSESP::webAPIService.webAPIService(&request); - request.url("/api/temperaturesensor/01-0203-0405-0607"); + request.url("/api/temperaturesensor/01_0203_0405_0607"); EMSESP::webAPIService.webAPIService(&request); ok = true; @@ -810,7 +810,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const shell.invoke_command("call system publish"); // rename - EMSESP::temperaturesensor_.update("01-0203-0405-0607", "testtemperature", 2); + EMSESP::temperaturesensor_.update("01_0203_0405_0607", "testtemperature", 2); shell.invoke_command("show values"); shell.invoke_command("call system publish"); ok = true; diff --git a/src/version.h b/src/version.h index 344e2f19f..af68b2d00 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.7.0-dev.21" +#define EMSESP_APP_VERSION "3.7.0-dev.22" diff --git a/src/web/WebCustomizationService.cpp b/src/web/WebCustomizationService.cpp index 407acbbf4..afefbb992 100644 --- a/src/web/WebCustomizationService.cpp +++ b/src/web/WebCustomizationService.cpp @@ -99,6 +99,10 @@ StateUpdateResult WebCustomization::update(JsonObject root, WebCustomization & c sensor.id = sensorJson["id"].as(); sensor.name = sensorJson["name"].as(); sensor.offset = sensorJson["offset"]; + if (sensor.id == sensor.name) { + sensor.name = ""; // no need to store id as name + } + std::replace(sensor.id.begin(), sensor.id.end(), '-', '_'); // change old ids to v3.7 style customizations.sensorCustomizations.push_back(sensor); // add to list } }