mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	Added samsung36 ir protocol (#1438)
* Added samsung36 ir protocol * Make linter happy * Added test and fixed python failure * Sorry for the commits but linter was still not happy :) * Okay have to run script/clang-format -i Co-authored-by: tuxBurner <tuxBurner@boggo.de>
This commit is contained in:
		| @@ -686,6 +686,42 @@ def samsung_action(var, config, args): | |||||||
|     cg.add(var.set_data(template_)) |     cg.add(var.set_data(template_)) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # Samsung36 | ||||||
|  | (Samsung36Data, Samsung36BinarySensor, Samsung36Trigger, Samsung36Action, | ||||||
|  |  Samsung36Dumper) = declare_protocol('Samsung36') | ||||||
|  | SAMSUNG36_SCHEMA = cv.Schema({ | ||||||
|  |     cv.Required(CONF_ADDRESS): cv.hex_uint16_t, | ||||||
|  |     cv.Required(CONF_COMMAND): cv.hex_uint32_t, | ||||||
|  | }) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @register_binary_sensor('samsung36', Samsung36BinarySensor, SAMSUNG36_SCHEMA) | ||||||
|  | def samsung36_binary_sensor(var, config): | ||||||
|  |     cg.add(var.set_data(cg.StructInitializer( | ||||||
|  |         Samsung36Data, | ||||||
|  |         ('address', config[CONF_ADDRESS]), | ||||||
|  |         ('command', config[CONF_COMMAND]), | ||||||
|  |     ))) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @register_trigger('samsung36', Samsung36Trigger, Samsung36Data) | ||||||
|  | def samsung36_trigger(var, config): | ||||||
|  |     pass | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @register_dumper('samsung36', Samsung36Dumper) | ||||||
|  | def samsung36_dumper(var, config): | ||||||
|  |     pass | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @register_action('samsung36', Samsung36Action, SAMSUNG36_SCHEMA) | ||||||
|  | def samsung36_action(var, config, args): | ||||||
|  |     template_ = yield cg.templatable(config[CONF_ADDRESS], args, cg.uint16) | ||||||
|  |     cg.add(var.set_address(template_)) | ||||||
|  |     template_ = yield cg.templatable(config[CONF_COMMAND], args, cg.uint32) | ||||||
|  |     cg.add(var.set_command(template_)) | ||||||
|  |  | ||||||
|  |  | ||||||
| # Panasonic | # Panasonic | ||||||
| (PanasonicData, PanasonicBinarySensor, PanasonicTrigger, PanasonicAction, | (PanasonicData, PanasonicBinarySensor, PanasonicTrigger, PanasonicAction, | ||||||
|  PanasonicDumper) = declare_protocol('Panasonic') |  PanasonicDumper) = declare_protocol('Panasonic') | ||||||
|   | |||||||
							
								
								
									
										103
									
								
								esphome/components/remote_base/samsung36_protocol.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								esphome/components/remote_base/samsung36_protocol.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | |||||||
|  | #include "samsung36_protocol.h" | ||||||
|  | #include "esphome/core/log.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace remote_base { | ||||||
|  |  | ||||||
|  | static const char *TAG = "remote.samsung36"; | ||||||
|  |  | ||||||
|  | static const uint8_t NBITS = 78; | ||||||
|  |  | ||||||
|  | static const uint32_t HEADER_HIGH_US = 4500; | ||||||
|  | static const uint32_t HEADER_LOW_US = 4500; | ||||||
|  | static const uint32_t BIT_HIGH_US = 500; | ||||||
|  | static const uint32_t BIT_ONE_LOW_US = 1500; | ||||||
|  | static const uint32_t BIT_ZERO_LOW_US = 500; | ||||||
|  | static const uint32_t MIDDLE_HIGH_US = 500; | ||||||
|  | static const uint32_t MIDDLE_LOW_US = 4500; | ||||||
|  | static const uint32_t FOOTER_HIGH_US = 500; | ||||||
|  | static const uint32_t FOOTER_LOW_US = 59000; | ||||||
|  |  | ||||||
|  | void Samsung36Protocol::encode(RemoteTransmitData *dst, const Samsung36Data &data) { | ||||||
|  |   dst->set_carrier_frequency(38000); | ||||||
|  |   dst->reserve(NBITS); | ||||||
|  |  | ||||||
|  |   // send header | ||||||
|  |   dst->item(HEADER_HIGH_US, HEADER_LOW_US); | ||||||
|  |  | ||||||
|  |   // send first 16 bits | ||||||
|  |   for (uint32_t mask = 1UL << 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); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // send middle header | ||||||
|  |   dst->item(MIDDLE_HIGH_US, MIDDLE_LOW_US); | ||||||
|  |  | ||||||
|  |   // send last 20 bits | ||||||
|  |   for (uint32_t mask = 1UL << 19; mask != 0; mask >>= 1) { | ||||||
|  |     if (data.command & mask) { | ||||||
|  |       dst->item(BIT_HIGH_US, BIT_ONE_LOW_US); | ||||||
|  |     } else { | ||||||
|  |       dst->item(BIT_HIGH_US, BIT_ZERO_LOW_US); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // footer | ||||||
|  |   dst->item(FOOTER_HIGH_US, FOOTER_LOW_US); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | optional<Samsung36Data> Samsung36Protocol::decode(RemoteReceiveData src) { | ||||||
|  |   Samsung36Data out{ | ||||||
|  |       .address = 0, | ||||||
|  |       .command = 0, | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   // check if header matches | ||||||
|  |   if (!src.expect_item(HEADER_HIGH_US, HEADER_LOW_US)) | ||||||
|  |     return {}; | ||||||
|  |  | ||||||
|  |   // check if we have enough bits | ||||||
|  |   if (src.size() != NBITS) | ||||||
|  |     return {}; | ||||||
|  |  | ||||||
|  |   // get the first 16 bits | ||||||
|  |   for (uint8_t i = 0; i < 16; i++) { | ||||||
|  |     out.address <<= 1UL; | ||||||
|  |     if (src.expect_item(BIT_HIGH_US, BIT_ONE_LOW_US)) { | ||||||
|  |       out.address |= 1UL; | ||||||
|  |     } else if (src.expect_item(BIT_HIGH_US, BIT_ZERO_LOW_US)) { | ||||||
|  |       out.address |= 0UL; | ||||||
|  |     } else { | ||||||
|  |       return {}; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // check if the middle mark matches | ||||||
|  |   if (!src.expect_item(MIDDLE_HIGH_US, MIDDLE_LOW_US)) { | ||||||
|  |     return {}; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // get the last 20 bits | ||||||
|  |   for (uint8_t i = 0; i < 20; i++) { | ||||||
|  |     out.command <<= 1UL; | ||||||
|  |     if (src.expect_item(BIT_HIGH_US, BIT_ONE_LOW_US)) { | ||||||
|  |       out.command |= 1UL; | ||||||
|  |     } else if (src.expect_item(BIT_HIGH_US, BIT_ZERO_LOW_US)) { | ||||||
|  |       out.command |= 0UL; | ||||||
|  |     } else { | ||||||
|  |       return {}; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return out; | ||||||
|  | } | ||||||
|  | void Samsung36Protocol::dump(const Samsung36Data &data) { | ||||||
|  |   ESP_LOGD(TAG, "Received Samsung36: address=0x%04X, command=0x%08X", data.address, data.command); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | }  // namespace remote_base | ||||||
|  | }  // namespace esphome | ||||||
							
								
								
									
										39
									
								
								esphome/components/remote_base/samsung36_protocol.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								esphome/components/remote_base/samsung36_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 Samsung36Data { | ||||||
|  |   uint16_t address; | ||||||
|  |   uint32_t command; | ||||||
|  |  | ||||||
|  |   bool operator==(const Samsung36Data &rhs) const { return address == rhs.address && command == rhs.command; } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | class Samsung36Protocol : public RemoteProtocol<Samsung36Data> { | ||||||
|  |  public: | ||||||
|  |   void encode(RemoteTransmitData *dst, const Samsung36Data &data) override; | ||||||
|  |   optional<Samsung36Data> decode(RemoteReceiveData src) override; | ||||||
|  |   void dump(const Samsung36Data &data) override; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | DECLARE_REMOTE_PROTOCOL(Samsung36) | ||||||
|  |  | ||||||
|  | template<typename... Ts> class Samsung36Action : public RemoteTransmitterActionBase<Ts...> { | ||||||
|  |  public: | ||||||
|  |   TEMPLATABLE_VALUE(uint16_t, address) | ||||||
|  |   TEMPLATABLE_VALUE(uint32_t, command) | ||||||
|  |  | ||||||
|  |   void encode(RemoteTransmitData *dst, Ts... x) override { | ||||||
|  |     Samsung36Data data{}; | ||||||
|  |     data.address = this->address_.value(x...); | ||||||
|  |     data.command = this->command_.value(x...); | ||||||
|  |     Samsung36Protocol().encode(dst, data); | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }  // namespace remote_base | ||||||
|  | }  // namespace esphome | ||||||
| @@ -1478,6 +1478,12 @@ switch: | |||||||
|     turn_on_action: |     turn_on_action: | ||||||
|       remote_transmitter.transmit_samsung: |       remote_transmitter.transmit_samsung: | ||||||
|         data: 0xABCDEF |         data: 0xABCDEF | ||||||
|  |   - platform: template | ||||||
|  |     name: Samsung36 | ||||||
|  |     turn_on_action: | ||||||
|  |       remote_transmitter.transmit_samsung36: | ||||||
|  |         address: 0x0400 | ||||||
|  |         command: 0x000E00FF       | ||||||
|   - platform: template |   - platform: template | ||||||
|     name: Sony |     name: Sony | ||||||
|     turn_on_action: |     turn_on_action: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user