diff --git a/components/panasonic_heatpump/binary_sensor/__init__.py b/components/panasonic_heatpump/binary_sensor/__init__.py index e334744..5b82aa8 100644 --- a/components/panasonic_heatpump/binary_sensor/__init__.py +++ b/components/panasonic_heatpump/binary_sensor/__init__.py @@ -146,10 +146,11 @@ CONFIG_SCHEMA = cv.Schema( ).extend(cv.COMPONENT_SCHEMA) async def to_code(config): - hub = await cg.get_variable(config[CONF_PANASONIC_HEATPUMP_ID]) - for key in TYPES: + parent = await cg.get_variable(config[CONF_PANASONIC_HEATPUMP_ID]) + for index, key in enumerate(TYPES): if child_config := config.get(key): var = await binary_sensor.new_binary_sensor(child_config) await cg.register_component(var, child_config) - await cg.register_parented(var, config[CONF_PANASONIC_HEATPUMP_ID]) - cg.add(getattr(hub, f"set_{key}_binary_sensor")(var)) + cg.add(var.set_parent(parent)) + cg.add(var.set_id(index)) + cg.add(parent.add_binary_sensor(var)) diff --git a/components/panasonic_heatpump/binary_sensor/panasonic_heatpump_binary_sensor.cpp b/components/panasonic_heatpump/binary_sensor/panasonic_heatpump_binary_sensor.cpp index c2f0f96..2ef6264 100644 --- a/components/panasonic_heatpump/binary_sensor/panasonic_heatpump_binary_sensor.cpp +++ b/components/panasonic_heatpump/binary_sensor/panasonic_heatpump_binary_sensor.cpp @@ -1,5 +1,4 @@ #include "panasonic_heatpump_binary_sensor.h" -#include "esphome/core/log.h" namespace esphome @@ -13,5 +12,153 @@ namespace esphome LOG_BINARY_SENSOR("", "Panasonic Heatpump Binary Sensor", this); delay(10); } + + void PanasonicHeatpumpBinarySensor::publish_new_state(const std::vector& data) + { + bool new_state; + switch (this->id_) + { + case BinarySensorIds::CONF_TOP0: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[4])); + if (this->state == new_state) return; + break; + } + case BinarySensorIds::CONF_TOP2: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[4])); + if (this->state == new_state) return; + break; + } + case BinarySensorIds::CONF_TOP3: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[7])); + if (this->state == new_state) return; + break; + } + case BinarySensorIds::CONF_TOP13: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[5])); + if (this->state == new_state) return; + break; + } + case BinarySensorIds::CONF_TOP26: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[111])); + if (this->state == new_state) return; + break; + } + case BinarySensorIds::CONF_TOP60: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[112])); + if (this->state == new_state) return; + break; + } + case BinarySensorIds::CONF_TOP61: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[112])); + if (this->state == new_state) return; + break; + } + case BinarySensorIds::CONF_TOP68: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[5])); + if (this->state == new_state) return; + break; + } + case BinarySensorIds::CONF_TOP69: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[117])); + if (this->state == new_state) return; + break; + } + case BinarySensorIds::CONF_TOP99: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[24])); + if (this->state == new_state) return; + break; + } + case BinarySensorIds::CONF_TOP100: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[24])); + if (this->state == new_state) return; + break; + } + case BinarySensorIds::CONF_TOP108: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit3and4(data[20])); + if (this->state == new_state) return; + break; + } + case BinarySensorIds::CONF_TOP109: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[20])); + if (this->state == new_state) return; + break; + } + case BinarySensorIds::CONF_TOP110: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[20])); + if (this->state == new_state) return; + break; + } + case BinarySensorIds::CONF_TOP119: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[23])); + if (this->state == new_state) return; + break; + } + case BinarySensorIds::CONF_TOP120: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[23])); + if (this->state == new_state) return; + break; + } + case BinarySensorIds::CONF_TOP121: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit3and4(data[23])); + if (this->state == new_state) return; + break; + } + case BinarySensorIds::CONF_TOP122: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[23])); + if (this->state == new_state) return; + break; + } + case BinarySensorIds::CONF_TOP123: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[116])); + if (this->state == new_state) return; + break; + } + case BinarySensorIds::CONF_TOP124: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit3and4(data[116])); + if (this->state == new_state) return; + break; + } + case BinarySensorIds::CONF_TOP129: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[26])); + if (this->state == new_state) return; + break; + } + case BinarySensorIds::CONF_TOP132: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit3and4(data[26])); + if (this->state == new_state) return; + break; + } + case BinarySensorIds::CONF_TOP133: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[26])); + if (this->state == new_state) return; + break; + } + default: return; + }; + this->publish_state(new_state); + } } // namespace panasonic_heatpump } // namespace esphome diff --git a/components/panasonic_heatpump/binary_sensor/panasonic_heatpump_binary_sensor.h b/components/panasonic_heatpump/binary_sensor/panasonic_heatpump_binary_sensor.h index 8d620ba..d24a899 100644 --- a/components/panasonic_heatpump/binary_sensor/panasonic_heatpump_binary_sensor.h +++ b/components/panasonic_heatpump/binary_sensor/panasonic_heatpump_binary_sensor.h @@ -1,18 +1,47 @@ #pragma once -#include "esphome/components/binary_sensor/binary_sensor.h" #include "esphome/core/component.h" +#include "esphome/components/binary_sensor/binary_sensor.h" #include "../panasonic_heatpump.h" +#include "../decode.h" namespace esphome { namespace panasonic_heatpump { - class PanasonicHeatpumpBinarySensor : public binary_sensor::BinarySensor, public Component, public Parented + enum BinarySensorIds : int + { + CONF_TOP0, + CONF_TOP2, + CONF_TOP3, + CONF_TOP13, + CONF_TOP26, + CONF_TOP60, + CONF_TOP61, + CONF_TOP68, + CONF_TOP69, + CONF_TOP99, + CONF_TOP100, + CONF_TOP108, + CONF_TOP109, + CONF_TOP110, + CONF_TOP119, + CONF_TOP120, + CONF_TOP121, + CONF_TOP122, + CONF_TOP123, + CONF_TOP124, + CONF_TOP129, + CONF_TOP132, + CONF_TOP133, + }; + + class PanasonicHeatpumpBinarySensor : public binary_sensor::BinarySensor, public Component, public Parented, public PanasonicHeatpumpEntity { public: PanasonicHeatpumpBinarySensor() = default; void dump_config() override; + void publish_new_state(const std::vector& data) override; }; } // namespace panasonic_heatpump } // namespace esphome diff --git a/components/panasonic_heatpump/commands.cpp b/components/panasonic_heatpump/commands.cpp index d554f80..3ad5bdb 100644 --- a/components/panasonic_heatpump/commands.cpp +++ b/components/panasonic_heatpump/commands.cpp @@ -90,17 +90,17 @@ namespace esphome { switch (input) { - case 0: return 18; // heat - case 1: return 19; // cool - case 2: return 24; // auto - case 3: return 25; // auto-heat - case 4: return 26; // auto-cool - case 5: return 33; // tank - case 6: return 34; // heat+tank - case 7: return 35; // cool+tank - case 8: return 40; // auto-tank - case 9: return 41; // auto-heat+tank - case 10: return 42; // auto-cool+tank + case 0: return 0b010010; // 0x12 = heat + case 1: return 0b100001; // 0x21 = tank + case 2: return 0b100010; // 0x22 = heat+tank + case 3: return 0b010011; // 0x13 = cool + case 4: return 0b100011; // 0x23 = cool+tank + case 5: return 0b011000; // 0x18 = auto + case 6: return 0b011001; // 0x19 = auto-heat + case 7: return 0b101000; // 0x28 = auto-tank + case 8: return 0b011010; // 0x1A = auto-cool + case 9: return 0b101001; // 0x29 = auto-heat+tank + case 10: return 0b101010; // 0x2A = auto-cool+tank default: return 0; // do nothing } } diff --git a/components/panasonic_heatpump/commands.h b/components/panasonic_heatpump/commands.h index ad7df8b..85de7a8 100644 --- a/components/panasonic_heatpump/commands.h +++ b/components/panasonic_heatpump/commands.h @@ -2,10 +2,18 @@ #include #include +#ifndef INIT_REQUEST_SIZE #define INIT_REQUEST_SIZE 8 +#endif +#ifndef INIT_RESPONSE_SIZE #define INIT_RESPONSE_SIZE 51 +#endif +#ifndef DATA_MESSAGE_SIZE #define DATA_MESSAGE_SIZE 111 +#endif +#ifndef OPTIONAL_MESSAGE_SIZE #define OPTIONAL_MESSAGE_SIZE 20 +#endif namespace esphome diff --git a/components/panasonic_heatpump/decode.cpp b/components/panasonic_heatpump/decode.cpp index 696c65a..491c73b 100644 --- a/components/panasonic_heatpump/decode.cpp +++ b/components/panasonic_heatpump/decode.cpp @@ -185,17 +185,17 @@ namespace esphome { switch ((int)(input & 0b111111)) { - case 18: return 0; // heat - case 19: return 1; // cool - case 24: return 2; // auto - case 25: return 3; // auto-heat - case 26: return 4; // auto-cool - case 33: return 5; // tank - case 34: return 6; // heat+tank - case 35: return 7; // cool+tank - case 40: return 8; // auto-tank - case 41: return 9; // auto-heat+tank - case 42: return 10; // auto-cool+tank + case 0b010010: return 0; // 0x12 = heat + case 0b100001: return 1; // 0x21 = tank + case 0b100010: return 2; // 0x22 = heat+tank + case 0b010011: return 3; // 0x13 = cool + case 0b100011: return 4; // 0x23 = cool+tank + case 0b011000: return 5; // 0x18 = auto + case 0b011001: return 6; // 0x19 = auto-heat + case 0b101000: return 7; // 0x28 = auto-tank + case 0b011010: return 8; // 0x1A = auto-cool + case 0b101001: return 9; // 0x29 = auto-heat+tank + case 0b101010: return 10; // 0x2A = auto-cool+tank default: return -1; // unknown } } diff --git a/components/panasonic_heatpump/decode.h b/components/panasonic_heatpump/decode.h index 32d61c8..b4d93ba 100644 --- a/components/panasonic_heatpump/decode.h +++ b/components/panasonic_heatpump/decode.h @@ -3,8 +3,12 @@ #include #include +#ifndef RESPONSE_MSG_SIZE #define RESPONSE_MSG_SIZE 203 +#endif +#ifndef NUMBER_OF_MODELS #define NUMBER_OF_MODELS 55 +#endif namespace esphome @@ -62,8 +66,8 @@ namespace esphome static const constexpr char* const PowerfulMode[] = { "4", "Off", "30min", "60min", "90min" }; static const constexpr char* const OperationMode[] = { - "11", "HEAT", "COOL", "AUTO", "AUTO(HEAT)", "AUTO(COOL)", - "TANK", "HEAT+TANK", "COOL+TANK", "AUTO+TANK", "AUTO(HEAT)+TANK", "AUTO(COOL)+TANK" + "11", "HEAT", "TANK", "HEAT+TANK", "COOL", "COOL+TANK", "AUTO", + "AUTO(HEAT)", "AUTO(TANK)", "AUTO(COOL)", "AUTO(HEAT)+TANK", "AUTO(COOL)+TANK" }; static const constexpr char* const ZoneState[] = { "3", "Zone 1", "Zone 2", "Zone 1 & 2" }; static const constexpr char* const ExtPadHeaterType[] = { "3", "Disabled", "Type-A", "Type-B" }; diff --git a/components/panasonic_heatpump/helpers.h b/components/panasonic_heatpump/helpers.h index 531f1d5..ab0ade2 100644 --- a/components/panasonic_heatpump/helpers.h +++ b/components/panasonic_heatpump/helpers.h @@ -5,7 +5,9 @@ #include #include +#ifndef UART_LOG_CHUNK_SIZE #define UART_LOG_CHUNK_SIZE 120 +#endif namespace esphome diff --git a/components/panasonic_heatpump/number/__init__.py b/components/panasonic_heatpump/number/__init__.py index c0960bf..9ad43eb 100644 --- a/components/panasonic_heatpump/number/__init__.py +++ b/components/panasonic_heatpump/number/__init__.py @@ -274,7 +274,7 @@ CONFIG_SCHEMA = cv.Schema( ).extend(cv.COMPONENT_SCHEMA) async def to_code(config): - hub = await cg.get_variable(config[CONF_PANASONIC_HEATPUMP_ID]) + parent = await cg.get_variable(config[CONF_PANASONIC_HEATPUMP_ID]) for index, key in enumerate(TYPES): if child_config := config.get(key): var = await number.new_number( @@ -284,6 +284,6 @@ async def to_code(config): step=CONF_NUMBERS[index][2] ) await cg.register_component(var, child_config) - await cg.register_parented(var, config[CONF_PANASONIC_HEATPUMP_ID]) - cg.add(getattr(hub, f"set_{key}_number")(var)) + cg.add(var.set_parent(parent)) cg.add(var.set_id(index)) + cg.add(parent.add_number(var)) diff --git a/components/panasonic_heatpump/number/panasonic_heatpump_number.cpp b/components/panasonic_heatpump/number/panasonic_heatpump_number.cpp index 3a2fc9f..5b112da 100644 --- a/components/panasonic_heatpump/number/panasonic_heatpump_number.cpp +++ b/components/panasonic_heatpump/number/panasonic_heatpump_number.cpp @@ -1,5 +1,4 @@ #include "panasonic_heatpump_number.h" -#include "esphome/core/log.h" namespace esphome @@ -16,8 +15,468 @@ namespace esphome void PanasonicHeatpumpNumber::control(float value) { - this->publish_state(value); - this->parent_->control_number(this, value); + switch (this->id_) + { + case NumberIds::CONF_SET5: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus128(value), 38); + break; + } + case NumberIds::CONF_SET6: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus128(value), 39); + break; + } + case NumberIds::CONF_SET7: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus128(value), 40); + break; + } + case NumberIds::CONF_SET8: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus128(value), 41); + break; + } + case NumberIds::CONF_SET11: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus128(value), 42); + break; + } + case NumberIds::CONF_SET15: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus1(value), 45); + break; + } + case NumberIds::CONF_SET16_01: + { + this->parent_->set_command_curve(PanasonicCommand::setPlus128(value), 75); + break; + } + case NumberIds::CONF_SET16_02: + { + this->parent_->set_command_curve(PanasonicCommand::setPlus128(value), 76); + break; + } + case NumberIds::CONF_SET16_03: + { + this->parent_->set_command_curve(PanasonicCommand::setPlus128(value), 77); + break; + } + case NumberIds::CONF_SET16_04: + { + this->parent_->set_command_curve(PanasonicCommand::setPlus128(value), 78); + break; + } + case NumberIds::CONF_SET16_05: + { + this->parent_->set_command_curve(PanasonicCommand::setPlus128(value), 79); + break; + } + case NumberIds::CONF_SET16_06: + { + this->parent_->set_command_curve(PanasonicCommand::setPlus128(value), 80); + break; + } + case NumberIds::CONF_SET16_07: + { + this->parent_->set_command_curve(PanasonicCommand::setPlus128(value), 81); + break; + } + case NumberIds::CONF_SET16_08: + { + this->parent_->set_command_curve(PanasonicCommand::setPlus128(value), 82); + break; + } + case NumberIds::CONF_SET16_09: + { + this->parent_->set_command_curve(PanasonicCommand::setPlus128(value), 86); + break; + } + case NumberIds::CONF_SET16_10: + { + this->parent_->set_command_curve(PanasonicCommand::setPlus128(value), 87); + break; + } + case NumberIds::CONF_SET16_11: + { + this->parent_->set_command_curve(PanasonicCommand::setPlus128(value), 88); + break; + } + case NumberIds::CONF_SET16_12: + { + this->parent_->set_command_curve(PanasonicCommand::setPlus128(value), 89); + break; + } + case NumberIds::CONF_SET16_13: + { + this->parent_->set_command_curve(PanasonicCommand::setPlus128(value), 90); + break; + } + case NumberIds::CONF_SET16_14: + { + this->parent_->set_command_curve(PanasonicCommand::setPlus128(value), 91); + break; + } + case NumberIds::CONF_SET16_15: + { + this->parent_->set_command_curve(PanasonicCommand::setPlus128(value), 92); + break; + } + case NumberIds::CONF_SET16_16: + { + this->parent_->set_command_curve(PanasonicCommand::setPlus128(value), 93); + break; + } + case NumberIds::CONF_SET18: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus128(value), 84); + break; + } + case NumberIds::CONF_SET19: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus128(value), 94); + break; + } + case NumberIds::CONF_SET20: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus128(value), 99); + break; + } + case NumberIds::CONF_SET21: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus1(value), 104); + break; + } + case NumberIds::CONF_SET22: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus128(value), 105); + break; + } + case NumberIds::CONF_SET23: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus128(value), 106); + break; + } + case NumberIds::CONF_SET27: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus128(value), 59); + break; + } + case NumberIds::CONF_SET29: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus128(value), 83); + break; + } + case NumberIds::CONF_SET36: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus128(value), 65); + break; + } + case NumberIds::CONF_SET37: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus128(value), 66); + break; + } + case NumberIds::CONF_SET38: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus128(value), 68); + break; + } + default: return; + }; + this->publish_state(state); + this->keep_state_ = 2; + } + + void PanasonicHeatpumpNumber::publish_new_state(const std::vector& data) + { + if (this->keep_state_ > 0) + { + this->keep_state_--; + return; + } + + float new_state; + switch (this->id_) + { + case NumberIds::CONF_SET11: + { + new_state = PanasonicDecode::getByteMinus128(data[42]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET20: + { + new_state = PanasonicDecode::getByteMinus128(data[99]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET18: + { + new_state = PanasonicDecode::getByteMinus128(data[84]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET19: + { + new_state = PanasonicDecode::getByteMinus128(data[94]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET5: + { + new_state = PanasonicDecode::getByteMinus128(data[38]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET6: + { + new_state = PanasonicDecode::getByteMinus128(data[39]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET16_01: + { + new_state = PanasonicDecode::getByteMinus128(data[75]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET16_02: + { + new_state = PanasonicDecode::getByteMinus128(data[76]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET16_04: + { + new_state = PanasonicDecode::getByteMinus128(data[78]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET16_03: + { + new_state = PanasonicDecode::getByteMinus128(data[77]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET7: + { + new_state = PanasonicDecode::getByteMinus128(data[40]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET8: + { + new_state = PanasonicDecode::getByteMinus128(data[41]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET16_09: + { + new_state = PanasonicDecode::getByteMinus128(data[86]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET16_10: + { + new_state = PanasonicDecode::getByteMinus128(data[87]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET16_12: + { + new_state = PanasonicDecode::getByteMinus128(data[89]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET16_11: + { + new_state = PanasonicDecode::getByteMinus128(data[88]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET29: + { + new_state = PanasonicDecode::getByteMinus128(data[83]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET16_05: + { + new_state = PanasonicDecode::getByteMinus128(data[79]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET16_06: + { + new_state = PanasonicDecode::getByteMinus128(data[80]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET16_08: + { + new_state = PanasonicDecode::getByteMinus128(data[82]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET16_07: + { + new_state = PanasonicDecode::getByteMinus128(data[81]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET16_13: + { + new_state = PanasonicDecode::getByteMinus128(data[90]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET16_14: + { + new_state = PanasonicDecode::getByteMinus128(data[91]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET16_16: + { + new_state = PanasonicDecode::getByteMinus128(data[93]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET16_15: + { + new_state = PanasonicDecode::getByteMinus128(data[92]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET15: + { + new_state = PanasonicDecode::getByteMinus1(data[45]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET21: + { + new_state = PanasonicDecode::getByteMinus1(data[104]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET22: + { + new_state = PanasonicDecode::getByteMinus128(data[105]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET23: + { + new_state = PanasonicDecode::getByteMinus128(data[106]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET27: + { + new_state = PanasonicDecode::getByteMinus128(data[59]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET36: + { + new_state = PanasonicDecode::getByteMinus128(data[65]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET37: + { + new_state = PanasonicDecode::getByteMinus128(data[66]); + if (this->state == new_state) return; + break; + } + case NumberIds::CONF_SET38: + { + new_state = PanasonicDecode::getByteMinus128(data[68]); + if (this->state == new_state) return; + break; + } + default: return; + }; + this->publish_state(new_state); + } + + bool PanasonicHeatpumpNumber::set_traits(const std::vector& data) + { + std::string top76 = PanasonicDecode::getTextState( + PanasonicDecode::WaterTempControl, PanasonicDecode::getBit7and8(data[28])); // Heating Mode + std::string top81 = PanasonicDecode::getTextState( + PanasonicDecode::WaterTempControl, PanasonicDecode::getBit5and6(data[28])); // Cooling Mode + + switch (this->id_) + { + case NumberIds::CONF_SET5: + { + if (this->traits.get_min_value() != -5.0 && top76 == PanasonicDecode::WaterTempControl[1]) + { + this->traits.set_min_value(-5.0); + this->traits.set_max_value(5.0); + return true; + } + if (this->traits.get_min_value() != 20.0 && top76 == PanasonicDecode::WaterTempControl[2]) + { + this->traits.set_min_value(20.0); + this->traits.set_max_value(60.0); + return true; + } + break; + } + case NumberIds::CONF_SET6: + { + if (this->traits.get_min_value() != -5.0 && top81 == PanasonicDecode::WaterTempControl[1]) + { + this->traits.set_min_value(-5.0); + this->traits.set_max_value(5.0); + return true; + } + if (this->traits.get_min_value() != 20.0 && top81 == PanasonicDecode::WaterTempControl[2]) + { + this->traits.set_min_value(20.0); + this->traits.set_max_value(60.0); + return true; + } + break; + } + case NumberIds::CONF_SET7: + { + if (this->traits.get_min_value() != -5.0 && top76 == PanasonicDecode::WaterTempControl[1]) + { + this->traits.set_min_value(-5.0); + this->traits.set_max_value(5.0); + return true; + } + if (this->traits.get_min_value() != 20.0 && top76 == PanasonicDecode::WaterTempControl[2]) + { + this->traits.set_min_value(20.0); + this->traits.set_max_value(60.0); + return true; + } + break; + } + case NumberIds::CONF_SET8: + { + if (this->traits.get_min_value() != -5.0 && top81 == PanasonicDecode::WaterTempControl[1]) + { + this->traits.set_min_value(-5.0); + this->traits.set_max_value(5.0); + return true; + } + if (this->traits.get_min_value() != 20.0 && top81 == PanasonicDecode::WaterTempControl[2]) + { + this->traits.set_min_value(20.0); + this->traits.set_max_value(60.0); + return true; + } + break; + } + }; + return false; } } // namespace panasonic_heatpump } // namespace esphome diff --git a/components/panasonic_heatpump/number/panasonic_heatpump_number.h b/components/panasonic_heatpump/number/panasonic_heatpump_number.h index 5b535fd..7c3b92f 100644 --- a/components/panasonic_heatpump/number/panasonic_heatpump_number.h +++ b/components/panasonic_heatpump/number/panasonic_heatpump_number.h @@ -1,23 +1,62 @@ #pragma once -#include "esphome/components/number/number.h" #include "esphome/core/component.h" +#include "esphome/components/number/number.h" #include "../panasonic_heatpump.h" +#include "../decode.h" +#include "../commands.h" namespace esphome { namespace panasonic_heatpump { - class PanasonicHeatpumpNumber : public number::Number, public Component, public Parented + enum NumberIds : int + { + CONF_SET5, + CONF_SET6, + CONF_SET7, + CONF_SET8, + CONF_SET11, + CONF_SET15, + CONF_SET16_01, + CONF_SET16_02, + CONF_SET16_03, + CONF_SET16_04, + CONF_SET16_05, + CONF_SET16_06, + CONF_SET16_07, + CONF_SET16_08, + CONF_SET16_09, + CONF_SET16_10, + CONF_SET16_11, + CONF_SET16_12, + CONF_SET16_13, + CONF_SET16_14, + CONF_SET16_15, + CONF_SET16_16, + CONF_SET18, + CONF_SET19, + CONF_SET20, + CONF_SET21, + CONF_SET22, + CONF_SET23, + CONF_SET27, + CONF_SET29, + CONF_SET36, + CONF_SET37, + CONF_SET38, + }; + + class PanasonicHeatpumpNumber : public number::Number, public Component, public Parented, public PanasonicHeatpumpEntity { public: PanasonicHeatpumpNumber() = default; void dump_config() override; - void set_id(int id) { this->id_ = id; } + void publish_new_state(const std::vector& data) override; + bool set_traits(const std::vector& data) override; protected: void control(float value) override; - int id_; }; } // namespace panasonic_heatpump } // namespace esphome diff --git a/components/panasonic_heatpump/panasonic_heatpump.cpp b/components/panasonic_heatpump/panasonic_heatpump.cpp index b39d1e9..484cdf0 100644 --- a/components/panasonic_heatpump/panasonic_heatpump.cpp +++ b/components/panasonic_heatpump/panasonic_heatpump.cpp @@ -20,12 +20,6 @@ namespace esphome delay(10); // NOLINT this->check_uart_settings(9600, 1, uart::UART_CONFIG_PARITY_EVEN, 8); - // initialize vector - for (int i = 0; i < RESPONSE_MSG_SIZE; i++) - { - this->last_message_.push_back(0); - } - this->update(); } @@ -55,48 +49,48 @@ namespace esphome case LoopState::SET_NUMBER_TRAITS: { this->set_number_traits(this->heatpump_message_); + this->loop_state_ = LoopState::SET_SELECT_TRAITS; + break; + } + case LoopState::SET_SELECT_TRAITS: + { + this->set_select_traits(this->heatpump_message_); this->loop_state_ = LoopState::PUBLISH_SENSOR; break; } case LoopState::PUBLISH_SENSOR: { - this->publish_sensor(this->heatpump_message_, this->last_message_); + this->publish_sensor(this->heatpump_message_); this->loop_state_ = LoopState::PUBLISH_BINARY_SENSOR; break; } case LoopState::PUBLISH_BINARY_SENSOR: { - this->publish_binary_sensor(this->heatpump_message_, this->last_message_); + this->publish_binary_sensor(this->heatpump_message_); this->loop_state_ = LoopState::PUBLISH_TEXT_SENSOR; break; } case LoopState::PUBLISH_TEXT_SENSOR: { - this->publish_text_sensor(this->heatpump_message_, this->last_message_); + this->publish_text_sensor(this->heatpump_message_); this->loop_state_ = LoopState::PUBLISH_NUMBER; break; } case LoopState::PUBLISH_NUMBER: { - this->publish_number(this->heatpump_message_, this->last_message_); + this->publish_number(this->heatpump_message_); this->loop_state_ = LoopState::PUBLISH_SELECT; break; } case LoopState::PUBLISH_SELECT: { - this->publish_select(this->heatpump_message_, this->last_message_); + this->publish_select(this->heatpump_message_); this->loop_state_ = LoopState::PUBLISH_SWITCH; break; } case LoopState::PUBLISH_SWITCH: { - this->publish_switch(this->heatpump_message_, this->last_message_); - this->loop_state_ = LoopState::STORE_RESPONSE; - break; - } - case LoopState::STORE_RESPONSE: - { - this->last_message_ = this->heatpump_message_; + this->publish_switch(this->heatpump_message_); this->loop_state_ = LoopState::SEND_REQUEST; break; } @@ -114,16 +108,19 @@ namespace esphome } default: { + if (this->set_traits_loop_) this->set_traits_total_++; + // Perform reboot only if a traits (e.g. min/max value of a number entity) was changed the second time. // The first traits change should happen before controller is connected to home assistant, // because the default min/max value is 0. - if (this->trait_update_counter_ > 1) + if (this->set_traits_total_ > 1) { ESP_LOGW(TAG, "Min/max values have changed. Rebooting so Home Assistant reconfigures the number component."); delay(100); // NOLINT App.safe_reboot(); } + this->set_traits_loop_ = false; this->loop_state_ = LoopState::READ_RESPONSE; break; } @@ -354,7 +351,7 @@ namespace esphome this->next_request_ = RequestType::COMMAND; } - void PanasonicHeatpumpComponent::set_command_bytes(const std::vector>& data) + void PanasonicHeatpumpComponent::set_command_curve(const uint8_t value, const uint8_t index) { if (this->next_request_ != RequestType::COMMAND) { @@ -362,13 +359,36 @@ namespace esphome this->command_message_.assign(std::begin(PanasonicCommand::CommandMessage), std::end(PanasonicCommand::CommandMessage)); } - // set command bytes - for (size_t i = 0; i < data.size(); ++i) + + // Set zone 1 curve bytes + if (index == 75 || index == 76 || index == 77 || index == 78 || + index == 86 || index == 87 || index == 88 || index == 89) { - uint8_t value = std::get<0>(data[i]); - uint8_t index = std::get<1>(data[i]); - this->command_message_[index] = value; + this->command_message_[75] = this->heatpump_message_[75]; + this->command_message_[76] = this->heatpump_message_[76]; + this->command_message_[77] = this->heatpump_message_[77]; + this->command_message_[78] = this->heatpump_message_[78]; + this->command_message_[86] = this->heatpump_message_[86]; + this->command_message_[87] = this->heatpump_message_[87]; + this->command_message_[88] = this->heatpump_message_[88]; + this->command_message_[89] = this->heatpump_message_[89]; } + // Set zone 2 curve bytes + if (index == 79 || index == 80 || index == 81 || index == 82 || + index == 90 || index == 91 || index == 92 || index == 93) + { + this->command_message_[79] = this->heatpump_message_[79]; + this->command_message_[80] = this->heatpump_message_[80]; + this->command_message_[81] = this->heatpump_message_[81]; + this->command_message_[82] = this->heatpump_message_[82]; + this->command_message_[90] = this->heatpump_message_[90]; + this->command_message_[91] = this->heatpump_message_[91]; + this->command_message_[92] = this->heatpump_message_[92]; + this->command_message_[93] = this->heatpump_message_[93]; + } + + // set command byte + this->command_message_[index] = value; // calculate and set set checksum (last element) this->command_message_.back() = PanasonicCommand::calcChecksum(this->command_message_, this->command_message_.size() - 1); @@ -376,406 +396,98 @@ namespace esphome this->next_request_ = RequestType::COMMAND; } + void PanasonicHeatpumpComponent::publish_binary_sensor(const std::vector& data) + { + if (data.empty()) return; + for (auto *entity : this->binary_sensors_) + { + entity->publish_new_state(data); + } + } + + void PanasonicHeatpumpComponent::publish_number(const std::vector& data) + { + if (data.empty()) return; + for (auto *entity : this->numbers_) + { + entity->publish_new_state(data); + } + } + void PanasonicHeatpumpComponent::set_number_traits(const std::vector& data) { -#ifdef USE_TEXT_SENSOR -#ifdef USE_NUMBER if (data.empty()) return; + std::string top76_str = PanasonicDecode::getTextState( + PanasonicDecode::WaterTempControl, PanasonicDecode::getBit7and8(data[28])); // Heating Mode + std::string top81_str = PanasonicDecode::getTextState( + PanasonicDecode::WaterTempControl, PanasonicDecode::getBit5and6(data[28])); // Cooling Mode + // ToDo: Convert top76 and top81 into int and pass them to set_traits(); // traits can be changed anytime, but entities will only be updated in home assistant, // if the traits was set before connecting to home assistant. If now a traits must be changed later, // a reboot of the ESP controller is required to see the changes in home assistant. bool change_detected = false; - std::string top76 = PanasonicDecode::getTextState( - PanasonicDecode::WaterTempControl, PanasonicDecode::getBit7and8(data[28])); // Heating Mode - std::string top81 = PanasonicDecode::getTextState( - PanasonicDecode::WaterTempControl, PanasonicDecode::getBit5and6(data[28])); // Cooling Mode - float set5_min = this->set5_number_->traits.get_min_value(); // Z1 Heat Request Temperature - float set6_min = this->set6_number_->traits.get_min_value(); // Z1 Cool Request Temperature - float set7_min = this->set7_number_->traits.get_min_value(); // Z2 Heat Request Temperature - float set8_min = this->set8_number_->traits.get_min_value(); // Z2 Cool Request Temperature - - if (set5_min >= 0.0 && top76 == PanasonicDecode::WaterTempControl[1]) + for (auto *entity : this->numbers_) { - this->set5_number_->traits.set_min_value(-5.0); - this->set5_number_->traits.set_max_value(5.0); - change_detected = true; + change_detected = entity->set_traits(data) ? true : change_detected; } - if (set6_min >= 0.0 && top81 == PanasonicDecode::WaterTempControl[1]) - { - this->set6_number_->traits.set_min_value(-5.0); - this->set6_number_->traits.set_max_value(5.0); - change_detected = true; - } - if (set7_min >= 0.0 && top76 == PanasonicDecode::WaterTempControl[1]) - { - this->set7_number_->traits.set_min_value(-5.0); - this->set7_number_->traits.set_max_value(5.0); - change_detected = true; - } - if (set8_min >= 0.0 && top81 == PanasonicDecode::WaterTempControl[1]) - { - this->set8_number_->traits.set_min_value(-5.0); - this->set8_number_->traits.set_max_value(5.0); - change_detected = true; - } - - if (set5_min <= 0.0 && top76 == PanasonicDecode::WaterTempControl[2]) - { - this->set5_number_->traits.set_min_value(20.0); - this->set5_number_->traits.set_max_value(60.0); - change_detected = true; - } - if (set6_min <= 0.0 && top81 == PanasonicDecode::WaterTempControl[2]) - { - this->set6_number_->traits.set_min_value(20.0); - this->set6_number_->traits.set_max_value(60.0); - change_detected = true; - } - if (set7_min <= 0.0 && top76 == PanasonicDecode::WaterTempControl[2]) - { - this->set7_number_->traits.set_min_value(20.0); - this->set7_number_->traits.set_max_value(60.0); - change_detected = true; - } - if (set8_min <= 0.0 && top81 == PanasonicDecode::WaterTempControl[2]) - { - this->set8_number_->traits.set_min_value(20.0); - this->set8_number_->traits.set_max_value(60.0); - change_detected = true; - } - if (change_detected) { - this->trait_update_counter_++; + this->set_traits_loop_ = true; } -#endif -#endif } - void PanasonicHeatpumpComponent::publish_sensor(const std::vector& data, const std::vector& last) + void PanasonicHeatpumpComponent::publish_select(const std::vector& data) { -#ifdef USE_SENSOR if (data.empty()) return; - if (this->top1_sensor_ && last[169] != data[169]) this->top1_sensor_->publish_state(PanasonicDecode::getPumpFlow(data, 169)); - if (this->top5_sensor_ && (last[143] != data[143] || last[118] != data[118])) this->top5_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[143]) + PanasonicDecode::getFractional(data[118], 0)); - if (this->top6_sensor_ && (last[144] != data[144] || last[118] != data[118])) this->top6_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[144]) + PanasonicDecode::getFractional(data[118], 3)); - if (this->top7_sensor_ && last[153] != data[153]) this->top7_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[153])); - if (this->top8_sensor_ && last[166] != data[166]) this->top8_sensor_->publish_state(PanasonicDecode::getByteMinus1(data[166])); - if (this->top9_sensor_ && last[42] != data[42]) this->top9_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[42])); - if (this->top10_sensor_ && last[141] != data[141]) this->top10_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[141])); - if (this->top11_sensor_ && last[182] != data[182]) this->top11_sensor_->publish_state(PanasonicDecode::getWordMinus1(data, 182)); - if (this->top12_sensor_ && last[179] != data[179]) this->top12_sensor_->publish_state(PanasonicDecode::getWordMinus1(data, 179)); - if (this->top14_sensor_ && last[142] != data[142]) this->top14_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[142])); - if (this->top15_sensor_ && last[194] != data[194]) this->top15_sensor_->publish_state(PanasonicDecode::getByteMinus1Times200(data[194])); - if (this->top16_sensor_ && last[193] != data[193]) this->top16_sensor_->publish_state(PanasonicDecode::getByteMinus1Times200(data[193])); - if (this->top21_sensor_ && last[158] != data[158]) this->top21_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[158])); - if (this->top22_sensor_ && last[99] != data[99]) this->top22_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[99])); - if (this->top23_sensor_ && last[84] != data[84]) this->top23_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[84])); - if (this->top24_sensor_ && last[94] != data[94]) this->top24_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[94])); - if (this->top25_sensor_ && last[44] != data[44]) this->top25_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[44])); - if (this->top27_sensor_ && last[38] != data[38]) this->top27_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[38])); - if (this->top28_sensor_ && last[39] != data[39]) this->top28_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[39])); - if (this->top29_sensor_ && last[75] != data[75]) this->top29_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[75])); - if (this->top30_sensor_ && last[76] != data[76]) this->top30_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[76])); - if (this->top31_sensor_ && last[78] != data[78]) this->top31_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[78])); - if (this->top32_sensor_ && last[77] != data[77]) this->top32_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[77])); - if (this->top33_sensor_ && last[156] != data[156]) this->top33_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[156])); - if (this->top34_sensor_ && last[40] != data[40]) this->top34_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[40])); - if (this->top35_sensor_ && last[41] != data[41]) this->top35_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[41])); - if (this->top36_sensor_ && last[145] != data[145]) this->top36_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[145])); - if (this->top37_sensor_ && last[146] != data[146]) this->top37_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[146])); - if (this->top38_sensor_ && last[196] != data[196]) this->top38_sensor_->publish_state(PanasonicDecode::getByteMinus1Times200(data[196])); - if (this->top39_sensor_ && last[195] != data[195]) this->top39_sensor_->publish_state(PanasonicDecode::getByteMinus1Times200(data[195])); - if (this->top40_sensor_ && last[198] != data[198]) this->top40_sensor_->publish_state(PanasonicDecode::getByteMinus1Times200(data[198])); - if (this->top41_sensor_ && last[197] != data[197]) this->top41_sensor_->publish_state(PanasonicDecode::getByteMinus1Times200(data[197])); - if (this->top42_sensor_ && last[147] != data[147]) this->top42_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[147])); - if (this->top43_sensor_ && last[148] != data[148]) this->top43_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[148])); - if (this->top45_sensor_ && last[43] != data[43]) this->top45_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[43])); - if (this->top46_sensor_ && last[149] != data[149]) this->top46_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[149])); - if (this->top47_sensor_ && last[150] != data[150]) this->top47_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[150])); - if (this->top48_sensor_ && last[151] != data[151]) this->top48_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[151])); - if (this->top49_sensor_ && last[154] != data[154]) this->top49_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[154])); - if (this->top50_sensor_ && last[155] != data[155]) this->top50_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[155])); - if (this->top51_sensor_ && last[157] != data[157]) this->top51_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[157])); - if (this->top52_sensor_ && last[159] != data[159]) this->top52_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[159])); - if (this->top53_sensor_ && last[160] != data[160]) this->top53_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[160])); - if (this->top54_sensor_ && last[161] != data[161]) this->top54_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[161])); - if (this->top55_sensor_ && last[162] != data[162]) this->top55_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[162])); - if (this->top56_sensor_ && last[139] != data[139]) this->top56_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[139])); - if (this->top57_sensor_ && last[140] != data[140]) this->top57_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[140])); - if (this->top62_sensor_ && last[173] != data[173]) this->top62_sensor_->publish_state(PanasonicDecode::getByteMinus1Times10(data[173])); - if (this->top63_sensor_ && last[174] != data[174]) this->top63_sensor_->publish_state(PanasonicDecode::getByteMinus1Times10(data[174])); - if (this->top64_sensor_ && last[163] != data[163]) this->top64_sensor_->publish_state(PanasonicDecode::getByteMinus1Div5(data[163])); - if (this->top65_sensor_ && last[171] != data[171]) this->top65_sensor_->publish_state(PanasonicDecode::getByteMinus1Times50(data[171])); - if (this->top66_sensor_ && last[164] != data[164]) this->top66_sensor_->publish_state(PanasonicDecode::getByteMinus1Times50(data[164])); - if (this->top67_sensor_ && last[165] != data[165]) this->top67_sensor_->publish_state(PanasonicDecode::getByteMinus1Div5(data[165])); - if (this->top70_sensor_ && last[100] != data[100]) this->top70_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[100])); - if (this->top71_sensor_ && last[101] != data[101]) this->top71_sensor_->publish_state(PanasonicDecode::getByteMinus1(data[101])); - if (this->top72_sensor_ && last[86] != data[86]) this->top72_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[86])); - if (this->top73_sensor_ && last[87] != data[87]) this->top73_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[87])); - if (this->top74_sensor_ && last[89] != data[89]) this->top74_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[89])); - if (this->top75_sensor_ && last[88] != data[88]) this->top75_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[88])); - if (this->top77_sensor_ && last[83] != data[83]) this->top77_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[83])); - if (this->top78_sensor_ && last[85] != data[85]) this->top78_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[85])); - if (this->top79_sensor_ && last[95] != data[95]) this->top79_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[95])); - if (this->top80_sensor_ && last[96] != data[96]) this->top80_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[96])); - if (this->top82_sensor_ && last[79] != data[79]) this->top82_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[79])); - if (this->top83_sensor_ && last[80] != data[80]) this->top83_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[80])); - if (this->top84_sensor_ && last[82] != data[82]) this->top84_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[82])); - if (this->top85_sensor_ && last[81] != data[81]) this->top85_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[81])); - if (this->top86_sensor_ && last[90] != data[90]) this->top86_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[90])); - if (this->top87_sensor_ && last[91] != data[91]) this->top87_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[91])); - if (this->top88_sensor_ && last[93] != data[93]) this->top88_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[93])); - if (this->top89_sensor_ && last[92] != data[92]) this->top89_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[92])); - if (this->top90_sensor_ && last[185] != data[185]) this->top90_sensor_->publish_state(PanasonicDecode::getWordMinus1(data, 185)); - if (this->top91_sensor_ && last[188] != data[188]) this->top91_sensor_->publish_state(PanasonicDecode::getWordMinus1(data, 188)); - if (this->top93_sensor_ && last[172] != data[172]) this->top93_sensor_->publish_state(PanasonicDecode::getByteMinus1(data[172])); - if (this->top95_sensor_ && last[45] != data[45]) this->top95_sensor_->publish_state(PanasonicDecode::getByteMinus1(data[45])); - if (this->top96_sensor_ && last[104] != data[104]) this->top96_sensor_->publish_state(PanasonicDecode::getByteMinus1(data[104])); - if (this->top97_sensor_ && last[105] != data[105]) this->top97_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[105])); - if (this->top98_sensor_ && last[106] != data[106]) this->top98_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[106])); - if (this->top102_sensor_ && last[61] != data[61]) this->top102_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[61])); - if (this->top103_sensor_ && last[62] != data[62]) this->top103_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[62])); - if (this->top104_sensor_ && last[63] != data[63]) this->top104_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[63])); - if (this->top105_sensor_ && last[64] != data[64]) this->top105_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[64])); - if (this->top113_sensor_ && last[59] != data[59]) this->top113_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[59])); - if (this->top115_sensor_ && last[125] != data[125]) this->top115_sensor_->publish_state(PanasonicDecode::getByteMinus1Div50(data[125])); - if (this->top116_sensor_ && last[126] != data[126]) this->top116_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[126])); - if (this->top117_sensor_ && last[127] != data[127]) this->top117_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[127])); - if (this->top118_sensor_ && last[128] != data[128]) this->top118_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[128])); - if (this->top127_sensor_ && last[177] != data[177]) this->top127_sensor_->publish_state(PanasonicDecode::getByteMinus1Div2(data[177])); - if (this->top128_sensor_ && last[178] != data[178]) this->top128_sensor_->publish_state(PanasonicDecode::getByteMinus1Div2(data[178])); - if (this->top131_sensor_ && last[65] != data[65]) this->top131_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[65])); - if (this->top134_sensor_ && last[66] != data[66]) this->top134_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[66])); - if (this->top135_sensor_ && last[68] != data[68]) this->top135_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[68])); - if (this->top136_sensor_ && last[67] != data[67]) this->top136_sensor_->publish_state(PanasonicDecode::getByteMinus1(data[67])); - if (this->top137_sensor_ && last[69] != data[69]) this->top137_sensor_->publish_state(PanasonicDecode::getByteMinus1(data[69])); - if (this->top138_sensor_ && last[70] != data[70]) this->top138_sensor_->publish_state(PanasonicDecode::getByteMinus1(data[70])); -#endif - } - - void PanasonicHeatpumpComponent::publish_binary_sensor(const std::vector& data, const std::vector& last) - { -#ifdef USE_BINARY_SENSOR - if (data.empty()) return; - if (this->top0_binary_sensor_ && last[4] != data[4]) this->top0_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[4]))); - if (this->top2_binary_sensor_ && last[4] != data[4]) this->top2_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[4]))); - if (this->top3_binary_sensor_ && last[7] != data[7]) this->top3_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[7]))); - if (this->top13_binary_sensor_ && last[5] != data[5]) this->top13_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[5]))); - if (this->top26_binary_sensor_ && last[111] != data[111]) this->top26_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[111]))); - if (this->top60_binary_sensor_ && last[112] != data[112]) this->top60_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[112]))); - if (this->top61_binary_sensor_ && last[112] != data[112]) this->top61_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[112]))); - if (this->top68_binary_sensor_ && last[5] != data[5]) this->top68_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[5]))); - if (this->top69_binary_sensor_ && last[117] != data[117]) this->top69_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[117]))); - if (this->top99_binary_sensor_ && last[24] != data[24]) this->top99_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[24]))); - if (this->top100_binary_sensor_ && last[24] != data[24]) this->top100_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[24]))); - if (this->top108_binary_sensor_ && last[20] != data[20]) this->top108_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit3and4(data[20]))); - if (this->top109_binary_sensor_ && last[20] != data[20]) this->top109_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[20]))); - if (this->top110_binary_sensor_ && last[20] != data[20]) this->top110_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[20]))); - if (this->top119_binary_sensor_ && last[23] != data[23]) this->top119_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[23]))); - if (this->top120_binary_sensor_ && last[23] != data[23]) this->top120_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[23]))); - if (this->top121_binary_sensor_ && last[23] != data[23]) this->top121_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit3and4(data[23]))); - if (this->top122_binary_sensor_ && last[23] != data[23]) this->top122_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[23]))); - if (this->top123_binary_sensor_ && last[116] != data[116]) this->top123_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[116]))); - if (this->top124_binary_sensor_ && last[116] != data[116]) this->top124_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit3and4(data[116]))); - if (this->top129_binary_sensor_ && last[26] != data[26]) this->top129_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[26]))); - if (this->top132_binary_sensor_ && last[26] != data[26]) this->top132_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit3and4(data[26]))); - if (this->top133_binary_sensor_ && last[26] != data[26]) this->top133_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[26]))); -#endif - } - - void PanasonicHeatpumpComponent::publish_text_sensor(const std::vector& data, const std::vector& last) - { -#ifdef USE_TEXT_SENSOR - if (data.empty()) return; - if (this->top4_text_sensor_ && last[6] != data[6]) this->top4_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::OperationMode, PanasonicDecode::getOperationMode(data[6]))); - if (this->top17_text_sensor_ && last[7] != data[7]) this->top17_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::PowerfulMode, PanasonicDecode::getBit6and7and8(data[7]))); - if (this->top18_text_sensor_ && last[7] != data[7]) this->top18_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::QuietMode, PanasonicDecode::getBit3and4and5(data[7]))); - if (this->top19_text_sensor_ && last[5] != data[5]) this->top19_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::HolidayState, PanasonicDecode::getBit3and4(data[5]))); - if (this->top20_text_sensor_ && last[111] != data[111]) this->top20_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::ThreeWayValve, PanasonicDecode::getBit7and8(data[111]))); - if (this->top44_text_sensor_ && (last[113] != data[113] || last[114] != data[114])) this->top44_text_sensor_->publish_state(PanasonicDecode::getErrorInfo(data[113], data[114])); - if (this->top58_text_sensor_ && last[9] != data[9]) this->top58_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::BlockedFree, PanasonicDecode::getBit5and6(data[9]))); - if (this->top59_text_sensor_ && last[9] != data[9]) this->top59_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::BlockedFree, PanasonicDecode::getBit7and8(data[9]))); - if (this->top76_text_sensor_ && last[28] != data[28]) this->top76_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::WaterTempControl, PanasonicDecode::getBit7and8(data[28]))); - if (this->top81_text_sensor_ && last[28] != data[28]) this->top81_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::WaterTempControl, PanasonicDecode::getBit5and6(data[28]))); - if (this->top92_text_sensor_ && last[129] != data[129]) this->top92_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::ModelNames, PanasonicDecode::getModel(data, 129))); - if (this->top94_text_sensor_ && last[6] != data[6]) this->top94_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::ZoneState, PanasonicDecode::getBit1and2(data[6]))); - if (this->top101_text_sensor_ && last[24] != data[24]) this->top101_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::SolarMode, PanasonicDecode::getBit3and4(data[24]))); - if (this->top106_text_sensor_ && last[29] != data[29]) this->top106_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::PumpFlowRateMode, PanasonicDecode::getBit3and4(data[29]))); - if (this->top107_text_sensor_ && last[20] != data[20]) this->top107_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::LiquidType, PanasonicDecode::getBit1(data[20]))); - if (this->top111_text_sensor_ && last[22] != data[22]) this->top111_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::ZoneSensorType, PanasonicDecode::getLowNibbleMinus1(data[22]))); - if (this->top112_text_sensor_ && last[22] != data[22]) this->top112_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::ZoneSensorType, PanasonicDecode::getHighNibbleMinus1(data[22]))); - if (this->top114_text_sensor_ && last[25] != data[25]) this->top114_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::ExtPadHeaterType, PanasonicDecode::getBit3and4(data[25]))); - if (this->top125_text_sensor_ && last[116] != data[116]) this->top125_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::TwoWayValve, PanasonicDecode::getBit5and6(data[116]))); - if (this->top126_text_sensor_ && last[116] != data[116]) this->top126_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::ThreeWayValve, PanasonicDecode::getBit7and8(data[116]))); - if (this->top130_text_sensor_ && last[26] != data[26]) this->top130_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::BivalentMode, PanasonicDecode::getBit5and6(data[26]))); -#endif - } - - void PanasonicHeatpumpComponent::publish_number(const std::vector& data, const std::vector& last) - { -#ifdef USE_NUMBER - if (data.empty()) return; - if (this->set11_number_ && last[42] != data[42]) this->set11_number_->publish_state(PanasonicDecode::getByteMinus128(data[42])); - if (this->set20_number_ && last[99] != data[99]) this->set20_number_->publish_state(PanasonicDecode::getByteMinus128(data[99])); - if (this->set18_number_ && last[84] != data[84]) this->set18_number_->publish_state(PanasonicDecode::getByteMinus128(data[84])); - if (this->set19_number_ && last[94] != data[94]) this->set19_number_->publish_state(PanasonicDecode::getByteMinus128(data[94])); - if (this->set5_number_ && last[38] != data[38]) this->set5_number_->publish_state(PanasonicDecode::getByteMinus128(data[38])); - if (this->set6_number_ && last[39] != data[39]) this->set6_number_->publish_state(PanasonicDecode::getByteMinus128(data[39])); - if (this->set16_01_number_ && last[75] != data[75]) this->set16_01_number_->publish_state(PanasonicDecode::getByteMinus128(data[75])); - if (this->set16_02_number_ && last[76] != data[76]) this->set16_02_number_->publish_state(PanasonicDecode::getByteMinus128(data[76])); - if (this->set16_04_number_ && last[78] != data[78]) this->set16_04_number_->publish_state(PanasonicDecode::getByteMinus128(data[78])); - if (this->set16_03_number_ && last[77] != data[77]) this->set16_03_number_->publish_state(PanasonicDecode::getByteMinus128(data[77])); - if (this->set7_number_ && last[40] != data[40]) this->set7_number_->publish_state(PanasonicDecode::getByteMinus128(data[40])); - if (this->set8_number_ && last[41] != data[41]) this->set8_number_->publish_state(PanasonicDecode::getByteMinus128(data[41])); - if (this->set16_09_number_ && last[86] != data[86]) this->set16_09_number_->publish_state(PanasonicDecode::getByteMinus128(data[86])); - if (this->set16_10_number_ && last[87] != data[87]) this->set16_10_number_->publish_state(PanasonicDecode::getByteMinus128(data[87])); - if (this->set16_12_number_ && last[89] != data[89]) this->set16_12_number_->publish_state(PanasonicDecode::getByteMinus128(data[89])); - if (this->set16_11_number_ && last[88] != data[88]) this->set16_11_number_->publish_state(PanasonicDecode::getByteMinus128(data[88])); - if (this->set29_number_ && last[83] != data[83]) this->set29_number_->publish_state(PanasonicDecode::getByteMinus128(data[83])); - if (this->set16_05_number_ && last[79] != data[79]) this->set16_05_number_->publish_state(PanasonicDecode::getByteMinus128(data[79])); - if (this->set16_06_number_ && last[80] != data[80]) this->set16_06_number_->publish_state(PanasonicDecode::getByteMinus128(data[80])); - if (this->set16_08_number_ && last[82] != data[82]) this->set16_08_number_->publish_state(PanasonicDecode::getByteMinus128(data[82])); - if (this->set16_07_number_ && last[81] != data[81]) this->set16_07_number_->publish_state(PanasonicDecode::getByteMinus128(data[81])); - if (this->set16_13_number_ && last[90] != data[90]) this->set16_13_number_->publish_state(PanasonicDecode::getByteMinus128(data[90])); - if (this->set16_14_number_ && last[91] != data[91]) this->set16_14_number_->publish_state(PanasonicDecode::getByteMinus128(data[91])); - if (this->set16_16_number_ && last[93] != data[93]) this->set16_16_number_->publish_state(PanasonicDecode::getByteMinus128(data[93])); - if (this->set16_15_number_ && last[92] != data[92]) this->set16_15_number_->publish_state(PanasonicDecode::getByteMinus128(data[92])); - if (this->set15_number_ && last[45] != data[45]) this->set15_number_->publish_state(PanasonicDecode::getByteMinus1(data[45])); - if (this->set21_number_ && last[104] != data[104]) this->set21_number_->publish_state(PanasonicDecode::getByteMinus1(data[104])); - if (this->set22_number_ && last[105] != data[105]) this->set22_number_->publish_state(PanasonicDecode::getByteMinus128(data[105])); - if (this->set23_number_ && last[106] != data[106]) this->set23_number_->publish_state(PanasonicDecode::getByteMinus128(data[106])); - if (this->set27_number_ && last[59] != data[59]) this->set27_number_->publish_state(PanasonicDecode::getByteMinus128(data[59])); - if (this->set36_number_ && last[65] != data[65]) this->set36_number_->publish_state(PanasonicDecode::getByteMinus128(data[65])); - if (this->set37_number_ && last[66] != data[66]) this->set37_number_->publish_state(PanasonicDecode::getByteMinus128(data[66])); - if (this->set38_number_ && last[68] != data[68]) this->set38_number_->publish_state(PanasonicDecode::getByteMinus128(data[68])); -#endif - } - - void PanasonicHeatpumpComponent::publish_select(const std::vector& data, const std::vector& last) - { -#ifdef USE_SELECT - if (data.empty()) return; - if (this->set9_select_ && last[6] != data[6]) this->set9_select_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::OperationMode, PanasonicDecode::getOperationMode(data[6]))); - if (this->set4_select_ && last[7] != data[7]) this->set4_select_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::PowerfulMode, PanasonicDecode::getBit6and7and8(data[7]))); - if (this->set3_select_ && last[7] != data[7]) this->set3_select_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::QuietMode, PanasonicDecode::getBit3and4and5(data[7]))); - if (this->set2_select_ && last[5] != data[5]) this->set2_select_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::HolidayState, PanasonicDecode::getBit3and4(data[5]))); - if (this->set17_select_ && last[6] != data[6]) this->set17_select_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::ZoneState, PanasonicDecode::getBit1and2(data[6]))); - if (this->set26_select_ && last[25] != data[25]) this->set26_select_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::ExtPadHeaterType, PanasonicDecode::getBit3and4(data[25]))); - if (this->set35_select_ && last[26] != data[26]) this->set35_select_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::BivalentMode, PanasonicDecode::getBit5and6(data[26]))); -#endif - } - - void PanasonicHeatpumpComponent::publish_switch(const std::vector& data, const std::vector& last) - { -#ifdef USE_SWITCH - if (data.empty()) return; - if (this->set1_switch_ && last[4] != data[4]) this->set1_switch_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[4]))); - if (this->set10_switch_ && last[4] != data[4]) this->set10_switch_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[4]))); - if (this->set24_switch_ && last[5] != data[5]) this->set24_switch_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[5]))); - if (this->set12_switch_ && last[111] != data[111]) this->set12_switch_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[111]))); - if (this->set13_switch_ && last[117] != data[117]) this->set13_switch_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[117]))); - if (this->set28_switch_ && last[24] != data[24]) this->set28_switch_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[24]))); - if (this->set25_switch_ && last[20] != data[20]) this->set25_switch_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit3and4(data[20]))); - if (this->set30_switch_ && last[23] != data[23]) this->set30_switch_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[23]))); - if (this->set33_switch_ && last[23] != data[23]) this->set33_switch_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[23]))); - if (this->set31_switch_ && last[23] != data[23]) this->set31_switch_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit3and4(data[23]))); - if (this->set32_switch_ && last[23] != data[23]) this->set32_switch_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[23]))); - if (this->set34_switch_ && last[26] != data[26]) this->set34_switch_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[26]))); -#endif - } - -#ifdef USE_NUMBER - void PanasonicHeatpumpComponent::control_number(number::Number* object, float value) - { - if (object == this->set5_number_) this->set_command_byte(PanasonicCommand::setPlus128(value), 38); - else if (object == this->set6_number_) this->set_command_byte(PanasonicCommand::setPlus128(value), 39); - else if (object == this->set7_number_) this->set_command_byte(PanasonicCommand::setPlus128(value), 40); - else if (object == this->set8_number_) this->set_command_byte(PanasonicCommand::setPlus128(value), 41); - else if (object == this->set11_number_) this->set_command_byte(PanasonicCommand::setPlus128(value), 42); - else if (object == this->set15_number_) this->set_command_byte(PanasonicCommand::setPlus1(value), 45); - else if (object == this->set18_number_) this->set_command_byte(PanasonicCommand::setPlus128(value), 84); - else if (object == this->set19_number_) this->set_command_byte(PanasonicCommand::setPlus128(value), 94); - else if (object == this->set20_number_) this->set_command_byte(PanasonicCommand::setPlus128(value), 99); - else if (object == this->set21_number_) this->set_command_byte(PanasonicCommand::setPlus1(value), 104); - else if (object == this->set22_number_) this->set_command_byte(PanasonicCommand::setPlus128(value), 105); - else if (object == this->set23_number_) this->set_command_byte(PanasonicCommand::setPlus128(value), 106); - else if (object == this->set27_number_) this->set_command_byte(PanasonicCommand::setPlus128(value), 59); - else if (object == this->set29_number_) this->set_command_byte(PanasonicCommand::setPlus128(value), 83); - else if (object == this->set36_number_) this->set_command_byte(PanasonicCommand::setPlus128(value), 65); - else if (object == this->set37_number_) this->set_command_byte(PanasonicCommand::setPlus128(value), 66); - else if (object == this->set38_number_) this->set_command_byte(PanasonicCommand::setPlus128(value), 68); - // Set zone 1 curve - if (object == this->set16_01_number_ || object == this->set16_02_number_ - || object == this->set16_03_number_ || object == this->set16_04_number_ - || object == this->set16_09_number_ || object == this->set16_10_number_ - || object == this->set16_11_number_ || object == this->set16_12_number_) + for (auto *entity : this->selects_) { - std::vector> curve; - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_01_number_->state), 75)); - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_02_number_->state), 76)); - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_03_number_->state), 77)); - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_04_number_->state), 78)); - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_09_number_->state), 86)); - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_10_number_->state), 87)); - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_11_number_->state), 88)); - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_12_number_->state), 89)); - this->set_command_bytes(curve); + entity->publish_new_state(data); } - // Set zone 2 curve - if (object == this->set16_05_number_ || object == this->set16_06_number_ - || object == this->set16_07_number_ || object == this->set16_08_number_ - || object == this->set16_13_number_ || object == this->set16_14_number_ - || object == this->set16_15_number_ || object == this->set16_16_number_) + } + + void PanasonicHeatpumpComponent::set_select_traits(const std::vector& data) + { + if (data.empty()) return; + bool top120 = PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[23])); // Heat Cool Control + + bool change_detected = false; + for (auto *entity : this->selects_) { - std::vector> curve; - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_05_number_->state), 79)); - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_06_number_->state), 80)); - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_07_number_->state), 81)); - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_08_number_->state), 82)); - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_13_number_->state), 90)); - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_14_number_->state), 91)); - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_15_number_->state), 92)); - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_16_number_->state), 93)); - this->set_command_bytes(curve); + change_detected = entity->set_traits(data) ? true : change_detected; + } + if (change_detected) + { + this->set_traits_loop_ = true; } } -#endif -#ifdef USE_SELECT - void PanasonicHeatpumpComponent::control_select(select::Select* object, size_t value) + void PanasonicHeatpumpComponent::publish_sensor(const std::vector& data) { - if (object == this->set2_select_) this->set_command_byte(PanasonicCommand::setPlus1Multiply16(value), 5); - else if (object == this->set3_select_) this->set_command_byte(PanasonicCommand::setPlus1Multiply8(value), 7); - else if (object == this->set4_select_) this->set_command_byte(PanasonicCommand::setPlus1(value), 7); - else if (object == this->set9_select_) this->set_command_byte(PanasonicCommand::setOperationMode(value), 6); - else if (object == this->set17_select_) this->set_command_byte(PanasonicCommand::setPlus1Multiply64(value), 6); - else if (object == this->set26_select_) this->set_command_byte(PanasonicCommand::setPlus1Multiply16(value), 25); - else if (object == this->set35_select_) this->set_command_byte(PanasonicCommand::setPlus1Multiply4(value), 26); + if (data.empty()) return; + for (auto *entity : this->sensors_) + { + entity->publish_new_state(data); + } } -#endif -#ifdef USE_SWITCH - void PanasonicHeatpumpComponent::control_switch(switch_::Switch* object, bool state) + void PanasonicHeatpumpComponent::publish_switch(const std::vector& data) { - size_t value = state ? 1 : 0; - - if (object == this->set1_switch_) this->set_command_byte(PanasonicCommand::setPlus1(value), 4); - else if (object == this->set10_switch_) this->set_command_byte(PanasonicCommand::setPlus1Multiply64(value), 4); - else if (object == this->set12_switch_) this->set_command_byte(PanasonicCommand::setMultiply2(value), 8); - else if (object == this->set13_switch_) this->set_command_byte(PanasonicCommand::setMultiply4(value), 8); - else if (object == this->set14_switch_) this->set_command_byte(PanasonicCommand::setPlus1Multiply16(value), 4); - else if (object == this->set24_switch_) this->set_command_byte(PanasonicCommand::setPlus1Multiply64(value), 5); - else if (object == this->set25_switch_) this->set_command_byte(PanasonicCommand::setPlus1Multiply16(value), 20); - else if (object == this->set28_switch_) this->set_command_byte(PanasonicCommand::setPlus1Multiply4(value), 24); - else if (object == this->set30_switch_) this->set_command_byte(PanasonicCommand::setPlus1(value), 23); - else if (object == this->set31_switch_) this->set_command_byte(PanasonicCommand::setPlus1Multiply16(value), 23); - else if (object == this->set32_switch_) this->set_command_byte(PanasonicCommand::setPlus1Multiply64(value), 23); - else if (object == this->set33_switch_) this->set_command_byte(PanasonicCommand::setPlus1Multiply4(value), 23); - else if (object == this->set34_switch_) this->set_command_byte(PanasonicCommand::setPlus1(value), 26); + if (data.empty()) return; + for (auto *entity : this->switches_) + { + entity->publish_new_state(data); + } + } + + void PanasonicHeatpumpComponent::publish_text_sensor(const std::vector& data) + { + if (data.empty()) return; + for (auto *entity : this->text_sensors_) + { + entity->publish_new_state(data); + } } -#endif } // namespace panasonic_heatpump } // namespace esphome diff --git a/components/panasonic_heatpump/panasonic_heatpump.h b/components/panasonic_heatpump/panasonic_heatpump.h index a6b63dc..c8e445c 100644 --- a/components/panasonic_heatpump/panasonic_heatpump.h +++ b/components/panasonic_heatpump/panasonic_heatpump.h @@ -1,33 +1,14 @@ #pragma once - +#include +#include +#include #include "esphome/core/component.h" #include "esphome/core/defines.h" #include "esphome/core/log.h" #include "esphome/components/uart/uart.h" -#ifdef USE_SENSOR -#include "esphome/components/sensor/sensor.h" -#endif -#ifdef USE_BINARY_SENSOR -#include "esphome/components/binary_sensor/binary_sensor.h" -#endif -#ifdef USE_TEXT_SENSOR -#include "esphome/components/text_sensor/text_sensor.h" -#endif -#ifdef USE_NUMBER -#include "esphome/components/number/number.h" -#endif -#ifdef USE_SELECT -#include "esphome/components/select/select.h" -#endif -#ifdef USE_SWITCH -#include "esphome/components/switch/switch.h" -#endif +#include "helpers.h" #include "decode.h" #include "commands.h" -#include "helpers.h" -#include -#include -#include namespace esphome @@ -39,13 +20,13 @@ namespace esphome READ_RESPONSE, CHECK_RESPONSE, SET_NUMBER_TRAITS, + SET_SELECT_TRAITS, PUBLISH_SENSOR, PUBLISH_BINARY_SENSOR, PUBLISH_TEXT_SENSOR, PUBLISH_NUMBER, PUBLISH_SELECT, PUBLISH_SWITCH, - STORE_RESPONSE, SEND_REQUEST, READ_REQUEST, RESTART_LOOP @@ -59,220 +40,22 @@ namespace esphome NONE }; + class PanasonicHeatpumpEntity + { + public: + virtual void set_id(const int id) { id_ = id; } + virtual void publish_new_state(const std::vector& data) = 0; + virtual bool set_traits(const std::vector& data) { return false; } + + protected: + int id_ { -1 }; + int keep_state_ { 0 }; + }; + class PanasonicHeatpumpComponent : public PollingComponent, public uart::UARTDevice { public: - // ToDo: Add template for custom sensor classes similar to SUB_SENSOR (see Pipsolar) -#ifdef USE_SENSOR - SUB_SENSOR(top1); - SUB_SENSOR(top5); - SUB_SENSOR(top6); - SUB_SENSOR(top7); - SUB_SENSOR(top8); - SUB_SENSOR(top9); - SUB_SENSOR(top10); - SUB_SENSOR(top11); - SUB_SENSOR(top12); - SUB_SENSOR(top14); - SUB_SENSOR(top15); - SUB_SENSOR(top16); - SUB_SENSOR(top21); - SUB_SENSOR(top22); - SUB_SENSOR(top23); - SUB_SENSOR(top24); - SUB_SENSOR(top25); - SUB_SENSOR(top27); - SUB_SENSOR(top28); - SUB_SENSOR(top29); - SUB_SENSOR(top30); - SUB_SENSOR(top31); - SUB_SENSOR(top32); - SUB_SENSOR(top33); - SUB_SENSOR(top34); - SUB_SENSOR(top35); - SUB_SENSOR(top36); - SUB_SENSOR(top37); - SUB_SENSOR(top38); - SUB_SENSOR(top39); - SUB_SENSOR(top40); - SUB_SENSOR(top41); - SUB_SENSOR(top42); - SUB_SENSOR(top43); - SUB_SENSOR(top45); - SUB_SENSOR(top46); - SUB_SENSOR(top47); - SUB_SENSOR(top48); - SUB_SENSOR(top49); - SUB_SENSOR(top50); - SUB_SENSOR(top51); - SUB_SENSOR(top52); - SUB_SENSOR(top53); - SUB_SENSOR(top54); - SUB_SENSOR(top55); - SUB_SENSOR(top56); - SUB_SENSOR(top57); - SUB_SENSOR(top62); - SUB_SENSOR(top63); - SUB_SENSOR(top64); - SUB_SENSOR(top65); - SUB_SENSOR(top66); - SUB_SENSOR(top67); - SUB_SENSOR(top70); - SUB_SENSOR(top71); - SUB_SENSOR(top72); - SUB_SENSOR(top73); - SUB_SENSOR(top74); - SUB_SENSOR(top75); - SUB_SENSOR(top77); - SUB_SENSOR(top78); - SUB_SENSOR(top79); - SUB_SENSOR(top80); - SUB_SENSOR(top82); - SUB_SENSOR(top83); - SUB_SENSOR(top84); - SUB_SENSOR(top85); - SUB_SENSOR(top86); - SUB_SENSOR(top87); - SUB_SENSOR(top88); - SUB_SENSOR(top89); - SUB_SENSOR(top90); - SUB_SENSOR(top91); - SUB_SENSOR(top93); - SUB_SENSOR(top95); - SUB_SENSOR(top96); - SUB_SENSOR(top97); - SUB_SENSOR(top98); - SUB_SENSOR(top102); - SUB_SENSOR(top103); - SUB_SENSOR(top104); - SUB_SENSOR(top105); - SUB_SENSOR(top113); - SUB_SENSOR(top115); - SUB_SENSOR(top116); - SUB_SENSOR(top117); - SUB_SENSOR(top118); - SUB_SENSOR(top127); - SUB_SENSOR(top128); - SUB_SENSOR(top131); - SUB_SENSOR(top134); - SUB_SENSOR(top135); - SUB_SENSOR(top136); - SUB_SENSOR(top137); - SUB_SENSOR(top138); -#endif -#ifdef USE_BINARY_SENSOR - SUB_BINARY_SENSOR(top0); - SUB_BINARY_SENSOR(top2); - SUB_BINARY_SENSOR(top3); - SUB_BINARY_SENSOR(top13); - SUB_BINARY_SENSOR(top26); - SUB_BINARY_SENSOR(top60); - SUB_BINARY_SENSOR(top61); - SUB_BINARY_SENSOR(top68); - SUB_BINARY_SENSOR(top69); - SUB_BINARY_SENSOR(top99); - SUB_BINARY_SENSOR(top100); - SUB_BINARY_SENSOR(top108); - SUB_BINARY_SENSOR(top109); - SUB_BINARY_SENSOR(top110); - SUB_BINARY_SENSOR(top119); - SUB_BINARY_SENSOR(top120); - SUB_BINARY_SENSOR(top121); - SUB_BINARY_SENSOR(top122); - SUB_BINARY_SENSOR(top123); - SUB_BINARY_SENSOR(top124); - SUB_BINARY_SENSOR(top129); - SUB_BINARY_SENSOR(top132); - SUB_BINARY_SENSOR(top133); -#endif -#ifdef USE_TEXT_SENSOR - SUB_TEXT_SENSOR(top4); - SUB_TEXT_SENSOR(top17); - SUB_TEXT_SENSOR(top18); - SUB_TEXT_SENSOR(top19); - SUB_TEXT_SENSOR(top20); - SUB_TEXT_SENSOR(top44); - SUB_TEXT_SENSOR(top58); - SUB_TEXT_SENSOR(top59); - SUB_TEXT_SENSOR(top76); - SUB_TEXT_SENSOR(top81); - SUB_TEXT_SENSOR(top92); - SUB_TEXT_SENSOR(top94); - SUB_TEXT_SENSOR(top101); - SUB_TEXT_SENSOR(top106); - SUB_TEXT_SENSOR(top107); - SUB_TEXT_SENSOR(top111); - SUB_TEXT_SENSOR(top112); - SUB_TEXT_SENSOR(top114); - SUB_TEXT_SENSOR(top125); - SUB_TEXT_SENSOR(top126); - SUB_TEXT_SENSOR(top130); -#endif -#ifdef USE_NUMBER - SUB_NUMBER(set5); - SUB_NUMBER(set6); - SUB_NUMBER(set7); - SUB_NUMBER(set8); - SUB_NUMBER(set11); - SUB_NUMBER(set15); - SUB_NUMBER(set16_01); - SUB_NUMBER(set16_02); - SUB_NUMBER(set16_03); - SUB_NUMBER(set16_04); - SUB_NUMBER(set16_05); - SUB_NUMBER(set16_06); - SUB_NUMBER(set16_07); - SUB_NUMBER(set16_08); - SUB_NUMBER(set16_09); - SUB_NUMBER(set16_10); - SUB_NUMBER(set16_11); - SUB_NUMBER(set16_12); - SUB_NUMBER(set16_13); - SUB_NUMBER(set16_14); - SUB_NUMBER(set16_15); - SUB_NUMBER(set16_16); - SUB_NUMBER(set18); - SUB_NUMBER(set19); - SUB_NUMBER(set20); - SUB_NUMBER(set21); - SUB_NUMBER(set22); - SUB_NUMBER(set23); - SUB_NUMBER(set27); - SUB_NUMBER(set29); - SUB_NUMBER(set36); - SUB_NUMBER(set37); - SUB_NUMBER(set38); - - void control_number(number::Number* object, float value); -#endif -#ifdef USE_SELECT - SUB_SELECT(set2); - SUB_SELECT(set3); - SUB_SELECT(set4); - SUB_SELECT(set9); - SUB_SELECT(set17); - SUB_SELECT(set26); - SUB_SELECT(set35); - - void control_select(select::Select* object, size_t value); -#endif -#ifdef USE_SWITCH - SUB_SWITCH(set1); - SUB_SWITCH(set10); - SUB_SWITCH(set12); - SUB_SWITCH(set13); - SUB_SWITCH(set14); - SUB_SWITCH(set24); - SUB_SWITCH(set25); - SUB_SWITCH(set28); - SUB_SWITCH(set30); - SUB_SWITCH(set31); - SUB_SWITCH(set32); - SUB_SWITCH(set33); - SUB_SWITCH(set34); - - void control_switch(switch_::Switch* object, bool state); -#endif + bool set_traits_loop_ { false }; PanasonicHeatpumpComponent() = default; // base class functions @@ -286,6 +69,18 @@ namespace esphome void set_log_uart_msg(bool enable) { this->log_uart_msg_ = enable; } // uart message variables to use in lambda functions int getResponseByte(const int index); + // command functions + void set_command_high_nibble(const uint8_t value, const uint8_t index); + void set_command_low_nibble(const uint8_t value, const uint8_t index); + void set_command_byte(const uint8_t value, const uint8_t index); + void set_command_curve(const uint8_t value, const uint8_t index); + // entity functions + void add_binary_sensor(PanasonicHeatpumpEntity *binary_sensor) { binary_sensors_.push_back(binary_sensor); } + void add_number(PanasonicHeatpumpEntity *number) { numbers_.push_back(number); } + void add_select(PanasonicHeatpumpEntity *select) { selects_.push_back(select); } + void add_sensor(PanasonicHeatpumpEntity *sensor) { sensors_.push_back(sensor); } + void add_switch(PanasonicHeatpumpEntity *switch_) { switches_.push_back(switch_); } + void add_text_sensor(PanasonicHeatpumpEntity *text_sensor) { text_sensors_.push_back(text_sensor); } protected: // options variables @@ -293,7 +88,6 @@ namespace esphome bool log_uart_msg_ { false }; // uart message variables std::vector heatpump_message_; - std::vector last_message_; std::vector response_message_; std::vector request_message_; std::vector command_message_; @@ -305,25 +99,29 @@ namespace esphome bool request_receiving_ { false }; RequestType next_request_ { RequestType::INITIAL }; LoopState loop_state_ { LoopState::RESTART_LOOP }; - uint16_t trait_update_counter_ { 0 }; + uint8_t set_traits_total_ { 0 }; + // entity vectors + std::vector binary_sensors_; + std::vector numbers_; + std::vector selects_; + std::vector sensors_; + std::vector switches_; + std::vector text_sensors_; // uart message functions void read_response(); void send_request(RequestType requestType); void read_request(); bool check_response(const std::vector& data); - void set_command_high_nibble(const uint8_t value, const uint8_t index); - void set_command_low_nibble(const uint8_t value, const uint8_t index); - void set_command_byte(const uint8_t value, const uint8_t index); - void set_command_bytes(const std::vector>& data); - // sensor and control publish functions + // entity functions + void publish_binary_sensor(const std::vector& data); + void publish_number(const std::vector& data); + void publish_select(const std::vector& data); + void publish_sensor(const std::vector& data); + void publish_switch(const std::vector& data); + void publish_text_sensor(const std::vector& data); void set_number_traits(const std::vector& data); - void publish_sensor(const std::vector& data, const std::vector& last); - void publish_binary_sensor(const std::vector& data, const std::vector& last); - void publish_text_sensor(const std::vector& data, const std::vector& last); - void publish_number(const std::vector& data, const std::vector& last); - void publish_select(const std::vector& data, const std::vector& last); - void publish_switch(const std::vector& data, const std::vector& last); + void set_select_traits(const std::vector& data); }; } // namespace panasonic_heatpump } // namespace esphome diff --git a/components/panasonic_heatpump/select/__init__.py b/components/panasonic_heatpump/select/__init__.py index 3986c48..8e0ff6c 100644 --- a/components/panasonic_heatpump/select/__init__.py +++ b/components/panasonic_heatpump/select/__init__.py @@ -30,7 +30,7 @@ CONF_SELECTS = [ [ "Off", "Scheduled", "Active", ], [ "Off", "Level 1", "Level 2", "Level 3", ], [ "Off", "30min", "60min", "90min", ], - [ "HEAT", "COOL", "AUTO", "AUTO(HEAT)", "AUTO(COOL)", "TANK", "HEAT+TANK", "COOL+TANK", "AUTO+TANK", "AUTO(HEAT)+TANK", "AUTO(COOL)+TANK", ], + [ ], [ "Zone 1", "Zone 2", "Zone 1 & 2", ], [ "Disabled", "Type-A", "Type-B" ], [ "Alternative", "Parallel", "Advanced Parallel" ], @@ -67,11 +67,11 @@ CONFIG_SCHEMA = cv.Schema( ).extend(cv.COMPONENT_SCHEMA) async def to_code(config): - hub = await cg.get_variable(config[CONF_PANASONIC_HEATPUMP_ID]) + parent = await cg.get_variable(config[CONF_PANASONIC_HEATPUMP_ID]) for index, key in enumerate(TYPES): if child_config := config.get(key): var = await select.new_select(child_config, options=CONF_SELECTS[index]) await cg.register_component(var, child_config) - await cg.register_parented(var, config[CONF_PANASONIC_HEATPUMP_ID]) - cg.add(getattr(hub, f"set_{key}_select")(var)) + cg.add(var.set_parent(parent)) cg.add(var.set_id(index)) + cg.add(parent.add_select(var)) diff --git a/components/panasonic_heatpump/select/panasonic_heatpump_select.cpp b/components/panasonic_heatpump/select/panasonic_heatpump_select.cpp index 062abf2..aacf1ee 100644 --- a/components/panasonic_heatpump/select/panasonic_heatpump_select.cpp +++ b/components/panasonic_heatpump/select/panasonic_heatpump_select.cpp @@ -1,5 +1,4 @@ #include "panasonic_heatpump_select.h" -#include "esphome/core/log.h" namespace esphome @@ -16,10 +15,135 @@ namespace esphome void PanasonicHeatpumpSelect::control(const std::string &value) { + auto optIndex = this->index_of(value); + if (!optIndex.has_value()) return; + size_t index = optIndex.value(); + + switch (this->id_) + { + case SelectIds::CONF_SET2: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus1Multiply16(index), 5); + break; + } + case SelectIds::CONF_SET3: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus1Multiply8(index), 7); + break; + } + case SelectIds::CONF_SET4: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus1(index), 7); + break; + } + case SelectIds::CONF_SET9: + { + this->parent_->set_command_byte(PanasonicCommand::setOperationMode(index), 6); + break; + } + case SelectIds::CONF_SET17: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus1Multiply64(index), 6); + break; + } + case SelectIds::CONF_SET26: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus1Multiply16(index), 25); + break; + } + case SelectIds::CONF_SET35: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus1Multiply4(index), 26); + break; + } + default: return; + }; this->publish_state(value); - auto index = this->active_index(); - if (index.has_value()) - this->parent_->control_select(this, index.value()); + this->keep_state_ = 2; + } + + void PanasonicHeatpumpSelect::publish_new_state(const std::vector& data) + { + if (this->keep_state_ > 0) + { + this->keep_state_--; + return; + } + + std::string new_state; + switch (this->id_) + { + case SelectIds::CONF_SET9: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::OperationMode, PanasonicDecode::getOperationMode(data[6])); + if (this->state == new_state) return; + break; + } + case SelectIds::CONF_SET4: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::PowerfulMode, PanasonicDecode::getBit6and7and8(data[7])); + if (this->state == new_state) return; + break; + } + case SelectIds::CONF_SET3: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::QuietMode, PanasonicDecode::getBit3and4and5(data[7])); + if (this->state == new_state) return; + break; + } + case SelectIds::CONF_SET2: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::HolidayState, PanasonicDecode::getBit3and4(data[5])); + if (this->state == new_state) return; + break; + } + case SelectIds::CONF_SET17: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::ZoneState, PanasonicDecode::getBit1and2(data[6])); + if (this->state == new_state) return; + break; + } + case SelectIds::CONF_SET26: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::ExtPadHeaterType, PanasonicDecode::getBit3and4(data[25])); + if (this->state == new_state) return; + break; + } + case SelectIds::CONF_SET35: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::BivalentMode, PanasonicDecode::getBit5and6(data[26])); + if (this->state == new_state) return; + break; + } + default: return; + }; + Select::publish_state(new_state); + } + + bool PanasonicHeatpumpSelect::set_traits(const std::vector& data) + { + bool top120 = PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[23])); // Heat Cool Control + + switch (this->id_) + { + case SelectIds::CONF_SET9: + { + if (this->traits.get_options().size() != 3 && !top120) + { + auto options = std::vector(PanasonicDecode::OperationMode + 1, PanasonicDecode::OperationMode + 4); + this->traits.set_options(options); + return true; + } + if (this->traits.get_options().size() != 10 && top120) + { + auto options = std::vector(PanasonicDecode::OperationMode + 1, std::end(PanasonicDecode::OperationMode)); + this->traits.set_options(options); + return true; + } + break; + } + }; + return false; } } // namespace panasonic_heatpump } // namespace esphome diff --git a/components/panasonic_heatpump/select/panasonic_heatpump_select.h b/components/panasonic_heatpump/select/panasonic_heatpump_select.h index 8f7ebe5..24f301b 100644 --- a/components/panasonic_heatpump/select/panasonic_heatpump_select.h +++ b/components/panasonic_heatpump/select/panasonic_heatpump_select.h @@ -1,23 +1,36 @@ #pragma once -#include "esphome/components/select/select.h" #include "esphome/core/component.h" +#include "esphome/components/select/select.h" #include "../panasonic_heatpump.h" +#include "../decode.h" +#include "../commands.h" namespace esphome { namespace panasonic_heatpump { - class PanasonicHeatpumpSelect : public select::Select, public Component, public Parented + enum SelectIds : int + { + CONF_SET2, + CONF_SET3, + CONF_SET4, + CONF_SET9, + CONF_SET17, + CONF_SET26, + CONF_SET35, + }; + + class PanasonicHeatpumpSelect : public select::Select, public Component, public Parented, public PanasonicHeatpumpEntity { public: PanasonicHeatpumpSelect() = default; void dump_config() override; - void set_id(int id) { this->id_ = id; } + void publish_new_state(const std::vector& data) override; + bool set_traits(const std::vector& data) override; protected: void control(const std::string &value) override; - int id_; }; } // namespace panasonic_heatpump } // namespace esphome diff --git a/components/panasonic_heatpump/sensor/__init__.py b/components/panasonic_heatpump/sensor/__init__.py index 0e16ea7..1305b18 100644 --- a/components/panasonic_heatpump/sensor/__init__.py +++ b/components/panasonic_heatpump/sensor/__init__.py @@ -896,10 +896,11 @@ CONFIG_SCHEMA = cv.Schema( ).extend(cv.COMPONENT_SCHEMA) async def to_code(config): - hub = await cg.get_variable(config[CONF_PANASONIC_HEATPUMP_ID]) - for key in TYPES: + parent = await cg.get_variable(config[CONF_PANASONIC_HEATPUMP_ID]) + for index, key in enumerate(TYPES): if child_config := config.get(key): var = await sensor.new_sensor(child_config) await cg.register_component(var, child_config) - await cg.register_parented(var, config[CONF_PANASONIC_HEATPUMP_ID]) - cg.add(getattr(hub, f"set_{key}_sensor")(var)) + cg.add(var.set_parent(parent)) + cg.add(var.set_id(index)) + cg.add(parent.add_sensor(var)) diff --git a/components/panasonic_heatpump/sensor/panasonic_heatpump_sensor.cpp b/components/panasonic_heatpump/sensor/panasonic_heatpump_sensor.cpp index 58c558c..c57113a 100644 --- a/components/panasonic_heatpump/sensor/panasonic_heatpump_sensor.cpp +++ b/components/panasonic_heatpump/sensor/panasonic_heatpump_sensor.cpp @@ -1,5 +1,4 @@ #include "panasonic_heatpump_sensor.h" -#include "esphome/core/log.h" namespace esphome @@ -13,5 +12,585 @@ namespace esphome LOG_SENSOR("", "Panasonic Heatpump Sensor", this); delay(10); } + + void PanasonicHeatpumpSensor::publish_new_state(const std::vector& data) + { + float new_state; + switch (this->id_) + { + case SensorIds::CONF_TOP1: + { + new_state = PanasonicDecode::getPumpFlow(data, 169); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP5: + { + new_state = PanasonicDecode::getByteMinus128(data[143]) + PanasonicDecode::getFractional(data[118], 0); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP6: + { + new_state = PanasonicDecode::getByteMinus128(data[144]) + PanasonicDecode::getFractional(data[118], 3); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP7: + { + new_state = PanasonicDecode::getByteMinus128(data[153]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP8: + { + new_state = PanasonicDecode::getByteMinus1(data[166]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP9: + { + new_state = PanasonicDecode::getByteMinus128(data[42]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP10: + { + new_state = PanasonicDecode::getByteMinus128(data[141]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP11: + { + new_state = PanasonicDecode::getWordMinus1(data, 182); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP12: + { + new_state = PanasonicDecode::getWordMinus1(data, 179); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP14: + { + new_state = PanasonicDecode::getByteMinus128(data[142]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP15: + { + new_state = PanasonicDecode::getByteMinus1Times200(data[194]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP16: + { + new_state = PanasonicDecode::getByteMinus1Times200(data[193]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP21: + { + new_state = PanasonicDecode::getByteMinus128(data[158]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP22: + { + new_state = PanasonicDecode::getByteMinus128(data[99]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP23: + { + new_state = PanasonicDecode::getByteMinus128(data[84]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP24: + { + new_state = PanasonicDecode::getByteMinus128(data[94]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP25: + { + new_state = PanasonicDecode::getByteMinus128(data[44]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP27: + { + new_state = PanasonicDecode::getByteMinus128(data[38]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP28: + { + new_state = PanasonicDecode::getByteMinus128(data[39]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP29: + { + new_state = PanasonicDecode::getByteMinus128(data[75]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP30: + { + new_state = PanasonicDecode::getByteMinus128(data[76]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP31: + { + new_state = PanasonicDecode::getByteMinus128(data[78]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP32: + { + new_state = PanasonicDecode::getByteMinus128(data[77]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP33: + { + new_state = PanasonicDecode::getByteMinus128(data[156]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP34: + { + new_state = PanasonicDecode::getByteMinus128(data[40]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP35: + { + new_state = PanasonicDecode::getByteMinus128(data[41]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP36: + { + new_state = PanasonicDecode::getByteMinus128(data[145]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP37: + { + new_state = PanasonicDecode::getByteMinus128(data[146]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP38: + { + new_state = PanasonicDecode::getByteMinus1Times200(data[196]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP39: + { + new_state = PanasonicDecode::getByteMinus1Times200(data[195]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP40: + { + new_state = PanasonicDecode::getByteMinus1Times200(data[198]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP41: + { + new_state = PanasonicDecode::getByteMinus1Times200(data[197]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP42: + { + new_state = PanasonicDecode::getByteMinus128(data[147]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP43: + { + new_state = PanasonicDecode::getByteMinus128(data[148]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP45: + { + new_state = PanasonicDecode::getByteMinus128(data[43]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP46: + { + new_state = PanasonicDecode::getByteMinus128(data[149]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP47: + { + new_state = PanasonicDecode::getByteMinus128(data[150]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP48: + { + new_state = PanasonicDecode::getByteMinus128(data[151]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP49: + { + new_state = PanasonicDecode::getByteMinus128(data[154]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP50: + { + new_state = PanasonicDecode::getByteMinus128(data[155]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP51: + { + new_state = PanasonicDecode::getByteMinus128(data[157]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP52: + { + new_state = PanasonicDecode::getByteMinus128(data[159]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP53: + { + new_state = PanasonicDecode::getByteMinus128(data[160]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP54: + { + new_state = PanasonicDecode::getByteMinus128(data[161]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP55: + { + new_state = PanasonicDecode::getByteMinus128(data[162]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP56: + { + new_state = PanasonicDecode::getByteMinus128(data[139]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP57: + { + new_state = PanasonicDecode::getByteMinus128(data[140]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP62: + { + new_state = PanasonicDecode::getByteMinus1Times10(data[173]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP63: + { + new_state = PanasonicDecode::getByteMinus1Times10(data[174]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP64: + { + new_state = PanasonicDecode::getByteMinus1Div5(data[163]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP65: + { + new_state = PanasonicDecode::getByteMinus1Times50(data[171]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP66: + { + new_state = PanasonicDecode::getByteMinus1Times50(data[164]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP67: + { + new_state = PanasonicDecode::getByteMinus1Div5(data[165]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP70: + { + new_state = PanasonicDecode::getByteMinus128(data[100]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP71: + { + new_state = PanasonicDecode::getByteMinus1(data[101]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP72: + { + new_state = PanasonicDecode::getByteMinus128(data[86]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP73: + { + new_state = PanasonicDecode::getByteMinus128(data[87]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP74: + { + new_state = PanasonicDecode::getByteMinus128(data[89]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP75: + { + new_state = PanasonicDecode::getByteMinus128(data[88]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP77: + { + new_state = PanasonicDecode::getByteMinus128(data[83]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP78: + { + new_state = PanasonicDecode::getByteMinus128(data[85]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP79: + { + new_state = PanasonicDecode::getByteMinus128(data[95]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP80: + { + new_state = PanasonicDecode::getByteMinus128(data[96]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP82: + { + new_state = PanasonicDecode::getByteMinus128(data[79]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP83: + { + new_state = PanasonicDecode::getByteMinus128(data[80]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP84: + { + new_state = PanasonicDecode::getByteMinus128(data[82]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP85: + { + new_state = PanasonicDecode::getByteMinus128(data[81]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP86: + { + new_state = PanasonicDecode::getByteMinus128(data[90]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP87: + { + new_state = PanasonicDecode::getByteMinus128(data[91]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP88: + { + new_state = PanasonicDecode::getByteMinus128(data[93]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP89: + { + new_state = PanasonicDecode::getByteMinus128(data[92]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP90: + { + new_state = PanasonicDecode::getWordMinus1(data, 185); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP91: + { + new_state = PanasonicDecode::getWordMinus1(data, 188); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP93: + { + new_state = PanasonicDecode::getByteMinus1(data[172]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP95: + { + new_state = PanasonicDecode::getByteMinus1(data[45]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP96: + { + new_state = PanasonicDecode::getByteMinus1(data[104]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP97: + { + new_state = PanasonicDecode::getByteMinus128(data[105]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP98: + { + new_state = PanasonicDecode::getByteMinus128(data[106]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP102: + { + new_state = PanasonicDecode::getByteMinus128(data[61]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP103: + { + new_state = PanasonicDecode::getByteMinus128(data[62]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP104: + { + new_state = PanasonicDecode::getByteMinus128(data[63]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP105: + { + new_state = PanasonicDecode::getByteMinus128(data[64]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP113: + { + new_state = PanasonicDecode::getByteMinus128(data[59]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP115: + { + new_state = PanasonicDecode::getByteMinus1Div50(data[125]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP116: + { + new_state = PanasonicDecode::getByteMinus128(data[126]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP117: + { + new_state = PanasonicDecode::getByteMinus128(data[127]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP118: + { + new_state = PanasonicDecode::getByteMinus128(data[128]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP127: + { + new_state = PanasonicDecode::getByteMinus1Div2(data[177]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP128: + { + new_state = PanasonicDecode::getByteMinus1Div2(data[178]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP131: + { + new_state = PanasonicDecode::getByteMinus128(data[65]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP134: + { + new_state = PanasonicDecode::getByteMinus128(data[66]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP135: + { + new_state = PanasonicDecode::getByteMinus128(data[68]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP136: + { + new_state = PanasonicDecode::getByteMinus1(data[67]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP137: + { + new_state = PanasonicDecode::getByteMinus1(data[69]); + if (this->get_state() == new_state) return; + break; + } + case SensorIds::CONF_TOP138: + { + new_state = PanasonicDecode::getByteMinus1(data[70]); + if (this->get_state() == new_state) return; + break; + } + default: return; + }; + this->publish_state(new_state); + } } // namespace panasonic_heatpump } // namespace esphome diff --git a/components/panasonic_heatpump/sensor/panasonic_heatpump_sensor.h b/components/panasonic_heatpump/sensor/panasonic_heatpump_sensor.h index 82072b9..fbc364d 100644 --- a/components/panasonic_heatpump/sensor/panasonic_heatpump_sensor.h +++ b/components/panasonic_heatpump/sensor/panasonic_heatpump_sensor.h @@ -1,18 +1,119 @@ #pragma once -#include "esphome/components/sensor/sensor.h" #include "esphome/core/component.h" +#include "esphome/components/sensor/sensor.h" #include "../panasonic_heatpump.h" +#include "../decode.h" namespace esphome { namespace panasonic_heatpump { - class PanasonicHeatpumpSensor : public sensor::Sensor, public Component, public Parented + enum SensorIds : int + { + CONF_TOP1, + CONF_TOP5, + CONF_TOP6, + CONF_TOP7, + CONF_TOP8, + CONF_TOP9, + CONF_TOP10, + CONF_TOP11, + CONF_TOP12, + CONF_TOP14, + CONF_TOP15, + CONF_TOP16, + CONF_TOP21, + CONF_TOP22, + CONF_TOP23, + CONF_TOP24, + CONF_TOP25, + CONF_TOP27, + CONF_TOP28, + CONF_TOP29, + CONF_TOP30, + CONF_TOP31, + CONF_TOP32, + CONF_TOP33, + CONF_TOP34, + CONF_TOP35, + CONF_TOP36, + CONF_TOP37, + CONF_TOP38, + CONF_TOP39, + CONF_TOP40, + CONF_TOP41, + CONF_TOP42, + CONF_TOP43, + CONF_TOP45, + CONF_TOP46, + CONF_TOP47, + CONF_TOP48, + CONF_TOP49, + CONF_TOP50, + CONF_TOP51, + CONF_TOP52, + CONF_TOP53, + CONF_TOP54, + CONF_TOP55, + CONF_TOP56, + CONF_TOP57, + CONF_TOP62, + CONF_TOP63, + CONF_TOP64, + CONF_TOP65, + CONF_TOP66, + CONF_TOP67, + CONF_TOP70, + CONF_TOP71, + CONF_TOP72, + CONF_TOP73, + CONF_TOP74, + CONF_TOP75, + CONF_TOP77, + CONF_TOP78, + CONF_TOP79, + CONF_TOP80, + CONF_TOP82, + CONF_TOP83, + CONF_TOP84, + CONF_TOP85, + CONF_TOP86, + CONF_TOP87, + CONF_TOP88, + CONF_TOP89, + CONF_TOP90, + CONF_TOP91, + CONF_TOP93, + CONF_TOP95, + CONF_TOP96, + CONF_TOP97, + CONF_TOP98, + CONF_TOP102, + CONF_TOP103, + CONF_TOP104, + CONF_TOP105, + CONF_TOP113, + CONF_TOP115, + CONF_TOP116, + CONF_TOP117, + CONF_TOP118, + CONF_TOP127, + CONF_TOP128, + CONF_TOP131, + CONF_TOP134, + CONF_TOP135, + CONF_TOP136, + CONF_TOP137, + CONF_TOP138, + }; + + class PanasonicHeatpumpSensor : public sensor::Sensor, public Component, public Parented, public PanasonicHeatpumpEntity { public: PanasonicHeatpumpSensor() = default; void dump_config() override; + void publish_new_state(const std::vector& data) override; }; } // namespace panasonic_heatpump } // namespace esphome diff --git a/components/panasonic_heatpump/switch/__init__.py b/components/panasonic_heatpump/switch/__init__.py index b718eab..bf88059 100644 --- a/components/panasonic_heatpump/switch/__init__.py +++ b/components/panasonic_heatpump/switch/__init__.py @@ -85,11 +85,11 @@ CONFIG_SCHEMA = cv.Schema( ).extend(cv.COMPONENT_SCHEMA) async def to_code(config): - hub = await cg.get_variable(config[CONF_PANASONIC_HEATPUMP_ID]) + parent = await cg.get_variable(config[CONF_PANASONIC_HEATPUMP_ID]) for index, key in enumerate(TYPES): if child_config := config.get(key): var = await switch.new_switch(child_config) await cg.register_component(var, child_config) - await cg.register_parented(var, config[CONF_PANASONIC_HEATPUMP_ID]) - cg.add(getattr(hub, f"set_{key}_switch")(var)) + cg.add(var.set_parent(parent)) cg.add(var.set_id(index)) + cg.add(parent.add_switch(var)) diff --git a/components/panasonic_heatpump/switch/panasonic_heatpump_switch.cpp b/components/panasonic_heatpump/switch/panasonic_heatpump_switch.cpp index 2716d43..651c0be 100644 --- a/components/panasonic_heatpump/switch/panasonic_heatpump_switch.cpp +++ b/components/panasonic_heatpump/switch/panasonic_heatpump_switch.cpp @@ -1,5 +1,4 @@ #include "panasonic_heatpump_switch.h" -#include "esphome/core/log.h" namespace esphome @@ -16,8 +15,166 @@ namespace esphome void PanasonicHeatpumpSwitch::write_state(bool state) { + size_t value = state ? 1 : 0; + switch (this->id_) + { + case SwitchIds::CONF_SET1: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus1(value), 4); + break; + } + case SwitchIds::CONF_SET10: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus1Multiply64(value), 4); + break; + } + case SwitchIds::CONF_SET12: + { + this->parent_->set_command_byte(PanasonicCommand::setMultiply2(value), 8); + break; + } + case SwitchIds::CONF_SET13: + { + this->parent_->set_command_byte(PanasonicCommand::setMultiply4(value), 8); + break; + } + case SwitchIds::CONF_SET14: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus1Multiply16(value), 4); + break; + } + case SwitchIds::CONF_SET24: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus1Multiply64(value), 5); + break; + } + case SwitchIds::CONF_SET25: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus1Multiply16(value), 20); + break; + } + case SwitchIds::CONF_SET28: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus1Multiply4(value), 24); + break; + } + case SwitchIds::CONF_SET30: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus1(value), 23); + break; + } + case SwitchIds::CONF_SET31: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus1Multiply16(value), 23); + break; + } + case SwitchIds::CONF_SET32: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus1Multiply64(value), 23); + break; + } + case SwitchIds::CONF_SET33: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus1Multiply4(value), 23); + break; + } + case SwitchIds::CONF_SET34: + { + this->parent_->set_command_byte(PanasonicCommand::setPlus1(value), 26); + break; + } + default: return; + }; this->publish_state(state); - this->parent_->control_switch(this, state); + this->keep_state_ = 2; + } + + void PanasonicHeatpumpSwitch::publish_new_state(const std::vector& data) + { + if (this->keep_state_ > 0) + { + this->keep_state_--; + return; + } + + bool new_state; + switch (this->id_) + { + case SwitchIds::CONF_SET1: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[4])); + if (this->state == new_state) return; + break; + } + case SwitchIds::CONF_SET10: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[4])); + 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) return; + break; + } + case SwitchIds::CONF_SET13: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[117])); + if (this->state == new_state) return; + break; + } + case SwitchIds::CONF_SET28: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[24])); + if (this->state == new_state) return; + break; + } + case SwitchIds::CONF_SET25: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit3and4(data[20])); + if (this->state == new_state) return; + break; + } + case SwitchIds::CONF_SET30: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[23])); + 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_SET31: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit3and4(data[23])); + if (this->state == new_state) return; + break; + } + case SwitchIds::CONF_SET32: + { + new_state = PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(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) return; + break; + } + default: return; + }; + this->publish_state(new_state); } } // namespace panasonic_heatpump } // namespace esphome diff --git a/components/panasonic_heatpump/switch/panasonic_heatpump_switch.h b/components/panasonic_heatpump/switch/panasonic_heatpump_switch.h index de9f4f7..7a0b709 100644 --- a/components/panasonic_heatpump/switch/panasonic_heatpump_switch.h +++ b/components/panasonic_heatpump/switch/panasonic_heatpump_switch.h @@ -1,23 +1,41 @@ #pragma once -#include "esphome/components/switch/switch.h" #include "esphome/core/component.h" +#include "esphome/components/switch/switch.h" #include "../panasonic_heatpump.h" +#include "../decode.h" +#include "../commands.h" namespace esphome { namespace panasonic_heatpump { - class PanasonicHeatpumpSwitch : public switch_::Switch, public Component, public Parented + enum SwitchIds : int + { + CONF_SET1, + CONF_SET10, + CONF_SET12, + CONF_SET13, + CONF_SET14, + CONF_SET24, + CONF_SET25, + CONF_SET28, + CONF_SET30, + CONF_SET31, + CONF_SET32, + CONF_SET33, + CONF_SET34, + }; + + class PanasonicHeatpumpSwitch : public switch_::Switch, public Component, public Parented, public PanasonicHeatpumpEntity { public: PanasonicHeatpumpSwitch() = default; void dump_config() override; - void set_id(int id) { this->id_ = id; } + void publish_new_state(const std::vector& data) override; protected: void write_state(bool state) override; - int id_; }; } // namespace panasonic_heatpump } // namespace esphome diff --git a/components/panasonic_heatpump/text_sensor/__init__.py b/components/panasonic_heatpump/text_sensor/__init__.py index 9596d9b..d635528 100644 --- a/components/panasonic_heatpump/text_sensor/__init__.py +++ b/components/panasonic_heatpump/text_sensor/__init__.py @@ -161,10 +161,11 @@ CONFIG_SCHEMA = cv.Schema( ).extend(cv.COMPONENT_SCHEMA) async def to_code(config): - hub = await cg.get_variable(config[CONF_PANASONIC_HEATPUMP_ID]) - for key in TYPES: + parent = await cg.get_variable(config[CONF_PANASONIC_HEATPUMP_ID]) + for index, key in enumerate(TYPES): if child_config := config.get(key): var = await text_sensor.new_text_sensor(child_config) await cg.register_component(var, child_config) - await cg.register_parented(var, config[CONF_PANASONIC_HEATPUMP_ID]) - cg.add(getattr(hub, f"set_{key}_text_sensor")(var)) + cg.add(var.set_parent(parent)) + cg.add(var.set_id(index)) + cg.add(parent.add_text_sensor(var)) 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 016838b..a8c8333 100644 --- a/components/panasonic_heatpump/text_sensor/panasonic_heatpump_text_sensor.cpp +++ b/components/panasonic_heatpump/text_sensor/panasonic_heatpump_text_sensor.cpp @@ -1,5 +1,4 @@ #include "panasonic_heatpump_text_sensor.h" -#include "esphome/core/log.h" namespace esphome @@ -13,5 +12,141 @@ namespace esphome LOG_TEXT_SENSOR("", "Panasonic Heatpump Text Sensor", this); delay(10); } + + void PanasonicHeatpumpTextSensor::publish_new_state(const std::vector& data) + { + std::string new_state; + switch (this->id_) + { + case TextSensorIds::CONF_TOP4: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::OperationMode, PanasonicDecode::getOperationMode(data[6])); + if (this->get_state() == new_state) return; + break; + } + case TextSensorIds::CONF_TOP17: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::PowerfulMode, PanasonicDecode::getBit6and7and8(data[7])); + if (this->get_state() == new_state) return; + break; + } + case TextSensorIds::CONF_TOP18: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::QuietMode, PanasonicDecode::getBit3and4and5(data[7])); + if (this->get_state() == new_state) return; + break; + } + case TextSensorIds::CONF_TOP19: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::HolidayState, PanasonicDecode::getBit3and4(data[5])); + if (this->get_state() == new_state) return; + break; + } + case TextSensorIds::CONF_TOP20: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::ThreeWayValve, PanasonicDecode::getBit7and8(data[111])); + if (this->get_state() == new_state) return; + break; + } + case TextSensorIds::CONF_TOP44: + { + new_state = PanasonicDecode::getErrorInfo(data[113], data[114]); + if (this->get_state() == new_state) return; + break; + } + case TextSensorIds::CONF_TOP58: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::BlockedFree, PanasonicDecode::getBit5and6(data[9])); + if (this->get_state() == new_state) return; + break; + } + case TextSensorIds::CONF_TOP59: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::BlockedFree, PanasonicDecode::getBit7and8(data[9])); + if (this->get_state() == new_state) return; + break; + } + case TextSensorIds::CONF_TOP76: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::WaterTempControl, PanasonicDecode::getBit7and8(data[28])); + if (this->get_state() == new_state) return; + break; + } + case TextSensorIds::CONF_TOP81: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::WaterTempControl, PanasonicDecode::getBit5and6(data[28])); + if (this->get_state() == new_state) return; + break; + } + case TextSensorIds::CONF_TOP92: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::ModelNames, PanasonicDecode::getModel(data, 129)); + if (this->get_state() == new_state) return; + break; + } + case TextSensorIds::CONF_TOP94: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::ZoneState, PanasonicDecode::getBit1and2(data[6])); + if (this->get_state() == new_state) return; + break; + } + case TextSensorIds::CONF_TOP101: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::SolarMode, PanasonicDecode::getBit3and4(data[24])); + if (this->get_state() == new_state) return; + break; + } + case TextSensorIds::CONF_TOP106: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::PumpFlowRateMode, PanasonicDecode::getBit3and4(data[29])); + if (this->get_state() == new_state) return; + break; + } + case TextSensorIds::CONF_TOP107: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::LiquidType, PanasonicDecode::getBit1(data[20])); + if (this->get_state() == new_state) return; + break; + } + case TextSensorIds::CONF_TOP111: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::ZoneSensorType, PanasonicDecode::getLowNibbleMinus1(data[22])); + if (this->get_state() == new_state) return; + break; + } + case TextSensorIds::CONF_TOP112: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::ZoneSensorType, PanasonicDecode::getHighNibbleMinus1(data[22])); + if (this->get_state() == new_state) return; + break; + } + case TextSensorIds::CONF_TOP114: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::ExtPadHeaterType, PanasonicDecode::getBit3and4(data[25])); + if (this->get_state() == new_state) return; + break; + } + case TextSensorIds::CONF_TOP125: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::TwoWayValve, PanasonicDecode::getBit5and6(data[116])); + if (this->get_state() == new_state) return; + break; + } + case TextSensorIds::CONF_TOP126: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::ThreeWayValve, PanasonicDecode::getBit7and8(data[116])); + if (this->get_state() == new_state) return; + break; + } + case TextSensorIds::CONF_TOP130: + { + new_state = PanasonicDecode::getTextState(PanasonicDecode::BivalentMode, PanasonicDecode::getBit5and6(data[26])); + if (this->get_state() == new_state) return; + break; + } + default: return; + }; + this->publish_state(new_state); + } } // namespace panasonic_heatpump } // namespace esphome 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 164d7eb..deca7dd 100644 --- a/components/panasonic_heatpump/text_sensor/panasonic_heatpump_text_sensor.h +++ b/components/panasonic_heatpump/text_sensor/panasonic_heatpump_text_sensor.h @@ -1,18 +1,45 @@ #pragma once -#include "esphome/components/text_sensor/text_sensor.h" #include "esphome/core/component.h" +#include "esphome/components/text_sensor/text_sensor.h" #include "../panasonic_heatpump.h" +#include "../decode.h" namespace esphome { namespace panasonic_heatpump { - class PanasonicHeatpumpTextSensor : public text_sensor::TextSensor, public Component, public Parented + enum TextSensorIds : int + { + CONF_TOP4, + CONF_TOP17, + CONF_TOP18, + CONF_TOP19, + CONF_TOP20, + CONF_TOP44, + CONF_TOP58, + CONF_TOP59, + CONF_TOP76, + CONF_TOP81, + CONF_TOP92, + CONF_TOP94, + CONF_TOP101, + CONF_TOP106, + CONF_TOP107, + CONF_TOP111, + CONF_TOP112, + CONF_TOP114, + CONF_TOP125, + CONF_TOP126, + CONF_TOP130, + }; + + class PanasonicHeatpumpTextSensor : public text_sensor::TextSensor, public Component, public Parented, public PanasonicHeatpumpEntity { public: PanasonicHeatpumpTextSensor() = default; void dump_config() override; + void publish_new_state(const std::vector& data) override; }; } // namespace panasonic_heatpump } // namespace esphome