mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	Climate IR LG - Support fan only mode and all "on" commands (#3712)
This commit is contained in:
		| @@ -6,18 +6,24 @@ namespace climate_ir_lg { | |||||||
|  |  | ||||||
| static const char *const TAG = "climate.climate_ir_lg"; | static const char *const TAG = "climate.climate_ir_lg"; | ||||||
|  |  | ||||||
| const uint32_t COMMAND_ON = 0x00000; | // Commands | ||||||
| const uint32_t COMMAND_ON_AI = 0x03000; | const uint32_t COMMAND_MASK = 0xFF000; | ||||||
| const uint32_t COMMAND_COOL = 0x08000; |  | ||||||
| const uint32_t COMMAND_HEAT = 0x0C000; |  | ||||||
| const uint32_t COMMAND_OFF = 0xC0000; | const uint32_t COMMAND_OFF = 0xC0000; | ||||||
| const uint32_t COMMAND_SWING = 0x10000; | const uint32_t COMMAND_SWING = 0x10000; | ||||||
| // On, 25C, Mode: Auto, Fan: Auto, Zone Follow: Off, Sensor Temp: Ignore. |  | ||||||
| const uint32_t COMMAND_AUTO = 0x0B000; |  | ||||||
| const uint32_t COMMAND_DRY_FAN = 0x09000; |  | ||||||
|  |  | ||||||
| const uint32_t COMMAND_MASK = 0xFF000; | const uint32_t COMMAND_ON_COOL = 0x00000; | ||||||
|  | const uint32_t COMMAND_ON_DRY = 0x01000; | ||||||
|  | const uint32_t COMMAND_ON_FAN_ONLY = 0x02000; | ||||||
|  | const uint32_t COMMAND_ON_AI = 0x03000; | ||||||
|  | const uint32_t COMMAND_ON_HEAT = 0x04000; | ||||||
|  |  | ||||||
|  | const uint32_t COMMAND_COOL = 0x08000; | ||||||
|  | const uint32_t COMMAND_DRY = 0x09000; | ||||||
|  | const uint32_t COMMAND_FAN_ONLY = 0x0A000; | ||||||
|  | const uint32_t COMMAND_AI = 0x0B000; | ||||||
|  | const uint32_t COMMAND_HEAT = 0x0C000; | ||||||
|  |  | ||||||
|  | // Fan speed | ||||||
| const uint32_t FAN_MASK = 0xF0; | const uint32_t FAN_MASK = 0xF0; | ||||||
| const uint32_t FAN_AUTO = 0x50; | const uint32_t FAN_AUTO = 0x50; | ||||||
| const uint32_t FAN_MIN = 0x00; | const uint32_t FAN_MIN = 0x00; | ||||||
| @@ -35,28 +41,28 @@ void LgIrClimate::transmit_state() { | |||||||
|   uint32_t remote_state = 0x8800000; |   uint32_t remote_state = 0x8800000; | ||||||
|  |  | ||||||
|   // ESP_LOGD(TAG, "climate_lg_ir mode_before_ code: 0x%02X", modeBefore_); |   // ESP_LOGD(TAG, "climate_lg_ir mode_before_ code: 0x%02X", modeBefore_); | ||||||
|  |  | ||||||
|  |   // Set command | ||||||
|   if (send_swing_cmd_) { |   if (send_swing_cmd_) { | ||||||
|     send_swing_cmd_ = false; |     send_swing_cmd_ = false; | ||||||
|     remote_state |= COMMAND_SWING; |     remote_state |= COMMAND_SWING; | ||||||
|   } else { |   } else { | ||||||
|     if (mode_before_ == climate::CLIMATE_MODE_OFF && this->mode == climate::CLIMATE_MODE_HEAT_COOL) { |     bool climate_is_off = (mode_before_ == climate::CLIMATE_MODE_OFF); | ||||||
|       remote_state |= COMMAND_ON_AI; |  | ||||||
|     } else if (mode_before_ == climate::CLIMATE_MODE_OFF && this->mode != climate::CLIMATE_MODE_OFF) { |  | ||||||
|       remote_state |= COMMAND_ON; |  | ||||||
|       this->mode = climate::CLIMATE_MODE_COOL; |  | ||||||
|     } else { |  | ||||||
|     switch (this->mode) { |     switch (this->mode) { | ||||||
|       case climate::CLIMATE_MODE_COOL: |       case climate::CLIMATE_MODE_COOL: | ||||||
|           remote_state |= COMMAND_COOL; |         remote_state |= climate_is_off ? COMMAND_ON_COOL : COMMAND_COOL; | ||||||
|           break; |  | ||||||
|         case climate::CLIMATE_MODE_HEAT: |  | ||||||
|           remote_state |= COMMAND_HEAT; |  | ||||||
|           break; |  | ||||||
|         case climate::CLIMATE_MODE_HEAT_COOL: |  | ||||||
|           remote_state |= COMMAND_AUTO; |  | ||||||
|         break; |         break; | ||||||
|       case climate::CLIMATE_MODE_DRY: |       case climate::CLIMATE_MODE_DRY: | ||||||
|           remote_state |= COMMAND_DRY_FAN; |         remote_state |= climate_is_off ? COMMAND_ON_DRY : COMMAND_DRY; | ||||||
|  |         break; | ||||||
|  |       case climate::CLIMATE_MODE_FAN_ONLY: | ||||||
|  |         remote_state |= climate_is_off ? COMMAND_ON_FAN_ONLY : COMMAND_FAN_ONLY; | ||||||
|  |         break; | ||||||
|  |       case climate::CLIMATE_MODE_HEAT_COOL: | ||||||
|  |         remote_state |= climate_is_off ? COMMAND_ON_AI : COMMAND_AI; | ||||||
|  |         break; | ||||||
|  |       case climate::CLIMATE_MODE_HEAT: | ||||||
|  |         remote_state |= climate_is_off ? COMMAND_ON_HEAT : COMMAND_HEAT; | ||||||
|         break; |         break; | ||||||
|       case climate::CLIMATE_MODE_OFF: |       case climate::CLIMATE_MODE_OFF: | ||||||
|       default: |       default: | ||||||
| @@ -64,14 +70,15 @@ void LgIrClimate::transmit_state() { | |||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   mode_before_ = this->mode; |   mode_before_ = this->mode; | ||||||
|  |  | ||||||
|   ESP_LOGD(TAG, "climate_lg_ir mode code: 0x%02X", this->mode); |   ESP_LOGD(TAG, "climate_lg_ir mode code: 0x%02X", this->mode); | ||||||
|  |  | ||||||
|  |   // Set fan speed | ||||||
|   if (this->mode == climate::CLIMATE_MODE_OFF) { |   if (this->mode == climate::CLIMATE_MODE_OFF) { | ||||||
|     remote_state |= FAN_AUTO; |     remote_state |= FAN_AUTO; | ||||||
|     } else if (this->mode == climate::CLIMATE_MODE_COOL || this->mode == climate::CLIMATE_MODE_DRY || |   } else { | ||||||
|                this->mode == climate::CLIMATE_MODE_HEAT) { |  | ||||||
|     switch (this->fan_mode.value()) { |     switch (this->fan_mode.value()) { | ||||||
|       case climate::CLIMATE_FAN_HIGH: |       case climate::CLIMATE_FAN_HIGH: | ||||||
|         remote_state |= FAN_MAX; |         remote_state |= FAN_MAX; | ||||||
| @@ -89,15 +96,12 @@ void LgIrClimate::transmit_state() { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|     if (this->mode == climate::CLIMATE_MODE_HEAT_COOL) { |   // Set temperature | ||||||
|       this->fan_mode = climate::CLIMATE_FAN_AUTO; |  | ||||||
|       // remote_state |= FAN_MODE_AUTO_DRY; |  | ||||||
|     } |  | ||||||
|   if (this->mode == climate::CLIMATE_MODE_COOL || this->mode == climate::CLIMATE_MODE_HEAT) { |   if (this->mode == climate::CLIMATE_MODE_COOL || this->mode == climate::CLIMATE_MODE_HEAT) { | ||||||
|     auto temp = (uint8_t) roundf(clamp<float>(this->target_temperature, TEMP_MIN, TEMP_MAX)); |     auto temp = (uint8_t) roundf(clamp<float>(this->target_temperature, TEMP_MIN, TEMP_MAX)); | ||||||
|     remote_state |= ((temp - 15) << TEMP_SHIFT); |     remote_state |= ((temp - 15) << TEMP_SHIFT); | ||||||
|   } |   } | ||||||
|   } |  | ||||||
|   transmit_(remote_state); |   transmit_(remote_state); | ||||||
|   this->publish_state(); |   this->publish_state(); | ||||||
| } | } | ||||||
| @@ -125,37 +129,42 @@ bool LgIrClimate::on_receive(remote_base::RemoteReceiveData data) { | |||||||
|   if ((remote_state & 0xFF00000) != 0x8800000) |   if ((remote_state & 0xFF00000) != 0x8800000) | ||||||
|     return false; |     return false; | ||||||
|  |  | ||||||
|   if ((remote_state & COMMAND_MASK) == COMMAND_ON) { |   // Get command | ||||||
|     this->mode = climate::CLIMATE_MODE_COOL; |  | ||||||
|   } else if ((remote_state & COMMAND_MASK) == COMMAND_ON_AI) { |  | ||||||
|     this->mode = climate::CLIMATE_MODE_HEAT_COOL; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if ((remote_state & COMMAND_MASK) == COMMAND_OFF) { |   if ((remote_state & COMMAND_MASK) == COMMAND_OFF) { | ||||||
|     this->mode = climate::CLIMATE_MODE_OFF; |     this->mode = climate::CLIMATE_MODE_OFF; | ||||||
|   } else if ((remote_state & COMMAND_MASK) == COMMAND_SWING) { |   } else if ((remote_state & COMMAND_MASK) == COMMAND_SWING) { | ||||||
|     this->swing_mode = |     this->swing_mode = | ||||||
|         this->swing_mode == climate::CLIMATE_SWING_OFF ? climate::CLIMATE_SWING_VERTICAL : climate::CLIMATE_SWING_OFF; |         this->swing_mode == climate::CLIMATE_SWING_OFF ? climate::CLIMATE_SWING_VERTICAL : climate::CLIMATE_SWING_OFF; | ||||||
|   } else { |   } else { | ||||||
|     if ((remote_state & COMMAND_MASK) == COMMAND_AUTO) { |     switch (remote_state & COMMAND_MASK) { | ||||||
|       this->mode = climate::CLIMATE_MODE_HEAT_COOL; |       case COMMAND_DRY: | ||||||
|     } else if ((remote_state & COMMAND_MASK) == COMMAND_DRY_FAN) { |       case COMMAND_ON_DRY: | ||||||
|         this->mode = climate::CLIMATE_MODE_DRY; |         this->mode = climate::CLIMATE_MODE_DRY; | ||||||
|     } else if ((remote_state & COMMAND_MASK) == COMMAND_HEAT) { |         break; | ||||||
|  |       case COMMAND_FAN_ONLY: | ||||||
|  |       case COMMAND_ON_FAN_ONLY: | ||||||
|  |         this->mode = climate::CLIMATE_MODE_FAN_ONLY; | ||||||
|  |         break; | ||||||
|  |       case COMMAND_AI: | ||||||
|  |       case COMMAND_ON_AI: | ||||||
|  |         this->mode = climate::CLIMATE_MODE_HEAT_COOL; | ||||||
|  |         break; | ||||||
|  |       case COMMAND_HEAT: | ||||||
|  |       case COMMAND_ON_HEAT: | ||||||
|         this->mode = climate::CLIMATE_MODE_HEAT; |         this->mode = climate::CLIMATE_MODE_HEAT; | ||||||
|     } else { |         break; | ||||||
|  |       case COMMAND_COOL: | ||||||
|  |       case COMMAND_ON_COOL: | ||||||
|  |       default: | ||||||
|         this->mode = climate::CLIMATE_MODE_COOL; |         this->mode = climate::CLIMATE_MODE_COOL; | ||||||
|  |         break; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Temperature |     // Get fan speed | ||||||
|     if (this->mode == climate::CLIMATE_MODE_COOL || this->mode == climate::CLIMATE_MODE_HEAT) |  | ||||||
|       this->target_temperature = ((remote_state & TEMP_MASK) >> TEMP_SHIFT) + 15; |  | ||||||
|  |  | ||||||
|     // Fan Speed |  | ||||||
|     if (this->mode == climate::CLIMATE_MODE_HEAT_COOL) { |     if (this->mode == climate::CLIMATE_MODE_HEAT_COOL) { | ||||||
|       this->fan_mode = climate::CLIMATE_FAN_AUTO; |       this->fan_mode = climate::CLIMATE_FAN_AUTO; | ||||||
|     } else if (this->mode == climate::CLIMATE_MODE_COOL || this->mode == climate::CLIMATE_MODE_HEAT || |     } else if (this->mode == climate::CLIMATE_MODE_COOL || this->mode == climate::CLIMATE_MODE_DRY || | ||||||
|                this->mode == climate::CLIMATE_MODE_DRY) { |                this->mode == climate::CLIMATE_MODE_FAN_ONLY || this->mode == climate::CLIMATE_MODE_HEAT) { | ||||||
|       if ((remote_state & FAN_MASK) == FAN_AUTO) { |       if ((remote_state & FAN_MASK) == FAN_AUTO) { | ||||||
|         this->fan_mode = climate::CLIMATE_FAN_AUTO; |         this->fan_mode = climate::CLIMATE_FAN_AUTO; | ||||||
|       } else if ((remote_state & FAN_MASK) == FAN_MIN) { |       } else if ((remote_state & FAN_MASK) == FAN_MIN) { | ||||||
| @@ -166,11 +175,17 @@ bool LgIrClimate::on_receive(remote_base::RemoteReceiveData data) { | |||||||
|         this->fan_mode = climate::CLIMATE_FAN_HIGH; |         this->fan_mode = climate::CLIMATE_FAN_HIGH; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // Get temperature | ||||||
|  |     if (this->mode == climate::CLIMATE_MODE_COOL || this->mode == climate::CLIMATE_MODE_HEAT) { | ||||||
|  |       this->target_temperature = ((remote_state & TEMP_MASK) >> TEMP_SHIFT) + 15; | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|   this->publish_state(); |   this->publish_state(); | ||||||
|  |  | ||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| void LgIrClimate::transmit_(uint32_t value) { | void LgIrClimate::transmit_(uint32_t value) { | ||||||
|   calc_checksum_(value); |   calc_checksum_(value); | ||||||
|   ESP_LOGD(TAG, "Sending climate_lg_ir code: 0x%02" PRIX32, value); |   ESP_LOGD(TAG, "Sending climate_lg_ir code: 0x%02" PRIX32, value); | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ const uint8_t TEMP_MAX = 30;  // Celsius | |||||||
| class LgIrClimate : public climate_ir::ClimateIR { | class LgIrClimate : public climate_ir::ClimateIR { | ||||||
|  public: |  public: | ||||||
|   LgIrClimate() |   LgIrClimate() | ||||||
|       : climate_ir::ClimateIR(TEMP_MIN, TEMP_MAX, 1.0f, true, false, |       : climate_ir::ClimateIR(TEMP_MIN, TEMP_MAX, 1.0f, true, true, | ||||||
|                               {climate::CLIMATE_FAN_AUTO, climate::CLIMATE_FAN_LOW, climate::CLIMATE_FAN_MEDIUM, |                               {climate::CLIMATE_FAN_AUTO, climate::CLIMATE_FAN_LOW, climate::CLIMATE_FAN_MEDIUM, | ||||||
|                                climate::CLIMATE_FAN_HIGH}, |                                climate::CLIMATE_FAN_HIGH}, | ||||||
|                               {climate::CLIMATE_SWING_OFF, climate::CLIMATE_SWING_VERTICAL}) {} |                               {climate::CLIMATE_SWING_OFF, climate::CLIMATE_SWING_VERTICAL}) {} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user