From cc606ed195cc717ebd3c45242f02ae62fa9463b8 Mon Sep 17 00:00:00 2001 From: ElVit Date: Mon, 13 Apr 2026 09:03:42 +0200 Subject: [PATCH 1/8] Added TOP143, SET43, SET44, SET45, SET46 --- components/panasonic_heatpump/README.md | 14 +- .../panasonic_heatpump/number/__init__.py | 6 + .../number/panasonic_heatpump_number.cpp | 126 ++++++++++-------- .../number/panasonic_heatpump_number.h | 1 + .../panasonic_heatpump/panasonic_heatpump.h | 2 +- .../panasonic_heatpump/select/__init__.py | 27 ++++ .../select/panasonic_heatpump_select.cpp | 29 ++-- .../select/panasonic_heatpump_select.h | 3 + .../panasonic_heatpump/sensor/__init__.py | 9 ++ .../sensor/panasonic_heatpump_sensor.cpp | 5 + .../sensor/panasonic_heatpump_sensor.h | 1 + 11 files changed, 151 insertions(+), 72 deletions(-) diff --git a/components/panasonic_heatpump/README.md b/components/panasonic_heatpump/README.md index 9fda697..a031fc8 100644 --- a/components/panasonic_heatpump/README.md +++ b/components/panasonic_heatpump/README.md @@ -344,6 +344,8 @@ sensor: name: "Bivalent Advanced DHW Delay" top142: name: "Expansion Valve" + top143: + name: ""DHW Sensor Selection" xtop0: name: "Heat Power Consumption Extra" @@ -551,6 +553,8 @@ number: name: "Set Bivalent AP Start Temp" set38: name: "Set Bivalent AP Stop Temp" + set46: + name: ""Set Heater On Outdoor Temp" ``` ### Switches @@ -624,6 +628,12 @@ select: name: "Set Quiet Mode Priority" set42: name: "Set Pump Flow Rate Mode" + set43: + name: ""Set DHW Sensor Selection" + set44: + name: ""Set DHW Heater State" + set45: + name: ""Set Room Heater State" ``` ### Climates @@ -714,8 +724,8 @@ the heatpump may not respond to any request messages. If the CZ-TAW1 is also connected to the ESP controller you will probably see some requests like 0x31 05 10 01 ... These are initial request messages. To fix this problem you can try: -- enable the switch `error_reset` -- turn off and on the power of the heatpump (switching the heatpump off is not enough) +* enable the switch `error_reset` +* turn off and on the power of the heatpump (switching the heatpump off is not enough) The heatpump will restart and should respond to the requests. diff --git a/components/panasonic_heatpump/number/__init__.py b/components/panasonic_heatpump/number/__init__.py index 254a48b..5a3a559 100644 --- a/components/panasonic_heatpump/number/__init__.py +++ b/components/panasonic_heatpump/number/__init__.py @@ -49,6 +49,7 @@ CONF_SET29 = "set29" # Set Heating Off Outdoor Temp CONF_SET36 = "set36" # Set Bivalent Start Temp CONF_SET37 = "set37" # Set Bivalent AP Start Temp CONF_SET38 = "set38" # Set Bivalent AP Stop Temp +CONF_SET46 = "set46" # Set Heater On Outdoor Temp TYPES = [ CONF_SET5, @@ -84,6 +85,7 @@ TYPES = [ CONF_SET36, CONF_SET37, CONF_SET38, + CONF_SET46, ] @@ -254,6 +256,10 @@ CONFIG_SCHEMA = cv.Schema( PanasonicHeatpumpNumber, unit_of_measurement=UNIT_CELSIUS, ).extend(number_options(-10.0, 0.0, 1.0)), + cv.Optional(CONF_SET46): number.number_schema( + PanasonicHeatpumpNumber, + unit_of_measurement=UNIT_CELSIUS, + ).extend(number_options(-15.0, 20.0, 1.0)), } ).extend(cv.COMPONENT_SCHEMA) diff --git a/components/panasonic_heatpump/number/panasonic_heatpump_number.cpp b/components/panasonic_heatpump/number/panasonic_heatpump_number.cpp index 57389e0..53a2377 100644 --- a/components/panasonic_heatpump/number/panasonic_heatpump_number.cpp +++ b/components/panasonic_heatpump/number/panasonic_heatpump_number.cpp @@ -111,6 +111,9 @@ void PanasonicHeatpumpNumber::control(float value) { case NumberIds::CONF_SET38: this->parent_->set_command_byte(PanasonicCommand::setPlus128(value_int), 68); break; + case NumberIds::CONF_SET46: + this->parent_->set_command_byte(PanasonicCommand::setPlus128(value_int), 85); + break; default: return; }; @@ -129,26 +132,6 @@ void PanasonicHeatpumpNumber::publish_new_state(const std::vector& data float new_state; switch (this->id_) { - case NumberIds::CONF_SET11: - new_state = PanasonicDecode::getByteMinus128(data[42]); - if (this->has_state() && this->state == new_state) - return; - break; - case NumberIds::CONF_SET20: - new_state = PanasonicDecode::getByteMinus128(data[99]); - if (this->has_state() && this->state == new_state) - return; - break; - case NumberIds::CONF_SET18: - new_state = PanasonicDecode::getByteMinus128(data[84]); - if (this->has_state() && this->state == new_state) - return; - break; - case NumberIds::CONF_SET19: - new_state = PanasonicDecode::getByteMinus128(data[94]); - if (this->has_state() && this->state == new_state) - return; - break; case NumberIds::CONF_SET5: new_state = PanasonicDecode::getByteMinus128(data[38]); if (this->has_state() && this->state == new_state) @@ -159,26 +142,6 @@ void PanasonicHeatpumpNumber::publish_new_state(const std::vector& data if (this->has_state() && this->state == new_state) return; break; - case NumberIds::CONF_SET16_01: - new_state = PanasonicDecode::getByteMinus128(data[75]); - if (this->has_state() && this->state == new_state) - return; - break; - case NumberIds::CONF_SET16_02: - new_state = PanasonicDecode::getByteMinus128(data[76]); - if (this->has_state() && this->state == new_state) - return; - break; - case NumberIds::CONF_SET16_04: - new_state = PanasonicDecode::getByteMinus128(data[78]); - if (this->has_state() && this->state == new_state) - return; - break; - case NumberIds::CONF_SET16_03: - new_state = PanasonicDecode::getByteMinus128(data[77]); - if (this->has_state() && this->state == new_state) - return; - break; case NumberIds::CONF_SET7: new_state = PanasonicDecode::getByteMinus128(data[40]); if (this->has_state() && this->state == new_state) @@ -189,28 +152,33 @@ void PanasonicHeatpumpNumber::publish_new_state(const std::vector& data if (this->has_state() && this->state == new_state) return; break; - case NumberIds::CONF_SET16_09: - new_state = PanasonicDecode::getByteMinus128(data[86]); + case NumberIds::CONF_SET11: + new_state = PanasonicDecode::getByteMinus128(data[42]); if (this->has_state() && this->state == new_state) return; break; - case NumberIds::CONF_SET16_10: - new_state = PanasonicDecode::getByteMinus128(data[87]); + case NumberIds::CONF_SET15: + new_state = PanasonicDecode::getByteMinus1(data[45]); if (this->has_state() && this->state == new_state) return; break; - case NumberIds::CONF_SET16_12: - new_state = PanasonicDecode::getByteMinus128(data[89]); + case NumberIds::CONF_SET16_01: + new_state = PanasonicDecode::getByteMinus128(data[75]); if (this->has_state() && this->state == new_state) return; break; - case NumberIds::CONF_SET16_11: - new_state = PanasonicDecode::getByteMinus128(data[88]); + case NumberIds::CONF_SET16_02: + new_state = PanasonicDecode::getByteMinus128(data[76]); if (this->has_state() && this->state == new_state) return; break; - case NumberIds::CONF_SET29: - new_state = PanasonicDecode::getByteMinus128(data[83]); + case NumberIds::CONF_SET16_03: + new_state = PanasonicDecode::getByteMinus128(data[77]); + if (this->has_state() && this->state == new_state) + return; + break; + case NumberIds::CONF_SET16_04: + new_state = PanasonicDecode::getByteMinus128(data[78]); if (this->has_state() && this->state == new_state) return; break; @@ -224,13 +192,33 @@ void PanasonicHeatpumpNumber::publish_new_state(const std::vector& data if (this->has_state() && this->state == new_state) return; break; + case NumberIds::CONF_SET16_07: + new_state = PanasonicDecode::getByteMinus128(data[81]); + if (this->has_state() && this->state == new_state) + return; + break; case NumberIds::CONF_SET16_08: new_state = PanasonicDecode::getByteMinus128(data[82]); if (this->has_state() && this->state == new_state) return; break; - case NumberIds::CONF_SET16_07: - new_state = PanasonicDecode::getByteMinus128(data[81]); + case NumberIds::CONF_SET16_09: + new_state = PanasonicDecode::getByteMinus128(data[86]); + if (this->has_state() && this->state == new_state) + return; + break; + case NumberIds::CONF_SET16_10: + new_state = PanasonicDecode::getByteMinus128(data[87]); + if (this->has_state() && this->state == new_state) + return; + break; + case NumberIds::CONF_SET16_11: + new_state = PanasonicDecode::getByteMinus128(data[88]); + if (this->has_state() && this->state == new_state) + return; + break; + case NumberIds::CONF_SET16_12: + new_state = PanasonicDecode::getByteMinus128(data[89]); if (this->has_state() && this->state == new_state) return; break; @@ -244,18 +232,28 @@ void PanasonicHeatpumpNumber::publish_new_state(const std::vector& data if (this->has_state() && this->state == new_state) return; break; - case NumberIds::CONF_SET16_16: - new_state = PanasonicDecode::getByteMinus128(data[93]); - if (this->has_state() && this->state == new_state) - return; - break; case NumberIds::CONF_SET16_15: new_state = PanasonicDecode::getByteMinus128(data[92]); if (this->has_state() && this->state == new_state) return; break; - case NumberIds::CONF_SET15: - new_state = PanasonicDecode::getByteMinus1(data[45]); + case NumberIds::CONF_SET16_16: + new_state = PanasonicDecode::getByteMinus128(data[93]); + if (this->has_state() && this->state == new_state) + return; + break; + case NumberIds::CONF_SET18: + new_state = PanasonicDecode::getByteMinus128(data[84]); + if (this->has_state() && this->state == new_state) + return; + break; + case NumberIds::CONF_SET19: + new_state = PanasonicDecode::getByteMinus128(data[94]); + if (this->has_state() && this->state == new_state) + return; + break; + case NumberIds::CONF_SET20: + new_state = PanasonicDecode::getByteMinus128(data[99]); if (this->has_state() && this->state == new_state) return; break; @@ -279,6 +277,11 @@ void PanasonicHeatpumpNumber::publish_new_state(const std::vector& data if (this->has_state() && this->state == new_state) return; break; + case NumberIds::CONF_SET29: + new_state = PanasonicDecode::getByteMinus128(data[83]); + if (this->has_state() && this->state == new_state) + return; + break; case NumberIds::CONF_SET36: new_state = PanasonicDecode::getByteMinus128(data[65]); if (this->has_state() && this->state == new_state) @@ -294,6 +297,11 @@ void PanasonicHeatpumpNumber::publish_new_state(const std::vector& data if (this->has_state() && this->state == new_state) return; break; + case NumberIds::CONF_SET43: + new_state = PanasonicDecode::getBit7and8(data[11]); + if (this->has_state() && this->state == new_state) + return; + break; default: return; }; diff --git a/components/panasonic_heatpump/number/panasonic_heatpump_number.h b/components/panasonic_heatpump/number/panasonic_heatpump_number.h index 9fd0fd3..6d15614 100644 --- a/components/panasonic_heatpump/number/panasonic_heatpump_number.h +++ b/components/panasonic_heatpump/number/panasonic_heatpump_number.h @@ -41,6 +41,7 @@ enum NumberIds : uint8_t { CONF_SET36, CONF_SET37, CONF_SET38, + CONF_SET46, }; class PanasonicHeatpumpNumber : public number::Number, diff --git a/components/panasonic_heatpump/panasonic_heatpump.h b/components/panasonic_heatpump/panasonic_heatpump.h index 6e0ef9f..fa496ef 100644 --- a/components/panasonic_heatpump/panasonic_heatpump.h +++ b/components/panasonic_heatpump/panasonic_heatpump.h @@ -12,7 +12,7 @@ #include "commands.h" #ifndef PANASONIC_HEATPUMP_VERSION -#define PANASONIC_HEATPUMP_VERSION "0.0.8" +#define PANASONIC_HEATPUMP_VERSION "0.0.9-beta.1" #endif #ifndef KEEP_STATE diff --git a/components/panasonic_heatpump/select/__init__.py b/components/panasonic_heatpump/select/__init__.py index 013dc43..d99c650 100644 --- a/components/panasonic_heatpump/select/__init__.py +++ b/components/panasonic_heatpump/select/__init__.py @@ -20,6 +20,9 @@ CONF_SET39 = "set39" # Set Heating Control CONF_SET40 = "set40" # Set Smart DHW CONF_SET41 = "set41" # Set Quiet Mode Priority CONF_SET42 = "set42" # Set Pump Flow Rate Mode +CONF_SET43 = "set43" # Set DHW Sensor Selection +CONF_SET44 = "set44" # Set DHW Heater State +CONF_SET45 = "set45" # Set Room Heater State TYPES = [ CONF_SET2, @@ -33,6 +36,9 @@ TYPES = [ CONF_SET40, CONF_SET41, CONF_SET42, + CONF_SET43, + CONF_SET44, + CONF_SET45, ] CONF_SELECTS = [ @@ -81,6 +87,18 @@ CONF_SELECTS = [ "DeltaT", "Max. Duty", ], + [ + "Top", + "Center", + ], + [ + "Blocked", + "Free", + ], + [ + "Blocked", + "Free", + ], ] CONF_SELECT_COOL_MODE = [ @@ -136,6 +154,15 @@ CONFIG_SCHEMA = cv.Schema( cv.Optional(CONF_SET42): select.select_schema( PanasonicHeatpumpSelect, ), + cv.Optional(CONF_SET43): select.select_schema( + PanasonicHeatpumpSelect, + ), + cv.Optional(CONF_SET44): select.select_schema( + PanasonicHeatpumpSelect, + ), + cv.Optional(CONF_SET45): select.select_schema( + PanasonicHeatpumpSelect, + ), } ).extend(cv.COMPONENT_SCHEMA) diff --git a/components/panasonic_heatpump/select/panasonic_heatpump_select.cpp b/components/panasonic_heatpump/select/panasonic_heatpump_select.cpp index 0267ffb..e702d90 100644 --- a/components/panasonic_heatpump/select/panasonic_heatpump_select.cpp +++ b/components/panasonic_heatpump/select/panasonic_heatpump_select.cpp @@ -49,6 +49,15 @@ void PanasonicHeatpumpSelect::control(const std::string& value) { case SelectIds::CONF_SET42: this->parent_->set_command_byte(PanasonicCommand::setPlus1Multiply16(index), 29); break; + case SelectIds::CONF_SET43: + this->parent_->set_command_byte(PanasonicCommand::setPlus1(value), 11); + break; + case SelectIds::CONF_SET44: + this->parent_->set_command_byte(PanasonicCommand::setPlus1Multiply4(value), 9); + break; + case SelectIds::CONF_SET45: + this->parent_->set_command_byte(PanasonicCommand::setPlus1(value), 9); + break; default: return; }; @@ -67,14 +76,8 @@ void PanasonicHeatpumpSelect::publish_new_state(const std::vector& data std::string new_state; switch (this->id_) { - case SelectIds::CONF_SET9: - new_state = - PanasonicDecode::getTextState(PanasonicDecode::OperationMode, PanasonicDecode::getOperationMode(data[6])); - if (this->has_state() && this->current_option() == new_state) - return; - break; - case SelectIds::CONF_SET4: - new_state = PanasonicDecode::getTextState(PanasonicDecode::PowerfulMode, PanasonicDecode::getBit6and7and8(data[7])); + case SelectIds::CONF_SET2: + new_state = PanasonicDecode::getTextState(PanasonicDecode::HolidayState, PanasonicDecode::getBit3and4(data[5])); if (this->has_state() && this->current_option() == new_state) return; break; @@ -83,8 +86,14 @@ void PanasonicHeatpumpSelect::publish_new_state(const std::vector& data if (this->has_state() && this->current_option() == new_state) return; break; - case SelectIds::CONF_SET2: - new_state = PanasonicDecode::getTextState(PanasonicDecode::HolidayState, PanasonicDecode::getBit3and4(data[5])); + case SelectIds::CONF_SET4: + new_state = PanasonicDecode::getTextState(PanasonicDecode::PowerfulMode, PanasonicDecode::getBit6and7and8(data[7])); + if (this->has_state() && this->current_option() == new_state) + return; + break; + case SelectIds::CONF_SET9: + new_state = + PanasonicDecode::getTextState(PanasonicDecode::OperationMode, PanasonicDecode::getOperationMode(data[6])); if (this->has_state() && this->current_option() == new_state) return; break; diff --git a/components/panasonic_heatpump/select/panasonic_heatpump_select.h b/components/panasonic_heatpump/select/panasonic_heatpump_select.h index e4a238a..0a1fb4f 100644 --- a/components/panasonic_heatpump/select/panasonic_heatpump_select.h +++ b/components/panasonic_heatpump/select/panasonic_heatpump_select.h @@ -19,6 +19,9 @@ enum SelectIds : uint8_t { CONF_SET40, CONF_SET41, CONF_SET42, + CONF_SET43, + CONF_SET44, + CONF_SET45, }; class PanasonicHeatpumpSelect : public select::Select, diff --git a/components/panasonic_heatpump/sensor/__init__.py b/components/panasonic_heatpump/sensor/__init__.py index 6707b49..9e4310e 100644 --- a/components/panasonic_heatpump/sensor/__init__.py +++ b/components/panasonic_heatpump/sensor/__init__.py @@ -134,6 +134,7 @@ CONF_TOP136 = "top136" # Bivalent Advanced Start Delay CONF_TOP137 = "top137" # Bivalent Advanced Stop Delay CONF_TOP138 = "top138" # Bivalent Advanced DHW Delay CONF_TOP142 = "top142" # Expansion Valve +CONF_TOP143 = "top143" # DHW Sensor Selection CONF_XTOP0 = "xtop0" # Heat Power Consumption Extra CONF_XTOP1 = "xtop1" # Cool Power Consumption Extra CONF_XTOP2 = "xtop2" # DHW Power Consumption Extra @@ -238,6 +239,7 @@ TYPES = [ CONF_TOP137, CONF_TOP138, CONF_TOP142, + CONF_TOP143, CONF_XTOP0, CONF_XTOP1, CONF_XTOP2, @@ -928,6 +930,13 @@ CONFIG_SCHEMA = cv.Schema( state_class=STATE_CLASS_MEASUREMENT, unit_of_measurement=UNIT_EMPTY, ), + cv.Optional(CONF_TOP143): sensor.sensor_schema( + PanasonicHeatpumpSensor, + accuracy_decimals=1, + device_class=DEVICE_CLASS_TEMPERATURE, + state_class=STATE_CLASS_MEASUREMENT, + unit_of_measurement=UNIT_CELSIUS, + ), cv.Optional(CONF_XTOP0): sensor.sensor_schema( PanasonicHeatpumpSensor, accuracy_decimals=0, diff --git a/components/panasonic_heatpump/sensor/panasonic_heatpump_sensor.cpp b/components/panasonic_heatpump/sensor/panasonic_heatpump_sensor.cpp index 7e4355e..503b51c 100644 --- a/components/panasonic_heatpump/sensor/panasonic_heatpump_sensor.cpp +++ b/components/panasonic_heatpump/sensor/panasonic_heatpump_sensor.cpp @@ -495,6 +495,11 @@ void PanasonicHeatpumpSensor::publish_new_state(const std::vector& data if (this->has_state() && this->get_state() == new_state) return; break; + case SensorIds::CONF_TOP143: + new_state = PanasonicDecode::getBit7and8(data[11]); + if (this->has_state() && this->get_state() == new_state) + return; + break; case SensorIds::CONF_XTOP0: new_state = PanasonicDecode::getWordMinus1(data, 14); diff --git a/components/panasonic_heatpump/sensor/panasonic_heatpump_sensor.h b/components/panasonic_heatpump/sensor/panasonic_heatpump_sensor.h index 84c4350..f696351 100644 --- a/components/panasonic_heatpump/sensor/panasonic_heatpump_sensor.h +++ b/components/panasonic_heatpump/sensor/panasonic_heatpump_sensor.h @@ -103,6 +103,7 @@ enum SensorIds : uint8_t { CONF_TOP137, CONF_TOP138, CONF_TOP142, + CONF_TOP143, CONF_XTOP0, CONF_XTOP1, From 652fb1b31f9997833cce74a488dc3d6e1c8da664 Mon Sep 17 00:00:00 2001 From: ElVit Date: Mon, 13 Apr 2026 09:04:05 +0200 Subject: [PATCH 2/8] Added new Heatpump Models --- components/panasonic_heatpump/decode.cpp | 17 ++++++++--------- components/panasonic_heatpump/decode.h | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/components/panasonic_heatpump/decode.cpp b/components/panasonic_heatpump/decode.cpp index 666484c..5cfe0d8 100644 --- a/components/panasonic_heatpump/decode.cpp +++ b/components/panasonic_heatpump/decode.cpp @@ -85,16 +85,15 @@ constexpr const uint8_t KnownModels[NUMBER_OF_MODELS][10] = { {0x12, 0xD7, 0x0D, 0x98, 0x11, 0x33, 0x94, 0x0C, 0x83, 0x10}, // 55 {0xE2, 0xD5, 0x0B, 0x08, 0x95, 0x02, 0xD6, 0x0F, 0x67, 0x95}, // 56 {0xE2, 0xD5, 0x0D, 0x36, 0x99, 0x02, 0xD6, 0x10, 0x66, 0x95}, // 57 - {0xE2, 0xCF, 0x0B, 0x84, 0x05, 0x12, 0xD0, 0x0B, 0x93, 0x05}, // 58 + {0xE2, 0xD5, 0x0F, 0x99, 0x94, 0x02, 0xD6, 0x10, 0x68, 0x95}, // 58 {0xE2, 0xD5, 0x0C, 0x67, 0x00, 0x83, 0x92, 0x0C, 0x28, 0x98}, // 59 - {0xE2, 0xD5, 0x0C, 0x67, 0x00, 0x83, 0x92, 0x0D, 0x29, 0x98}, // 60 - {0xE2, 0xD5, 0x0D, 0x08, 0x95, 0x02, 0xD6, 0x10, 0x67, 0x95}, // 61 - {0xE2, 0xD5, 0x0C, 0x08, 0x95, 0x02, 0xD6, 0x0D, 0x67, 0x95}, // 62 - {0xE2, 0xD5, 0x0C, 0x08, 0x95, 0x02, 0xD6, 0x10, 0x67, 0x95}, // 63 - {0xE2, 0xD5, 0x0C, 0x08, 0x95, 0x02, 0xD6, 0x10, 0x66, 0x95}, // 64 - {0xE2, 0xD5, 0x0B, 0x08, 0x95, 0x02, 0xD6, 0x0E, 0x68, 0x95}, // 65 - {0xE2, 0xCF, 0x0C, 0x88, 0x05, 0x12, 0xD0, 0x0C, 0x97, 0x05}, // 66 - {0x12, 0xD7, 0x0D, 0x85, 0x11, 0x37, 0x94, 0x0E, 0x84, 0x10}, // 67 + {0xE2, 0xCF, 0x0D, 0x86, 0x05, 0x12, 0xD0, 0x0E, 0x95, 0x05}, // 60 + {0x12, 0xD7, 0x0C, 0x98, 0x14, 0x35, 0x94, 0x0D, 0x83, 0x10}, // 61 + {0xE2, 0xD5, 0x0C, 0x08, 0x95, 0x02, 0xD6, 0x10, 0x67, 0x95}, // 62 + {0xC2, 0xD3, 0x0D, 0x35, 0x65, 0xB2, 0xD3, 0x0B, 0x96, 0x65}, // 63 + {0xE2, 0xD5, 0x0C, 0x29, 0x99, 0x83, 0x92, 0x0C, 0x29, 0x98}, // 64 + {0x62, 0xD2, 0x0B, 0x45, 0x54, 0x42, 0xD2, 0x0B, 0x72, 0x66}, // 65 + {0xE2, 0xCF, 0x0B, 0x82, 0x09, 0x12, 0xD0, 0x0B, 0x10, 0x11}, // 66 }; int PanasonicDecode::getBit1(uint8_t input) { diff --git a/components/panasonic_heatpump/decode.h b/components/panasonic_heatpump/decode.h index da1a71b..7c48d1d 100644 --- a/components/panasonic_heatpump/decode.h +++ b/components/panasonic_heatpump/decode.h @@ -7,7 +7,7 @@ #define RESPONSE_MSG_SIZE 203 #endif #ifndef NUMBER_OF_MODELS -#define NUMBER_OF_MODELS 68 +#define NUMBER_OF_MODELS 67 #endif namespace esphome { From ef0cbc6447bbc5431b397728834725dd5b6563b5 Mon Sep 17 00:00:00 2001 From: ElVit Date: Mon, 13 Apr 2026 12:20:11 +0200 Subject: [PATCH 3/8] Added TOP143, SET43, SET44, SET45, SET46 --- components/panasonic_heatpump/README.md | 12 +++++----- components/panasonic_heatpump/decode.h | 18 +++++++-------- .../number/panasonic_heatpump_number.cpp | 4 ++-- .../select/panasonic_heatpump_select.cpp | 22 ++++++++++++++++--- .../panasonic_heatpump/sensor/__init__.py | 15 +++---------- .../sensor/panasonic_heatpump_sensor.cpp | 5 ----- .../sensor/panasonic_heatpump_sensor.h | 1 - .../switch/panasonic_heatpump_switch.cpp | 22 +++++++++---------- .../text_sensor/__init__.py | 7 ++++++ .../panasonic_heatpump_text_sensor.cpp | 5 +++++ .../panasonic_heatpump_text_sensor.h | 1 + 11 files changed, 63 insertions(+), 49 deletions(-) diff --git a/components/panasonic_heatpump/README.md b/components/panasonic_heatpump/README.md index a031fc8..c7412f0 100644 --- a/components/panasonic_heatpump/README.md +++ b/components/panasonic_heatpump/README.md @@ -344,8 +344,6 @@ sensor: name: "Bivalent Advanced DHW Delay" top142: name: "Expansion Valve" - top143: - name: ""DHW Sensor Selection" xtop0: name: "Heat Power Consumption Extra" @@ -475,6 +473,8 @@ text_sensor: name: "SmartDHW" top141: name: "Quiet Mode Priority" + top143: + name: "DHW Sensor Selection" ``` ### Numbers @@ -554,7 +554,7 @@ number: set38: name: "Set Bivalent AP Stop Temp" set46: - name: ""Set Heater On Outdoor Temp" + name: "Set Heater On Outdoor Temp" ``` ### Switches @@ -629,11 +629,11 @@ select: set42: name: "Set Pump Flow Rate Mode" set43: - name: ""Set DHW Sensor Selection" + name: "Set DHW Sensor Selection" set44: - name: ""Set DHW Heater State" + name: "Set DHW Heater State" set45: - name: ""Set Room Heater State" + name: "Set Room Heater State" ``` ### Climates diff --git a/components/panasonic_heatpump/decode.h b/components/panasonic_heatpump/decode.h index 7c48d1d..81ddb54 100644 --- a/components/panasonic_heatpump/decode.h +++ b/components/panasonic_heatpump/decode.h @@ -70,8 +70,9 @@ class PanasonicDecode { static const constexpr char* const HeatingControl[] = {"2", "Comfort", "Efficiency"}; static const constexpr char* const SmartDHW[] = {"2", "Variable", "Standard"}; static const constexpr char* const QuietModePriority[] = {"2", "Sound", "Capacity"}; + static const constexpr char* const DHWSensorSelection[] = {"2", "Top", "Center"}; static const constexpr char* const ModelNames[] = { - "58", // string representation of number of known models (last model number + 1) + "67", // string representation of number of known models (last model number + 1) "WH-MDC05H3E5", // 0 "WH-MDC07H3E5", // 1 "IDU:WH-SXC09H3E5, ODU:WH-UX09HE5", // 2 @@ -130,16 +131,15 @@ class PanasonicDecode { "IDU:WH-ADC0316M9E8AN2, ODU:WH-WXG09ME8", // 55 "IDU:WH-SDC0309K3E5, ODU:WH-UDZ07KE5", // 56 "IDU:WH-ADC0309K3E5AN, ODU:WH-UDZ05KE5", // 57 - "IDU:WH-SQC16H9E8, ODU:WH-UQ16HE8", // 58 + "IDU:WH-ADC0309K3E5, ODU:WH-UDZ09KE5", // 58 "IDU:WH-ADC0509L3E5AN, ODU:WH-WDG07LE5", // 59 - "IDU:WH-ADC0509L3E5AN, ODU:WH-WDG09LE5", // 60 - "IDU:WH-SDC0309K3E5, ODU:WH-UDZ07KE5", // 61 + "IDU:WH-SXC12H9E8, ODU:WH-UX12HE8", // 60 + "IDU:WH-SDC0316M9E8, ODU:WH-WXG09ME8", // 61 "IDU:WH-SDC0309K3E5, ODU:WH-UDZ07KE5", // 62 - "IDU:WH-SDC0309K3E5, ODU:WH-UDZ07KE5", // 63 - "IDU:WH-SDC0309K3E5, ODU:WH-UDZ05KE5", // 64 - "IDU:WH-SDC0309K3E5, ODU:WH-UDZ09KE5", // 65 - "IDU:WH-SDC09H3E8, ODU:WH-UD09HE8", // 66 - "WH-WXG12ME8", // 67 + "WH-MDC09J3E5-1", // 63 + "IDU:WH-ADC0509L3E5, ODU:WH-WDG09LE5", // 64 + "IDU:WH-ADC0309J3E5, ODU:WH-UD09JE5-1", // 65 + "IDU:WH-SDC12H6E5, ODU:WH-UD12HE5", // 66 }; }; diff --git a/components/panasonic_heatpump/number/panasonic_heatpump_number.cpp b/components/panasonic_heatpump/number/panasonic_heatpump_number.cpp index 53a2377..d1b3bde 100644 --- a/components/panasonic_heatpump/number/panasonic_heatpump_number.cpp +++ b/components/panasonic_heatpump/number/panasonic_heatpump_number.cpp @@ -297,8 +297,8 @@ void PanasonicHeatpumpNumber::publish_new_state(const std::vector& data if (this->has_state() && this->state == new_state) return; break; - case NumberIds::CONF_SET43: - new_state = PanasonicDecode::getBit7and8(data[11]); + case NumberIds::CONF_SET46: + new_state = PanasonicDecode::getByteMinus128(data[85]); if (this->has_state() && this->state == new_state) return; break; diff --git a/components/panasonic_heatpump/select/panasonic_heatpump_select.cpp b/components/panasonic_heatpump/select/panasonic_heatpump_select.cpp index e702d90..b3527a1 100644 --- a/components/panasonic_heatpump/select/panasonic_heatpump_select.cpp +++ b/components/panasonic_heatpump/select/panasonic_heatpump_select.cpp @@ -50,13 +50,13 @@ void PanasonicHeatpumpSelect::control(const std::string& value) { this->parent_->set_command_byte(PanasonicCommand::setPlus1Multiply16(index), 29); break; case SelectIds::CONF_SET43: - this->parent_->set_command_byte(PanasonicCommand::setPlus1(value), 11); + this->parent_->set_command_byte(PanasonicCommand::setPlus1(index), 11); break; case SelectIds::CONF_SET44: - this->parent_->set_command_byte(PanasonicCommand::setPlus1Multiply4(value), 9); + this->parent_->set_command_byte(PanasonicCommand::setPlus1Multiply4(index), 9); break; case SelectIds::CONF_SET45: - this->parent_->set_command_byte(PanasonicCommand::setPlus1(value), 9); + this->parent_->set_command_byte(PanasonicCommand::setPlus1(index), 9); break; default: return; @@ -135,6 +135,22 @@ void PanasonicHeatpumpSelect::publish_new_state(const std::vector& data if (this->has_state() && this->current_option() == new_state) return; break; + case SelectIds::CONF_SET43: + new_state = + PanasonicDecode::getTextState(PanasonicDecode::DHWSensorSelection, PanasonicDecode::getBit7and8(data[11])); + if (this->has_state() && this->current_option() == new_state) + return; + break; + case SelectIds::CONF_SET44: + new_state = PanasonicDecode::getTextState(PanasonicDecode::BlockedFree, PanasonicDecode::getBit5and6(data[9])); + if (this->has_state() && this->current_option() == new_state) + return; + break; + case SelectIds::CONF_SET45: + new_state = PanasonicDecode::getTextState(PanasonicDecode::BlockedFree, PanasonicDecode::getBit7and8(data[9])); + if (this->has_state() && this->current_option() == new_state) + return; + break; default: return; }; diff --git a/components/panasonic_heatpump/sensor/__init__.py b/components/panasonic_heatpump/sensor/__init__.py index 9e4310e..e962e6c 100644 --- a/components/panasonic_heatpump/sensor/__init__.py +++ b/components/panasonic_heatpump/sensor/__init__.py @@ -134,7 +134,6 @@ CONF_TOP136 = "top136" # Bivalent Advanced Start Delay CONF_TOP137 = "top137" # Bivalent Advanced Stop Delay CONF_TOP138 = "top138" # Bivalent Advanced DHW Delay CONF_TOP142 = "top142" # Expansion Valve -CONF_TOP143 = "top143" # DHW Sensor Selection CONF_XTOP0 = "xtop0" # Heat Power Consumption Extra CONF_XTOP1 = "xtop1" # Cool Power Consumption Extra CONF_XTOP2 = "xtop2" # DHW Power Consumption Extra @@ -239,7 +238,6 @@ TYPES = [ CONF_TOP137, CONF_TOP138, CONF_TOP142, - CONF_TOP143, CONF_XTOP0, CONF_XTOP1, CONF_XTOP2, @@ -590,16 +588,16 @@ CONFIG_SCHEMA = cv.Schema( cv.Optional(CONF_TOP62): sensor.sensor_schema( PanasonicHeatpumpSensor, accuracy_decimals=2, - icon=ICON_FAN, state_class=STATE_CLASS_MEASUREMENT, unit_of_measurement=UNIT_ROTATIONS_PER_MINUTE, + icon=ICON_FAN, ), cv.Optional(CONF_TOP63): sensor.sensor_schema( PanasonicHeatpumpSensor, accuracy_decimals=2, - icon=ICON_FAN, state_class=STATE_CLASS_MEASUREMENT, unit_of_measurement=UNIT_ROTATIONS_PER_MINUTE, + icon=ICON_FAN, ), cv.Optional(CONF_TOP64): sensor.sensor_schema( PanasonicHeatpumpSensor, @@ -926,16 +924,9 @@ CONFIG_SCHEMA = cv.Schema( cv.Optional(CONF_TOP142): sensor.sensor_schema( PanasonicHeatpumpSensor, accuracy_decimals=0, - icon=ICON_VALVE, state_class=STATE_CLASS_MEASUREMENT, unit_of_measurement=UNIT_EMPTY, - ), - cv.Optional(CONF_TOP143): sensor.sensor_schema( - PanasonicHeatpumpSensor, - accuracy_decimals=1, - device_class=DEVICE_CLASS_TEMPERATURE, - state_class=STATE_CLASS_MEASUREMENT, - unit_of_measurement=UNIT_CELSIUS, + icon=ICON_VALVE, ), cv.Optional(CONF_XTOP0): sensor.sensor_schema( PanasonicHeatpumpSensor, diff --git a/components/panasonic_heatpump/sensor/panasonic_heatpump_sensor.cpp b/components/panasonic_heatpump/sensor/panasonic_heatpump_sensor.cpp index 503b51c..7e4355e 100644 --- a/components/panasonic_heatpump/sensor/panasonic_heatpump_sensor.cpp +++ b/components/panasonic_heatpump/sensor/panasonic_heatpump_sensor.cpp @@ -495,11 +495,6 @@ void PanasonicHeatpumpSensor::publish_new_state(const std::vector& data if (this->has_state() && this->get_state() == new_state) return; break; - case SensorIds::CONF_TOP143: - new_state = PanasonicDecode::getBit7and8(data[11]); - if (this->has_state() && this->get_state() == new_state) - return; - break; case SensorIds::CONF_XTOP0: new_state = PanasonicDecode::getWordMinus1(data, 14); diff --git a/components/panasonic_heatpump/sensor/panasonic_heatpump_sensor.h b/components/panasonic_heatpump/sensor/panasonic_heatpump_sensor.h index f696351..84c4350 100644 --- a/components/panasonic_heatpump/sensor/panasonic_heatpump_sensor.h +++ b/components/panasonic_heatpump/sensor/panasonic_heatpump_sensor.h @@ -103,7 +103,6 @@ enum SensorIds : uint8_t { CONF_TOP137, CONF_TOP138, CONF_TOP142, - CONF_TOP143, CONF_XTOP0, CONF_XTOP1, diff --git a/components/panasonic_heatpump/switch/panasonic_heatpump_switch.cpp b/components/panasonic_heatpump/switch/panasonic_heatpump_switch.cpp index 868017c..c78ee1a 100644 --- a/components/panasonic_heatpump/switch/panasonic_heatpump_switch.cpp +++ b/components/panasonic_heatpump/switch/panasonic_heatpump_switch.cpp @@ -83,11 +83,6 @@ void PanasonicHeatpumpSwitch::publish_new_state(const std::vector& data if (this->state == new_state) return; break; - case SwitchIds::CONF_SET24: - new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[5])); - if (this->state == new_state) - return; - break; case SwitchIds::CONF_SET12: new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[111])); if (this->state == new_state) @@ -98,8 +93,8 @@ void PanasonicHeatpumpSwitch::publish_new_state(const std::vector& data if (this->state == new_state) return; break; - case SwitchIds::CONF_SET28: - new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[24])); + case SwitchIds::CONF_SET24: + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[5])); if (this->state == new_state) return; break; @@ -108,13 +103,13 @@ void PanasonicHeatpumpSwitch::publish_new_state(const std::vector& data if (this->state == new_state) return; break; - case SwitchIds::CONF_SET30: - new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[23])); + case SwitchIds::CONF_SET28: + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[24])); if (this->state == new_state) return; break; - case SwitchIds::CONF_SET33: - new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[23])); + case SwitchIds::CONF_SET30: + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[23])); if (this->state == new_state) return; break; @@ -128,6 +123,11 @@ void PanasonicHeatpumpSwitch::publish_new_state(const std::vector& data if (this->state == new_state) return; break; + case SwitchIds::CONF_SET33: + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[23])); + if (this->state == new_state) + return; + break; case SwitchIds::CONF_SET34: new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[26])); if (this->state == new_state) diff --git a/components/panasonic_heatpump/text_sensor/__init__.py b/components/panasonic_heatpump/text_sensor/__init__.py index bb6c174..dac49b4 100644 --- a/components/panasonic_heatpump/text_sensor/__init__.py +++ b/components/panasonic_heatpump/text_sensor/__init__.py @@ -26,6 +26,7 @@ ICON_THERMOMETER = "mdi:thermometer" ICON_BIVALENT = "mdi:vector-combine" ICON_HEATING_CONTROL = "mdi:thermostat-auto" ICON_SMART_DHW = "mdi:water-boiler-auto" +ICON_DHW = "mdi:water-boiler" CONF_TOP4 = "top4" # Operation Mode # TODO: Split up top4 into top4_1 (Heating Mode State) and top4_2 (DHW Mode State) @@ -52,6 +53,7 @@ CONF_TOP130 = "top130" # Bivalent Mode CONF_TOP139 = "top139" # HeatingControl CONF_TOP140 = "top140" # SmartDHW CONF_TOP141 = "top141" # Quiet Mode Priority +CONF_TOP143 = "top143" # DHW Sensor Selection TYPES = [ CONF_TOP4, @@ -78,6 +80,7 @@ TYPES = [ CONF_TOP139, CONF_TOP140, CONF_TOP141, + CONF_TOP143, ] PanasonicHeatpumpTextSensor = panasonic_heatpump_ns.class_( @@ -185,6 +188,10 @@ CONFIG_SCHEMA = cv.Schema( PanasonicHeatpumpTextSensor, icon=ICON_QUIET_MODE, ), + cv.Optional(CONF_TOP143): text_sensor.text_sensor_schema( + PanasonicHeatpumpTextSensor, + icon=ICON_DHW, + ), } ).extend(cv.COMPONENT_SCHEMA) diff --git a/components/panasonic_heatpump/text_sensor/panasonic_heatpump_text_sensor.cpp b/components/panasonic_heatpump/text_sensor/panasonic_heatpump_text_sensor.cpp index 79ea7ae..c8caf35 100644 --- a/components/panasonic_heatpump/text_sensor/panasonic_heatpump_text_sensor.cpp +++ b/components/panasonic_heatpump/text_sensor/panasonic_heatpump_text_sensor.cpp @@ -143,6 +143,11 @@ void PanasonicHeatpumpTextSensor::publish_new_state(const std::vector& if (this->has_state() && this->get_state() == new_state) return; break; + case TextSensorIds::CONF_TOP143: + new_state = PanasonicDecode::getTextState(PanasonicDecode::DHWSensorSelection, PanasonicDecode::getBit7and8(data[11])); + if (this->has_state() && this->get_state() == new_state) + return; + break; default: return; }; diff --git a/components/panasonic_heatpump/text_sensor/panasonic_heatpump_text_sensor.h b/components/panasonic_heatpump/text_sensor/panasonic_heatpump_text_sensor.h index 7d34d9d..2514131 100644 --- a/components/panasonic_heatpump/text_sensor/panasonic_heatpump_text_sensor.h +++ b/components/panasonic_heatpump/text_sensor/panasonic_heatpump_text_sensor.h @@ -31,6 +31,7 @@ enum TextSensorIds : uint8_t { CONF_TOP139, CONF_TOP140, CONF_TOP141, + CONF_TOP143, }; class PanasonicHeatpumpTextSensor : public text_sensor::TextSensor, From 65765bd1ca53116c6010a1b977ec637f9a6535db Mon Sep 17 00:00:00 2001 From: ElVit Date: Mon, 13 Apr 2026 20:08:54 +0200 Subject: [PATCH 4/8] Added new line in README --- components/panasonic_heatpump/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/panasonic_heatpump/README.md b/components/panasonic_heatpump/README.md index c7412f0..88dc76f 100644 --- a/components/panasonic_heatpump/README.md +++ b/components/panasonic_heatpump/README.md @@ -723,7 +723,8 @@ When the ESP controller is connected initially to the heatpump (and the heatpump the heatpump may not respond to any request messages. If the CZ-TAW1 is also connected to the ESP controller you will probably see some requests like 0x31 05 10 01 ... These are initial request messages. -To fix this problem you can try: +To fix this problem you can try: + * enable the switch `error_reset` * turn off and on the power of the heatpump (switching the heatpump off is not enough) From d6edd5a7239da3b3bd516d6c2cbca304d13553d9 Mon Sep 17 00:00:00 2001 From: ElVit <54866762+ElVit@users.noreply.github.com> Date: Wed, 15 Apr 2026 09:29:16 +0200 Subject: [PATCH 5/8] Update README.md --- components/panasonic_heatpump/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/panasonic_heatpump/README.md b/components/panasonic_heatpump/README.md index 88dc76f..0520be9 100644 --- a/components/panasonic_heatpump/README.md +++ b/components/panasonic_heatpump/README.md @@ -723,7 +723,7 @@ When the ESP controller is connected initially to the heatpump (and the heatpump the heatpump may not respond to any request messages. If the CZ-TAW1 is also connected to the ESP controller you will probably see some requests like 0x31 05 10 01 ... These are initial request messages. -To fix this problem you can try: +To solve this problem you can try one of the follwing: * enable the switch `error_reset` * turn off and on the power of the heatpump (switching the heatpump off is not enough) From f8439ee93b37eb55983639f9d272a639373ef148 Mon Sep 17 00:00:00 2001 From: ElVit <54866762+ElVit@users.noreply.github.com> Date: Wed, 15 Apr 2026 09:38:31 +0200 Subject: [PATCH 6/8] Update panasonic_heatpump_text_sensor.cpp --- .../text_sensor/panasonic_heatpump_text_sensor.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/panasonic_heatpump/text_sensor/panasonic_heatpump_text_sensor.cpp b/components/panasonic_heatpump/text_sensor/panasonic_heatpump_text_sensor.cpp index c8caf35..a6b3b02 100644 --- a/components/panasonic_heatpump/text_sensor/panasonic_heatpump_text_sensor.cpp +++ b/components/panasonic_heatpump/text_sensor/panasonic_heatpump_text_sensor.cpp @@ -144,7 +144,8 @@ void PanasonicHeatpumpTextSensor::publish_new_state(const std::vector& return; break; case TextSensorIds::CONF_TOP143: - new_state = PanasonicDecode::getTextState(PanasonicDecode::DHWSensorSelection, PanasonicDecode::getBit7and8(data[11])); + new_state = + PanasonicDecode::getTextState(PanasonicDecode::DHWSensorSelection, PanasonicDecode::getBit7and8(data[11])); if (this->has_state() && this->get_state() == new_state) return; break; From 18b18bc15640265e278a0b0d9cebca52a9f4a416 Mon Sep 17 00:00:00 2001 From: ElVit Date: Fri, 17 Apr 2026 10:44:07 +0200 Subject: [PATCH 7/8] Set default value for attribute MODE to BOX for all number entities --- components/panasonic_heatpump/number/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/panasonic_heatpump/number/__init__.py b/components/panasonic_heatpump/number/__init__.py index 5a3a559..ea4c96a 100644 --- a/components/panasonic_heatpump/number/__init__.py +++ b/components/panasonic_heatpump/number/__init__.py @@ -9,6 +9,7 @@ from esphome.const import ( CONF_MIN_VALUE, CONF_MAX_VALUE, CONF_STEP, + CONF_MODE, ) from .. import ( CONF_PANASONIC_HEATPUMP_ID, @@ -95,6 +96,7 @@ def number_options(min_val, max_val, step) -> cv.Schema: cv.Optional(CONF_MIN_VALUE, default=min_val): cv.float_, cv.Optional(CONF_MAX_VALUE, default=max_val): cv.float_, cv.Optional(CONF_STEP, default=step): cv.float_range(min=1.0, max=10.0), + cv.Optional(CONF_MODE, default="BOX"): cv.enum(number.NUMBER_MODES, upper=True), } ) return schema From 61cbc3bfbf8895d8c4f417c243285d61f3a3bde2 Mon Sep 17 00:00:00 2001 From: ElVit Date: Fri, 17 Apr 2026 10:45:49 +0200 Subject: [PATCH 8/8] Set default value for attribute MODE to BOX for all number entities --- components/panasonic_heatpump/number/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/panasonic_heatpump/number/__init__.py b/components/panasonic_heatpump/number/__init__.py index ea4c96a..d731d2a 100644 --- a/components/panasonic_heatpump/number/__init__.py +++ b/components/panasonic_heatpump/number/__init__.py @@ -96,7 +96,9 @@ def number_options(min_val, max_val, step) -> cv.Schema: cv.Optional(CONF_MIN_VALUE, default=min_val): cv.float_, cv.Optional(CONF_MAX_VALUE, default=max_val): cv.float_, cv.Optional(CONF_STEP, default=step): cv.float_range(min=1.0, max=10.0), - cv.Optional(CONF_MODE, default="BOX"): cv.enum(number.NUMBER_MODES, upper=True), + cv.Optional(CONF_MODE, default="BOX"): cv.enum( + number.NUMBER_MODES, upper=True + ), } ) return schema