Added options "min_temperature", "max_temperature" and "temperature_step" to the climate component.

Added option "min_value", "max_value" and "step" to the number component.
Added option "cool_mode" to select and climate component and removed it from panasonic_heatpump component.
Removed function "set_traits", because the user can now set its own limits in yaml.
This commit is contained in:
ElVit 2025-06-24 14:10:53 +02:00
parent 472d36bf72
commit 18b8ed0f4a
17 changed files with 188 additions and 204 deletions

View File

@ -77,21 +77,34 @@ text_sensor:
- platform: panasonic_heatpump
top4:
name: "Operating Mode State"
number:
- platform: panasonic_heatpump
set5:
name: "Set Z1 Heat Request Temperature"
min_value: -5.0
max_value: 5.0
step: 1.0
select:
- platform: panasonic_heatpump
cool_mode: true
set2:
name: "Set Holiday Mode"
switch:
- platform: panasonic_heatpump
set1:
name: "Set Heatpump"
- platform: panasonic_heatpump
set1:
name: "Set Heatpump"
climate:
- platform: panasonic_heatpump
cool_mode: true
tank:
name: "DHW"
min_temperature: -5.0
max_temperature: 5.0
temperature_step: 0.5
```
## Configuration variables
@ -413,6 +426,8 @@ text_sensor:
### Numbers
All numbers are optional and all default number variables can be applied.
Additionally the options `min_value`, `max_value` and `step` can override the default limits of each set entitiy.
This is usefull for example for `set5` to `set8` if `direct temperature` is configured instead of `compensation curve` (see `top76` and `top81`).
Here a list of all supported numbers:
```yaml
@ -525,11 +540,14 @@ switch:
### Selects
All selects are optional and all default select variables can be applied.
Additionally the option `cool_mode` can be configured.
If `cool_mode` is set to `true` the entity `set9` will have the additional select options `COOL`, `COOL+TANK`, `AUTO` and `AUTO+TANK`.
Here a list of all supported selects:
```yaml
select:
- platform: panasonic_heatpump
cool_mode: false
set2:
name: "Set Holiday Mode"
set3:
@ -546,6 +564,27 @@ select:
name: "Set Bivalent Mode"
```
### Climates
All climates are optional and all default climate variables can be applied.
Additionally the option `cool_mode` can be configured.
If `cool_mode` is set to `true` the entity `zone1` and `zone2` will have the additional climate modes `COOL` and `AUTO`.
Additionally the options `min_temperature`, `max_temperature` and `temperature_step` can override the default limits on each climate entitiy.
This is usefull for example for `zone1` and `zone2` if `direct temperature` is configured instead of `compensation curve` (see `top76` and `top81`).
Here a list of all supported climates:
```yaml
climate:
- platform: panasonic_heatpump
cool_mode: false
tank:
name: "DHW"
zone1:
name: "Zone 1"
zone2:
name: "Zone 2"
```
## Custom Entities (For Advanced Users)
If you review the [ProtocolByteDecrypt.md](https://github.com/Egyras/HeishaMon/blob/master/ProtocolByteDecrypt.md) file you will find also some TOPs and SETs which are not implemented yet in heishamon.

View File

@ -11,7 +11,6 @@ DEPENDENCIES = ['uart']
CONF_PANASONIC_HEATPUMP_ID = "panasonic_heatpump"
CONF_UART_CLIENT = "uart_client_id"
CONF_LOG_UART_MSG = "log_uart_msg"
CONF_COOL_MODE = "cool_mode"
panasonic_heatpump_ns = cg.esphome_ns.namespace('panasonic_heatpump')
@ -24,7 +23,6 @@ CONFIG_SCHEMA = (
cv.Optional(CONF_UART_CLIENT): cv.use_id(uart.UARTComponent),
cv.Optional(CONF_LOG_UART_MSG, default=False): cv.boolean,
cv.Optional(CONF_COOL_MODE, default=False): cv.boolean,
}
)
.extend(cv.polling_component_schema("3s"))
@ -41,4 +39,3 @@ async def to_code(config):
cg.add(var.set_uart_client(uart_client))
cg.add(var.set_log_uart_msg(config[CONF_LOG_UART_MSG]))
cg.add(var.set_cool_mode(config[CONF_COOL_MODE]))

View File

@ -28,30 +28,37 @@ TYPES = [
CONF_CLIMATE_ZONE2,
]
def climate_options(min_temp, max_temp, temp_step) -> cv.Schema:
schema = cv.Schema({
cv.Optional(CONF_MIN_TEMPERATURE, default=min_temp): cv.float_,
cv.Optional(CONF_MAX_TEMPERATURE, default=max_temp): cv.float_,
cv.Optional(CONF_TEMPERATURE_STEP, default=temp_step): cv.float_,
})
return schema
PanasonicHeatpumpClimate = panasonic_heatpump_ns.class_("PanasonicHeatpumpClimate", climate.Climate, cg.Component)
CONFIG_SCHEMA = cv.Schema(
{
cv.GenerateID(CONF_PANASONIC_HEATPUMP_ID): cv.use_id(PanasonicHeatpumpComponent),
cv.GenerateID(CONF_PANASONIC_HEATPUMP_ID): cv.use_id(
PanasonicHeatpumpComponent
),
cv.Optional(CONF_COOL_MODE, default=False): cv.boolean,
cv.Optional(CONF_CLIMATE_TANK): climate.climate_schema(PanasonicHeatpumpClimate)
.extend({
cv.Optional(CONF_MIN_TEMPERATURE, default=20.0): cv.float_range(min=-5.0, max=20.0),
cv.Optional(CONF_MAX_TEMPERATURE, default=65.0): cv.float_range(min=5.0, max=75.0),
}
cv.Optional(CONF_CLIMATE_TANK): climate.climate_schema(
PanasonicHeatpumpClimate
).extend(
climate_options(20.0, 65.0, 0.5)
),
cv.Optional(CONF_CLIMATE_ZONE1): climate.climate_schema(PanasonicHeatpumpClimate)
.extend({
cv.Optional(CONF_MIN_TEMPERATURE, default=-5.0): cv.float_range(min=-5.0, max=20.0),
cv.Optional(CONF_MAX_TEMPERATURE, default=5.0): cv.float_range(min=5.0, max=75.0),
}
cv.Optional(CONF_CLIMATE_ZONE1): climate.climate_schema(
PanasonicHeatpumpClimate
).extend(
climate_options(-5.0, 5.0, 0.5)
),
cv.Optional(CONF_CLIMATE_ZONE2): climate.climate_schema(PanasonicHeatpumpClimate)
.extend({
cv.Optional(CONF_MIN_TEMPERATURE, default=-5.0): cv.float_range(min=-5.0, max=20.0),
cv.Optional(CONF_MAX_TEMPERATURE, default=5.0): cv.float_range(min=5.0, max=75.0),
}
cv.Optional(CONF_CLIMATE_ZONE2): climate.climate_schema(
PanasonicHeatpumpClimate
).extend(
climate_options(-5.0, 5.0, 0.5)
),
}
).extend(cv.COMPONENT_SCHEMA)
@ -66,5 +73,6 @@ async def to_code(config):
cg.add(var.set_id(index))
cg.add(var.set_min_temperature(child_config[CONF_MIN_TEMPERATURE]))
cg.add(var.set_max_temperature(child_config[CONF_MAX_TEMPERATURE]))
cg.add(var.set_temperature_step(child_config[CONF_TEMPERATURE_STEP]))
cg.add(var.set_cool_mode(config[CONF_COOL_MODE]))
cg.add(parent.add_climate(var))

View File

@ -19,7 +19,9 @@ namespace esphome
//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))
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);
@ -106,25 +108,25 @@ namespace esphome
if (data.empty()) return;
uint8_t new_mode;
float new_target_temp_high;
float new_target_temp_low;
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_high = PanasonicDecode::getByteMinus128(data[42]); // set11
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_high = PanasonicDecode::getByteMinus128(data[38]); // set5
new_target_temp_low = PanasonicDecode::getByteMinus128(data[39]); // set6
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_high = PanasonicDecode::getByteMinus128(data[40]); // set7
new_target_temp_low = PanasonicDecode::getByteMinus128(data[41]); // set8
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;
@ -132,24 +134,24 @@ namespace esphome
if (!this->get_traits().get_supports_two_point_target_temperature() &&
this->mode == new_mode &&
this->target_temperature == new_target_temp_high &&
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_high &&
this->target_temperature_low == new_target_temp_low &&
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;
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_high;
this->target_temperature_low = new_target_temp_low;
this->target_temperature_high = new_target_temp_heat;
this->target_temperature_low = new_target_temp_cool;
}
else
{
this->target_temperature = new_target_temp_high;
this->target_temperature = new_target_temp_heat;
}
this->current_temperature = new_current_temp;
this->publish_state();

View File

@ -29,6 +29,7 @@ namespace esphome
void set_cool_mode(bool value) { this->cool_mode_ = value; }
void set_min_temperature(float value) { this->min_temperature_ = value; }
void set_max_temperature(float value) { this->max_temperature_ = value; }
void set_temperature_step(float value) { this->temperature_step_ = value; }
protected:
void control(const climate::ClimateCall &call) override;

View File

@ -269,7 +269,7 @@ namespace esphome
if ((index < 0) || (index >= size))
{
return "UNKNOWN";
return "UNDEFINED";
}
return array[index + 1];

View File

@ -6,6 +6,9 @@ from esphome.const import (
UNIT_KELVIN,
UNIT_MINUTE,
ENTITY_CATEGORY_CONFIG,
CONF_MIN_VALUE,
CONF_MAX_VALUE,
CONF_STEP,
)
from .. import CONF_PANASONIC_HEATPUMP_ID, PanasonicHeatpumpComponent, panasonic_heatpump_ns
@ -80,195 +83,234 @@ TYPES = [
CONF_SET38,
]
# min_value, max_value, step
CONF_NUMBERS = [
[ 0, 0, 1, ],
[ 0, 0, 1, ],
[ 0, 0, 1, ],
[ 0, 0, 1, ],
[ 40, 75, 1, ],
[ 64, 254, 1, ],
[ -15, 35, 1, ],
[ -15, 35, 1, ],
[ -15, 35, 1, ],
[ -15, 35, 1, ],
[ -15, 35, 1, ],
[ -15, 35, 1, ],
[ -15, 35, 1, ],
[ -15, 35, 1, ],
[ -15, 35, 1, ],
[ -15, 35, 1, ],
[ -15, 35, 1, ],
[ -15, 35, 1, ],
[ -15, 35, 1, ],
[ -15, 35, 1, ],
[ -15, 35, 1, ],
[ -15, 35, 1, ],
[ 1, 15, 1, ],
[ 1, 15, 1, ],
[ -12, -2, 1, ],
[ 0, 250, 1, ],
[ 1, 15, 1, ],
[ 1, 15, 1, ],
[ 0, 10, 1, ],
[ 5, 35, 1, ],
[ -15, 35, 1, ],
[ -10, 0, 1, ],
[ -10, 0, 1, ],
]
def number_options(min_val, max_val, step) -> cv.Schema:
schema = cv.Schema({
cv.Optional(CONF_MIN_VALUE, default=min_val): cv.float_,
cv.Optional(CONF_MAX_VALUE, default=max_val): cv.float_,
cv.Optional(CONF_STEP, default=step): cv.float_range(min=1.0, max=10.0),
})
return schema
PanasonicHeatpumpNumber = panasonic_heatpump_ns.class_("PanasonicHeatpumpNumber", number.Number, cg.Component)
CONFIG_SCHEMA = cv.Schema(
{
cv.GenerateID(CONF_PANASONIC_HEATPUMP_ID): cv.use_id(PanasonicHeatpumpComponent),
cv.GenerateID(CONF_PANASONIC_HEATPUMP_ID): cv.use_id(
PanasonicHeatpumpComponent
),
cv.Optional(CONF_SET5): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
).extend(
number_options(-5.0, 5.0, 1.0)
),
cv.Optional(CONF_SET6): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
).extend(
number_options(-5.0, 5.0, 1.0)
),
cv.Optional(CONF_SET7): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
).extend(
number_options(-5.0, 5.0, 1.0)
),
cv.Optional(CONF_SET8): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
).extend(
number_options(-5.0, 5.0, 1.0)
),
cv.Optional(CONF_SET11): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
).extend(
number_options(40.0, 75.0, 1.0)
),
cv.Optional(CONF_SET15): number.number_schema(
PanasonicHeatpumpNumber,
).extend(
number_options(64.0, 254.0, 1.0)
),
cv.Optional(CONF_SET16_01): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
entity_category=ENTITY_CATEGORY_CONFIG,
).extend(
number_options(20.0, 60.0, 1.0)
),
cv.Optional(CONF_SET16_02): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
entity_category=ENTITY_CATEGORY_CONFIG,
).extend(
number_options(20.0, 60.0, 1.0)
),
cv.Optional(CONF_SET16_03): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
entity_category=ENTITY_CATEGORY_CONFIG,
).extend(
number_options(-20.0, 15.0, 1.0)
),
cv.Optional(CONF_SET16_04): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
entity_category=ENTITY_CATEGORY_CONFIG,
).extend(
number_options(-20.0, 15.0, 1.0)
),
cv.Optional(CONF_SET16_05): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
entity_category=ENTITY_CATEGORY_CONFIG,
).extend(
number_options(20.0, 60.0, 1.0)
),
cv.Optional(CONF_SET16_06): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
entity_category=ENTITY_CATEGORY_CONFIG,
).extend(
number_options(20.0, 60.0, 1.0)
),
cv.Optional(CONF_SET16_07): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
entity_category=ENTITY_CATEGORY_CONFIG,
).extend(
number_options(-20.0, 15.0, 1.0)
),
cv.Optional(CONF_SET16_08): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
entity_category=ENTITY_CATEGORY_CONFIG,
).extend(
number_options(-20.0, 15.0, 1.0)
),
cv.Optional(CONF_SET16_09): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
entity_category=ENTITY_CATEGORY_CONFIG,
).extend(
number_options(5.0, 20.0, 1.0)
),
cv.Optional(CONF_SET16_10): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
entity_category=ENTITY_CATEGORY_CONFIG,
).extend(
number_options(5.0, 20.0, 1.0)
),
cv.Optional(CONF_SET16_11): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
entity_category=ENTITY_CATEGORY_CONFIG,
).extend(
number_options(15.0, 30.0, 1.0)
),
cv.Optional(CONF_SET16_12): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
entity_category=ENTITY_CATEGORY_CONFIG,
).extend(
number_options(15.0, 30.0, 1.0)
),
cv.Optional(CONF_SET16_13): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
entity_category=ENTITY_CATEGORY_CONFIG,
).extend(
number_options(5.0, 20.0, 1.0)
),
cv.Optional(CONF_SET16_14): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
entity_category=ENTITY_CATEGORY_CONFIG,
).extend(
number_options(5.0, 20.0, 1.0)
),
cv.Optional(CONF_SET16_15): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
entity_category=ENTITY_CATEGORY_CONFIG,
).extend(
number_options(15.0, 30.0, 1.0)
),
cv.Optional(CONF_SET16_16): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
entity_category=ENTITY_CATEGORY_CONFIG,
).extend(
number_options(15.0, 30.0, 1.0)
),
cv.Optional(CONF_SET18): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_KELVIN,
).extend(
number_options(1.0, 15.0, 1.0)
),
cv.Optional(CONF_SET19): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_KELVIN,
).extend(
number_options(1.0, 15.0, 1.0)
),
cv.Optional(CONF_SET20): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_KELVIN,
).extend(
number_options(112.0, -2.0, 1.0)
),
cv.Optional(CONF_SET21): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_MINUTE,
).extend(
number_options(0.0, 250.0, 1.0)
),
cv.Optional(CONF_SET22): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_KELVIN,
).extend(
number_options(1.0, 15.0, 1.0)
),
cv.Optional(CONF_SET23): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_KELVIN,
).extend(
number_options(1.0, 15.0, 1.0)
),
cv.Optional(CONF_SET27): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_KELVIN,
).extend(
number_options(0.0, 10.0, 1.0)
),
cv.Optional(CONF_SET29): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
).extend(
number_options(5.0, 35.0, 1.0)
),
cv.Optional(CONF_SET36): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
).extend(
number_options(-15.0, 35.0, 1.0)
),
cv.Optional(CONF_SET37): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
).extend(
number_options(-10.0, 0.0, 1.0)
),
cv.Optional(CONF_SET38): number.number_schema(
PanasonicHeatpumpNumber,
unit_of_measurement=UNIT_CELSIUS,
).extend(
number_options(-10.0, 0.0, 1.0)
),
}
).extend(cv.COMPONENT_SCHEMA)
@ -279,9 +321,9 @@ async def to_code(config):
if child_config := config.get(key):
var = await number.new_number(
child_config,
min_value=CONF_NUMBERS[index][0],
max_value=CONF_NUMBERS[index][1],
step=CONF_NUMBERS[index][2]
min_value=child_config[CONF_MIN_VALUE],
max_value=child_config[CONF_MAX_VALUE],
step=child_config[CONF_STEP],
)
await cg.register_component(var, child_config)
cg.add(var.set_parent(parent))

View File

@ -403,46 +403,5 @@ namespace esphome
this->publish_state(new_state);
}
bool PanasonicHeatpumpNumber::set_traits(std::map<std::string, int>& traits_settings)
{
if (traits_settings.empty()) return false;
switch (this->id_)
{
case NumberIds::CONF_SET5: // Set Z1 Heat Request Temperature
case NumberIds::CONF_SET7: // Set Z2 Heat Request Temperature
if (this->traits.get_min_value() != -5.0 && traits_settings["heating_mode"] == 0)
{
this->traits.set_min_value(-5.0);
this->traits.set_max_value(5.0);
return true;
}
if (this->traits.get_min_value() != 20.0 && traits_settings["heating_mode"] == 1)
{
this->traits.set_min_value(20.0);
this->traits.set_max_value(60.0);
return true;
}
break;
case NumberIds::CONF_SET6: // Set Z1 Cool Request Temperature
case NumberIds::CONF_SET8: // Set Z2 Cool Request Temperature
if (this->traits.get_min_value() != -5.0 && traits_settings["cooling_mode"] == 0)
{
this->traits.set_min_value(-5.0);
this->traits.set_max_value(5.0);
return true;
}
if (this->traits.get_min_value() != 20.0 && traits_settings["cooling_mode"] == 1)
{
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

@ -54,7 +54,6 @@ namespace esphome
PanasonicHeatpumpNumber() = default;
void dump_config() override;
void publish_new_state(const std::vector<uint8_t>& data) override;
bool set_traits(std::map<std::string, int>& traits_settings) override;
protected:
void control(float value) override;

View File

@ -43,28 +43,7 @@ namespace esphome
{
bool result = this->check_response(this->heatpump_message_);
this->loop_state_ = result ?
LoopState::SET_NUMBER_TRAITS : LoopState::SEND_REQUEST;
break;
}
// 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.
case LoopState::SET_NUMBER_TRAITS:
{
for (auto *entity : this->numbers_)
{
this->traits_changed_ = entity->set_traits(this->traits_settings_) ? true : this->traits_changed_;
}
this->loop_state_ = LoopState::SET_SELECT_TRAITS;
break;
}
case LoopState::SET_SELECT_TRAITS:
{
for (auto *entity : this->selects_)
{
this->traits_changed_ = entity->set_traits(this->traits_settings_) ? true : this->traits_changed_;
}
this->loop_state_ = LoopState::PUBLISH_SENSOR;
LoopState::PUBLISH_SENSOR : LoopState::SEND_REQUEST;
break;
}
case LoopState::PUBLISH_SENSOR:
@ -144,19 +123,6 @@ namespace esphome
}
default:
{
if (this->traits_changed_) this->traits_update_counter_++;
// 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 initial traits value is 0 or an empty vector.
if (this->traits_update_counter_ > 1)
{
ESP_LOGW(TAG, "Limit values have changed. Rebooting so Home Assistant can reconfigures the entity limits.");
delay(100); // NOLINT
App.safe_reboot();
}
this->traits_changed_ = false;
this->loop_state_ = LoopState::READ_RESPONSE;
break;
}
@ -331,11 +297,6 @@ namespace esphome
if (this->last_response_count_ == this->current_response_count_) return false;
this->last_response_count_ = this->current_response_count_;
// Save some topic values that are needed for setting traits
traits_settings_["heating_mode"] = PanasonicDecode::getBit7and8(data[28]); // top76
traits_settings_["cooling_mode"] = PanasonicDecode::getBit5and6(data[28]); // top81
traits_settings_["cool_mode_configured"] = this->cool_mode_;
return true;
}

View File

@ -20,8 +20,6 @@ namespace esphome
{
READ_RESPONSE,
CHECK_RESPONSE,
SET_NUMBER_TRAITS,
SET_SELECT_TRAITS,
PUBLISH_SENSOR,
PUBLISH_BINARY_SENSOR,
PUBLISH_TEXT_SENSOR,
@ -47,7 +45,6 @@ namespace esphome
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(std::map<std::string, int>& traits_settings) { return false; }
protected:
int id_ { -1 };
@ -57,8 +54,6 @@ namespace esphome
class PanasonicHeatpumpComponent : public PollingComponent, public uart::UARTDevice
{
public:
bool traits_changed_ { false };
PanasonicHeatpumpComponent() = default;
// base class functions
float get_setup_priority() const override { return setup_priority::DATA; }
@ -69,7 +64,6 @@ namespace esphome
// option functions
void set_uart_client(uart::UARTComponent* uart) { this->uart_client_ = uart; }
void set_log_uart_msg(bool active) { this->log_uart_msg_ = active; }
void set_cool_mode(bool active) { this->cool_mode_ = active; }
// uart message variables to use in lambda functions
int getResponseByte(const int index);
// command functions
@ -90,13 +84,11 @@ namespace esphome
// options variables
uart::UARTComponent* uart_client_ { nullptr };
bool log_uart_msg_ { false };
bool cool_mode_ { false };
// uart message variables
std::vector<uint8_t> heatpump_message_;
std::vector<uint8_t> response_message_;
std::vector<uint8_t> request_message_;
std::vector<uint8_t> command_message_;
std::map<std::string, int> traits_settings_;
uint8_t payload_length_;
uint8_t byte_;
uint8_t current_response_count_ { 0 };
@ -105,7 +97,6 @@ namespace esphome
bool request_receiving_ { false };
RequestType next_request_ { RequestType::INITIAL };
LoopState loop_state_ { LoopState::RESTART_LOOP };
uint8_t traits_update_counter_ { 0 };
// entity vectors
std::vector<PanasonicHeatpumpEntity *> binary_sensors_;
std::vector<PanasonicHeatpumpEntity *> climates_;

View File

@ -7,6 +7,7 @@ from esphome.const import (
from .. import CONF_PANASONIC_HEATPUMP_ID, PanasonicHeatpumpComponent, panasonic_heatpump_ns
CONF_COOL_MODE = "cool_mode"
CONF_SET2 = "set2" # Set Holiday Mode
CONF_SET3 = "set3" # Set Quiet Mode
CONF_SET4 = "set4" # Set Powerful Mode
@ -30,17 +31,21 @@ CONF_SELECTS = [
[ "Off", "Scheduled", "Active", ],
[ "Off", "Level 1", "Level 2", "Level 3", ],
[ "Off", "30min", "60min", "90min", ],
[ ],
[ "TANK", "HEAT", "HEAT+TANK", ],
[ "Zone 1", "Zone 2", "Zone 1 & 2", ],
[ "Disabled", "Type-A", "Type-B" ],
[ "Alternative", "Parallel", "Advanced Parallel" ],
]
CONF_SELECT_COOL_MODE = [ "TANK", "HEAT", "HEAT+TANK", "COOL", "COOL+TANK", "AUTO", "AUTO+TANK", ]
PanasonicHeatpumpSelect = panasonic_heatpump_ns.class_("PanasonicHeatpumpSelect", select.Select, cg.Component)
CONFIG_SCHEMA = cv.Schema(
{
cv.GenerateID(CONF_PANASONIC_HEATPUMP_ID): cv.use_id(PanasonicHeatpumpComponent),
cv.GenerateID(CONF_PANASONIC_HEATPUMP_ID): cv.use_id(
PanasonicHeatpumpComponent
),
cv.Optional(CONF_COOL_MODE, default=False): cv.boolean,
cv.Optional(CONF_SET2): select.select_schema(
PanasonicHeatpumpSelect,
@ -70,7 +75,9 @@ async def to_code(config):
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])
child_options = CONF_SELECT_COOL_MODE if config[CONF_COOL_MODE] and key == CONF_SET9 else CONF_SELECTS[index]
var = await select.new_select(child_config, options=child_options)
await cg.register_component(var, child_config)
cg.add(var.set_parent(parent))
cg.add(var.set_id(index))

View File

@ -121,32 +121,5 @@ namespace esphome
this->publish_state(new_state);
}
bool PanasonicHeatpumpSelect::set_traits(std::map<std::string, int>& traits_settings)
{
if (traits_settings.empty()) return false;
switch (this->id_)
{
case SelectIds::CONF_SET9:
{
if (this->traits.get_options().size() != 3 && traits_settings["cool_mode_configured"] == 0)
{
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() != 7 && traits_settings["cool_mode_configured"] == 1)
{
auto options = std::vector<std::string>(PanasonicDecode::OperationMode + 1, PanasonicDecode::OperationMode + 8);
this->traits.set_options(options);
return true;
}
break;
}
};
return false;
}
} // namespace panasonic_heatpump
} // namespace esphome

View File

@ -28,7 +28,6 @@ namespace esphome
PanasonicHeatpumpSelect() = default;
void dump_config() override;
void publish_new_state(const std::vector<uint8_t>& data) override;
bool set_traits(std::map<std::string, int>& traits_settings) override;
protected:
void control(const std::string &value) override;

View File

@ -230,7 +230,9 @@ PanasonicHeatpumpSensor = panasonic_heatpump_ns.class_("PanasonicHeatpumpSensor"
CONFIG_SCHEMA = cv.Schema(
{
cv.GenerateID(CONF_PANASONIC_HEATPUMP_ID): cv.use_id(PanasonicHeatpumpComponent),
cv.GenerateID(CONF_PANASONIC_HEATPUMP_ID): cv.use_id(
PanasonicHeatpumpComponent
),
cv.Optional(CONF_TOP1): sensor.sensor_schema(
PanasonicHeatpumpSensor,

View File

@ -40,7 +40,9 @@ PanasonicHeatpumpSwitch = panasonic_heatpump_ns.class_("PanasonicHeatpumpSwitch"
CONFIG_SCHEMA = cv.Schema(
{
cv.GenerateID(CONF_PANASONIC_HEATPUMP_ID): cv.use_id(PanasonicHeatpumpComponent),
cv.GenerateID(CONF_PANASONIC_HEATPUMP_ID): cv.use_id(
PanasonicHeatpumpComponent
),
cv.Optional(CONF_SET1): switch.switch_schema(
PanasonicHeatpumpSwitch,

View File

@ -75,7 +75,9 @@ PanasonicHeatpumpTextSensor = panasonic_heatpump_ns.class_("PanasonicHeatpumpTex
CONFIG_SCHEMA = cv.Schema(
{
cv.GenerateID(CONF_PANASONIC_HEATPUMP_ID): cv.use_id(PanasonicHeatpumpComponent),
cv.GenerateID(CONF_PANASONIC_HEATPUMP_ID): cv.use_id(
PanasonicHeatpumpComponent
),
cv.Optional(CONF_TOP4): text_sensor.text_sensor_schema(
PanasonicHeatpumpTextSensor,