mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 06:33:51 +00:00 
			
		
		
		
	Added heatpumpir support (#1343)
Co-authored-by: Otto winter <otto@otto-winter.com> Co-authored-by: Oxan van Leeuwen <oxan@oxanvanleeuwen.nl>
This commit is contained in:
		| @@ -64,6 +64,7 @@ esphome/components/graph/* @synco | ||||
| esphome/components/havells_solar/* @sourabhjaiswal | ||||
| esphome/components/hbridge/fan/* @WeekendWarrior | ||||
| esphome/components/hbridge/light/* @DotNetDann | ||||
| esphome/components/heatpumpir/* @rob-deutsch | ||||
| esphome/components/hitachi_ac424/* @sourabhjaiswal | ||||
| esphome/components/homeassistant/* @OttoWinter | ||||
| esphome/components/hrxl_maxsonar_wr/* @netmikey | ||||
|   | ||||
							
								
								
									
										0
									
								
								esphome/components/heatpumpir/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								esphome/components/heatpumpir/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										114
									
								
								esphome/components/heatpumpir/climate.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								esphome/components/heatpumpir/climate.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,114 @@ | ||||
| import esphome.codegen as cg | ||||
| import esphome.config_validation as cv | ||||
| from esphome.components import climate_ir | ||||
| from esphome.const import ( | ||||
|     CONF_ID, | ||||
|     CONF_MAX_TEMPERATURE, | ||||
|     CONF_MIN_TEMPERATURE, | ||||
|     CONF_PROTOCOL, | ||||
|     CONF_VISUAL, | ||||
| ) | ||||
|  | ||||
| CODEOWNERS = ["@rob-deutsch"] | ||||
|  | ||||
| AUTO_LOAD = ["climate_ir"] | ||||
|  | ||||
| heatpumpir_ns = cg.esphome_ns.namespace("heatpumpir") | ||||
| HeatpumpIRClimate = heatpumpir_ns.class_("HeatpumpIRClimate", climate_ir.ClimateIR) | ||||
|  | ||||
| Protocol = heatpumpir_ns.enum("Protocol") | ||||
| PROTOCOLS = { | ||||
|     "aux": Protocol.PROTOCOL_AUX, | ||||
|     "ballu": Protocol.PROTOCOL_BALLU, | ||||
|     "carrier_mca": Protocol.PROTOCOL_CARRIER_MCA, | ||||
|     "carrier_nqv": Protocol.PROTOCOL_CARRIER_NQV, | ||||
|     "daikin_arc417": Protocol.PROTOCOL_DAIKIN_ARC417, | ||||
|     "daikin_arc480": Protocol.PROTOCOL_DAIKIN_ARC480, | ||||
|     "daikin": Protocol.PROTOCOL_DAIKIN, | ||||
|     "fuego": Protocol.PROTOCOL_FUEGO, | ||||
|     "fujitsu_awyz": Protocol.PROTOCOL_FUJITSU_AWYZ, | ||||
|     "gree": Protocol.PROTOCOL_GREE, | ||||
|     "greeya": Protocol.PROTOCOL_GREEYAA, | ||||
|     "greeyan": Protocol.PROTOCOL_GREEYAN, | ||||
|     "hisense_aud": Protocol.PROTOCOL_HISENSE_AUD, | ||||
|     "hitachi": Protocol.PROTOCOL_HITACHI, | ||||
|     "hyundai": Protocol.PROTOCOL_HYUNDAI, | ||||
|     "ivt": Protocol.PROTOCOL_IVT, | ||||
|     "midea": Protocol.PROTOCOL_MIDEA, | ||||
|     "mitsubishi_fa": Protocol.PROTOCOL_MITSUBISHI_FA, | ||||
|     "mitsubishi_fd": Protocol.PROTOCOL_MITSUBISHI_FD, | ||||
|     "mitsubishi_fe": Protocol.PROTOCOL_MITSUBISHI_FE, | ||||
|     "mitsubishi_heavy_fdtc": Protocol.PROTOCOL_MITSUBISHI_HEAVY_FDTC, | ||||
|     "mitsubishi_heavy_zj": Protocol.PROTOCOL_MITSUBISHI_HEAVY_ZJ, | ||||
|     "mitsubishi_heavy_zm": Protocol.PROTOCOL_MITSUBISHI_HEAVY_ZM, | ||||
|     "mitsubishi_heavy_zmp": Protocol.PROTOCOL_MITSUBISHI_HEAVY_ZMP, | ||||
|     "mitsubishi_heavy_kj": Protocol.PROTOCOL_MITSUBISHI_KJ, | ||||
|     "mitsubishi_msc": Protocol.PROTOCOL_MITSUBISHI_MSC, | ||||
|     "mitsubishi_msy": Protocol.PROTOCOL_MITSUBISHI_MSY, | ||||
|     "mitsubishi_sez": Protocol.PROTOCOL_MITSUBISHI_SEZ, | ||||
|     "panasonic_ckp": Protocol.PROTOCOL_PANASONIC_CKP, | ||||
|     "panasonic_dke": Protocol.PROTOCOL_PANASONIC_DKE, | ||||
|     "panasonic_jke": Protocol.PROTOCOL_PANASONIC_JKE, | ||||
|     "panasonic_lke": Protocol.PROTOCOL_PANASONIC_LKE, | ||||
|     "panasonic_nke": Protocol.PROTOCOL_PANASONIC_NKE, | ||||
|     "samsung_aqv": Protocol.PROTOCOL_SAMSUNG_AQV, | ||||
|     "samsung_fjm": Protocol.PROTOCOL_SAMSUNG_FJM, | ||||
|     "sharp": Protocol.PROTOCOL_SHARP, | ||||
|     "toshiba_daiseikai": Protocol.PROTOCOL_TOSHIBA_DAISEIKAI, | ||||
|     "toshiba": Protocol.PROTOCOL_TOSHIBA, | ||||
| } | ||||
|  | ||||
| CONF_HORIZONTAL_DEFAULT = "horizontal_default" | ||||
| HorizontalDirections = heatpumpir_ns.enum("HorizontalDirections") | ||||
| HORIZONTAL_DIRECTIONS = { | ||||
|     "auto": HorizontalDirections.HORIZONTAL_DIRECTION_AUTO, | ||||
|     "middle": HorizontalDirections.HORIZONTAL_DIRECTION_MIDDLE, | ||||
|     "left": HorizontalDirections.HORIZONTAL_DIRECTION_LEFT, | ||||
|     "mleft": HorizontalDirections.HORIZONTAL_DIRECTION_MLEFT, | ||||
|     "mright": HorizontalDirections.HORIZONTAL_DIRECTION_MRIGHT, | ||||
|     "right": HorizontalDirections.HORIZONTAL_DIRECTION_RIGHT, | ||||
| } | ||||
|  | ||||
| CONF_VERTICAL_DEFAULT = "vertical_default" | ||||
| VerticalDirections = heatpumpir_ns.enum("VerticalDirections") | ||||
| VERTICAL_DIRECTIONS = { | ||||
|     "auto": VerticalDirections.VERTICAL_DIRECTION_AUTO, | ||||
|     "up": VerticalDirections.VERTICAL_DIRECTION_UP, | ||||
|     "mup": VerticalDirections.VERTICAL_DIRECTION_MUP, | ||||
|     "middle": VerticalDirections.VERTICAL_DIRECTION_MIDDLE, | ||||
|     "mdown": VerticalDirections.VERTICAL_DIRECTION_MDOWN, | ||||
|     "down": VerticalDirections.VERTICAL_DIRECTION_DOWN, | ||||
| } | ||||
|  | ||||
| CONFIG_SCHEMA = cv.All( | ||||
|     climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend( | ||||
|         { | ||||
|             cv.GenerateID(): cv.declare_id(HeatpumpIRClimate), | ||||
|             cv.Required(CONF_PROTOCOL): cv.enum(PROTOCOLS), | ||||
|             cv.Required(CONF_HORIZONTAL_DEFAULT): cv.enum(HORIZONTAL_DIRECTIONS), | ||||
|             cv.Required(CONF_VERTICAL_DEFAULT): cv.enum(VERTICAL_DIRECTIONS), | ||||
|             cv.Required(CONF_MIN_TEMPERATURE): cv.temperature, | ||||
|             cv.Required(CONF_MAX_TEMPERATURE): cv.temperature, | ||||
|         } | ||||
|     ), | ||||
|     cv.only_with_arduino, | ||||
| ) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|     var = cg.new_Pvariable(config[CONF_ID]) | ||||
|     if CONF_VISUAL not in config: | ||||
|         config[CONF_VISUAL] = {} | ||||
|     visual = config[CONF_VISUAL] | ||||
|     if CONF_MAX_TEMPERATURE not in visual: | ||||
|         visual[CONF_MAX_TEMPERATURE] = config[CONF_MAX_TEMPERATURE] | ||||
|     if CONF_MIN_TEMPERATURE not in visual: | ||||
|         visual[CONF_MIN_TEMPERATURE] = config[CONF_MIN_TEMPERATURE] | ||||
|     yield climate_ir.register_climate_ir(var, config) | ||||
|     cg.add(var.set_protocol(config[CONF_PROTOCOL])) | ||||
|     cg.add(var.set_horizontal_default(config[CONF_HORIZONTAL_DEFAULT])) | ||||
|     cg.add(var.set_vertical_default(config[CONF_VERTICAL_DEFAULT])) | ||||
|     cg.add(var.set_max_temperature(config[CONF_MIN_TEMPERATURE])) | ||||
|     cg.add(var.set_min_temperature(config[CONF_MAX_TEMPERATURE])) | ||||
|  | ||||
|     cg.add_library("tonia/HeatpumpIR", "1.0.15") | ||||
							
								
								
									
										183
									
								
								esphome/components/heatpumpir/heatpumpir.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										183
									
								
								esphome/components/heatpumpir/heatpumpir.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,183 @@ | ||||
| #include "heatpumpir.h" | ||||
|  | ||||
| #ifdef USE_ARDUINO | ||||
|  | ||||
| #include <map> | ||||
| #include "ir_sender_esphome.h" | ||||
| #include "HeatpumpIRFactory.h" | ||||
| #include "esphome/core/log.h" | ||||
|  | ||||
| namespace esphome { | ||||
| namespace heatpumpir { | ||||
|  | ||||
| static const char *const TAG = "heatpumpir.climate"; | ||||
|  | ||||
| const std::map<Protocol, std::function<HeatpumpIR *()>> PROTOCOL_CONSTRUCTOR_MAP = { | ||||
|     {PROTOCOL_AUX, []() { return new AUXHeatpumpIR(); }},                                    // NOLINT | ||||
|     {PROTOCOL_BALLU, []() { return new BalluHeatpumpIR(); }},                                // NOLINT | ||||
|     {PROTOCOL_CARRIER_MCA, []() { return new CarrierMCAHeatpumpIR(); }},                     // NOLINT | ||||
|     {PROTOCOL_CARRIER_NQV, []() { return new CarrierNQVHeatpumpIR(); }},                     // NOLINT | ||||
|     {PROTOCOL_DAIKIN_ARC417, []() { return new DaikinHeatpumpARC417IR(); }},                 // NOLINT | ||||
|     {PROTOCOL_DAIKIN_ARC480, []() { return new DaikinHeatpumpARC480A14IR(); }},              // NOLINT | ||||
|     {PROTOCOL_DAIKIN, []() { return new DaikinHeatpumpIR(); }},                              // NOLINT | ||||
|     {PROTOCOL_FUEGO, []() { return new FuegoHeatpumpIR(); }},                                // NOLINT | ||||
|     {PROTOCOL_FUJITSU_AWYZ, []() { return new FujitsuHeatpumpIR(); }},                       // NOLINT | ||||
|     {PROTOCOL_GREE, []() { return new GreeGenericHeatpumpIR(); }},                           // NOLINT | ||||
|     {PROTOCOL_GREEYAA, []() { return new GreeYAAHeatpumpIR(); }},                            // NOLINT | ||||
|     {PROTOCOL_GREEYAN, []() { return new GreeYANHeatpumpIR(); }},                            // NOLINT | ||||
|     {PROTOCOL_HISENSE_AUD, []() { return new HisenseHeatpumpIR(); }},                        // NOLINT | ||||
|     {PROTOCOL_HITACHI, []() { return new HitachiHeatpumpIR(); }},                            // NOLINT | ||||
|     {PROTOCOL_HYUNDAI, []() { return new HyundaiHeatpumpIR(); }},                            // NOLINT | ||||
|     {PROTOCOL_IVT, []() { return new IVTHeatpumpIR(); }},                                    // NOLINT | ||||
|     {PROTOCOL_MIDEA, []() { return new MideaHeatpumpIR(); }},                                // NOLINT | ||||
|     {PROTOCOL_MITSUBISHI_FA, []() { return new MitsubishiFAHeatpumpIR(); }},                 // NOLINT | ||||
|     {PROTOCOL_MITSUBISHI_FD, []() { return new MitsubishiFDHeatpumpIR(); }},                 // NOLINT | ||||
|     {PROTOCOL_MITSUBISHI_FE, []() { return new MitsubishiFEHeatpumpIR(); }},                 // NOLINT | ||||
|     {PROTOCOL_MITSUBISHI_HEAVY_FDTC, []() { return new MitsubishiHeavyFDTCHeatpumpIR(); }},  // NOLINT | ||||
|     {PROTOCOL_MITSUBISHI_HEAVY_ZJ, []() { return new MitsubishiHeavyZJHeatpumpIR(); }},      // NOLINT | ||||
|     {PROTOCOL_MITSUBISHI_HEAVY_ZM, []() { return new MitsubishiHeavyZMHeatpumpIR(); }},      // NOLINT | ||||
|     {PROTOCOL_MITSUBISHI_HEAVY_ZMP, []() { return new MitsubishiHeavyZMPHeatpumpIR(); }},    // NOLINT | ||||
|     {PROTOCOL_MITSUBISHI_KJ, []() { return new MitsubishiKJHeatpumpIR(); }},                 // NOLINT | ||||
|     {PROTOCOL_MITSUBISHI_MSC, []() { return new MitsubishiMSCHeatpumpIR(); }},               // NOLINT | ||||
|     {PROTOCOL_MITSUBISHI_MSY, []() { return new MitsubishiMSYHeatpumpIR(); }},               // NOLINT | ||||
|     {PROTOCOL_MITSUBISHI_SEZ, []() { return new MitsubishiSEZKDXXHeatpumpIR(); }},           // NOLINT | ||||
|     {PROTOCOL_PANASONIC_CKP, []() { return new PanasonicCKPHeatpumpIR(); }},                 // NOLINT | ||||
|     {PROTOCOL_PANASONIC_DKE, []() { return new PanasonicDKEHeatpumpIR(); }},                 // NOLINT | ||||
|     {PROTOCOL_PANASONIC_JKE, []() { return new PanasonicJKEHeatpumpIR(); }},                 // NOLINT | ||||
|     {PROTOCOL_PANASONIC_LKE, []() { return new PanasonicLKEHeatpumpIR(); }},                 // NOLINT | ||||
|     {PROTOCOL_PANASONIC_NKE, []() { return new PanasonicNKEHeatpumpIR(); }},                 // NOLINT | ||||
|     {PROTOCOL_SAMSUNG_AQV, []() { return new SamsungAQVHeatpumpIR(); }},                     // NOLINT | ||||
|     {PROTOCOL_SAMSUNG_FJM, []() { return new SamsungFJMHeatpumpIR(); }},                     // NOLINT | ||||
|     {PROTOCOL_SHARP, []() { return new SharpHeatpumpIR(); }},                                // NOLINT | ||||
|     {PROTOCOL_TOSHIBA_DAISEIKAI, []() { return new ToshibaDaiseikaiHeatpumpIR(); }},         // NOLINT | ||||
|     {PROTOCOL_TOSHIBA, []() { return new ToshibaHeatpumpIR(); }},                            // NOLINT | ||||
| }; | ||||
|  | ||||
| void HeatpumpIRClimate::setup() { | ||||
|   auto protocol_constructor = PROTOCOL_CONSTRUCTOR_MAP.find(protocol_); | ||||
|   if (protocol_constructor == PROTOCOL_CONSTRUCTOR_MAP.end()) { | ||||
|     ESP_LOGE(TAG, "Invalid protocol"); | ||||
|     return; | ||||
|   } | ||||
|   this->heatpump_ir_ = protocol_constructor->second(); | ||||
|   climate_ir::ClimateIR::setup(); | ||||
| } | ||||
|  | ||||
| void HeatpumpIRClimate::transmit_state() { | ||||
|   uint8_t power_mode_cmd; | ||||
|   uint8_t operating_mode_cmd; | ||||
|   uint8_t temperature_cmd; | ||||
|   uint8_t fan_speed_cmd; | ||||
|  | ||||
|   uint8_t swing_v_cmd; | ||||
|   switch (default_vertical_direction_) { | ||||
|     case VERTICAL_DIRECTION_AUTO: | ||||
|       swing_v_cmd = VDIR_AUTO; | ||||
|       break; | ||||
|     case VERTICAL_DIRECTION_UP: | ||||
|       swing_v_cmd = VDIR_UP; | ||||
|       break; | ||||
|     case VERTICAL_DIRECTION_MUP: | ||||
|       swing_v_cmd = VDIR_MUP; | ||||
|       break; | ||||
|     case VERTICAL_DIRECTION_MIDDLE: | ||||
|       swing_v_cmd = VDIR_MIDDLE; | ||||
|       break; | ||||
|     case VERTICAL_DIRECTION_MDOWN: | ||||
|       swing_v_cmd = VDIR_MDOWN; | ||||
|       break; | ||||
|     case VERTICAL_DIRECTION_DOWN: | ||||
|       swing_v_cmd = VDIR_DOWN; | ||||
|       break; | ||||
|     default: | ||||
|       ESP_LOGE(TAG, "Invalid default vertical direction"); | ||||
|       return; | ||||
|   } | ||||
|   if ((this->swing_mode == climate::CLIMATE_SWING_VERTICAL) || (this->swing_mode == climate::CLIMATE_SWING_BOTH)) { | ||||
|     swing_v_cmd = VDIR_SWING; | ||||
|   } | ||||
|  | ||||
|   uint8_t swing_h_cmd; | ||||
|   switch (default_horizontal_direction_) { | ||||
|     case HORIZONTAL_DIRECTION_AUTO: | ||||
|       swing_h_cmd = HDIR_AUTO; | ||||
|       break; | ||||
|     case HORIZONTAL_DIRECTION_MIDDLE: | ||||
|       swing_h_cmd = HDIR_MIDDLE; | ||||
|       break; | ||||
|     case HORIZONTAL_DIRECTION_LEFT: | ||||
|       swing_h_cmd = HDIR_LEFT; | ||||
|       break; | ||||
|     case HORIZONTAL_DIRECTION_MLEFT: | ||||
|       swing_h_cmd = HDIR_MLEFT; | ||||
|       break; | ||||
|     case HORIZONTAL_DIRECTION_MRIGHT: | ||||
|       swing_h_cmd = HDIR_MRIGHT; | ||||
|       break; | ||||
|     case HORIZONTAL_DIRECTION_RIGHT: | ||||
|       swing_h_cmd = HDIR_RIGHT; | ||||
|       break; | ||||
|     default: | ||||
|       ESP_LOGE(TAG, "Invalid default horizontal direction"); | ||||
|       return; | ||||
|   } | ||||
|   if ((this->swing_mode == climate::CLIMATE_SWING_HORIZONTAL) || (this->swing_mode == climate::CLIMATE_SWING_BOTH)) { | ||||
|     swing_h_cmd = HDIR_SWING; | ||||
|   } | ||||
|  | ||||
|   switch (this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO)) { | ||||
|     case climate::CLIMATE_FAN_LOW: | ||||
|       fan_speed_cmd = FAN_2; | ||||
|       break; | ||||
|     case climate::CLIMATE_FAN_MEDIUM: | ||||
|       fan_speed_cmd = FAN_3; | ||||
|       break; | ||||
|     case climate::CLIMATE_FAN_HIGH: | ||||
|       fan_speed_cmd = FAN_4; | ||||
|       break; | ||||
|     case climate::CLIMATE_FAN_AUTO: | ||||
|     default: | ||||
|       fan_speed_cmd = FAN_AUTO; | ||||
|       break; | ||||
|   } | ||||
|  | ||||
|   switch (this->mode) { | ||||
|     case climate::CLIMATE_MODE_COOL: | ||||
|       power_mode_cmd = POWER_ON; | ||||
|       operating_mode_cmd = MODE_COOL; | ||||
|       break; | ||||
|     case climate::CLIMATE_MODE_HEAT: | ||||
|       power_mode_cmd = POWER_ON; | ||||
|       operating_mode_cmd = MODE_HEAT; | ||||
|       break; | ||||
|     case climate::CLIMATE_MODE_AUTO: | ||||
|       power_mode_cmd = POWER_ON; | ||||
|       operating_mode_cmd = MODE_AUTO; | ||||
|       break; | ||||
|     case climate::CLIMATE_MODE_FAN_ONLY: | ||||
|       power_mode_cmd = POWER_ON; | ||||
|       operating_mode_cmd = MODE_FAN; | ||||
|       break; | ||||
|     case climate::CLIMATE_MODE_DRY: | ||||
|       power_mode_cmd = POWER_ON; | ||||
|       operating_mode_cmd = MODE_DRY; | ||||
|       break; | ||||
|     case climate::CLIMATE_MODE_OFF: | ||||
|     default: | ||||
|       power_mode_cmd = POWER_OFF; | ||||
|       operating_mode_cmd = MODE_AUTO; | ||||
|       break; | ||||
|   } | ||||
|  | ||||
|   temperature_cmd = (uint8_t) clamp(this->target_temperature, this->min_temperature_, this->max_temperature_); | ||||
|  | ||||
|   IRSenderESPHome esp_sender(0, this->transmitter_); | ||||
|  | ||||
|   heatpump_ir_->send(esp_sender, power_mode_cmd, operating_mode_cmd, fan_speed_cmd, temperature_cmd, swing_v_cmd, | ||||
|                      swing_h_cmd); | ||||
| } | ||||
|  | ||||
| }  // namespace heatpumpir | ||||
| }  // namespace esphome | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										116
									
								
								esphome/components/heatpumpir/heatpumpir.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								esphome/components/heatpumpir/heatpumpir.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,116 @@ | ||||
| #pragma once | ||||
|  | ||||
| #ifdef USE_ARDUINO | ||||
|  | ||||
| #include "esphome/components/climate_ir/climate_ir.h" | ||||
|  | ||||
| // Forward-declare HeatpumpIR class from library. We cannot include its header here because it has unnamespaced defines | ||||
| // that conflict with ESPHome. | ||||
| class HeatpumpIR; | ||||
|  | ||||
| namespace esphome { | ||||
| namespace heatpumpir { | ||||
|  | ||||
| // Simple enum to represent protocols. | ||||
| enum Protocol { | ||||
|   PROTOCOL_AUX, | ||||
|   PROTOCOL_BALLU, | ||||
|   PROTOCOL_CARRIER_MCA, | ||||
|   PROTOCOL_CARRIER_NQV, | ||||
|   PROTOCOL_DAIKIN_ARC417, | ||||
|   PROTOCOL_DAIKIN_ARC480, | ||||
|   PROTOCOL_DAIKIN, | ||||
|   PROTOCOL_FUEGO, | ||||
|   PROTOCOL_FUJITSU_AWYZ, | ||||
|   PROTOCOL_GREE, | ||||
|   PROTOCOL_GREEYAA, | ||||
|   PROTOCOL_GREEYAN, | ||||
|   PROTOCOL_HISENSE_AUD, | ||||
|   PROTOCOL_HITACHI, | ||||
|   PROTOCOL_HYUNDAI, | ||||
|   PROTOCOL_IVT, | ||||
|   PROTOCOL_MIDEA, | ||||
|   PROTOCOL_MITSUBISHI_FA, | ||||
|   PROTOCOL_MITSUBISHI_FD, | ||||
|   PROTOCOL_MITSUBISHI_FE, | ||||
|   PROTOCOL_MITSUBISHI_HEAVY_FDTC, | ||||
|   PROTOCOL_MITSUBISHI_HEAVY_ZJ, | ||||
|   PROTOCOL_MITSUBISHI_HEAVY_ZM, | ||||
|   PROTOCOL_MITSUBISHI_HEAVY_ZMP, | ||||
|   PROTOCOL_MITSUBISHI_KJ, | ||||
|   PROTOCOL_MITSUBISHI_MSC, | ||||
|   PROTOCOL_MITSUBISHI_MSY, | ||||
|   PROTOCOL_MITSUBISHI_SEZ, | ||||
|   PROTOCOL_PANASONIC_CKP, | ||||
|   PROTOCOL_PANASONIC_DKE, | ||||
|   PROTOCOL_PANASONIC_JKE, | ||||
|   PROTOCOL_PANASONIC_LKE, | ||||
|   PROTOCOL_PANASONIC_NKE, | ||||
|   PROTOCOL_SAMSUNG_AQV, | ||||
|   PROTOCOL_SAMSUNG_FJM, | ||||
|   PROTOCOL_SHARP, | ||||
|   PROTOCOL_TOSHIBA_DAISEIKAI, | ||||
|   PROTOCOL_TOSHIBA, | ||||
| }; | ||||
|  | ||||
| // Simple enum to represent horizontal directios | ||||
| enum HorizontalDirection { | ||||
|   HORIZONTAL_DIRECTION_AUTO = 0, | ||||
|   HORIZONTAL_DIRECTION_MIDDLE = 1, | ||||
|   HORIZONTAL_DIRECTION_LEFT = 2, | ||||
|   HORIZONTAL_DIRECTION_MLEFT = 3, | ||||
|   HORIZONTAL_DIRECTION_MRIGHT = 4, | ||||
|   HORIZONTAL_DIRECTION_RIGHT = 5, | ||||
| }; | ||||
|  | ||||
| // Simple enum to represent vertical directions | ||||
| enum VerticalDirection { | ||||
|   VERTICAL_DIRECTION_AUTO = 0, | ||||
|   VERTICAL_DIRECTION_UP = 1, | ||||
|   VERTICAL_DIRECTION_MUP = 2, | ||||
|   VERTICAL_DIRECTION_MIDDLE = 3, | ||||
|   VERTICAL_DIRECTION_MDOWN = 4, | ||||
|   VERTICAL_DIRECTION_DOWN = 5, | ||||
| }; | ||||
|  | ||||
| // Temperature | ||||
| const float TEMP_MIN = 0;    // Celsius | ||||
| const float TEMP_MAX = 100;  // Celsius | ||||
|  | ||||
| class HeatpumpIRClimate : public climate_ir::ClimateIR { | ||||
|  public: | ||||
|   HeatpumpIRClimate() | ||||
|       : climate_ir::ClimateIR( | ||||
|             TEMP_MIN, TEMP_MAX, 1.0f, true, true, | ||||
|             std::set<climate::ClimateFanMode>{climate::CLIMATE_FAN_LOW, climate::CLIMATE_FAN_MEDIUM, | ||||
|                                               climate::CLIMATE_FAN_HIGH, climate::CLIMATE_FAN_AUTO}, | ||||
|             std::set<climate::ClimateSwingMode>{climate::CLIMATE_SWING_OFF, climate::CLIMATE_SWING_HORIZONTAL, | ||||
|                                                 climate::CLIMATE_SWING_VERTICAL, climate::CLIMATE_SWING_BOTH}) {} | ||||
|   void setup() override; | ||||
|   void set_protocol(Protocol protocol) { this->protocol_ = protocol; } | ||||
|   void set_horizontal_default(HorizontalDirection horizontal_direction) { | ||||
|     this->default_horizontal_direction_ = horizontal_direction; | ||||
|   } | ||||
|   void set_vertical_default(VerticalDirection vertical_direction) { | ||||
|     this->default_vertical_direction_ = vertical_direction; | ||||
|   } | ||||
|  | ||||
|   void set_max_temperature(float temperature) { this->max_temperature_ = temperature; } | ||||
|   void set_min_temperature(float temperature) { this->min_temperature_ = temperature; } | ||||
|  | ||||
|  protected: | ||||
|   HeatpumpIR *heatpump_ir_; | ||||
|   /// Transmit via IR the state of this climate controller. | ||||
|   void transmit_state() override; | ||||
|   Protocol protocol_; | ||||
|   HorizontalDirection default_horizontal_direction_; | ||||
|   VerticalDirection default_vertical_direction_; | ||||
|  | ||||
|   float max_temperature_; | ||||
|   float min_temperature_; | ||||
| }; | ||||
|  | ||||
| }  // namespace heatpumpir | ||||
| }  // namespace esphome | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										32
									
								
								esphome/components/heatpumpir/ir_sender_esphome.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								esphome/components/heatpumpir/ir_sender_esphome.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| #include "ir_sender_esphome.h" | ||||
|  | ||||
| #ifdef USE_ARDUINO | ||||
|  | ||||
| namespace esphome { | ||||
| namespace heatpumpir { | ||||
|  | ||||
| void IRSenderESPHome::setFrequency(int frequency) {  // NOLINT(readability-identifier-naming) | ||||
|   auto data = transmit_.get_data(); | ||||
|   data->set_carrier_frequency(1000 * frequency); | ||||
| } | ||||
|  | ||||
| // Send an IR 'mark' symbol, i.e. transmitter ON | ||||
| void IRSenderESPHome::mark(int mark_length) { | ||||
|   auto data = transmit_.get_data(); | ||||
|   data->mark(mark_length); | ||||
| } | ||||
|  | ||||
| // Send an IR 'space' symbol, i.e. transmitter OFF | ||||
| void IRSenderESPHome::space(int space_length) { | ||||
|   if (space_length) { | ||||
|     auto data = transmit_.get_data(); | ||||
|     data->space(space_length); | ||||
|   } else { | ||||
|     transmit_.perform(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| }  // namespace heatpumpir | ||||
| }  // namespace esphome | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										27
									
								
								esphome/components/heatpumpir/ir_sender_esphome.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								esphome/components/heatpumpir/ir_sender_esphome.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| #pragma once | ||||
|  | ||||
| #ifdef USE_ARDUINO | ||||
|  | ||||
| #include "esphome/components/remote_base/remote_base.h" | ||||
| #include "esphome/components/remote_transmitter/remote_transmitter.h" | ||||
| #include <IRSender.h>  // arduino-heatpump library | ||||
|  | ||||
| namespace esphome { | ||||
| namespace heatpumpir { | ||||
|  | ||||
| class IRSenderESPHome : public IRSender { | ||||
|  public: | ||||
|   IRSenderESPHome(uint8_t pin, remote_transmitter::RemoteTransmitterComponent *transmitter) | ||||
|       : IRSender(pin), transmit_(transmitter->transmit()){}; | ||||
|   void setFrequency(int frequency) override;  // NOLINT(readability-identifier-naming) | ||||
|   void space(int space_length) override; | ||||
|   void mark(int mark_length) override; | ||||
|  | ||||
|  protected: | ||||
|   remote_transmitter::RemoteTransmitterComponent::TransmitCall transmit_; | ||||
| }; | ||||
|  | ||||
| }  // namespace heatpumpir | ||||
| }  // namespace esphome | ||||
|  | ||||
| #endif | ||||
| @@ -49,6 +49,7 @@ lib_deps = | ||||
|     glmnet/Dsmr@0.5                                       ; dsmr | ||||
|     rweather/Crypto@0.2.0                                 ; dsmr | ||||
|     dudanov/MideaUART@1.1.8                               ; midea | ||||
|     tonia/HeatpumpIR@^1.0.15                              ; heatpumpir | ||||
| build_flags = | ||||
|     ${common.build_flags} | ||||
|     -DUSE_ARDUINO | ||||
|   | ||||
| @@ -1681,6 +1681,13 @@ climate: | ||||
|     name: Toshiba Climate | ||||
|   - platform: hitachi_ac344 | ||||
|     name: Hitachi Climate | ||||
|   - platform: heatpumpir | ||||
|     protocol: mitsubishi_heavy_zm | ||||
|     horizontal_default: left | ||||
|     vertical_default: up | ||||
|     name: HeatpumpIR Climate | ||||
|     min_temperature: 18 | ||||
|     max_temperature: 30 | ||||
|   - platform: midea | ||||
|     id: midea_unit | ||||
|     uart_id: uart0 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user