Refactored Code: Moved most code from main component class to entity component classes. Set traits for select entities.

This commit is contained in:
ElVit 2025-06-10 20:08:35 +02:00
parent b229ee80e6
commit f9f29a635d
25 changed files with 2076 additions and 721 deletions

View File

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

View File

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

View File

@ -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<PanasonicHeatpumpComponent>
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<PanasonicHeatpumpComponent>, public PanasonicHeatpumpEntity
{
public:
PanasonicHeatpumpBinarySensor() = default;
void dump_config() override;
void publish_new_state(const std::vector<uint8_t>& data) override;
};
} // namespace panasonic_heatpump
} // namespace esphome

View File

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

View File

@ -2,10 +2,18 @@
#include <cmath>
#include <vector>
#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

View File

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

View File

@ -3,8 +3,12 @@
#include <string>
#include <vector>
#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" };

View File

@ -5,7 +5,9 @@
#include <vector>
#include <string>
#ifndef UART_LOG_CHUNK_SIZE
#define UART_LOG_CHUNK_SIZE 120
#endif
namespace esphome

View File

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

View File

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

View File

@ -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<PanasonicHeatpumpComponent>
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<PanasonicHeatpumpComponent>, public PanasonicHeatpumpEntity
{
public:
PanasonicHeatpumpNumber() = default;
void dump_config() override;
void set_id(int id) { this->id_ = id; }
void publish_new_state(const std::vector<uint8_t>& data) override;
bool set_traits(const std::vector<uint8_t>& data) override;
protected:
void control(float value) override;
int id_;
};
} // namespace panasonic_heatpump
} // namespace esphome

View File

@ -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<std::tuple<uint8_t, uint8_t>>& 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<uint8_t>& data)
{
if (data.empty()) return;
for (auto *entity : this->binary_sensors_)
{
entity->publish_new_state(data);
}
}
void PanasonicHeatpumpComponent::publish_number(const std::vector<uint8_t>& data)
{
if (data.empty()) return;
for (auto *entity : this->numbers_)
{
entity->publish_new_state(data);
}
}
void PanasonicHeatpumpComponent::set_number_traits(const std::vector<uint8_t>& 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<uint8_t>& data, const std::vector<uint8_t>& last)
void PanasonicHeatpumpComponent::publish_select(const std::vector<uint8_t>& 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<uint8_t>& data, const std::vector<uint8_t>& 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<uint8_t>& data, const std::vector<uint8_t>& 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<uint8_t>& data, const std::vector<uint8_t>& 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<uint8_t>& data, const std::vector<uint8_t>& 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<uint8_t>& data, const std::vector<uint8_t>& 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<std::tuple<uint8_t, uint8_t>> 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<uint8_t>& 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<std::tuple<uint8_t, uint8_t>> 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<uint8_t>& 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<uint8_t>& 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<uint8_t>& data)
{
if (data.empty()) return;
for (auto *entity : this->text_sensors_)
{
entity->publish_new_state(data);
}
}
#endif
} // namespace panasonic_heatpump
} // namespace esphome

View File

@ -1,33 +1,14 @@
#pragma once
#include <vector>
#include <tuple>
#include <string>
#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 <vector>
#include <tuple>
#include <string>
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<uint8_t>& data) = 0;
virtual bool set_traits(const std::vector<uint8_t>& 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<uint8_t> heatpump_message_;
std::vector<uint8_t> last_message_;
std::vector<uint8_t> response_message_;
std::vector<uint8_t> request_message_;
std::vector<uint8_t> 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<PanasonicHeatpumpEntity *> binary_sensors_;
std::vector<PanasonicHeatpumpEntity *> numbers_;
std::vector<PanasonicHeatpumpEntity *> selects_;
std::vector<PanasonicHeatpumpEntity *> sensors_;
std::vector<PanasonicHeatpumpEntity *> switches_;
std::vector<PanasonicHeatpumpEntity *> text_sensors_;
// uart message functions
void read_response();
void send_request(RequestType requestType);
void read_request();
bool check_response(const std::vector<uint8_t>& 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<std::tuple<uint8_t, uint8_t>>& data);
// sensor and control publish functions
// entity functions
void publish_binary_sensor(const std::vector<uint8_t>& data);
void publish_number(const std::vector<uint8_t>& data);
void publish_select(const std::vector<uint8_t>& data);
void publish_sensor(const std::vector<uint8_t>& data);
void publish_switch(const std::vector<uint8_t>& data);
void publish_text_sensor(const std::vector<uint8_t>& data);
void set_number_traits(const std::vector<uint8_t>& data);
void publish_sensor(const std::vector<uint8_t>& data, const std::vector<uint8_t>& last);
void publish_binary_sensor(const std::vector<uint8_t>& data, const std::vector<uint8_t>& last);
void publish_text_sensor(const std::vector<uint8_t>& data, const std::vector<uint8_t>& last);
void publish_number(const std::vector<uint8_t>& data, const std::vector<uint8_t>& last);
void publish_select(const std::vector<uint8_t>& data, const std::vector<uint8_t>& last);
void publish_switch(const std::vector<uint8_t>& data, const std::vector<uint8_t>& last);
void set_select_traits(const std::vector<uint8_t>& data);
};
} // namespace panasonic_heatpump
} // namespace esphome

View File

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

View File

@ -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<uint8_t>& 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<uint8_t>& 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<std::string>(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<std::string>(PanasonicDecode::OperationMode + 1, std::end(PanasonicDecode::OperationMode));
this->traits.set_options(options);
return true;
}
break;
}
};
return false;
}
} // namespace panasonic_heatpump
} // namespace esphome

View File

@ -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<PanasonicHeatpumpComponent>
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<PanasonicHeatpumpComponent>, public PanasonicHeatpumpEntity
{
public:
PanasonicHeatpumpSelect() = default;
void dump_config() override;
void set_id(int id) { this->id_ = id; }
void publish_new_state(const std::vector<uint8_t>& data) override;
bool set_traits(const std::vector<uint8_t>& data) override;
protected:
void control(const std::string &value) override;
int id_;
};
} // namespace panasonic_heatpump
} // namespace esphome

View File

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

View File

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

View File

@ -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<PanasonicHeatpumpComponent>
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<PanasonicHeatpumpComponent>, public PanasonicHeatpumpEntity
{
public:
PanasonicHeatpumpSensor() = default;
void dump_config() override;
void publish_new_state(const std::vector<uint8_t>& data) override;
};
} // namespace panasonic_heatpump
} // namespace esphome

View File

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

View File

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

View File

@ -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<PanasonicHeatpumpComponent>
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<PanasonicHeatpumpComponent>, public PanasonicHeatpumpEntity
{
public:
PanasonicHeatpumpSwitch() = default;
void dump_config() override;
void set_id(int id) { this->id_ = id; }
void publish_new_state(const std::vector<uint8_t>& data) override;
protected:
void write_state(bool state) override;
int id_;
};
} // namespace panasonic_heatpump
} // namespace esphome

View File

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

View File

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

View File

@ -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<PanasonicHeatpumpComponent>
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<PanasonicHeatpumpComponent>, public PanasonicHeatpumpEntity
{
public:
PanasonicHeatpumpTextSensor() = default;
void dump_config() override;
void publish_new_state(const std::vector<uint8_t>& data) override;
};
} // namespace panasonic_heatpump
} // namespace esphome