Merge remote-tracking branch 'upstream/dev' into dev

This commit is contained in:
hpanther
2020-10-30 14:38:31 +01:00
26 changed files with 389 additions and 282 deletions

View File

@@ -123,6 +123,10 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
register_telegram_type(0x31B, F("RC300WWtemp"), true, [&](std::shared_ptr<const Telegram> t) { process_RC300WWtemp(t); });
register_telegram_type(0x31D, F("RC300WWmode2"), false, [&](std::shared_ptr<const Telegram> t) { process_RC300WWmode2(t); });
register_telegram_type(0x31E, F("RC300WWmode2"), false, [&](std::shared_ptr<const Telegram> t) { process_RC300WWmode2(t); });
register_telegram_type(0x23A, F("RC300OutdoorTemp"), true, [&](std::shared_ptr<const Telegram> t) { process_RC300OutdoorTemp(t); });
register_telegram_type(0x267, F("RC300Floordry"), false, [&](std::shared_ptr<const Telegram> t) { process_RC300Floordry(t); });
register_telegram_type(0x240, F("RC300Settings"), true, [&](std::shared_ptr<const Telegram> t) { process_RC300Settings(t); });
register_telegram_type(0xBF, F("RC300Error"), false, [&](std::shared_ptr<const Telegram> t) { process_RC300Error(t); });
// JUNKERS/HT3
} else if (model == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) {
@@ -186,6 +190,8 @@ void Thermostat::device_info_web(JsonArray & root) {
print_value_json(root, F("intoffset"), nullptr, F_(intoffset), nullptr, json_main);
print_value_json(root, F("minexttemp"), nullptr, F_(minexttemp), F_(degrees), json_main);
print_value_json(root, F("building"), nullptr, F_(building), nullptr, json_main);
print_value_json(root, F("floordry"), nullptr, F_(floordry), nullptr, json_main);
print_value_json(root, F("floordrytemp"), nullptr, F_(floordrytemp), F_(degrees), json_main);
print_value_json(root, F("wwmode"), nullptr, F_(wwmode), nullptr, json_main);
print_value_json(root, F("wwtemp"), nullptr, F_(wwtemp), nullptr, json_main);
print_value_json(root, F("wwtemplow"), nullptr, F_(wwtemplow), nullptr, json_main);
@@ -268,6 +274,8 @@ void Thermostat::show_values(uuid::console::Shell & shell) {
print_value_json(shell, F("intoffset"), nullptr, F_(intoffset), nullptr, json_main);
print_value_json(shell, F("minexttemp"), nullptr, F_(minexttemp), F_(degrees), json_main);
print_value_json(shell, F("building"), nullptr, F_(building), nullptr, json_main);
print_value_json(shell, F("floordry"), nullptr, F_(floordry), nullptr, json_main);
print_value_json(shell, F("floordrytemp"), nullptr, F_(floordrytemp), F_(degrees), json_main);
print_value_json(shell, F("wwmode"), nullptr, F_(wwmode), nullptr, json_main);
print_value_json(shell, F("wwtemp"), nullptr, F_(wwtemp), nullptr, json_main);
print_value_json(shell, F("wwtemplow"), nullptr, F_(wwtemplow), nullptr, json_main);
@@ -399,11 +407,23 @@ bool Thermostat::export_values_main(JsonObject & rootThermostat) {
}
}
// Damped outdoor temperature
// Damped outdoor temperature (RC35)
if (Helpers::hasValue(dampedoutdoortemp_)) {
rootThermostat["dampedtemp"] = dampedoutdoortemp_;
}
// Damped outdoor temperature (RC300)
if (Helpers::hasValue(dampedoutdoortemp2_)) {
rootThermostat["dampedtemp"] = (float)dampedoutdoortemp2_ / 10;
}
// Floordry
if (Helpers::hasValue(floordrystatus_) && Helpers::hasValue(floordrytemp_) && (floordrytemp_ > 0)) {
char s[10];
rootThermostat["floordry"] = Helpers::render_enum(s, {"off", "start", "heat", "hold", "cool", "end"}, floordrystatus_);
rootThermostat["floordrytemp"] = floordrytemp_;
}
// Temp sensor 1
if (Helpers::hasValue(tempsensor1_)) {
rootThermostat["inttemp1"] = (float)tempsensor1_ / 10;
@@ -427,7 +447,11 @@ bool Thermostat::export_values_main(JsonObject & rootThermostat) {
// Building
if (Helpers::hasValue(ibaBuildingType_)) {
char s[10];
rootThermostat["building"] = Helpers::render_enum(s, {"light", "medium", "heavy"}, ibaBuildingType_);
if (model == EMS_DEVICE_FLAG_RC300 || model == EMS_DEVICE_FLAG_RC100) {
rootThermostat["building"] = Helpers::render_enum(s, {"light", "medium", "heavy"}, ibaBuildingType_ - 1);
} else {
rootThermostat["building"] = Helpers::render_enum(s, {"light", "medium", "heavy"}, ibaBuildingType_);
}
}
// Warm water mode
@@ -773,7 +797,7 @@ void Thermostat::register_mqtt_ha_config() {
Mqtt::publish_retain(F("homeassistant/sensor/ems-esp/thermostat/config"), doc.as<JsonObject>(), true); // publish the config payload with retain flag
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(time), this->device_type(), "time", nullptr, nullptr);
// Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(error), this->device_type(), "errorcode", nullptr, nullptr);
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(error), this->device_type(), "errorcode", nullptr, nullptr);
uint8_t model = this->model();
@@ -782,7 +806,16 @@ void Thermostat::register_mqtt_ha_config() {
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(language), this->device_type(), "language", nullptr, nullptr);
}
if (model == EMS_DEVICE_FLAG_RC35 || model == EMS_DEVICE_FLAG_RC35) {
if (model == EMS_DEVICE_FLAG_RC300 || model == EMS_DEVICE_FLAG_RC100) {
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(dampedtemp), this->device_type(), "dampedtemp", F_(degrees), F_(icontemperature));
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(building), this->device_type(), "building", nullptr, nullptr);
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(floordry), this->device_type(), "floordry", nullptr, nullptr);
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(floordrytemp), this->device_type(), "floordrytemp", F_(degrees), F_(icontemperature));
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(wwmode), this->device_type(), "wwmode", nullptr, nullptr);
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(wwtemp), this->device_type(), "wwtemp", F_(degrees), F_(icontemperature));
}
if (model == EMS_DEVICE_FLAG_RC35 || model == EMS_DEVICE_FLAG_RC30_1) {
// excluding inttemp1, inttemp2, intoffset, minexttemp
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(dampedtemp), this->device_type(), "dampedtemp", F_(degrees), F_(icontemperature));
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(building), this->device_type(), "building", nullptr, nullptr);
@@ -1266,6 +1299,37 @@ void Thermostat::process_RC300WWmode2(std::shared_ptr<const Telegram> telegram)
// pos 3 = current status of DHW circulation pump
}
// 0x23A damped outdoor temp
void Thermostat::process_RC300OutdoorTemp(std::shared_ptr<const Telegram> telegram) {
changed_ |= telegram->read_value(dampedoutdoortemp2_, 0); // is *10
}
// 0x240 RC300 parameter
void Thermostat::process_RC300Settings(std::shared_ptr<const Telegram> telegram) {
changed_ |= telegram->read_value(ibaBuildingType_ , 9); // 1=light, 2=medium, 3=heavy
}
// 0x267 RC300 floordrying
void Thermostat::process_RC300Floordry(std::shared_ptr<const Telegram> telegram) {
changed_ |= telegram->read_value(floordrystatus_ , 0);
changed_ |= telegram->read_value(floordrytemp_ , 1);
}
// 0xBF RC300 Errormessage
void Thermostat::process_RC300Error(std::shared_ptr<const Telegram> telegram) {
if (errorCode_.empty()) {
errorCode_.resize(10, '\0');
}
char buf[4];
buf[0] = telegram->message_data[5];
buf[1] = telegram->message_data[6];
buf[2] = telegram->message_data[7];
buf[3] = 0;
changed_ |= telegram->read_value(errorNumber_, 8);
snprintf_P(&errorCode_[0], errorCode_.capacity() + 1, PSTR("%s(%d)"), buf, errorNumber_);
}
// type 0x41 - data from the RC30 thermostat(0x10) - 14 bytes long
void Thermostat::process_RC30Monitor(std::shared_ptr<const Telegram> telegram) {
std::shared_ptr<Thermostat::HeatingCircuit> hc = heating_circuit(telegram);
@@ -1472,7 +1536,12 @@ bool Thermostat::set_building(const char * value, const int8_t id) {
}
LOG_INFO(F("Setting building to %s"), value);
write_command(EMS_TYPE_IBASettings, 6, bd, EMS_TYPE_IBASettings);
if ((this->model() == EMS_DEVICE_FLAG_RC300) || (this->model() == EMS_DEVICE_FLAG_RC100)) {
write_command(0x240, 9, bd + 1, 0x240);
} else {
write_command(EMS_TYPE_IBASettings, 6, bd, EMS_TYPE_IBASettings);
}
return true;
}
@@ -1676,7 +1745,7 @@ bool Thermostat::set_datetime(const char * value, const int8_t id) {
}
data[0] = tm_->tm_year - 100; // Bosch counts from 2000
data[1] = tm_->tm_mon;
data[1] = tm_->tm_mon + 1;
data[2] = tm_->tm_hour;
data[3] = tm_->tm_mday;
data[4] = tm_->tm_min;
@@ -2197,6 +2266,7 @@ void Thermostat::add_commands() {
register_mqtt_cmd(F("wwmode"), [&](const char * value, const int8_t id) { return set_wwmode(value, id); });
register_mqtt_cmd(F("wwtemp"), [&](const char * value, const int8_t id) { return set_wwtemp(value, id); });
register_mqtt_cmd(F("wwtemplow"), [&](const char * value, const int8_t id) { return set_wwtemplow(value, id); });
register_mqtt_cmd(F("building"), [&](const char * value, const int8_t id) { return set_building(value, id); });
break;
case EMS_DEVICE_FLAG_RC20_2:
register_mqtt_cmd(F("nighttemp"), [&](const char * value, const int8_t id) { return set_nighttemp(value, id); });
@@ -2238,4 +2308,4 @@ void Thermostat::add_commands() {
}
} // namespace emsesp
} // namespace emsesp

View File

@@ -147,10 +147,13 @@ class Thermostat : public EMSdevice {
uint8_t ibaBuildingType_ = EMS_VALUE_UINT_NOTSET; // building type: 0 = light, 1 = medium, 2 = heavy
uint8_t ibaClockOffset_ = EMS_VALUE_UINT_NOTSET; // offset (in sec) to clock, 0xff = -1 s, 0x02 = 2 s
uint16_t errorNumber_ = EMS_VALUE_USHORT_NOTSET;
int8_t dampedoutdoortemp_ = EMS_VALUE_INT_NOTSET;
uint16_t tempsensor1_ = EMS_VALUE_USHORT_NOTSET;
uint16_t tempsensor2_ = EMS_VALUE_USHORT_NOTSET;
uint16_t errorNumber_ = EMS_VALUE_USHORT_NOTSET;
int8_t dampedoutdoortemp_ = EMS_VALUE_INT_NOTSET;
uint16_t tempsensor1_ = EMS_VALUE_USHORT_NOTSET;
uint16_t tempsensor2_ = EMS_VALUE_USHORT_NOTSET;
int16_t dampedoutdoortemp2_ = EMS_VALUE_SHORT_NOTSET;
uint8_t floordrystatus_ = EMS_VALUE_UINT_NOTSET;
uint8_t floordrytemp_ = EMS_VALUE_UINT_NOTSET;
uint8_t wwExtra1_ = EMS_VALUE_UINT_NOTSET; // wwExtra active for wwSystem 1
uint8_t wwExtra2_ = EMS_VALUE_UINT_NOTSET;
@@ -267,6 +270,10 @@ class Thermostat : public EMSdevice {
void process_RC300WWmode(std::shared_ptr<const Telegram> telegram);
void process_RC300WWmode2(std::shared_ptr<const Telegram> telegram);
void process_RC300WWtemp(std::shared_ptr<const Telegram> telegram);
void process_RC300OutdoorTemp(std::shared_ptr<const Telegram> telegram);
void process_RC300Settings(std::shared_ptr<const Telegram> telegram);
void process_RC300Error(std::shared_ptr<const Telegram> telegram);
void process_RC300Floordry(std::shared_ptr<const Telegram> telegram);
void process_JunkersMonitor(std::shared_ptr<const Telegram> telegram);
void process_JunkersSet(std::shared_ptr<const Telegram> telegram);
void process_JunkersSet2(std::shared_ptr<const Telegram> telegram);

View File

@@ -311,7 +311,7 @@ std::string EMSdevice::telegram_type_name(std::shared_ptr<const Telegram> telegr
}
for (const auto & tf : telegram_functions_) {
if ((tf.telegram_type_id_ == telegram->type_id) && ((telegram->type_id & 0xFFF0) != 0xF0)) {
if ((tf.telegram_type_id_ == telegram->type_id) && (telegram->type_id != 0xFF)) {
return uuid::read_flash_string(tf.telegram_type_name_);
}
}

View File

@@ -239,6 +239,9 @@ MAKE_PSTR(inttemp2, "Temperature sensor 2")
MAKE_PSTR(intoffset, "Offset int. temperature")
MAKE_PSTR(minexttemp, "Min ext. temperature")
MAKE_PSTR(building, "Building")
MAKE_PSTR(floordry, "Floordrying")
MAKE_PSTR(floordrytemp, "Floordrying temperature")
MAKE_PSTR(wwmode, "Warm water mode")
MAKE_PSTR(wwtemp, "Warm water high temperature")
MAKE_PSTR(wwtemplow, "Warm water low temperature")

View File

@@ -796,9 +796,9 @@ void Mqtt::register_mqtt_ha_sensor(const char * prefix,
// name
char new_name[50];
if (prefix != nullptr) {
snprintf_P(new_name, sizeof(new_name), PSTR("%s %s %s"), device_name.c_str(), prefix, name);
snprintf_P(new_name, sizeof(new_name), PSTR("%s %s %s"), device_name.c_str(), prefix, uuid::read_flash_string(name).c_str());
} else {
snprintf_P(new_name, sizeof(new_name), PSTR("%s %s"), device_name.c_str(), name);
snprintf_P(new_name, sizeof(new_name), PSTR("%s %s"), device_name.c_str(), uuid::read_flash_string(name).c_str());
}
new_name[0] = toupper(new_name[0]); // capitalize first letter

View File

@@ -171,21 +171,22 @@ void RxService::add(uint8_t * data, uint8_t length) {
// EMS 1 has type_id always in data[2], if it gets a ems+ inquiry it will reply with FF but short length
// i.e. sending 0B A1 FF 00 01 D8 20 CRC to a MM10 Mixer (ems1.0), the reply is 21 0B FF 00 CRC
// see: https://github.com/proddy/EMS-ESP/issues/380#issuecomment-633663007
if (data[2] < 0xF0 || length < 6) {
if (data[2] != 0xFF || length < 6) {
// EMS 1.0
// also handle F7, F9 as EMS 1.0, see https://github.com/proddy/EMS-ESP/issues/109#issuecomment-492781044
type_id = data[2];
message_data = data + 4;
message_length = length - 5;
} else if (data[1] & 0x80) {
// EMS 2.0 read request
type_id = (data[5] << 8) + data[6] + 256;
message_data = data + 4; // only data is the requested length
message_length = 1;
} else {
// EMS 2.0 / EMS+
uint8_t shift = 0; // default when data[2] is 0xFF
if (data[2] != 0xFF) {
// its F9 or F7, re-calculate shift. If the 5th byte is not 0xFF then telegram is 1 byte longer
shift = (data[4] != 0xFF) ? 2 : 1;
}
type_id = (data[4 + shift] << 8) + data[5 + shift] + 256;
message_data = data + 6 + shift;
message_length = length - 7 - shift;
type_id = (data[4] << 8) + data[5] + 256;
message_data = data + 6;
message_length = length - 7;
}
// if we're watching and "raw" print out actual telegram as bytes to the console
@@ -439,21 +440,20 @@ void TxService::add(uint8_t operation, const uint8_t * data, const uint8_t lengt
// work out depending on the type, where the data message block starts and the message length
// same logic as in RxService::add(), but adjusted for no appended CRC
if (data[2] < 0xF0) {
if (data[2] != 0xFF) {
// EMS 1.0
type_id = data[2];
message_data = data + 4;
message_length = length - 4;
} else if (data[1] & 0x80) {
type_id = (data[5] << 8) + data[6] + 256;
message_data = data + 4;
message_length = 1;
} else {
// EMS 2.0 / EMS+
uint8_t shift = 0; // default when data[2] is 0xFF
if (data[2] != 0xFF) {
// its F9 or F7, re-calculate shift. If the 5th byte is not 0xFF then telegram is 1 byte longer
shift = (data[4] != 0xFF) ? 2 : 1;
}
type_id = (data[4 + shift] << 8) + data[5 + shift] + 256;
message_data = data + 6 + shift;
message_length = length - 6 - shift;
type_id = (data[4] << 8) + data[5] + 256;
message_data = data + 6;
message_length = length - 6;
}
// if we don't have a type_id or empty data block, exit

View File

@@ -1 +1 @@
#define EMSESP_APP_VERSION "2.1.0b12"
#define EMSESP_APP_VERSION "2.1.0b13"