diff --git a/components/mitsubishi_heatpump/__init__.py b/components/mitsubishi_heatpump/__init__.py index b5f213d..c134dea 100644 --- a/components/mitsubishi_heatpump/__init__.py +++ b/components/mitsubishi_heatpump/__init__.py @@ -2,11 +2,23 @@ import esphome.codegen as cg import esphome.config_validation as cv from esphome.components import climate from esphome.components.logger import HARDWARE_UART_TO_SERIAL -from esphome.const import CONF_ID, CONF_HARDWARE_UART, CONF_UPDATE_INTERVAL +from esphome.const import ( + CONF_ID, + CONF_HARDWARE_UART, + CONF_UPDATE_INTERVAL, + CONF_MODE, + CONF_FAN_MODE, + CONF_SWING_MODE, +) from esphome.core import CORE, coroutine AUTO_LOAD = ["climate"] +CONF_SUPPORTS = "supports" +DEFAULT_CLIMATE_MODES = ['AUTO', 'COOL', 'HEAT', 'DRY', 'FAN_ONLY'] +DEFAULT_FAN_MODES = ['AUTO', 'DIFFUSE', 'LOW', 'MEDIUM', 'MIDDLE', 'HIGH'] +DEFAULT_SWING_MODES = ['OFF', 'VERTICAL'] + MitsubishiHeatPump = cg.global_ns.class_("MitsubishiHeatPump", climate.Climate, cg.PollingComponent) @@ -32,6 +44,18 @@ CONFIG_SCHEMA = climate.CLIMATE_SCHEMA.extend( cv.update_interval, cv.Range(max=cv.TimePeriod(milliseconds=9000)) ), + + # Optionally override the supported ClimateTraits. + cv.Optional(CONF_SUPPORTS, default={}): cv.Schema( + { + cv.Optional(CONF_MODE, default=DEFAULT_CLIMATE_MODES): + cv.ensure_list(climate.validate_climate_mode), + cv.Optional(CONF_FAN_MODE, default=DEFAULT_FAN_MODES): + cv.ensure_list(climate.validate_climate_fan_mode), + cv.Optional(CONF_SWING_MODE, default=DEFAULT_SWING_MODES): + cv.ensure_list(climate.validate_climate_swing_mode), + } + ), } ).extend(cv.COMPONENT_SCHEMA) @@ -40,6 +64,19 @@ CONFIG_SCHEMA = climate.CLIMATE_SCHEMA.extend( def to_code(config): serial = HARDWARE_UART_TO_SERIAL[config[CONF_HARDWARE_UART]] var = cg.new_Pvariable(config[CONF_ID], cg.RawExpression(f'&{serial}')) + + traits = [] + for mode in config[CONF_SUPPORTS][CONF_MODE]: + if mode == 'OFF': + continue + traits.append(f'set_supports_{mode.lower()}_mode') + for mode in config[CONF_SUPPORTS][CONF_FAN_MODE]: + traits.append(f'set_supports_fan_mode_{mode.lower()}') + for mode in config[CONF_SUPPORTS][CONF_SWING_MODE]: + traits.append(f'set_supports_swing_mode_{mode.lower()}') + for trait in traits: + cg.add(getattr(var.config_traits(), trait)(True)) + yield cg.register_component(var, config) yield climate.register_climate(var, config) cg.add_library("https://github.com/SwiCago/HeatPump", None) diff --git a/components/mitsubishi_heatpump/espmhp.cpp b/components/mitsubishi_heatpump/espmhp.cpp index d182fbe..3f00f2a 100644 --- a/components/mitsubishi_heatpump/espmhp.cpp +++ b/components/mitsubishi_heatpump/espmhp.cpp @@ -32,7 +32,15 @@ MitsubishiHeatPump::MitsubishiHeatPump( ) : PollingComponent{poll_interval}, // member initializers list hw_serial_{hw_serial} -{ } +{ + this->traits_.set_supports_action(true); + this->traits_.set_supports_current_temperature(true); + this->traits_.set_supports_two_point_target_temperature(false); + this->traits_.set_supports_away(false); + this->traits_.set_visual_min_temperature(ESPMHP_MIN_TEMPERATURE); + this->traits_.set_visual_max_temperature(ESPMHP_MAX_TEMPERATURE); + this->traits_.set_visual_temperature_step(ESPMHP_TEMPERATURE_STEP); +} void MitsubishiHeatPump::check_logger_conflict_() { #ifdef USE_LOGGER @@ -57,7 +65,7 @@ void MitsubishiHeatPump::update() { } /** - * Define our supported traits. + * Get our supported traits. * * Note: * Many of the following traits are only available in the 1.5.0 dev train of @@ -67,33 +75,17 @@ void MitsubishiHeatPump::update() { * This class' supported climate::ClimateTraits. */ climate::ClimateTraits MitsubishiHeatPump::traits() { - auto traits = climate::ClimateTraits(); - traits.set_supports_action(true); - traits.set_supports_current_temperature(true); - traits.set_supports_auto_mode(true); - traits.set_supports_cool_mode(true); - traits.set_supports_heat_mode(true); - traits.set_supports_dry_mode(true); - traits.set_supports_fan_only_mode(true); - traits.set_supports_two_point_target_temperature(false); - traits.set_supports_away(false); - traits.set_visual_min_temperature(ESPMHP_MIN_TEMPERATURE); - traits.set_visual_max_temperature(ESPMHP_MAX_TEMPERATURE); - traits.set_visual_temperature_step(ESPMHP_TEMPERATURE_STEP); - traits.set_supports_fan_mode_on(false); - traits.set_supports_fan_mode_off(false); - traits.set_supports_fan_mode_auto(true); - traits.set_supports_fan_mode_focus(false); - traits.set_supports_fan_mode_diffuse(true); - traits.set_supports_fan_mode_low(true); - traits.set_supports_fan_mode_medium(true); - traits.set_supports_fan_mode_middle(true); - traits.set_supports_fan_mode_high(true); - traits.set_supports_swing_mode_off(true); - traits.set_supports_swing_mode_both(false); - traits.set_supports_swing_mode_vertical(true); - traits.set_supports_swing_mode_horizontal(false); - return traits; + return traits_; +} + +/** + * Modify our supported traits. + * + * Returns: + * A reference to this class' supported climate::ClimateTraits. + */ +climate::ClimateTraits& MitsubishiHeatPump::config_traits() { + return traits_; } /** diff --git a/components/mitsubishi_heatpump/espmhp.h b/components/mitsubishi_heatpump/espmhp.h index ee431d3..b13097d 100644 --- a/components/mitsubishi_heatpump/espmhp.h +++ b/components/mitsubishi_heatpump/espmhp.h @@ -80,6 +80,9 @@ class MitsubishiHeatPump : public PollingComponent, public climate::Climate { // Configure the climate object with traits that we support. climate::ClimateTraits traits() override; + // Get a mutable reference to the traits that we support. + climate::ClimateTraits& config_traits(); + // Debugging function to print the object's state. void dump_state(); @@ -90,6 +93,9 @@ class MitsubishiHeatPump : public PollingComponent, public climate::Climate { // HeatPump object using the underlying Arduino library. HeatPump* hp; + // The ClimateTraits supported by this HeatPump. + climate::ClimateTraits traits_; + // Allow the HeatPump class to use get_hw_serial_ friend class HeatPump;