mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	Add IR Noblex climate component (#4913)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
		
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							cb2f5eb781
						
					
				
				
					commit
					e01ba894ed
				
			| @@ -209,6 +209,7 @@ esphome/components/nextion/sensor/* @senexcrenshaw | |||||||
| esphome/components/nextion/switch/* @senexcrenshaw | esphome/components/nextion/switch/* @senexcrenshaw | ||||||
| esphome/components/nextion/text_sensor/* @senexcrenshaw | esphome/components/nextion/text_sensor/* @senexcrenshaw | ||||||
| esphome/components/nfc/* @jesserockz | esphome/components/nfc/* @jesserockz | ||||||
|  | esphome/components/noblex/* @AGalfra | ||||||
| esphome/components/number/* @esphome/core | esphome/components/number/* @esphome/core | ||||||
| esphome/components/ota/* @esphome/core | esphome/components/ota/* @esphome/core | ||||||
| esphome/components/output/* @esphome/core | esphome/components/output/* @esphome/core | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								esphome/components/noblex/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								esphome/components/noblex/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | CODEOWNERS = ["@AGalfra"] | ||||||
							
								
								
									
										20
									
								
								esphome/components/noblex/climate.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								esphome/components/noblex/climate.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | import esphome.codegen as cg | ||||||
|  | import esphome.config_validation as cv | ||||||
|  | from esphome.components import climate_ir | ||||||
|  | from esphome.const import CONF_ID | ||||||
|  |  | ||||||
|  | AUTO_LOAD = ["climate_ir"] | ||||||
|  |  | ||||||
|  | noblex_ns = cg.esphome_ns.namespace("noblex") | ||||||
|  | NoblexClimate = noblex_ns.class_("NoblexClimate", climate_ir.ClimateIR) | ||||||
|  |  | ||||||
|  | CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend( | ||||||
|  |     { | ||||||
|  |         cv.GenerateID(): cv.declare_id(NoblexClimate), | ||||||
|  |     } | ||||||
|  | ) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | async def to_code(config): | ||||||
|  |     var = cg.new_Pvariable(config[CONF_ID]) | ||||||
|  |     await climate_ir.register_climate_ir(var, config) | ||||||
							
								
								
									
										309
									
								
								esphome/components/noblex/noblex.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										309
									
								
								esphome/components/noblex/noblex.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,309 @@ | |||||||
|  | #include "noblex.h" | ||||||
|  | #include "esphome/core/log.h" | ||||||
|  | #include "esphome/core/helpers.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace noblex { | ||||||
|  |  | ||||||
|  | static const char *const TAG = "noblex.climate"; | ||||||
|  |  | ||||||
|  | const uint16_t NOBLEX_HEADER_MARK = 9000; | ||||||
|  | const uint16_t NOBLEX_HEADER_SPACE = 4500; | ||||||
|  | const uint16_t NOBLEX_BIT_MARK = 660; | ||||||
|  | const uint16_t NOBLEX_ONE_SPACE = 1640; | ||||||
|  | const uint16_t NOBLEX_ZERO_SPACE = 520; | ||||||
|  | const uint32_t NOBLEX_GAP = 20000; | ||||||
|  | const uint8_t NOBLEX_POWER = 0x10; | ||||||
|  |  | ||||||
|  | using IRNoblexMode = enum IRNoblexMode { | ||||||
|  |   IR_NOBLEX_MODE_AUTO = 0b000, | ||||||
|  |   IR_NOBLEX_MODE_COOL = 0b100, | ||||||
|  |   IR_NOBLEX_MODE_DRY = 0b010, | ||||||
|  |   IR_NOBLEX_MODE_FAN = 0b110, | ||||||
|  |   IR_NOBLEX_MODE_HEAT = 0b001, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | using IRNoblexFan = enum IRNoblexFan { | ||||||
|  |   IR_NOBLEX_FAN_AUTO = 0b00, | ||||||
|  |   IR_NOBLEX_FAN_LOW = 0b10, | ||||||
|  |   IR_NOBLEX_FAN_MEDIUM = 0b01, | ||||||
|  |   IR_NOBLEX_FAN_HIGH = 0b11, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | // Transmit via IR the state of this climate controller. | ||||||
|  | void NoblexClimate::transmit_state() { | ||||||
|  |   uint8_t remote_state[8] = {0x80, 0x10, 0x00, 0x0A, 0x50, 0x00, 0x20, 0x00};  // OFF, COOL, 24C, FAN_AUTO | ||||||
|  |  | ||||||
|  |   auto powered_on = this->mode != climate::CLIMATE_MODE_OFF; | ||||||
|  |   if (powered_on) { | ||||||
|  |     remote_state[0] |= 0x10;  // power bit | ||||||
|  |     remote_state[2] = 0x02; | ||||||
|  |   } | ||||||
|  |   if (powered_on != this->powered_on_assumed) | ||||||
|  |     this->powered_on_assumed = powered_on; | ||||||
|  |  | ||||||
|  |   auto temp = (uint8_t) roundf(clamp<float>(this->target_temperature, NOBLEX_TEMP_MIN, NOBLEX_TEMP_MAX)); | ||||||
|  |   remote_state[1] = reverse_bits(uint8_t((temp - NOBLEX_TEMP_MIN) & 0x0F)); | ||||||
|  |  | ||||||
|  |   switch (this->mode) { | ||||||
|  |     case climate::CLIMATE_MODE_HEAT_COOL: | ||||||
|  |       remote_state[0] |= (IRNoblexMode::IR_NOBLEX_MODE_AUTO << 5); | ||||||
|  |       remote_state[1] = 0x90;  // NOBLEX_TEMP_MAP 25C | ||||||
|  |       break; | ||||||
|  |     case climate::CLIMATE_MODE_COOL: | ||||||
|  |       remote_state[0] |= (IRNoblexMode::IR_NOBLEX_MODE_COOL << 5); | ||||||
|  |       break; | ||||||
|  |     case climate::CLIMATE_MODE_DRY: | ||||||
|  |       remote_state[0] |= (IRNoblexMode::IR_NOBLEX_MODE_DRY << 5); | ||||||
|  |       break; | ||||||
|  |     case climate::CLIMATE_MODE_FAN_ONLY: | ||||||
|  |       remote_state[0] |= (IRNoblexMode::IR_NOBLEX_MODE_FAN << 5); | ||||||
|  |       break; | ||||||
|  |     case climate::CLIMATE_MODE_HEAT: | ||||||
|  |       remote_state[0] |= (IRNoblexMode::IR_NOBLEX_MODE_HEAT << 5); | ||||||
|  |       break; | ||||||
|  |     case climate::CLIMATE_MODE_OFF: | ||||||
|  |     default: | ||||||
|  |       powered_on = false; | ||||||
|  |       this->powered_on_assumed = powered_on; | ||||||
|  |       remote_state[0] &= 0xEF; | ||||||
|  |       remote_state[2] = 0x00; | ||||||
|  |       break; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   switch (this->fan_mode.value()) { | ||||||
|  |     case climate::CLIMATE_FAN_LOW: | ||||||
|  |       remote_state[0] |= (IRNoblexFan::IR_NOBLEX_FAN_LOW << 2); | ||||||
|  |       break; | ||||||
|  |     case climate::CLIMATE_FAN_MEDIUM: | ||||||
|  |       remote_state[0] |= (IRNoblexFan::IR_NOBLEX_FAN_MEDIUM << 2); | ||||||
|  |       break; | ||||||
|  |     case climate::CLIMATE_FAN_HIGH: | ||||||
|  |       remote_state[0] |= (IRNoblexFan::IR_NOBLEX_FAN_HIGH << 2); | ||||||
|  |       break; | ||||||
|  |     case climate::CLIMATE_FAN_AUTO: | ||||||
|  |     default: | ||||||
|  |       remote_state[0] |= (IRNoblexFan::IR_NOBLEX_FAN_AUTO << 2); | ||||||
|  |       break; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   switch (this->swing_mode) { | ||||||
|  |     case climate::CLIMATE_SWING_VERTICAL: | ||||||
|  |       remote_state[0] |= 0x02; | ||||||
|  |       remote_state[4] = 0x58; | ||||||
|  |       break; | ||||||
|  |     case climate::CLIMATE_SWING_OFF: | ||||||
|  |     default: | ||||||
|  |       remote_state[0] &= 0xFD; | ||||||
|  |       remote_state[4] = 0x50; | ||||||
|  |       break; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   uint8_t crc = 0; | ||||||
|  |   for (uint8_t i : remote_state) { | ||||||
|  |     crc += reverse_bits(i); | ||||||
|  |   } | ||||||
|  |   crc = reverse_bits(uint8_t(crc & 0x0F)) >> 4; | ||||||
|  |  | ||||||
|  |   ESP_LOGD(TAG, "Sending noblex code: %02X%02X %02X%02X %02X%02X %02X%02X", remote_state[0], remote_state[1], | ||||||
|  |            remote_state[2], remote_state[3], remote_state[4], remote_state[5], remote_state[6], remote_state[7]); | ||||||
|  |  | ||||||
|  |   ESP_LOGV(TAG, "CRC: %01X", crc); | ||||||
|  |  | ||||||
|  |   auto transmit = this->transmitter_->transmit(); | ||||||
|  |   auto *data = transmit.get_data(); | ||||||
|  |   data->set_carrier_frequency(38000); | ||||||
|  |  | ||||||
|  |   // Header | ||||||
|  |   data->mark(NOBLEX_HEADER_MARK); | ||||||
|  |   data->space(NOBLEX_HEADER_SPACE); | ||||||
|  |   // Data (sent remote_state from the MSB to the LSB) | ||||||
|  |   for (uint8_t i : remote_state) { | ||||||
|  |     for (int8_t j = 7; j >= 0; j--) { | ||||||
|  |       if ((i == 4) & (j == 4)) { | ||||||
|  |         // Header intermediate | ||||||
|  |         data->mark(NOBLEX_BIT_MARK); | ||||||
|  |         data->space(NOBLEX_GAP);  // gap en bit 36 | ||||||
|  |       } else { | ||||||
|  |         data->mark(NOBLEX_BIT_MARK); | ||||||
|  |         bool bit = i & (1 << j); | ||||||
|  |         data->space(bit ? NOBLEX_ONE_SPACE : NOBLEX_ZERO_SPACE); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   // send crc | ||||||
|  |   for (int8_t i = 3; i >= 0; i--) { | ||||||
|  |     data->mark(NOBLEX_BIT_MARK); | ||||||
|  |     bool bit = crc & (1 << i); | ||||||
|  |     data->space(bit ? NOBLEX_ONE_SPACE : NOBLEX_ZERO_SPACE); | ||||||
|  |   } | ||||||
|  |   // Footer | ||||||
|  |   data->mark(NOBLEX_BIT_MARK); | ||||||
|  |  | ||||||
|  |   transmit.perform(); | ||||||
|  | }  // end transmit_state() | ||||||
|  |  | ||||||
|  | // Handle received IR Buffer | ||||||
|  | bool NoblexClimate::on_receive(remote_base::RemoteReceiveData data) { | ||||||
|  |   uint8_t remote_state[8] = {0}; | ||||||
|  |   uint8_t crc = 0, crc_calculated = 0; | ||||||
|  |  | ||||||
|  |   if (!receiving_) { | ||||||
|  |     // Validate header | ||||||
|  |     if (data.expect_item(NOBLEX_HEADER_MARK, NOBLEX_HEADER_SPACE)) { | ||||||
|  |       ESP_LOGV(TAG, "Header"); | ||||||
|  |       receiving_ = true; | ||||||
|  |       // Read first 36 bits | ||||||
|  |       for (int i = 0; i < 5; i++) { | ||||||
|  |         // Read bit | ||||||
|  |         for (int j = 7; j >= 0; j--) { | ||||||
|  |           if ((i == 4) & (j == 4)) { | ||||||
|  |             remote_state[i] |= 1 << j; | ||||||
|  |             // Header intermediate | ||||||
|  |             ESP_LOGVV(TAG, "GAP"); | ||||||
|  |             return false; | ||||||
|  |           } else if (data.expect_item(NOBLEX_BIT_MARK, NOBLEX_ONE_SPACE)) { | ||||||
|  |             remote_state[i] |= 1 << j; | ||||||
|  |           } else if (!data.expect_item(NOBLEX_BIT_MARK, NOBLEX_ZERO_SPACE)) { | ||||||
|  |             ESP_LOGVV(TAG, "Byte %d bit %d fail", i, j); | ||||||
|  |             return false; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |         ESP_LOGV(TAG, "Byte %d %02X", i, remote_state[i]); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |     } else { | ||||||
|  |       ESP_LOGV(TAG, "Header fail"); | ||||||
|  |       receiving_ = false; | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   } else { | ||||||
|  |     // Read the remaining 28 bits | ||||||
|  |     for (int i = 4; i < 8; i++) { | ||||||
|  |       // Read bit | ||||||
|  |       for (int j = 7; j >= 0; j--) { | ||||||
|  |         if ((i == 4) & (j >= 4)) { | ||||||
|  |           // nothing | ||||||
|  |         } else if (data.expect_item(NOBLEX_BIT_MARK, NOBLEX_ONE_SPACE)) { | ||||||
|  |           remote_state[i] |= 1 << j; | ||||||
|  |         } else if (!data.expect_item(NOBLEX_BIT_MARK, NOBLEX_ZERO_SPACE)) { | ||||||
|  |           ESP_LOGVV(TAG, "Byte %d bit %d fail", i, j); | ||||||
|  |           return false; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       ESP_LOGV(TAG, "Byte %d %02X", i, remote_state[i]); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Read crc | ||||||
|  |     for (int i = 3; i >= 0; i--) { | ||||||
|  |       if (data.expect_item(NOBLEX_BIT_MARK, NOBLEX_ONE_SPACE)) { | ||||||
|  |         crc |= 1 << i; | ||||||
|  |       } else if (!data.expect_item(NOBLEX_BIT_MARK, NOBLEX_ZERO_SPACE)) { | ||||||
|  |         ESP_LOGVV(TAG, "Bit %d CRC fail", i); | ||||||
|  |         return false; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     ESP_LOGV(TAG, "CRC %02X", crc); | ||||||
|  |  | ||||||
|  |     // Validate footer | ||||||
|  |     if (!data.expect_mark(NOBLEX_BIT_MARK)) { | ||||||
|  |       ESP_LOGV(TAG, "Footer fail"); | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     receiving_ = false; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   for (uint8_t i : remote_state) | ||||||
|  |     crc_calculated += reverse_bits(i); | ||||||
|  |   crc_calculated = reverse_bits(uint8_t(crc_calculated & 0x0F)) >> 4; | ||||||
|  |   ESP_LOGVV(TAG, "CRC calc %02X", crc_calculated); | ||||||
|  |  | ||||||
|  |   if (crc != crc_calculated) { | ||||||
|  |     ESP_LOGV(TAG, "CRC fail"); | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   ESP_LOGD(TAG, "Received noblex code: %02X%02X %02X%02X %02X%02X %02X%02X", remote_state[0], remote_state[1], | ||||||
|  |            remote_state[2], remote_state[3], remote_state[4], remote_state[5], remote_state[6], remote_state[7]); | ||||||
|  |  | ||||||
|  |   auto powered_on = false; | ||||||
|  |   if ((remote_state[0] & NOBLEX_POWER) == NOBLEX_POWER) { | ||||||
|  |     powered_on = true; | ||||||
|  |     this->powered_on_assumed = powered_on; | ||||||
|  |   } else { | ||||||
|  |     powered_on = false; | ||||||
|  |     this->powered_on_assumed = powered_on; | ||||||
|  |     this->mode = climate::CLIMATE_MODE_OFF; | ||||||
|  |   } | ||||||
|  |   // powr on/off button | ||||||
|  |   ESP_LOGV(TAG, "Power: %01X", powered_on); | ||||||
|  |  | ||||||
|  |   // Set received mode | ||||||
|  |   if (powered_on_assumed) { | ||||||
|  |     auto mode = (remote_state[0] & 0xE0) >> 5; | ||||||
|  |     ESP_LOGV(TAG, "Mode: %02X", mode); | ||||||
|  |     switch (mode) { | ||||||
|  |       case IRNoblexMode::IR_NOBLEX_MODE_AUTO: | ||||||
|  |         this->mode = climate::CLIMATE_MODE_HEAT_COOL; | ||||||
|  |         break; | ||||||
|  |       case IRNoblexMode::IR_NOBLEX_MODE_COOL: | ||||||
|  |         this->mode = climate::CLIMATE_MODE_COOL; | ||||||
|  |         break; | ||||||
|  |       case IRNoblexMode::IR_NOBLEX_MODE_DRY: | ||||||
|  |         this->mode = climate::CLIMATE_MODE_DRY; | ||||||
|  |         break; | ||||||
|  |       case IRNoblexMode::IR_NOBLEX_MODE_FAN: | ||||||
|  |         this->mode = climate::CLIMATE_MODE_FAN_ONLY; | ||||||
|  |         break; | ||||||
|  |       case IRNoblexMode::IR_NOBLEX_MODE_HEAT: | ||||||
|  |         this->mode = climate::CLIMATE_MODE_HEAT; | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Set received temp | ||||||
|  |   uint8_t temp = remote_state[1]; | ||||||
|  |   ESP_LOGVV(TAG, "Temperature Raw: %02X", temp); | ||||||
|  |  | ||||||
|  |   temp = 0x0F & reverse_bits(temp); | ||||||
|  |   temp += NOBLEX_TEMP_MIN; | ||||||
|  |   ESP_LOGV(TAG, "Temperature Climate: %u", temp); | ||||||
|  |   this->target_temperature = temp; | ||||||
|  |  | ||||||
|  |   // Set received fan speed | ||||||
|  |   auto fan = (remote_state[0] & 0x0C) >> 2; | ||||||
|  |   ESP_LOGV(TAG, "Fan: %02X", fan); | ||||||
|  |   switch (fan) { | ||||||
|  |     case IRNoblexFan::IR_NOBLEX_FAN_HIGH: | ||||||
|  |       this->fan_mode = climate::CLIMATE_FAN_HIGH; | ||||||
|  |       break; | ||||||
|  |     case IRNoblexFan::IR_NOBLEX_FAN_MEDIUM: | ||||||
|  |       this->fan_mode = climate::CLIMATE_FAN_MEDIUM; | ||||||
|  |       break; | ||||||
|  |     case IRNoblexFan::IR_NOBLEX_FAN_LOW: | ||||||
|  |       this->fan_mode = climate::CLIMATE_FAN_LOW; | ||||||
|  |       break; | ||||||
|  |     case IRNoblexFan::IR_NOBLEX_FAN_AUTO: | ||||||
|  |     default: | ||||||
|  |       this->fan_mode = climate::CLIMATE_FAN_AUTO; | ||||||
|  |       break; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Set received swing status | ||||||
|  |   if (remote_state[0] & 0x02) { | ||||||
|  |     ESP_LOGV(TAG, "Swing vertical"); | ||||||
|  |     this->swing_mode = climate::CLIMATE_SWING_VERTICAL; | ||||||
|  |   } else { | ||||||
|  |     ESP_LOGV(TAG, "Swing OFF"); | ||||||
|  |     this->swing_mode = climate::CLIMATE_SWING_OFF; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   for (uint8_t &i : remote_state) | ||||||
|  |     i = 0; | ||||||
|  |   this->publish_state(); | ||||||
|  |   return true; | ||||||
|  | }  // end on_receive() | ||||||
|  |  | ||||||
|  | }  // namespace noblex | ||||||
|  | }  // namespace esphome | ||||||
							
								
								
									
										47
									
								
								esphome/components/noblex/noblex.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								esphome/components/noblex/noblex.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "esphome/components/climate_ir/climate_ir.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace noblex { | ||||||
|  |  | ||||||
|  | // Temperature | ||||||
|  | const uint8_t NOBLEX_TEMP_MIN = 16;  // Celsius | ||||||
|  | const uint8_t NOBLEX_TEMP_MAX = 30;  // Celsius | ||||||
|  |  | ||||||
|  | class NoblexClimate : public climate_ir::ClimateIR { | ||||||
|  |  public: | ||||||
|  |   NoblexClimate() | ||||||
|  |       : climate_ir::ClimateIR(NOBLEX_TEMP_MIN, NOBLEX_TEMP_MAX, 1.0f, true, true, | ||||||
|  |                               {climate::CLIMATE_FAN_AUTO, climate::CLIMATE_FAN_LOW, climate::CLIMATE_FAN_MEDIUM, | ||||||
|  |                                climate::CLIMATE_FAN_HIGH}, | ||||||
|  |                               {climate::CLIMATE_SWING_OFF, climate::CLIMATE_SWING_VERTICAL}) {} | ||||||
|  |  | ||||||
|  |   void setup() override { | ||||||
|  |     climate_ir::ClimateIR::setup(); | ||||||
|  |     this->powered_on_assumed = this->mode != climate::CLIMATE_MODE_OFF; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Override control to change settings of the climate device. | ||||||
|  |   void control(const climate::ClimateCall &call) override { | ||||||
|  |     send_swing_cmd_ = call.get_swing_mode().has_value(); | ||||||
|  |     // swing resets after unit powered off | ||||||
|  |     if (call.get_mode().has_value() && *call.get_mode() == climate::CLIMATE_MODE_OFF) | ||||||
|  |       this->swing_mode = climate::CLIMATE_SWING_OFF; | ||||||
|  |     climate_ir::ClimateIR::control(call); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // used to track when to send the power toggle command. | ||||||
|  |   bool powered_on_assumed; | ||||||
|  |  | ||||||
|  |  protected: | ||||||
|  |   /// Transmit via IR the state of this climate controller. | ||||||
|  |   void transmit_state() override; | ||||||
|  |   /// Handle received IR Buffer. | ||||||
|  |   bool on_receive(remote_base::RemoteReceiveData data) override; | ||||||
|  |   bool send_swing_cmd_{false}; | ||||||
|  |   bool receiving_ = false; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }  // namespace noblex | ||||||
|  | }  // namespace esphome | ||||||
| @@ -2303,6 +2303,11 @@ climate: | |||||||
|     heat_mode: extended |     heat_mode: extended | ||||||
|   - platform: whynter |   - platform: whynter | ||||||
|     name: Whynter |     name: Whynter | ||||||
|  |   - platform: noblex | ||||||
|  |     name: AC Living | ||||||
|  |     id: noblex_ac | ||||||
|  |     sensor: ${sensorname}_sensor | ||||||
|  |     receiver_id: rcvr | ||||||
|   - platform: gree |   - platform: gree | ||||||
|     name: GREE |     name: GREE | ||||||
|     model: generic |     model: generic | ||||||
| @@ -2939,6 +2944,7 @@ tm1651: | |||||||
|   dio_pin: GPIO23 |   dio_pin: GPIO23 | ||||||
|  |  | ||||||
| remote_receiver: | remote_receiver: | ||||||
|  |   id: rcvr | ||||||
|   pin: GPIO32 |   pin: GPIO32 | ||||||
|   dump: all |   dump: all | ||||||
|   on_coolix: |   on_coolix: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user