mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	Add Toshiba AC generic IR remote protocol (#2019)
This commit is contained in:
		| @@ -950,6 +950,53 @@ async def samsung36_action(var, config, args): | |||||||
|     cg.add(var.set_command(template_)) |     cg.add(var.set_command(template_)) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # Toshiba AC | ||||||
|  | ( | ||||||
|  |     ToshibaAcData, | ||||||
|  |     ToshibaAcBinarySensor, | ||||||
|  |     ToshibaAcTrigger, | ||||||
|  |     ToshibaAcAction, | ||||||
|  |     ToshibaAcDumper, | ||||||
|  | ) = declare_protocol("ToshibaAc") | ||||||
|  | TOSHIBAAC_SCHEMA = cv.Schema( | ||||||
|  |     { | ||||||
|  |         cv.Required(CONF_RC_CODE_1): cv.hex_uint64_t, | ||||||
|  |         cv.Optional(CONF_RC_CODE_2, default=0): cv.hex_uint64_t, | ||||||
|  |     } | ||||||
|  | ) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @register_binary_sensor("toshiba_ac", ToshibaAcBinarySensor, TOSHIBAAC_SCHEMA) | ||||||
|  | def toshibaac_binary_sensor(var, config): | ||||||
|  |     cg.add( | ||||||
|  |         var.set_data( | ||||||
|  |             cg.StructInitializer( | ||||||
|  |                 ToshibaAcData, | ||||||
|  |                 ("rc_code_1", config[CONF_RC_CODE_1]), | ||||||
|  |                 ("rc_code_2", config[CONF_RC_CODE_2]), | ||||||
|  |             ) | ||||||
|  |         ) | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @register_trigger("toshiba_ac", ToshibaAcTrigger, ToshibaAcData) | ||||||
|  | def toshibaac_trigger(var, config): | ||||||
|  |     pass | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @register_dumper("toshiba_ac", ToshibaAcDumper) | ||||||
|  | def toshibaac_dumper(var, config): | ||||||
|  |     pass | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @register_action("toshiba_ac", ToshibaAcAction, TOSHIBAAC_SCHEMA) | ||||||
|  | async def toshibaac_action(var, config, args): | ||||||
|  |     template_ = await cg.templatable(config[CONF_RC_CODE_1], args, cg.uint64) | ||||||
|  |     cg.add(var.set_rc_code_1(template_)) | ||||||
|  |     template_ = await cg.templatable(config[CONF_RC_CODE_2], args, cg.uint64) | ||||||
|  |     cg.add(var.set_rc_code_2(template_)) | ||||||
|  |  | ||||||
|  |  | ||||||
| # Panasonic | # Panasonic | ||||||
| ( | ( | ||||||
|     PanasonicData, |     PanasonicData, | ||||||
|   | |||||||
							
								
								
									
										111
									
								
								esphome/components/remote_base/toshiba_ac_protocol.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								esphome/components/remote_base/toshiba_ac_protocol.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,111 @@ | |||||||
|  | #include "toshiba_ac_protocol.h" | ||||||
|  | #include "esphome/core/log.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace remote_base { | ||||||
|  |  | ||||||
|  | static const char *const TAG = "remote.toshibaac"; | ||||||
|  |  | ||||||
|  | static const uint32_t HEADER_HIGH_US = 4500; | ||||||
|  | static const uint32_t HEADER_LOW_US = 4500; | ||||||
|  | static const uint32_t BIT_HIGH_US = 560; | ||||||
|  | static const uint32_t BIT_ONE_LOW_US = 1690; | ||||||
|  | static const uint32_t BIT_ZERO_LOW_US = 560; | ||||||
|  | static const uint32_t FOOTER_HIGH_US = 560; | ||||||
|  | static const uint32_t FOOTER_LOW_US = 4500; | ||||||
|  | static const uint16_t PACKET_SPACE = 5500; | ||||||
|  |  | ||||||
|  | void ToshibaAcProtocol::encode(RemoteTransmitData *dst, const ToshibaAcData &data) { | ||||||
|  |   dst->set_carrier_frequency(38000); | ||||||
|  |   dst->reserve((3 + (48 * 2)) * 3); | ||||||
|  |  | ||||||
|  |   for (uint8_t repeat = 0; repeat < 2; repeat++) { | ||||||
|  |     dst->item(HEADER_HIGH_US, HEADER_LOW_US); | ||||||
|  |     for (uint8_t bit = 48; bit > 0; bit--) { | ||||||
|  |       dst->mark(BIT_HIGH_US); | ||||||
|  |       if ((data.rc_code_1 >> (bit - 1)) & 1) | ||||||
|  |         dst->space(BIT_ONE_LOW_US); | ||||||
|  |       else | ||||||
|  |         dst->space(BIT_ZERO_LOW_US); | ||||||
|  |     } | ||||||
|  |     dst->item(FOOTER_HIGH_US, FOOTER_LOW_US); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (data.rc_code_2 != 0) { | ||||||
|  |     dst->item(HEADER_HIGH_US, HEADER_LOW_US); | ||||||
|  |     for (uint8_t bit = 48; bit > 0; bit--) { | ||||||
|  |       dst->mark(BIT_HIGH_US); | ||||||
|  |       if ((data.rc_code_2 >> (bit - 1)) & 1) | ||||||
|  |         dst->space(BIT_ONE_LOW_US); | ||||||
|  |       else | ||||||
|  |         dst->space(BIT_ZERO_LOW_US); | ||||||
|  |     } | ||||||
|  |     dst->item(FOOTER_HIGH_US, FOOTER_LOW_US); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | optional<ToshibaAcData> ToshibaAcProtocol::decode(RemoteReceiveData src) { | ||||||
|  |   uint64_t packet = 0; | ||||||
|  |   ToshibaAcData out{ | ||||||
|  |       .rc_code_1 = 0, | ||||||
|  |       .rc_code_2 = 0, | ||||||
|  |   }; | ||||||
|  |   // *** Packet 1 | ||||||
|  |   if (!src.expect_item(HEADER_HIGH_US, HEADER_LOW_US)) | ||||||
|  |     return {}; | ||||||
|  |   for (uint8_t bit_counter = 0; bit_counter < 48; bit_counter++) { | ||||||
|  |     if (src.expect_item(BIT_HIGH_US, BIT_ONE_LOW_US)) { | ||||||
|  |       packet = (packet << 1) | 1; | ||||||
|  |     } else if (src.expect_item(BIT_HIGH_US, BIT_ZERO_LOW_US)) { | ||||||
|  |       packet = (packet << 1) | 0; | ||||||
|  |     } else { | ||||||
|  |       return {}; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   if (!src.expect_item(FOOTER_HIGH_US, PACKET_SPACE)) | ||||||
|  |     return {}; | ||||||
|  |  | ||||||
|  |   // *** Packet 2 | ||||||
|  |   if (!src.expect_item(HEADER_HIGH_US, HEADER_LOW_US)) | ||||||
|  |     return {}; | ||||||
|  |   for (uint8_t bit_counter = 0; bit_counter < 48; bit_counter++) { | ||||||
|  |     if (src.expect_item(BIT_HIGH_US, BIT_ONE_LOW_US)) { | ||||||
|  |       out.rc_code_1 = (out.rc_code_1 << 1) | 1; | ||||||
|  |     } else if (src.expect_item(BIT_HIGH_US, BIT_ZERO_LOW_US)) { | ||||||
|  |       out.rc_code_1 = (out.rc_code_1 << 1) | 0; | ||||||
|  |     } else { | ||||||
|  |       return {}; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   // The first two packets must match | ||||||
|  |   if (packet != out.rc_code_1) | ||||||
|  |     return {}; | ||||||
|  |   // The third packet isn't always present | ||||||
|  |   if (!src.expect_item(FOOTER_HIGH_US, PACKET_SPACE)) | ||||||
|  |     return out; | ||||||
|  |  | ||||||
|  |   // *** Packet 3 | ||||||
|  |   if (!src.expect_item(HEADER_HIGH_US, HEADER_LOW_US)) | ||||||
|  |     return {}; | ||||||
|  |   for (uint8_t bit_counter = 0; bit_counter < 48; bit_counter++) { | ||||||
|  |     if (src.expect_item(BIT_HIGH_US, BIT_ONE_LOW_US)) { | ||||||
|  |       out.rc_code_2 = (out.rc_code_2 << 1) | 1; | ||||||
|  |     } else if (src.expect_item(BIT_HIGH_US, BIT_ZERO_LOW_US)) { | ||||||
|  |       out.rc_code_2 = (out.rc_code_2 << 1) | 0; | ||||||
|  |     } else { | ||||||
|  |       return {}; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return out; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ToshibaAcProtocol::dump(const ToshibaAcData &data) { | ||||||
|  |   if (data.rc_code_2 != 0) | ||||||
|  |     ESP_LOGD(TAG, "Received Toshiba AC: rc_code_1=0x%" PRIX64 ", rc_code_2=0x%" PRIX64, data.rc_code_1, data.rc_code_2); | ||||||
|  |   else | ||||||
|  |     ESP_LOGD(TAG, "Received Toshiba AC: rc_code_1=0x%" PRIX64, data.rc_code_1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | }  // namespace remote_base | ||||||
|  | }  // namespace esphome | ||||||
							
								
								
									
										39
									
								
								esphome/components/remote_base/toshiba_ac_protocol.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								esphome/components/remote_base/toshiba_ac_protocol.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "esphome/core/component.h" | ||||||
|  | #include "remote_base.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace remote_base { | ||||||
|  |  | ||||||
|  | struct ToshibaAcData { | ||||||
|  |   uint64_t rc_code_1; | ||||||
|  |   uint64_t rc_code_2; | ||||||
|  |  | ||||||
|  |   bool operator==(const ToshibaAcData &rhs) const { return rc_code_1 == rhs.rc_code_1 && rc_code_2 == rhs.rc_code_2; } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | class ToshibaAcProtocol : public RemoteProtocol<ToshibaAcData> { | ||||||
|  |  public: | ||||||
|  |   void encode(RemoteTransmitData *dst, const ToshibaAcData &data) override; | ||||||
|  |   optional<ToshibaAcData> decode(RemoteReceiveData src) override; | ||||||
|  |   void dump(const ToshibaAcData &data) override; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | DECLARE_REMOTE_PROTOCOL(ToshibaAc) | ||||||
|  |  | ||||||
|  | template<typename... Ts> class ToshibaAcAction : public RemoteTransmitterActionBase<Ts...> { | ||||||
|  |  public: | ||||||
|  |   TEMPLATABLE_VALUE(uint64_t, rc_code_1) | ||||||
|  |   TEMPLATABLE_VALUE(uint64_t, rc_code_2) | ||||||
|  |  | ||||||
|  |   void encode(RemoteTransmitData *dst, Ts... x) override { | ||||||
|  |     ToshibaAcData data{}; | ||||||
|  |     data.rc_code_1 = this->rc_code_1_.value(x...); | ||||||
|  |     data.rc_code_2 = this->rc_code_2_.value(x...); | ||||||
|  |     ToshibaAcProtocol().encode(dst, data); | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }  // namespace remote_base | ||||||
|  | }  // namespace esphome | ||||||
| @@ -1626,6 +1626,12 @@ switch: | |||||||
|       remote_transmitter.transmit_samsung36: |       remote_transmitter.transmit_samsung36: | ||||||
|         address: 0x0400 |         address: 0x0400 | ||||||
|         command: 0x000E00FF |         command: 0x000E00FF | ||||||
|  |   - platform: template | ||||||
|  |     name: ToshibaAC | ||||||
|  |     turn_on_action: | ||||||
|  |       - remote_transmitter.transmit_toshiba_ac: | ||||||
|  |           rc_code_1: 0xB24DBF4050AF | ||||||
|  |           rc_code_2: 0xD5660001003C | ||||||
|   - platform: template |   - platform: template | ||||||
|     name: Sony |     name: Sony | ||||||
|     turn_on_action: |     turn_on_action: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user