mirror of
https://github.com/ElVit/esphome_components.git
synced 2026-10-18 04:34:48 +02:00
Update panasonic_heatpump_climate.cpp
This commit is contained in:
@@ -1,229 +1,206 @@
|
||||
#include "panasonic_heatpump_climate.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace panasonic_heatpump {
|
||||
static const char* const TAG = "panasonic_heatpump.climate";
|
||||
|
||||
namespace esphome
|
||||
{
|
||||
namespace panasonic_heatpump
|
||||
{
|
||||
static const char *const TAG = "panasonic_heatpump.climate";
|
||||
void PanasonicHeatpumpClimate::dump_config() {
|
||||
LOG_CLIMATE("", "Panasonic Heatpump Climate", this);
|
||||
}
|
||||
|
||||
void PanasonicHeatpumpClimate::dump_config()
|
||||
{
|
||||
LOG_CLIMATE("", "Panasonic Heatpump Climate", this);
|
||||
climate::ClimateTraits PanasonicHeatpumpClimate::traits() {
|
||||
auto traits = climate::ClimateTraits();
|
||||
|
||||
// traits.set_supports_action(true);
|
||||
traits.set_supports_current_temperature(true);
|
||||
if (this->cool_mode_ &&
|
||||
(this->id_ == ClimateIds::CONF_CLIMATE_ZONE1 || this->id_ == ClimateIds::CONF_CLIMATE_ZONE2)) {
|
||||
traits.set_supports_two_point_target_temperature(true);
|
||||
this->supported_modes_.insert(climate::CLIMATE_MODE_COOL);
|
||||
this->supported_modes_.insert(climate::CLIMATE_MODE_AUTO);
|
||||
}
|
||||
|
||||
traits.set_supported_modes(this->supported_modes_);
|
||||
traits.set_visual_min_temperature(this->min_temperature_);
|
||||
traits.set_visual_max_temperature(this->max_temperature_);
|
||||
traits.set_visual_temperature_step(this->temperature_step_);
|
||||
|
||||
return traits;
|
||||
}
|
||||
|
||||
void PanasonicHeatpumpClimate::control(const climate::ClimateCall& call) {
|
||||
if (call.get_mode().has_value()) {
|
||||
int byte6 = this->parent_->getResponseByte(6);
|
||||
if (byte6 >= 0) {
|
||||
climate::ClimateMode new_mode = *call.get_mode();
|
||||
uint8_t newByte6 = this->setClimateMode(new_mode, (uint8_t)byte6);
|
||||
this->parent_->set_command_byte(newByte6, 6);
|
||||
}
|
||||
}
|
||||
|
||||
climate::ClimateTraits PanasonicHeatpumpClimate::traits()
|
||||
{
|
||||
auto traits = climate::ClimateTraits();
|
||||
if (call.get_target_temperature().has_value()) {
|
||||
float new_temp = *call.get_target_temperature();
|
||||
switch (this->id_) {
|
||||
case ClimateIds::CONF_CLIMATE_TANK:
|
||||
this->parent_->set_command_byte(PanasonicCommand::setPlus128(new_temp), 42); // set11
|
||||
break;
|
||||
case ClimateIds::CONF_CLIMATE_ZONE1:
|
||||
this->parent_->set_command_byte(PanasonicCommand::setPlus128(new_temp), 38); // set5
|
||||
break;
|
||||
case ClimateIds::CONF_CLIMATE_ZONE2:
|
||||
this->parent_->set_command_byte(PanasonicCommand::setPlus128(new_temp), 40); // set7
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
//traits.set_supports_action(true);
|
||||
traits.set_supports_current_temperature(true);
|
||||
if (this->cool_mode_ &&
|
||||
(this->id_ == ClimateIds::CONF_CLIMATE_ZONE1 ||
|
||||
this->id_ == ClimateIds::CONF_CLIMATE_ZONE2))
|
||||
{
|
||||
traits.set_supports_two_point_target_temperature(true);
|
||||
this->supported_modes_.insert(climate::CLIMATE_MODE_COOL);
|
||||
this->supported_modes_.insert(climate::CLIMATE_MODE_AUTO);
|
||||
}
|
||||
if (call.get_target_temperature_high().has_value()) {
|
||||
float new_temp = *call.get_target_temperature_high();
|
||||
switch (this->id_) {
|
||||
case ClimateIds::CONF_CLIMATE_ZONE1:
|
||||
this->parent_->set_command_byte(PanasonicCommand::setPlus128(new_temp), 38); // set5
|
||||
break;
|
||||
case ClimateIds::CONF_CLIMATE_ZONE2:
|
||||
this->parent_->set_command_byte(PanasonicCommand::setPlus128(new_temp), 40); // set7
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
traits.set_supported_modes(this->supported_modes_);
|
||||
traits.set_visual_min_temperature(this->min_temperature_);
|
||||
traits.set_visual_max_temperature(this->max_temperature_);
|
||||
traits.set_visual_temperature_step(this->temperature_step_);
|
||||
if (call.get_target_temperature_low().has_value()) {
|
||||
float new_temp = *call.get_target_temperature_low();
|
||||
switch (this->id_) {
|
||||
case ClimateIds::CONF_CLIMATE_ZONE1:
|
||||
this->parent_->set_command_byte(PanasonicCommand::setPlus128(new_temp), 39); // set6
|
||||
break;
|
||||
case ClimateIds::CONF_CLIMATE_ZONE2:
|
||||
this->parent_->set_command_byte(PanasonicCommand::setPlus128(new_temp), 41); // set8
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
return traits;
|
||||
}
|
||||
this->publish_state();
|
||||
this->keep_state_ = 2;
|
||||
}
|
||||
|
||||
void PanasonicHeatpumpClimate::control(const climate::ClimateCall &call)
|
||||
{
|
||||
if (call.get_mode().has_value())
|
||||
{
|
||||
int byte6 = this->parent_->getResponseByte(6);
|
||||
if (byte6 >= 0)
|
||||
{
|
||||
climate::ClimateMode new_mode = *call.get_mode();
|
||||
uint8_t newByte6 = this->setClimateMode(new_mode, (uint8_t)byte6);
|
||||
this->parent_->set_command_byte(newByte6, 6);
|
||||
}
|
||||
}
|
||||
void PanasonicHeatpumpClimate::publish_new_state(const std::vector<uint8_t>& data) {
|
||||
if (this->keep_state_ > 0) {
|
||||
this->keep_state_--;
|
||||
return;
|
||||
}
|
||||
if (data.empty())
|
||||
return;
|
||||
|
||||
if (call.get_target_temperature().has_value())
|
||||
{
|
||||
float new_temp = *call.get_target_temperature();
|
||||
switch (this->id_)
|
||||
{
|
||||
case ClimateIds::CONF_CLIMATE_TANK:
|
||||
this->parent_->set_command_byte(PanasonicCommand::setPlus128(new_temp), 42); // set11
|
||||
break;
|
||||
case ClimateIds::CONF_CLIMATE_ZONE1:
|
||||
this->parent_->set_command_byte(PanasonicCommand::setPlus128(new_temp), 38); // set5
|
||||
break;
|
||||
case ClimateIds::CONF_CLIMATE_ZONE2:
|
||||
this->parent_->set_command_byte(PanasonicCommand::setPlus128(new_temp), 40); // set7
|
||||
break;
|
||||
};
|
||||
}
|
||||
uint8_t new_mode;
|
||||
float new_target_temp_heat;
|
||||
float new_target_temp_cool;
|
||||
float new_current_temp;
|
||||
|
||||
if (call.get_target_temperature_high().has_value())
|
||||
{
|
||||
float new_temp = *call.get_target_temperature_high();
|
||||
switch (this->id_)
|
||||
{
|
||||
case ClimateIds::CONF_CLIMATE_ZONE1:
|
||||
this->parent_->set_command_byte(PanasonicCommand::setPlus128(new_temp), 38); // set5
|
||||
break;
|
||||
case ClimateIds::CONF_CLIMATE_ZONE2:
|
||||
this->parent_->set_command_byte(PanasonicCommand::setPlus128(new_temp), 40); // set7
|
||||
break;
|
||||
};
|
||||
}
|
||||
new_mode = this->getClimateMode(data[6]); // set9
|
||||
switch (this->id_) {
|
||||
case ClimateIds::CONF_CLIMATE_TANK:
|
||||
new_target_temp_heat = PanasonicDecode::getByteMinus128(data[42]); // set11
|
||||
new_current_temp = PanasonicDecode::getByteMinus128(data[141]); // top10
|
||||
break;
|
||||
case ClimateIds::CONF_CLIMATE_ZONE1:
|
||||
new_target_temp_heat = PanasonicDecode::getByteMinus128(data[38]); // set5
|
||||
new_target_temp_cool = PanasonicDecode::getByteMinus128(data[39]); // set6
|
||||
new_current_temp = PanasonicDecode::getByteMinus128(data[139]); // top56
|
||||
break;
|
||||
case ClimateIds::CONF_CLIMATE_ZONE2:
|
||||
new_target_temp_heat = PanasonicDecode::getByteMinus128(data[40]); // set7
|
||||
new_target_temp_cool = PanasonicDecode::getByteMinus128(data[41]); // set8
|
||||
new_current_temp = PanasonicDecode::getByteMinus128(data[140]); // top57
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
};
|
||||
|
||||
if (call.get_target_temperature_low().has_value())
|
||||
{
|
||||
float new_temp = *call.get_target_temperature_low();
|
||||
switch (this->id_)
|
||||
{
|
||||
case ClimateIds::CONF_CLIMATE_ZONE1:
|
||||
this->parent_->set_command_byte(PanasonicCommand::setPlus128(new_temp), 39); // set6
|
||||
break;
|
||||
case ClimateIds::CONF_CLIMATE_ZONE2:
|
||||
this->parent_->set_command_byte(PanasonicCommand::setPlus128(new_temp), 41); // set8
|
||||
break;
|
||||
};
|
||||
}
|
||||
if (!this->get_traits().get_supports_two_point_target_temperature() && this->mode == new_mode &&
|
||||
this->target_temperature == new_target_temp_heat && this->current_temperature == new_current_temp)
|
||||
return;
|
||||
if (this->get_traits().get_supports_two_point_target_temperature() && this->mode == new_mode &&
|
||||
this->target_temperature_high == new_target_temp_heat && this->target_temperature_low == new_target_temp_cool &&
|
||||
this->current_temperature == new_current_temp)
|
||||
return;
|
||||
|
||||
this->publish_state();
|
||||
this->keep_state_ = 2;
|
||||
}
|
||||
if (new_mode != 255)
|
||||
this->mode = (climate::ClimateMode)new_mode;
|
||||
// this->action = climate::CLIMATE_ACTION_IDLE;
|
||||
if (this->get_traits().get_supports_two_point_target_temperature()) {
|
||||
this->target_temperature_high = new_target_temp_heat;
|
||||
this->target_temperature_low = new_target_temp_cool;
|
||||
} else {
|
||||
this->target_temperature = new_target_temp_heat;
|
||||
}
|
||||
this->current_temperature = new_current_temp;
|
||||
this->publish_state();
|
||||
}
|
||||
|
||||
void PanasonicHeatpumpClimate::publish_new_state(const std::vector<uint8_t>& data)
|
||||
{
|
||||
if (this->keep_state_ > 0)
|
||||
{
|
||||
this->keep_state_--;
|
||||
return;
|
||||
}
|
||||
if (data.empty()) return;
|
||||
uint8_t PanasonicHeatpumpClimate::getClimateMode(const uint8_t input) {
|
||||
switch (this->id_) {
|
||||
case ClimateIds::CONF_CLIMATE_TANK:
|
||||
switch ((uint8_t)(input & 0b110000)) {
|
||||
case 0b010000:
|
||||
return climate::CLIMATE_MODE_OFF;
|
||||
case 0b100000:
|
||||
return climate::CLIMATE_MODE_HEAT;
|
||||
default:
|
||||
return 255;
|
||||
};
|
||||
case ClimateIds::CONF_CLIMATE_ZONE1:
|
||||
case ClimateIds::CONF_CLIMATE_ZONE2:
|
||||
switch ((uint8_t)(input & 0b1111)) {
|
||||
case 0b0001:
|
||||
return climate::CLIMATE_MODE_OFF;
|
||||
case 0b0010:
|
||||
return climate::CLIMATE_MODE_HEAT;
|
||||
case 0b0011:
|
||||
return climate::CLIMATE_MODE_COOL;
|
||||
case 0b1000:
|
||||
return climate::CLIMATE_MODE_AUTO;
|
||||
case 0b1001:
|
||||
return climate::CLIMATE_MODE_AUTO; // 0x19 = auto-heat
|
||||
case 0b1010:
|
||||
return climate::CLIMATE_MODE_AUTO; // 0x1A = auto-cool
|
||||
default:
|
||||
return 255;
|
||||
};
|
||||
default:
|
||||
return 255;
|
||||
};
|
||||
}
|
||||
|
||||
uint8_t new_mode;
|
||||
float new_target_temp_heat;
|
||||
float new_target_temp_cool;
|
||||
float new_current_temp;
|
||||
|
||||
new_mode = this->getClimateMode(data[6]); // set9
|
||||
switch (this->id_)
|
||||
{
|
||||
case ClimateIds::CONF_CLIMATE_TANK:
|
||||
new_target_temp_heat = PanasonicDecode::getByteMinus128(data[42]); // set11
|
||||
new_current_temp = PanasonicDecode::getByteMinus128(data[141]); // top10
|
||||
break;
|
||||
case ClimateIds::CONF_CLIMATE_ZONE1:
|
||||
new_target_temp_heat = PanasonicDecode::getByteMinus128(data[38]); // set5
|
||||
new_target_temp_cool = PanasonicDecode::getByteMinus128(data[39]); // set6
|
||||
new_current_temp = PanasonicDecode::getByteMinus128(data[139]); // top56
|
||||
break;
|
||||
case ClimateIds::CONF_CLIMATE_ZONE2:
|
||||
new_target_temp_heat = PanasonicDecode::getByteMinus128(data[40]); // set7
|
||||
new_target_temp_cool = PanasonicDecode::getByteMinus128(data[41]); // set8
|
||||
new_current_temp = PanasonicDecode::getByteMinus128(data[140]); // top57
|
||||
break;
|
||||
default: return;
|
||||
};
|
||||
|
||||
if (!this->get_traits().get_supports_two_point_target_temperature() &&
|
||||
this->mode == new_mode &&
|
||||
this->target_temperature == new_target_temp_heat &&
|
||||
this->current_temperature == new_current_temp) return;
|
||||
if (this->get_traits().get_supports_two_point_target_temperature() &&
|
||||
this->mode == new_mode &&
|
||||
this->target_temperature_high == new_target_temp_heat &&
|
||||
this->target_temperature_low == new_target_temp_cool &&
|
||||
this->current_temperature == new_current_temp) return;
|
||||
|
||||
if (new_mode != 255) this->mode = (climate::ClimateMode)new_mode;
|
||||
//this->action = climate::CLIMATE_ACTION_IDLE;
|
||||
if (this->get_traits().get_supports_two_point_target_temperature())
|
||||
{
|
||||
this->target_temperature_high = new_target_temp_heat;
|
||||
this->target_temperature_low = new_target_temp_cool;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->target_temperature = new_target_temp_heat;
|
||||
}
|
||||
this->current_temperature = new_current_temp;
|
||||
this->publish_state();
|
||||
}
|
||||
|
||||
uint8_t PanasonicHeatpumpClimate::getClimateMode(const uint8_t input)
|
||||
{
|
||||
switch (this->id_)
|
||||
{
|
||||
case ClimateIds::CONF_CLIMATE_TANK:
|
||||
switch ((uint8_t)(input & 0b110000))
|
||||
{
|
||||
case 0b010000:
|
||||
return climate::CLIMATE_MODE_OFF;
|
||||
case 0b100000:
|
||||
return climate::CLIMATE_MODE_HEAT;
|
||||
default: return 255;
|
||||
};
|
||||
case ClimateIds::CONF_CLIMATE_ZONE1:
|
||||
case ClimateIds::CONF_CLIMATE_ZONE2:
|
||||
switch ((uint8_t)(input & 0b1111))
|
||||
{
|
||||
case 0b0001:
|
||||
return climate::CLIMATE_MODE_OFF;
|
||||
case 0b0010:
|
||||
return climate::CLIMATE_MODE_HEAT;
|
||||
case 0b0011:
|
||||
return climate::CLIMATE_MODE_COOL;
|
||||
case 0b1000:
|
||||
return climate::CLIMATE_MODE_AUTO;
|
||||
case 0b1001:
|
||||
return climate::CLIMATE_MODE_AUTO; // 0x19 = auto-heat
|
||||
case 0b1010:
|
||||
return climate::CLIMATE_MODE_AUTO; // 0x1A = auto-cool
|
||||
default: return 255;
|
||||
};
|
||||
default: return 255;
|
||||
};
|
||||
}
|
||||
|
||||
uint8_t PanasonicHeatpumpClimate::setClimateMode(const climate::ClimateMode mode, uint8_t byte)
|
||||
{
|
||||
uint8_t newByte = byte;
|
||||
switch (this->id_)
|
||||
{
|
||||
case ClimateIds::CONF_CLIMATE_TANK:
|
||||
newByte = newByte & 0b11001111;
|
||||
switch (mode)
|
||||
{
|
||||
case climate::CLIMATE_MODE_OFF:
|
||||
return newByte + 0b010000;
|
||||
case climate::CLIMATE_MODE_HEAT:
|
||||
return newByte + 0b100000;
|
||||
default: return 0;
|
||||
};
|
||||
case ClimateIds::CONF_CLIMATE_ZONE1:
|
||||
case ClimateIds::CONF_CLIMATE_ZONE2:
|
||||
newByte = newByte & 0b11110000;
|
||||
switch (mode)
|
||||
{
|
||||
case climate::CLIMATE_MODE_OFF:
|
||||
return newByte + 0b0001;
|
||||
case climate::CLIMATE_MODE_HEAT:
|
||||
return newByte + 0b0010;
|
||||
case climate::CLIMATE_MODE_COOL:
|
||||
return newByte + 0b0011;
|
||||
case climate::CLIMATE_MODE_AUTO:
|
||||
return newByte + 0b1000;
|
||||
default: return 0;
|
||||
};
|
||||
default: return 0;
|
||||
};
|
||||
}
|
||||
} // namespace panasonic_heatpump
|
||||
} // namespace esphome
|
||||
uint8_t PanasonicHeatpumpClimate::setClimateMode(const climate::ClimateMode mode, uint8_t byte) {
|
||||
uint8_t newByte = byte;
|
||||
switch (this->id_) {
|
||||
case ClimateIds::CONF_CLIMATE_TANK:
|
||||
newByte = newByte & 0b11001111;
|
||||
switch (mode) {
|
||||
case climate::CLIMATE_MODE_OFF:
|
||||
return newByte + 0b010000;
|
||||
case climate::CLIMATE_MODE_HEAT:
|
||||
return newByte + 0b100000;
|
||||
default:
|
||||
return 0;
|
||||
};
|
||||
case ClimateIds::CONF_CLIMATE_ZONE1:
|
||||
case ClimateIds::CONF_CLIMATE_ZONE2:
|
||||
newByte = newByte & 0b11110000;
|
||||
switch (mode) {
|
||||
case climate::CLIMATE_MODE_OFF:
|
||||
return newByte + 0b0001;
|
||||
case climate::CLIMATE_MODE_HEAT:
|
||||
return newByte + 0b0010;
|
||||
case climate::CLIMATE_MODE_COOL:
|
||||
return newByte + 0b0011;
|
||||
case climate::CLIMATE_MODE_AUTO:
|
||||
return newByte + 0b1000;
|
||||
default:
|
||||
return 0;
|
||||
};
|
||||
default:
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
} // namespace panasonic_heatpump
|
||||
} // namespace esphome
|
||||
|
||||
Reference in New Issue
Block a user