diff --git a/components/panasonic_heatpump/commands.cpp b/components/panasonic_heatpump/commands.cpp index b880e48..9c30a53 100644 --- a/components/panasonic_heatpump/commands.cpp +++ b/components/panasonic_heatpump/commands.cpp @@ -95,17 +95,17 @@ namespace esphome { switch (input) { - case 0: return 18; // heat-only - case 1: return 19; // cool-only + 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; // dhw-only - case 6: return 34; // heat+dhw - case 7: return 35; // cool+dhw - case 8: return 40; // auto-dhw - case 9: return 41; // auto-heat+dhw - case 10: return 42; // auto-cool+dhw + 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 default: return 0; // do nothing } } diff --git a/components/panasonic_heatpump/decode.cpp b/components/panasonic_heatpump/decode.cpp index 1536b90..696c65a 100644 --- a/components/panasonic_heatpump/decode.cpp +++ b/components/panasonic_heatpump/decode.cpp @@ -11,19 +11,19 @@ namespace esphome constexpr const char* const PanasonicDecode::InactiveActive[]; constexpr const char* const PanasonicDecode::PumpFlowRateMode[]; constexpr const char* const PanasonicDecode::HolidayState[]; - constexpr const char* const PanasonicDecode::OpModeDesc[]; - constexpr const char* const PanasonicDecode::Powerfulmode[]; - constexpr const char* const PanasonicDecode::Quietmode[]; - constexpr const char* const PanasonicDecode::Valve[]; - constexpr const char* const PanasonicDecode::Valve2[]; + constexpr const char* const PanasonicDecode::OperationMode[]; + constexpr const char* const PanasonicDecode::PowerfulMode[]; + constexpr const char* const PanasonicDecode::QuietMode[]; + constexpr const char* const PanasonicDecode::ThreeWayValve[]; + constexpr const char* const PanasonicDecode::TwoWayValve[]; constexpr const char* const PanasonicDecode::MixingValve[]; - constexpr const char* const PanasonicDecode::ZonesState[]; - constexpr const char* const PanasonicDecode::HeatCoolModeDesc[]; - constexpr const char* const PanasonicDecode::SolarModeDesc[]; - constexpr const char* const PanasonicDecode::ZonesSensorType[]; + constexpr const char* const PanasonicDecode::ZoneState[]; + constexpr const char* const PanasonicDecode::WaterTempControl[]; + constexpr const char* const PanasonicDecode::SolarMode[]; + constexpr const char* const PanasonicDecode::ZoneSensorType[]; constexpr const char* const PanasonicDecode::LiquidType[]; constexpr const char* const PanasonicDecode::ExtPadHeaterType[]; - constexpr const char* const PanasonicDecode::Bivalent[]; + constexpr const char* const PanasonicDecode::BivalentMode[]; constexpr const char* const PanasonicDecode::ModelNames[]; constexpr const uint8_t KnownModels[NUMBER_OF_MODELS][10] = @@ -170,32 +170,32 @@ namespace esphome return (input & 0b1111) - 1; } - int PanasonicDecode::getWordMinus1(uint8_t low, uint8_t hi) + int PanasonicDecode::getWordMinus1(const std::vector& data, uint8_t index) { - return ((hi << 8) + low) - 1; + return ((data[index + 1] << 8) + data[index]) - 1; } - int PanasonicDecode::getUintt16(uint8_t input1, uint8_t input2) + int PanasonicDecode::getUintt16(const std::vector& data, uint8_t index) { - return (static_cast((input2 << 8) | input1)) - 1; + return (static_cast((data[index + 1] << 8) | data[index])) - 1; } // TOP4 // - int PanasonicDecode::getOpMode(uint8_t input) + int PanasonicDecode::getOperationMode(uint8_t input) { switch ((int)(input & 0b111111)) { - case 18: return 0; // heat-only - case 19: return 1; // cool-only + 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; // dhw-only - case 34: return 6; // heat+dhw - case 35: return 7; // cool+dhw - case 40: return 8; // auto-dhw - case 41: return 9; // auto-heat+dhw - case 42: return 10; // auto-cool+dhw + 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 default: return -1; // unknown } } @@ -222,9 +222,9 @@ namespace esphome // TOP1 // // input1 = data[169] // input2 = data[170] - float PanasonicDecode::getPumpFlow(uint8_t input1, uint8_t input2) + float PanasonicDecode::getPumpFlow(const std::vector& data, uint8_t index) { - return (((float)input1 - 1) / 256) + ((int)input2); + return (((float)data[index] - 1) / 256) + ((int)data[index + 1]); } // TOP5, TOP6 // diff --git a/components/panasonic_heatpump/decode.h b/components/panasonic_heatpump/decode.h index 4651504..32d61c8 100644 --- a/components/panasonic_heatpump/decode.h +++ b/components/panasonic_heatpump/decode.h @@ -33,12 +33,12 @@ namespace esphome static int getByteMinus1Times200(uint8_t input); static int getHighNibbleMinus1(uint8_t input); static int getLowNibbleMinus1(uint8_t input); - static int getWordMinus1(uint8_t hi, uint8_t low); - static int getUintt16(uint8_t input1, uint8_t input2); + static int getWordMinus1(const std::vector& data, uint8_t index); + static int getUintt16(const std::vector& data, uint8_t index); - static int getOpMode(uint8_t input); + static int getOperationMode(uint8_t input); static int getModel(const std::vector& data, uint8_t index); - static float getPumpFlow(uint8_t input1, uint8_t input2); + static float getPumpFlow(const std::vector& data, uint8_t index); static float getFractional(uint8_t input, uint8_t shift); static std::string getErrorInfo(uint8_t errorType, uint8_t errorNumber); @@ -50,21 +50,24 @@ namespace esphome static const constexpr char* const OffOn[] = { "2", "Off", "On" }; static const constexpr char* const InactiveActive[] = { "2", "Inactive", "Active" }; static const constexpr char* const PumpFlowRateMode[] = { "2", "DeltaT", "Max flow" }; - static const constexpr char* const Valve[] = { "2", "Room", "DHW" }; - static const constexpr char* const Valve2[] = { "2", "Cool", "Heat" }; - static const constexpr char* const HeatCoolModeDesc[] = { "2", "Comp. Curve", "Direct" }; + static const constexpr char* const ThreeWayValve[] = { "2", "Buffer Tank", "DHW Tank" }; + static const constexpr char* const TwoWayValve[] = { "2", "Cool", "Heat" }; + static const constexpr char* const WaterTempControl[] = { "2", "Comp. Curve", "Direct" }; static const constexpr char* const LiquidType[] = { "2", "Water", "Glycol" }; static const constexpr char* const HolidayState[] = { "3", "Off", "Scheduled", "Active" }; - static const constexpr char* const SolarModeDesc[] = { "3", "Disabled", "Buffer", "DHW" }; + static const constexpr char* const SolarMode[] = { "3", "Disabled", "Buffer Tank", "DHW Tank" }; static const constexpr char* const MixingValve[] = { "4", "Off", "Decrease","Increase", "Invalid" }; - static const constexpr char* const ZonesSensorType[] = { "4", "Water Temperature", "External Thermostat", "Internal Thermostat", "Thermistor" }; - static const constexpr char* const Quietmode[] = { "4", "Off", "Level 1", "Level 2", "Level 3" }; - static const constexpr char* const Powerfulmode[] = { "4", "Off", "30min", "60min", "90min" }; - static const constexpr char* const OpModeDesc[] = { "11", "Heat only", "Cool only", "Auto", "Auto(heat)", "Auto(cool)", "DHW only", - "Heat+DHW", "Cool+DHW", "Auto+DHW", "Auto(heat)+DHW", "Auto(cool)+DHW" }; - static const constexpr char* const ZonesState[] = { "3", "Zone 1", "Zone 2", "Zone 1 & 2" }; + static const constexpr char* const ZoneSensorType[] = { "4", "Water Temperature", "External Thermostat", "Internal Thermostat", "Thermistor" }; + static const constexpr char* const QuietMode[] = { "4", "Off", "Level 1", "Level 2", "Level 3" }; + 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" + }; + 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" }; - static const constexpr char* const Bivalent[] = { "3", "Alternative", "Parallel", "Advanced Parallel" }; + static const constexpr char* const BivalentMode[] = { "3", "Alternative", "Parallel", "Advanced Parallel" }; static const constexpr char* const ModelNames[] = { "55", // string representation of number of known models (last model number + 1) diff --git a/components/panasonic_heatpump/number/__init__.py b/components/panasonic_heatpump/number/__init__.py index 101241b..26038f3 100644 --- a/components/panasonic_heatpump/number/__init__.py +++ b/components/panasonic_heatpump/number/__init__.py @@ -16,15 +16,15 @@ CONF_SET7 = "set7" # Set Z2 Heat Request Temperature CONF_SET8 = "set8" # Set Z2 Cool Request Temperature CONF_SET11 = "set11" # Set DHW Temp CONF_SET15 = "set15" # Set Max Pump Duty -CONF_SET16_1 = "set16_1" # Set Zone1 Heat Target High -CONF_SET16_2 = "set16_2" # Set Zone1 Heat Target Low -CONF_SET16_3 = "set16_3" # Set Zone1 Heat Outside Low -CONF_SET16_4 = "set16_4" # Set Zone1 Heat Outside High -CONF_SET16_5 = "set16_5" # Set Zone2 Heat Target High -CONF_SET16_6 = "set16_6" # Set Zone2 Heat Target Low -CONF_SET16_7 = "set16_7" # Set Zone2 Heat Outside Low -CONF_SET16_8 = "set16_8" # Set Zone2 Heat Outside High -CONF_SET16_9 = "set16_9" # Set Zone1 Cool Target High +CONF_SET16_01 = "set16_01" # Set Zone1 Heat Target High +CONF_SET16_02 = "set16_02" # Set Zone1 Heat Target Low +CONF_SET16_03 = "set16_03" # Set Zone1 Heat Outside Low +CONF_SET16_04 = "set16_04" # Set Zone1 Heat Outside High +CONF_SET16_05 = "set16_05" # Set Zone2 Heat Target High +CONF_SET16_06 = "set16_06" # Set Zone2 Heat Target Low +CONF_SET16_07 = "set16_07" # Set Zone2 Heat Outside Low +CONF_SET16_08 = "set16_08" # Set Zone2 Heat Outside High +CONF_SET16_09 = "set16_09" # Set Zone1 Cool Target High CONF_SET16_10 = "set16_10" # Set Zone1 Cool Target Low CONF_SET16_11 = "set16_11" # Set Zone1 Cool Outside Low CONF_SET16_12 = "set16_12" # Set Zone1 Cool Outside High @@ -51,15 +51,15 @@ TYPES = [ CONF_SET8, CONF_SET11, CONF_SET15, - CONF_SET16_1, - CONF_SET16_2, - CONF_SET16_3, - CONF_SET16_4, - CONF_SET16_5, - CONF_SET16_6, - CONF_SET16_7, - CONF_SET16_8, - CONF_SET16_9, + 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, @@ -146,47 +146,47 @@ CONFIG_SCHEMA = cv.Schema( cv.Optional(CONF_SET15): number.number_schema( PanasonicHeatpumpNumber, ), - cv.Optional(CONF_SET16_1): number.number_schema( + cv.Optional(CONF_SET16_01): number.number_schema( PanasonicHeatpumpNumber, unit_of_measurement=UNIT_CELSIUS, entity_category=ENTITY_CATEGORY_CONFIG, ), - cv.Optional(CONF_SET16_2): number.number_schema( + cv.Optional(CONF_SET16_02): number.number_schema( PanasonicHeatpumpNumber, unit_of_measurement=UNIT_CELSIUS, entity_category=ENTITY_CATEGORY_CONFIG, ), - cv.Optional(CONF_SET16_3): number.number_schema( + cv.Optional(CONF_SET16_03): number.number_schema( PanasonicHeatpumpNumber, unit_of_measurement=UNIT_CELSIUS, entity_category=ENTITY_CATEGORY_CONFIG, ), - cv.Optional(CONF_SET16_4): number.number_schema( + cv.Optional(CONF_SET16_04): number.number_schema( PanasonicHeatpumpNumber, unit_of_measurement=UNIT_CELSIUS, entity_category=ENTITY_CATEGORY_CONFIG, ), - cv.Optional(CONF_SET16_5): number.number_schema( + cv.Optional(CONF_SET16_05): number.number_schema( PanasonicHeatpumpNumber, unit_of_measurement=UNIT_CELSIUS, entity_category=ENTITY_CATEGORY_CONFIG, ), - cv.Optional(CONF_SET16_6): number.number_schema( + cv.Optional(CONF_SET16_06): number.number_schema( PanasonicHeatpumpNumber, unit_of_measurement=UNIT_CELSIUS, entity_category=ENTITY_CATEGORY_CONFIG, ), - cv.Optional(CONF_SET16_7): number.number_schema( + cv.Optional(CONF_SET16_07): number.number_schema( PanasonicHeatpumpNumber, unit_of_measurement=UNIT_CELSIUS, entity_category=ENTITY_CATEGORY_CONFIG, ), - cv.Optional(CONF_SET16_8): number.number_schema( + cv.Optional(CONF_SET16_08): number.number_schema( PanasonicHeatpumpNumber, unit_of_measurement=UNIT_CELSIUS, entity_category=ENTITY_CATEGORY_CONFIG, ), - cv.Optional(CONF_SET16_9): number.number_schema( + cv.Optional(CONF_SET16_09): number.number_schema( PanasonicHeatpumpNumber, unit_of_measurement=UNIT_CELSIUS, entity_category=ENTITY_CATEGORY_CONFIG, diff --git a/components/panasonic_heatpump/panasonic_heatpump.cpp b/components/panasonic_heatpump/panasonic_heatpump.cpp index 1b0134a..5461378 100644 --- a/components/panasonic_heatpump/panasonic_heatpump.cpp +++ b/components/panasonic_heatpump/panasonic_heatpump.cpp @@ -19,6 +19,13 @@ namespace esphome ESP_LOGCONFIG(TAG, "Setting up Panasonic Heatpump ..."); 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(); } @@ -53,37 +60,43 @@ namespace esphome } case LoopState::PUBLISH_SENSOR: { - this->publish_sensor(this->heatpump_message_); + this->publish_sensor(this->heatpump_message_, this->last_message_); this->loop_state_ = LoopState::PUBLISH_BINARY_SENSOR; break; } case LoopState::PUBLISH_BINARY_SENSOR: { - this->publish_binary_sensor(this->heatpump_message_); + this->publish_binary_sensor(this->heatpump_message_, this->last_message_); this->loop_state_ = LoopState::PUBLISH_TEXT_SENSOR; break; } case LoopState::PUBLISH_TEXT_SENSOR: { - this->publish_text_sensor(this->heatpump_message_); + this->publish_text_sensor(this->heatpump_message_, this->last_message_); this->loop_state_ = LoopState::PUBLISH_NUMBER; break; } case LoopState::PUBLISH_NUMBER: { - this->publish_number(this->heatpump_message_); + this->publish_number(this->heatpump_message_, this->last_message_); this->loop_state_ = LoopState::PUBLISH_SELECT; break; } case LoopState::PUBLISH_SELECT: { - this->publish_select(this->heatpump_message_); + this->publish_select(this->heatpump_message_, this->last_message_); this->loop_state_ = LoopState::PUBLISH_SWITCH; break; } case LoopState::PUBLISH_SWITCH: { - this->publish_switch(this->heatpump_message_); + 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->loop_state_ = LoopState::SEND_REQUEST; break; } @@ -286,18 +299,56 @@ namespace esphome return true; } + void PanasonicHeatpumpComponent::set_command_high_nibble(const uint8_t value, const uint8_t index) + { + if (this->next_request_ != RequestType::COMMAND) + { + // initialize the command + this->command_message_.assign(std::begin(PanasonicCommand::CommandMessage), + std::end(PanasonicCommand::CommandMessage)); + } + uint8_t lowNibble = this->heatpump_message_[index] & 0b1111; + uint8_t highNibble = value << 4; + // set command byte + this->command_message_[index] = highNibble + lowNibble; + // calculate and set set checksum (last element) + this->command_message_.back() = PanasonicCommand::calcChecksum(this->command_message_, this->command_message_.size() - 1); + + // command will be send on next loop + this->next_request_ = RequestType::COMMAND; + } + + void PanasonicHeatpumpComponent::set_command_low_nibble(const uint8_t value, const uint8_t index) + { + if (this->next_request_ != RequestType::COMMAND) + { + // initialize the command + this->command_message_.assign(std::begin(PanasonicCommand::CommandMessage), + std::end(PanasonicCommand::CommandMessage)); + } + uint8_t highNibble = this->heatpump_message_[index] & 0b11110000; + uint8_t lowNibble = value & 0b1111; + // set command byte + this->command_message_[index] = highNibble + lowNibble; + // calculate and set set checksum (last element) + this->command_message_.back() = PanasonicCommand::calcChecksum(this->command_message_, this->command_message_.size() - 1); + + // command will be send on next loop + this->next_request_ = RequestType::COMMAND; + } + void PanasonicHeatpumpComponent::set_command_byte(const uint8_t value, const uint8_t index) { if (this->next_request_ != RequestType::COMMAND) { // initialize the command - command_message_.assign(std::begin(PanasonicCommand::CommandMessage), + this->command_message_.assign(std::begin(PanasonicCommand::CommandMessage), std::end(PanasonicCommand::CommandMessage)); } // set command byte - command_message_[index] = value; + this->command_message_[index] = value; // calculate and set set checksum (last element) - command_message_.back() = PanasonicCommand::calcChecksum(command_message_, command_message_.size() - 1); + this->command_message_.back() = PanasonicCommand::calcChecksum(this->command_message_, this->command_message_.size() - 1); // command will be send on next loop this->next_request_ = RequestType::COMMAND; @@ -308,7 +359,7 @@ namespace esphome if (this->next_request_ != RequestType::COMMAND) { // initialize the command - command_message_.assign(std::begin(PanasonicCommand::CommandMessage), + this->command_message_.assign(std::begin(PanasonicCommand::CommandMessage), std::end(PanasonicCommand::CommandMessage)); } // set command bytes @@ -316,10 +367,10 @@ namespace esphome { uint8_t value = std::get<0>(data[i]); uint8_t index = std::get<1>(data[i]); - command_message_[index] = value; + this->command_message_[index] = value; } // calculate and set set checksum (last element) - command_message_.back() = PanasonicCommand::calcChecksum(command_message_, command_message_.size() - 1); + this->command_message_.back() = PanasonicCommand::calcChecksum(this->command_message_, this->command_message_.size() - 1); // command will be send on next loop this->next_request_ = RequestType::COMMAND; @@ -337,58 +388,58 @@ namespace esphome bool change_detected = false; std::string top76 = PanasonicDecode::getTextState( - PanasonicDecode::HeatCoolModeDesc, PanasonicDecode::getBit7and8(data[28])); // Heating Mode + PanasonicDecode::WaterTempControl, PanasonicDecode::getBit7and8(data[28])); // Heating Mode std::string top81 = PanasonicDecode::getTextState( - PanasonicDecode::HeatCoolModeDesc, PanasonicDecode::getBit5and6(data[28])); // Cooling Mode + 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::HeatCoolModeDesc[1]) + if (set5_min >= 0.0 && top76 == PanasonicDecode::WaterTempControl[1]) { this->set5_number_->traits.set_min_value(-5.0); this->set5_number_->traits.set_max_value(5.0); change_detected = true; } - if (set6_min >= 0.0 && top81 == PanasonicDecode::HeatCoolModeDesc[1]) + 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::HeatCoolModeDesc[1]) + 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::HeatCoolModeDesc[1]) + 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::HeatCoolModeDesc[2]) + 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::HeatCoolModeDesc[2]) + 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::HeatCoolModeDesc[2]) + 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::HeatCoolModeDesc[2]) + 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); @@ -403,235 +454,236 @@ namespace esphome #endif } - void PanasonicHeatpumpComponent::publish_sensor(const std::vector& data) + void PanasonicHeatpumpComponent::publish_sensor(const std::vector& data, const std::vector& last) { #ifdef USE_SENSOR if (data.empty()) return; - if (this->top1_sensor_) this->top1_sensor_->publish_state(PanasonicDecode::getPumpFlow(data[169], data[170])); - if (this->top5_sensor_) this->top5_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[143]) + PanasonicDecode::getFractional(data[118], 0)); - if (this->top6_sensor_) this->top6_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[144]) + PanasonicDecode::getFractional(data[118], 3)); - if (this->top7_sensor_) this->top7_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[153])); - if (this->top8_sensor_) this->top8_sensor_->publish_state(PanasonicDecode::getByteMinus1(data[166])); - if (this->top9_sensor_) this->top9_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[42])); - if (this->top10_sensor_) this->top10_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[141])); - if (this->top11_sensor_) this->top11_sensor_->publish_state(PanasonicDecode::getWordMinus1(data[182], data[183])); - if (this->top12_sensor_) this->top12_sensor_->publish_state(PanasonicDecode::getWordMinus1(data[179], data[180])); - if (this->top14_sensor_) this->top14_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[142])); - if (this->top15_sensor_) this->top15_sensor_->publish_state(PanasonicDecode::getByteMinus1Times200(data[194])); - if (this->top16_sensor_) this->top16_sensor_->publish_state(PanasonicDecode::getByteMinus1Times200(data[193])); - if (this->top21_sensor_) this->top21_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[158])); - if (this->top22_sensor_) this->top22_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[99])); - if (this->top23_sensor_) this->top23_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[84])); - if (this->top24_sensor_) this->top24_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[94])); - if (this->top25_sensor_) this->top25_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[44])); - if (this->top27_sensor_) this->top27_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[38])); - if (this->top28_sensor_) this->top28_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[39])); - if (this->top29_sensor_) this->top29_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[75])); - if (this->top30_sensor_) this->top30_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[76])); - if (this->top31_sensor_) this->top31_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[78])); - if (this->top32_sensor_) this->top32_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[77])); - if (this->top33_sensor_) this->top33_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[156])); - if (this->top34_sensor_) this->top34_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[40])); - if (this->top35_sensor_) this->top35_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[41])); - if (this->top36_sensor_) this->top36_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[145])); - if (this->top37_sensor_) this->top37_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[146])); - if (this->top38_sensor_) this->top38_sensor_->publish_state(PanasonicDecode::getByteMinus1Times200(data[196])); - if (this->top39_sensor_) this->top39_sensor_->publish_state(PanasonicDecode::getByteMinus1Times200(data[195])); - if (this->top40_sensor_) this->top40_sensor_->publish_state(PanasonicDecode::getByteMinus1Times200(data[198])); - if (this->top41_sensor_) this->top41_sensor_->publish_state(PanasonicDecode::getByteMinus1Times200(data[197])); - if (this->top42_sensor_) this->top42_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[147])); - if (this->top43_sensor_) this->top43_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[148])); - if (this->top45_sensor_) this->top45_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[43])); - if (this->top46_sensor_) this->top46_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[149])); - if (this->top47_sensor_) this->top47_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[150])); - if (this->top48_sensor_) this->top48_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[151])); - if (this->top49_sensor_) this->top49_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[154])); - if (this->top50_sensor_) this->top50_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[155])); - if (this->top51_sensor_) this->top51_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[157])); - if (this->top52_sensor_) this->top52_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[159])); - if (this->top53_sensor_) this->top53_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[160])); - if (this->top54_sensor_) this->top54_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[161])); - if (this->top55_sensor_) this->top55_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[162])); - if (this->top56_sensor_) this->top56_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[139])); - if (this->top57_sensor_) this->top57_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[140])); - if (this->top62_sensor_) this->top62_sensor_->publish_state(PanasonicDecode::getByteMinus1Times10(data[173])); - if (this->top63_sensor_) this->top63_sensor_->publish_state(PanasonicDecode::getByteMinus1Times10(data[174])); - if (this->top64_sensor_) this->top64_sensor_->publish_state(PanasonicDecode::getByteMinus1Div5(data[163])); - if (this->top65_sensor_) this->top65_sensor_->publish_state(PanasonicDecode::getByteMinus1Times50(data[171])); - if (this->top66_sensor_) this->top66_sensor_->publish_state(PanasonicDecode::getByteMinus1Times50(data[164])); - if (this->top67_sensor_) this->top67_sensor_->publish_state(PanasonicDecode::getByteMinus1Div5(data[165])); - if (this->top70_sensor_) this->top70_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[100])); - if (this->top71_sensor_) this->top71_sensor_->publish_state(PanasonicDecode::getByteMinus1(data[101])); - if (this->top72_sensor_) this->top72_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[86])); - if (this->top73_sensor_) this->top73_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[87])); - if (this->top74_sensor_) this->top74_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[89])); - if (this->top75_sensor_) this->top75_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[88])); - if (this->top77_sensor_) this->top77_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[83])); - if (this->top78_sensor_) this->top78_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[85])); - if (this->top79_sensor_) this->top79_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[95])); - if (this->top80_sensor_) this->top80_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[96])); - if (this->top82_sensor_) this->top82_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[79])); - if (this->top83_sensor_) this->top83_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[80])); - if (this->top84_sensor_) this->top84_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[82])); - if (this->top85_sensor_) this->top85_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[81])); - if (this->top86_sensor_) this->top86_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[90])); - if (this->top87_sensor_) this->top87_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[91])); - if (this->top88_sensor_) this->top88_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[93])); - if (this->top89_sensor_) this->top89_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[92])); - if (this->top90_sensor_) this->top90_sensor_->publish_state(PanasonicDecode::getWordMinus1(data[185], data[186])); - if (this->top91_sensor_) this->top91_sensor_->publish_state(PanasonicDecode::getWordMinus1(data[188], data[189])); - if (this->top93_sensor_) this->top93_sensor_->publish_state(PanasonicDecode::getByteMinus1(data[172])); - if (this->top95_sensor_) this->top95_sensor_->publish_state(PanasonicDecode::getByteMinus1(data[45])); - if (this->top96_sensor_) this->top96_sensor_->publish_state(PanasonicDecode::getByteMinus1(data[104])); - if (this->top97_sensor_) this->top97_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[105])); - if (this->top98_sensor_) this->top98_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[106])); - if (this->top102_sensor_) this->top102_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[61])); - if (this->top103_sensor_) this->top103_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[62])); - if (this->top104_sensor_) this->top104_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[63])); - if (this->top105_sensor_) this->top105_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[64])); - if (this->top113_sensor_) this->top113_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[59])); - if (this->top115_sensor_) this->top115_sensor_->publish_state(PanasonicDecode::getByteMinus1Div50(data[125])); - if (this->top116_sensor_) this->top116_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[126])); - if (this->top117_sensor_) this->top117_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[127])); - if (this->top118_sensor_) this->top118_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[128])); - if (this->top127_sensor_) this->top127_sensor_->publish_state(PanasonicDecode::getByteMinus1Div2(data[177])); - if (this->top128_sensor_) this->top128_sensor_->publish_state(PanasonicDecode::getByteMinus1Div2(data[178])); - if (this->top131_sensor_) this->top131_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[65])); - if (this->top134_sensor_) this->top134_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[66])); - if (this->top135_sensor_) this->top135_sensor_->publish_state(PanasonicDecode::getByteMinus128(data[68])); - if (this->top136_sensor_) this->top136_sensor_->publish_state(PanasonicDecode::getByteMinus1(data[67])); - if (this->top137_sensor_) this->top137_sensor_->publish_state(PanasonicDecode::getByteMinus1(data[69])); - if (this->top138_sensor_) this->top138_sensor_->publish_state(PanasonicDecode::getByteMinus1(data[70])); + 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) + 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_) this->top0_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[4]))); - if (this->top2_binary_sensor_) this->top2_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[4]))); - if (this->top3_binary_sensor_) this->top3_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[7]))); - if (this->top13_binary_sensor_) this->top13_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[5]))); - if (this->top26_binary_sensor_) this->top26_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[111]))); - if (this->top60_binary_sensor_) this->top60_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[112]))); - if (this->top61_binary_sensor_) this->top61_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[112]))); - if (this->top68_binary_sensor_) this->top68_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[5]))); - if (this->top69_binary_sensor_) this->top69_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[117]))); - if (this->top99_binary_sensor_) this->top99_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[24]))); - if (this->top100_binary_sensor_) this->top100_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[24]))); - if (this->top108_binary_sensor_) this->top108_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit3and4(data[20]))); - if (this->top109_binary_sensor_) this->top109_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[20]))); - if (this->top110_binary_sensor_) this->top110_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[20]))); - if (this->top119_binary_sensor_) this->top119_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[23]))); - if (this->top120_binary_sensor_) this->top120_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[23]))); - if (this->top121_binary_sensor_) this->top121_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit3and4(data[23]))); - if (this->top122_binary_sensor_) this->top122_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[23]))); - if (this->top123_binary_sensor_) this->top123_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[116]))); - if (this->top124_binary_sensor_) this->top124_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit3and4(data[116]))); - if (this->top129_binary_sensor_) this->top129_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[26]))); - if (this->top132_binary_sensor_) this->top132_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit3and4(data[26]))); - if (this->top133_binary_sensor_) this->top133_binary_sensor_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[26]))); + 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) + 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_) this->top4_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::OpModeDesc, PanasonicDecode::getOpMode(data[6]))); - if (this->top17_text_sensor_) this->top17_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::Powerfulmode, PanasonicDecode::getBit6and7and8(data[7]))); - if (this->top18_text_sensor_) this->top18_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::Quietmode, PanasonicDecode::getBit3and4and5(data[7]))); - if (this->top19_text_sensor_) this->top19_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::HolidayState, PanasonicDecode::getBit3and4(data[5]))); - if (this->top20_text_sensor_) this->top20_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::Valve, PanasonicDecode::getBit7and8(data[111]))); - if (this->top44_text_sensor_) this->top44_text_sensor_->publish_state(PanasonicDecode::getErrorInfo(data[113], data[114])); - if (this->top58_text_sensor_) this->top58_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::BlockedFree, PanasonicDecode::getBit5and6(data[9]))); - if (this->top59_text_sensor_) this->top59_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::BlockedFree, PanasonicDecode::getBit7and8(data[9]))); - if (this->top76_text_sensor_) this->top76_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::HeatCoolModeDesc, PanasonicDecode::getBit7and8(data[28]))); - if (this->top81_text_sensor_) this->top81_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::HeatCoolModeDesc, PanasonicDecode::getBit5and6(data[28]))); - if (this->top92_text_sensor_) this->top92_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::ModelNames, PanasonicDecode::getModel(data, 129))); - if (this->top94_text_sensor_) this->top94_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::ZonesState, PanasonicDecode::getBit1and2(data[6]))); - if (this->top101_text_sensor_) this->top101_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::SolarModeDesc, PanasonicDecode::getBit3and4(data[24]))); - if (this->top106_text_sensor_) this->top106_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::PumpFlowRateMode, PanasonicDecode::getBit3and4(data[29]))); - if (this->top107_text_sensor_) this->top107_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::LiquidType, PanasonicDecode::getBit1(data[20]))); - if (this->top111_text_sensor_) this->top111_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::ZonesSensorType, PanasonicDecode::getLowNibbleMinus1(data[22]))); - if (this->top112_text_sensor_) this->top112_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::ZonesSensorType, PanasonicDecode::getHighNibbleMinus1(data[22]))); - if (this->top114_text_sensor_) this->top114_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::ExtPadHeaterType, PanasonicDecode::getBit3and4(data[25]))); - if (this->top125_text_sensor_) this->top125_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::Valve2, PanasonicDecode::getBit5and6(data[116]))); - if (this->top126_text_sensor_) this->top126_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::Valve, PanasonicDecode::getBit7and8(data[116]))); - if (this->top130_text_sensor_) this->top130_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::Bivalent, PanasonicDecode::getBit5and6(data[26]))); + 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) + void PanasonicHeatpumpComponent::publish_number(const std::vector& data, const std::vector& last) { #ifdef USE_NUMBER if (data.empty()) return; - if (this->set11_number_) this->set11_number_->publish_state(PanasonicDecode::getByteMinus128(data[42])); - if (this->set20_number_) this->set20_number_->publish_state(PanasonicDecode::getByteMinus128(data[99])); - if (this->set18_number_) this->set18_number_->publish_state(PanasonicDecode::getByteMinus128(data[84])); - if (this->set19_number_) this->set19_number_->publish_state(PanasonicDecode::getByteMinus128(data[94])); - if (this->set5_number_) this->set5_number_->publish_state(PanasonicDecode::getByteMinus128(data[38])); - if (this->set6_number_) this->set6_number_->publish_state(PanasonicDecode::getByteMinus128(data[39])); - if (this->set16_1_number_) this->set16_1_number_->publish_state(PanasonicDecode::getByteMinus128(data[75])); - if (this->set16_2_number_) this->set16_2_number_->publish_state(PanasonicDecode::getByteMinus128(data[76])); - if (this->set16_4_number_) this->set16_4_number_->publish_state(PanasonicDecode::getByteMinus128(data[78])); - if (this->set16_3_number_) this->set16_3_number_->publish_state(PanasonicDecode::getByteMinus128(data[77])); - if (this->set7_number_) this->set7_number_->publish_state(PanasonicDecode::getByteMinus128(data[40])); - if (this->set8_number_) this->set8_number_->publish_state(PanasonicDecode::getByteMinus128(data[41])); - if (this->set16_9_number_) this->set16_9_number_->publish_state(PanasonicDecode::getByteMinus128(data[86])); - if (this->set16_10_number_) this->set16_10_number_->publish_state(PanasonicDecode::getByteMinus128(data[87])); - if (this->set16_12_number_) this->set16_12_number_->publish_state(PanasonicDecode::getByteMinus128(data[89])); - if (this->set16_11_number_) this->set16_11_number_->publish_state(PanasonicDecode::getByteMinus128(data[88])); - if (this->set29_number_) this->set29_number_->publish_state(PanasonicDecode::getByteMinus128(data[83])); - if (this->set16_5_number_) this->set16_5_number_->publish_state(PanasonicDecode::getByteMinus128(data[79])); - if (this->set16_6_number_) this->set16_6_number_->publish_state(PanasonicDecode::getByteMinus128(data[80])); - if (this->set16_8_number_) this->set16_8_number_->publish_state(PanasonicDecode::getByteMinus128(data[82])); - if (this->set16_7_number_) this->set16_7_number_->publish_state(PanasonicDecode::getByteMinus128(data[81])); - if (this->set16_13_number_) this->set16_13_number_->publish_state(PanasonicDecode::getByteMinus128(data[90])); - if (this->set16_14_number_) this->set16_14_number_->publish_state(PanasonicDecode::getByteMinus128(data[91])); - if (this->set16_16_number_) this->set16_16_number_->publish_state(PanasonicDecode::getByteMinus128(data[93])); - if (this->set16_15_number_) this->set16_15_number_->publish_state(PanasonicDecode::getByteMinus128(data[92])); - if (this->set15_number_) this->set15_number_->publish_state(PanasonicDecode::getByteMinus1(data[45])); - if (this->set21_number_) this->set21_number_->publish_state(PanasonicDecode::getByteMinus1(data[104])); - if (this->set22_number_) this->set22_number_->publish_state(PanasonicDecode::getByteMinus128(data[105])); - if (this->set23_number_) this->set23_number_->publish_state(PanasonicDecode::getByteMinus128(data[106])); - if (this->set27_number_) this->set27_number_->publish_state(PanasonicDecode::getByteMinus128(data[59])); - if (this->set36_number_) this->set36_number_->publish_state(PanasonicDecode::getByteMinus128(data[65])); - if (this->set37_number_) this->set37_number_->publish_state(PanasonicDecode::getByteMinus128(data[66])); - if (this->set38_number_) this->set38_number_->publish_state(PanasonicDecode::getByteMinus128(data[68])); + 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) + void PanasonicHeatpumpComponent::publish_select(const std::vector& data, const std::vector& last) { #ifdef USE_SELECT if (data.empty()) return; - if (this->set9_select_) this->set9_select_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::OpModeDesc, PanasonicDecode::getOpMode(data[6]))); - if (this->set4_select_) this->set4_select_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::Powerfulmode, PanasonicDecode::getBit6and7and8(data[7]))); - if (this->set3_select_) this->set3_select_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::Quietmode, PanasonicDecode::getBit3and4and5(data[7]))); - if (this->set2_select_) this->set2_select_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::HolidayState, PanasonicDecode::getBit3and4(data[5]))); - if (this->set17_select_) this->set17_select_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::ZonesState, PanasonicDecode::getBit1and2(data[6]))); - if (this->set26_select_) this->set26_select_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::ExtPadHeaterType, PanasonicDecode::getBit3and4(data[25]))); - if (this->set35_select_) this->set35_select_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::Bivalent, PanasonicDecode::getBit5and6(data[26]))); + 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) + void PanasonicHeatpumpComponent::publish_switch(const std::vector& data, const std::vector& last) { -#ifdef USE_SWITCH +#ifdef USE_SWITCH if (data.empty()) return; - if (this->set1_switch_) this->set1_switch_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[4]))); - if (this->set10_switch_) this->set10_switch_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[4]))); - if (this->set24_switch_) this->set24_switch_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[5]))); - if (this->set12_switch_) this->set12_switch_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[111]))); - if (this->set13_switch_) this->set13_switch_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[117]))); - if (this->set28_switch_) this->set28_switch_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[24]))); - if (this->set30_switch_) this->set30_switch_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[23]))); - if (this->set33_switch_) this->set33_switch_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit5and6(data[23]))); - if (this->set31_switch_) this->set31_switch_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit3and4(data[23]))); - if (this->set32_switch_) this->set32_switch_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit1and2(data[23]))); - if (this->set34_switch_) this->set34_switch_->publish_state(PanasonicDecode::getBinaryState(PanasonicDecode::getBit7and8(data[26]))); + 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 } @@ -656,33 +708,33 @@ namespace esphome 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_1_number_ || object == this->set16_2_number_ - || object == this->set16_3_number_ || object == this->set16_4_number_ - || object == this->set16_9_number_ || object == this->set16_10_number_ + 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_) { std::vector> curve; - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_1_number_->state), 75)); - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_2_number_->state), 76)); - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_3_number_->state), 77)); - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_4_number_->state), 78)); - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_9_number_->state), 86)); + 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); } // Set zone 2 curve - if (object == this->set16_5_number_ || object == this->set16_6_number_ - || object == this->set16_7_number_ || object == this->set16_8_number_ + 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_) { std::vector> curve; - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_5_number_->state), 79)); - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_6_number_->state), 80)); - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_7_number_->state), 81)); - curve.push_back(std::make_tuple(PanasonicCommand::setPlus128(this->set16_8_number_->state), 82)); + 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)); diff --git a/components/panasonic_heatpump/panasonic_heatpump.h b/components/panasonic_heatpump/panasonic_heatpump.h index d39e79f..a6b63dc 100644 --- a/components/panasonic_heatpump/panasonic_heatpump.h +++ b/components/panasonic_heatpump/panasonic_heatpump.h @@ -45,6 +45,7 @@ namespace esphome PUBLISH_NUMBER, PUBLISH_SELECT, PUBLISH_SWITCH, + STORE_RESPONSE, SEND_REQUEST, READ_REQUEST, RESTART_LOOP @@ -214,15 +215,15 @@ namespace esphome SUB_NUMBER(set8); SUB_NUMBER(set11); SUB_NUMBER(set15); - SUB_NUMBER(set16_1); - SUB_NUMBER(set16_2); - SUB_NUMBER(set16_3); - SUB_NUMBER(set16_4); - SUB_NUMBER(set16_5); - SUB_NUMBER(set16_6); - SUB_NUMBER(set16_7); - SUB_NUMBER(set16_8); - SUB_NUMBER(set16_9); + 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); @@ -292,6 +293,7 @@ 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_; @@ -310,16 +312,18 @@ namespace esphome 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 void set_number_traits(const std::vector& data); - void publish_sensor(const std::vector& data); - void publish_binary_sensor(const std::vector& data); - void publish_text_sensor(const std::vector& data); - void publish_number(const std::vector& data); - void publish_select(const std::vector& data); - void publish_switch(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); }; } // namespace panasonic_heatpump } // namespace esphome diff --git a/components/panasonic_heatpump/select/__init__.py b/components/panasonic_heatpump/select/__init__.py index b6e6b15..3986c48 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 only", "Cool only", "Auto", "Auto(heat)", "Auto(cool)", "DHW only", "Heat+DHW", "Cool+DHW", "Auto+DHW", "Auto(heat)+DHW", "Auto(cool)+DHW", ], + [ "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" ], diff --git a/components/panasonic_heatpump/text_sensor/__init__.py b/components/panasonic_heatpump/text_sensor/__init__.py index ad00a96..9596d9b 100644 --- a/components/panasonic_heatpump/text_sensor/__init__.py +++ b/components/panasonic_heatpump/text_sensor/__init__.py @@ -7,7 +7,7 @@ from esphome.const import ( from .. import CONF_PANASONIC_HEATPUMP_ID, PanasonicHeatpumpComponent, panasonic_heatpump_ns -ICON_OPERATING_MODE = "mdi:thermostat" +ICON_OPERATION_MODE = "mdi:thermostat" ICON_POWERFUL_MODE = "mdi:arm-flex" ICON_QUIET_MODE = "mdi:sleep" ICON_HOLIDAY_MODE = "mdi:palm-tree" @@ -24,7 +24,7 @@ ICON_PUMP = "mdi:pump" ICON_EXTERNAL_PAD_HEATER = "mdi:radiator" -CONF_TOP4 = "top4" # Operating Mode State +CONF_TOP4 = "top4" # Operation Mode # ToDo: Split up top4 into top4_1 (Heating Mode State) and top4_2 (DHW Mode State) CONF_TOP17 = "top17" # Powerful Mode Time CONF_TOP18 = "top18" # Quiet Mode Level @@ -79,7 +79,7 @@ CONFIG_SCHEMA = cv.Schema( cv.Optional(CONF_TOP4): text_sensor.text_sensor_schema( PanasonicHeatpumpTextSensor, - icon=ICON_OPERATING_MODE, + icon=ICON_OPERATION_MODE, ), cv.Optional(CONF_TOP17): text_sensor.text_sensor_schema( PanasonicHeatpumpTextSensor,