mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	add tcl112 support for dry, fan and swing (#939)
This commit is contained in:
		
				
					committed by
					
						 Otto Winter
						Otto Winter
					
				
			
			
				
	
			
			
			
						parent
						
							d7a2816c58
						
					
				
				
					commit
					92d93d658c
				
			| @@ -15,6 +15,12 @@ const uint8_t TCL112_COOL = 3; | ||||
| const uint8_t TCL112_FAN = 7; | ||||
| const uint8_t TCL112_AUTO = 8; | ||||
|  | ||||
| const uint8_t TCL112_FAN_AUTO = 0; | ||||
| const uint8_t TCL112_FAN_LOW = 2; | ||||
| const uint8_t TCL112_FAN_MED = 3; | ||||
| const uint8_t TCL112_FAN_HIGH = 5; | ||||
|  | ||||
| const uint8_t TCL112_VSWING_MASK = 0x38; | ||||
| const uint8_t TCL112_POWER_MASK = 0x04; | ||||
|  | ||||
| const uint8_t TCL112_HALF_DEGREE = 0b00100000; | ||||
| @@ -53,6 +59,14 @@ void Tcl112Climate::transmit_state() { | ||||
|       remote_state[6] &= 0xF0; | ||||
|       remote_state[6] |= TCL112_HEAT; | ||||
|       break; | ||||
|     case climate::CLIMATE_MODE_DRY: | ||||
|       remote_state[6] &= 0xF0; | ||||
|       remote_state[6] |= TCL112_DRY; | ||||
|       break; | ||||
|     case climate::CLIMATE_MODE_FAN_ONLY: | ||||
|       remote_state[6] &= 0xF0; | ||||
|       remote_state[6] |= TCL112_FAN; | ||||
|       break; | ||||
|     case climate::CLIMATE_MODE_OFF: | ||||
|     default: | ||||
|       remote_state[5] &= ~TCL112_POWER_MASK; | ||||
| @@ -72,6 +86,29 @@ void Tcl112Climate::transmit_state() { | ||||
|   remote_state[7] &= 0xF0;                    // Clear temp bits. | ||||
|   remote_state[7] |= ((uint8_t) TCL112_TEMP_MAX - half_degrees / 2); | ||||
|  | ||||
|   // Set fan | ||||
|   uint8_t selected_fan; | ||||
|   switch (this->fan_mode) { | ||||
|     case climate::CLIMATE_FAN_HIGH: | ||||
|       selected_fan = TCL112_FAN_HIGH; | ||||
|       break; | ||||
|     case climate::CLIMATE_FAN_MEDIUM: | ||||
|       selected_fan = TCL112_FAN_MED; | ||||
|       break; | ||||
|     case climate::CLIMATE_FAN_LOW: | ||||
|       selected_fan = TCL112_FAN_LOW; | ||||
|       break; | ||||
|     case climate::CLIMATE_FAN_AUTO: | ||||
|     default: | ||||
|       selected_fan = TCL112_FAN_AUTO; | ||||
|   } | ||||
|   remote_state[8] |= selected_fan; | ||||
|  | ||||
|   // Set swing | ||||
|   if (this->swing_mode == climate::CLIMATE_SWING_VERTICAL) { | ||||
|     remote_state[8] |= TCL112_VSWING_MASK; | ||||
|   } | ||||
|  | ||||
|   // Calculate & set the checksum for the current internal state of the remote. | ||||
|   // Stored the checksum value in the last byte. | ||||
|   for (uint8_t checksum_byte = 0; checksum_byte < TCL112_STATE_LENGTH - 1; checksum_byte++) | ||||
| @@ -107,7 +144,7 @@ void Tcl112Climate::transmit_state() { | ||||
| bool Tcl112Climate::on_receive(remote_base::RemoteReceiveData data) { | ||||
|   // Validate header | ||||
|   if (!data.expect_item(TCL112_HEADER_MARK, TCL112_HEADER_SPACE)) { | ||||
|     ESP_LOGV(TAG, "Header fail"); | ||||
|     ESP_LOGVV(TAG, "Header fail"); | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
| @@ -119,14 +156,14 @@ bool Tcl112Climate::on_receive(remote_base::RemoteReceiveData data) { | ||||
|       if (data.expect_item(TCL112_BIT_MARK, TCL112_ONE_SPACE)) | ||||
|         remote_state[i] |= 1 << j; | ||||
|       else if (!data.expect_item(TCL112_BIT_MARK, TCL112_ZERO_SPACE)) { | ||||
|         ESP_LOGV(TAG, "Byte %d bit %d fail", i, j); | ||||
|         ESP_LOGVV(TAG, "Byte %d bit %d fail", i, j); | ||||
|         return false; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   // Validate footer | ||||
|   if (!data.expect_mark(TCL112_BIT_MARK)) { | ||||
|     ESP_LOGV(TAG, "Footer fail"); | ||||
|     ESP_LOGVV(TAG, "Footer fail"); | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
| @@ -136,7 +173,7 @@ bool Tcl112Climate::on_receive(remote_base::RemoteReceiveData data) { | ||||
|   for (uint8_t checksum_byte = 0; checksum_byte < TCL112_STATE_LENGTH - 1; checksum_byte++) | ||||
|     checksum += remote_state[checksum_byte]; | ||||
|   if (checksum != remote_state[TCL112_STATE_LENGTH - 1]) { | ||||
|     ESP_LOGV(TAG, "Checksum fail"); | ||||
|     ESP_LOGVV(TAG, "Checksum fail"); | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
| @@ -161,7 +198,11 @@ bool Tcl112Climate::on_receive(remote_base::RemoteReceiveData data) { | ||||
|         this->mode = climate::CLIMATE_MODE_COOL; | ||||
|         break; | ||||
|       case TCL112_DRY: | ||||
|         this->mode = climate::CLIMATE_MODE_DRY; | ||||
|         break; | ||||
|       case TCL112_FAN: | ||||
|         this->mode = climate::CLIMATE_MODE_FAN_ONLY; | ||||
|         break; | ||||
|       case TCL112_AUTO: | ||||
|         this->mode = climate::CLIMATE_MODE_AUTO; | ||||
|         break; | ||||
| @@ -171,6 +212,28 @@ bool Tcl112Climate::on_receive(remote_base::RemoteReceiveData data) { | ||||
|   if (remote_state[12] & TCL112_HALF_DEGREE) | ||||
|     temp += .5f; | ||||
|   this->target_temperature = temp; | ||||
|   auto fan = remote_state[8] & 0x7; | ||||
|   switch (fan) { | ||||
|     case TCL112_FAN_HIGH: | ||||
|       this->fan_mode = climate::CLIMATE_FAN_HIGH; | ||||
|       break; | ||||
|     case TCL112_FAN_MED: | ||||
|       this->fan_mode = climate::CLIMATE_FAN_MEDIUM; | ||||
|       break; | ||||
|     case TCL112_FAN_LOW: | ||||
|       this->fan_mode = climate::CLIMATE_FAN_LOW; | ||||
|       break; | ||||
|     case TCL112_FAN_AUTO: | ||||
|     default: | ||||
|       this->fan_mode = climate::CLIMATE_FAN_AUTO; | ||||
|       break; | ||||
|   } | ||||
|   if ((remote_state[8] & TCL112_VSWING_MASK) == TCL112_VSWING_MASK) { | ||||
|     this->swing_mode = climate::CLIMATE_SWING_VERTICAL; | ||||
|   } else { | ||||
|     this->swing_mode = climate::CLIMATE_SWING_OFF; | ||||
|   } | ||||
|  | ||||
|   this->publish_state(); | ||||
|   return true; | ||||
| } | ||||
|   | ||||
| @@ -11,7 +11,11 @@ const float TCL112_TEMP_MIN = 16.0; | ||||
|  | ||||
| class Tcl112Climate : public climate_ir::ClimateIR { | ||||
|  public: | ||||
|   Tcl112Climate() : climate_ir::ClimateIR(TCL112_TEMP_MIN, TCL112_TEMP_MAX, .5f) {} | ||||
|   Tcl112Climate() | ||||
|       : climate_ir::ClimateIR(TCL112_TEMP_MIN, TCL112_TEMP_MAX, .5f, 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}) {} | ||||
|  | ||||
|  protected: | ||||
|   /// Transmit via IR the state of this climate controller. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user