mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	Add AEHA IR Protocol (#3726)
This commit is contained in:
		| @@ -1338,3 +1338,48 @@ def midea_dumper(var, config): | ||||
| ) | ||||
| async def midea_action(var, config, args): | ||||
|     cg.add(var.set_code(config[CONF_CODE])) | ||||
|  | ||||
|  | ||||
| # AEHA | ||||
| AEHAData, AEHABinarySensor, AEHATrigger, AEHAAction, AEHADumper = declare_protocol( | ||||
|     "AEHA" | ||||
| ) | ||||
| AEHA_SCHEMA = cv.Schema( | ||||
|     { | ||||
|         cv.Required(CONF_ADDRESS): cv.hex_uint16_t, | ||||
|         cv.Required(CONF_DATA): cv.All( | ||||
|             [cv.Any(cv.hex_uint8_t, cv.uint8_t)], | ||||
|             cv.Length(min=2, max=35), | ||||
|         ), | ||||
|     } | ||||
| ) | ||||
|  | ||||
|  | ||||
| @register_binary_sensor("aeha", AEHABinarySensor, AEHA_SCHEMA) | ||||
| def aeha_binary_sensor(var, config): | ||||
|     cg.add( | ||||
|         var.set_data( | ||||
|             cg.StructInitializer( | ||||
|                 AEHAData, | ||||
|                 ("address", config[CONF_ADDRESS]), | ||||
|                 ("data", config[CONF_DATA]), | ||||
|             ) | ||||
|         ) | ||||
|     ) | ||||
|  | ||||
|  | ||||
| @register_trigger("aeha", AEHATrigger, AEHAData) | ||||
| def aeha_trigger(var, config): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| @register_dumper("aeha", AEHADumper) | ||||
| def aeha_dumper(var, config): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| @register_action("aeha", AEHAAction, AEHA_SCHEMA) | ||||
| async def aeha_action(var, config, args): | ||||
|     template_ = await cg.templatable(config[CONF_ADDRESS], args, cg.uint16) | ||||
|     cg.add(var.set_address(template_)) | ||||
|     cg.add(var.set_data(config[CONF_DATA])) | ||||
|   | ||||
							
								
								
									
										103
									
								
								esphome/components/remote_base/aeha_protocol.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								esphome/components/remote_base/aeha_protocol.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | ||||
| #include "aeha_protocol.h" | ||||
| #include "esphome/core/log.h" | ||||
| #include <cinttypes> | ||||
|  | ||||
| namespace esphome { | ||||
| namespace remote_base { | ||||
|  | ||||
| static const char *const TAG = "remote.aeha"; | ||||
|  | ||||
| static const uint16_t BITWISE = 425; | ||||
| static const uint16_t HEADER_HIGH_US = BITWISE * 8; | ||||
| static const uint16_t HEADER_LOW_US = BITWISE * 4; | ||||
| static const uint16_t BIT_HIGH_US = BITWISE; | ||||
| static const uint16_t BIT_ONE_LOW_US = BITWISE * 3; | ||||
| static const uint16_t BIT_ZERO_LOW_US = BITWISE; | ||||
| static const uint16_t TRAILER = BITWISE; | ||||
|  | ||||
| void AEHAProtocol::encode(RemoteTransmitData *dst, const AEHAData &data) { | ||||
|   dst->set_carrier_frequency(38000); | ||||
|   dst->reserve(2 + 32 + (data.data.size() * 2) + 1); | ||||
|  | ||||
|   dst->item(HEADER_HIGH_US, HEADER_LOW_US); | ||||
|  | ||||
|   for (uint16_t mask = 1 << 15; mask != 0; mask >>= 1) { | ||||
|     if (data.address & mask) { | ||||
|       dst->item(BIT_HIGH_US, BIT_ONE_LOW_US); | ||||
|     } else { | ||||
|       dst->item(BIT_HIGH_US, BIT_ZERO_LOW_US); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   for (uint8_t bit : data.data) { | ||||
|     for (uint8_t mask = 1 << 7; mask != 0; mask >>= 1) { | ||||
|       if (bit & mask) { | ||||
|         dst->item(BIT_HIGH_US, BIT_ONE_LOW_US); | ||||
|       } else { | ||||
|         dst->item(BIT_HIGH_US, BIT_ZERO_LOW_US); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   dst->mark(TRAILER); | ||||
| } | ||||
| optional<AEHAData> AEHAProtocol::decode(RemoteReceiveData src) { | ||||
|   AEHAData out{ | ||||
|       .address = 0, | ||||
|       .data = {}, | ||||
|   }; | ||||
|   if (!src.expect_item(HEADER_HIGH_US, HEADER_LOW_US)) | ||||
|     return {}; | ||||
|  | ||||
|   for (uint16_t mask = 1 << 15; mask != 0; mask >>= 1) { | ||||
|     if (src.expect_item(BIT_HIGH_US, BIT_ONE_LOW_US)) { | ||||
|       out.address |= mask; | ||||
|     } else if (src.expect_item(BIT_HIGH_US, BIT_ZERO_LOW_US)) { | ||||
|       out.address &= ~mask; | ||||
|     } else { | ||||
|       return {}; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   for (uint8_t pos = 0; pos < 35; pos++) { | ||||
|     uint8_t data = 0; | ||||
|     for (uint8_t mask = 1 << 7; mask != 0; mask >>= 1) { | ||||
|       if (src.expect_item(BIT_HIGH_US, BIT_ONE_LOW_US)) { | ||||
|         data |= mask; | ||||
|       } else if (src.expect_item(BIT_HIGH_US, BIT_ZERO_LOW_US)) { | ||||
|         data &= ~mask; | ||||
|       } else if (pos > 1 && src.expect_mark(TRAILER)) { | ||||
|         return out; | ||||
|       } else { | ||||
|         return {}; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     out.data.push_back(data); | ||||
|   } | ||||
|  | ||||
|   if (src.expect_mark(TRAILER)) { | ||||
|     return out; | ||||
|   } | ||||
|  | ||||
|   return {}; | ||||
| } | ||||
|  | ||||
| std::string AEHAProtocol::format_data_(const std::vector<uint8_t> &data) { | ||||
|   std::string out; | ||||
|   for (uint8_t byte : data) { | ||||
|     char buf[6]; | ||||
|     sprintf(buf, "0x%02X,", byte); | ||||
|     out += buf; | ||||
|   } | ||||
|   out.pop_back(); | ||||
|   return out; | ||||
| } | ||||
|  | ||||
| void AEHAProtocol::dump(const AEHAData &data) { | ||||
|   auto data_str = format_data_(data.data); | ||||
|   ESP_LOGD(TAG, "Received AEHA: address=0x%04X, data=[%s]", data.address, data_str.c_str()); | ||||
| } | ||||
|  | ||||
| }  // namespace remote_base | ||||
| }  // namespace esphome | ||||
							
								
								
									
										42
									
								
								esphome/components/remote_base/aeha_protocol.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								esphome/components/remote_base/aeha_protocol.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "remote_base.h" | ||||
|  | ||||
| namespace esphome { | ||||
| namespace remote_base { | ||||
|  | ||||
| struct AEHAData { | ||||
|   uint16_t address; | ||||
|   std::vector<uint8_t> data; | ||||
|  | ||||
|   bool operator==(const AEHAData &rhs) const { return address == rhs.address && data == rhs.data; } | ||||
| }; | ||||
|  | ||||
| class AEHAProtocol : public RemoteProtocol<AEHAData> { | ||||
|  public: | ||||
|   void encode(RemoteTransmitData *dst, const AEHAData &data) override; | ||||
|   optional<AEHAData> decode(RemoteReceiveData src) override; | ||||
|   void dump(const AEHAData &data) override; | ||||
|  | ||||
|  private: | ||||
|   std::string format_data_(const std::vector<uint8_t> &data); | ||||
| }; | ||||
|  | ||||
| DECLARE_REMOTE_PROTOCOL(AEHA) | ||||
|  | ||||
| template<typename... Ts> class AEHAAction : public RemoteTransmitterActionBase<Ts...> { | ||||
|  public: | ||||
|   TEMPLATABLE_VALUE(uint16_t, address) | ||||
|   TEMPLATABLE_VALUE(std::vector<uint8_t>, data) | ||||
|  | ||||
|   void set_data(const std::vector<uint8_t> &data) { data_ = data; } | ||||
|   void encode(RemoteTransmitData *dst, Ts... x) override { | ||||
|     AEHAData data{}; | ||||
|     data.address = this->address_.value(x...); | ||||
|     data.data = this->data_.value(x...); | ||||
|     AEHAProtocol().encode(dst, data); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| }  // namespace remote_base | ||||
| }  // namespace esphome | ||||
| @@ -2085,6 +2085,13 @@ switch: | ||||
|     turn_on_action: | ||||
|       remote_transmitter.transmit_raw: | ||||
|         code: [1000, -1000] | ||||
|   - platform: template | ||||
|     name: AEHA | ||||
|     id: eaha_hitachi_climate_power_on | ||||
|     turn_on_action: | ||||
|       remote_transmitter.transmit_aeha: | ||||
|         address: 0x8008 | ||||
|         data: [0x00, 0x02, 0xFD, 0xFF, 0x00, 0x33, 0xCC, 0x49, 0xB6, 0xC8, 0x37, 0x16, 0xE9, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xCA, 0x35, 0x8F, 0x70, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF] | ||||
|   - platform: template | ||||
|     name: Living Room Lights | ||||
|     id: livingroom_lights | ||||
|   | ||||
		Reference in New Issue
	
	Block a user