mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	Add xor automation condition (#5453)
This commit is contained in:
		| @@ -141,6 +141,7 @@ AUTOMATION_SCHEMA = cv.Schema( | |||||||
| AndCondition = cg.esphome_ns.class_("AndCondition", Condition) | AndCondition = cg.esphome_ns.class_("AndCondition", Condition) | ||||||
| OrCondition = cg.esphome_ns.class_("OrCondition", Condition) | OrCondition = cg.esphome_ns.class_("OrCondition", Condition) | ||||||
| NotCondition = cg.esphome_ns.class_("NotCondition", Condition) | NotCondition = cg.esphome_ns.class_("NotCondition", Condition) | ||||||
|  | XorCondition = cg.esphome_ns.class_("XorCondition", Condition) | ||||||
|  |  | ||||||
|  |  | ||||||
| @register_condition("and", AndCondition, validate_condition_list) | @register_condition("and", AndCondition, validate_condition_list) | ||||||
| @@ -161,6 +162,12 @@ async def not_condition_to_code(config, condition_id, template_arg, args): | |||||||
|     return cg.new_Pvariable(condition_id, template_arg, condition) |     return cg.new_Pvariable(condition_id, template_arg, condition) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @register_condition("xor", XorCondition, validate_condition_list) | ||||||
|  | async def xor_condition_to_code(config, condition_id, template_arg, args): | ||||||
|  |     conditions = await build_condition_list(config, template_arg, args) | ||||||
|  |     return cg.new_Pvariable(condition_id, template_arg, conditions) | ||||||
|  |  | ||||||
|  |  | ||||||
| @register_condition("lambda", LambdaCondition, cv.returning_lambda) | @register_condition("lambda", LambdaCondition, cv.returning_lambda) | ||||||
| async def lambda_condition_to_code(config, condition_id, template_arg, args): | async def lambda_condition_to_code(config, condition_id, template_arg, args): | ||||||
|     lambda_ = await cg.process_lambda(config, args, return_type=bool) |     lambda_ = await cg.process_lambda(config, args, return_type=bool) | ||||||
|   | |||||||
| @@ -48,6 +48,22 @@ template<typename... Ts> class NotCondition : public Condition<Ts...> { | |||||||
|   Condition<Ts...> *condition_; |   Condition<Ts...> *condition_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | template<typename... Ts> class XorCondition : public Condition<Ts...> { | ||||||
|  |  public: | ||||||
|  |   explicit XorCondition(const std::vector<Condition<Ts...> *> &conditions) : conditions_(conditions) {} | ||||||
|  |   bool check(Ts... x) override { | ||||||
|  |     bool xor_state = false; | ||||||
|  |     for (auto *condition : this->conditions_) { | ||||||
|  |       xor_state = xor_state ^ condition->check(x...); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return xor_state; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  protected: | ||||||
|  |   std::vector<Condition<Ts...> *> conditions_; | ||||||
|  | }; | ||||||
|  |  | ||||||
| template<typename... Ts> class LambdaCondition : public Condition<Ts...> { | template<typename... Ts> class LambdaCondition : public Condition<Ts...> { | ||||||
|  public: |  public: | ||||||
|   explicit LambdaCondition(std::function<bool(Ts...)> &&f) : f_(std::move(f)) {} |   explicit LambdaCondition(std::function<bool(Ts...)> &&f) : f_(std::move(f)) {} | ||||||
|   | |||||||
| @@ -3104,11 +3104,39 @@ time: | |||||||
|   - platform: ds1307 |   - platform: ds1307 | ||||||
|     id: ds1307_time |     id: ds1307_time | ||||||
|     update_interval: never |     update_interval: never | ||||||
|     on_time: |  | ||||||
|       seconds: 0 |  | ||||||
|       then: ds1307.read_time |  | ||||||
|     i2c_id: i2c_bus |     i2c_id: i2c_bus | ||||||
|  |     on_time: | ||||||
|  |       - seconds: 0 | ||||||
|  |         then: ds1307.read_time | ||||||
|  |       - at: "16:00:00" | ||||||
|  |         then: | ||||||
|  |           - if: | ||||||
|  |               condition: | ||||||
|  |                 or: | ||||||
|  |                   - binary_sensor.is_on: close_sensor | ||||||
|  |                   - binary_sensor.is_on: open_sensor | ||||||
|  |               then: | ||||||
|  |                 logger.log: "close_sensor or open_sensor is on" | ||||||
|  |           - if: | ||||||
|  |               condition: | ||||||
|  |                 and: | ||||||
|  |                   - binary_sensor.is_on: close_sensor | ||||||
|  |                   - binary_sensor.is_on: open_sensor | ||||||
|  |               then: | ||||||
|  |                 logger.log: "close_sensor and open_sensor are both on" | ||||||
|  |           - if: | ||||||
|  |               condition: | ||||||
|  |                 xor: | ||||||
|  |                   - binary_sensor.is_on: close_sensor | ||||||
|  |                   - binary_sensor.is_on: open_sensor | ||||||
|  |               then: | ||||||
|  |                 logger.log: "close_sensor or open_sensor is exclusively on" | ||||||
|  |           - if: | ||||||
|  |               condition: | ||||||
|  |                 not: | ||||||
|  |                   - binary_sensor.is_on: close_sensor | ||||||
|  |               then: | ||||||
|  |                 logger.log: "close_sensor is not on" | ||||||
| cover: | cover: | ||||||
|   - platform: template |   - platform: template | ||||||
|     name: Template Cover |     name: Template Cover | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user