Merge pull request #1843 from MichaelDvP/dev

remotetemp CMD, temperaturesensor id, controlsettings BC400, Boiler/HP
This commit is contained in:
Proddy
2024-07-04 16:52:18 +02:00
committed by GitHub
11 changed files with 71 additions and 23 deletions

View File

@@ -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)

View File

@@ -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[]) => ({

View File

@@ -720,11 +720,7 @@ void Thermostat::process_RC20Set_2(std::shared_ptr<const Telegram> telegram) {
// 0xAF - for reading the roomtemperature from the RC20/ES72 thermostat (0x18, 0x19, ..)
void Thermostat::process_RC20Remote(std::shared_ptr<const Telegram> 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_ptr<Thermostat::HeatingCi
register_device_value(tag, &hc->dewoffset, 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));
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_ptr<Thermostat::HeatingCi
tag, &hc->heatingtype, 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_ptr<Thermostat::HeatingCi
tag, &hc->vacreducemode, 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_ptr<Thermostat::HeatingCi
register_device_value(tag, &hc->program, 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,

View File

@@ -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
}

View File

@@ -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))

View File

@@ -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

View File

@@ -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
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:

View File

@@ -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<JsonObject>());
}
@@ -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,

View File

@@ -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;

View File

@@ -1 +1 @@
#define EMSESP_APP_VERSION "3.7.0-dev.21"
#define EMSESP_APP_VERSION "3.7.0-dev.22"

View File

@@ -99,6 +99,10 @@ StateUpdateResult WebCustomization::update(JsonObject root, WebCustomization & c
sensor.id = sensorJson["id"].as<std::string>();
sensor.name = sensorJson["name"].as<std::string>();
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
}
}