blueprint: name: Humidity Controlled Fan with Hysteresis description: > Controls fans based on humidity sensor readings with hysteresis to prevent flip-flopping and safety mechanisms to prevent runaway operation. Supports multiple fans and the Zooz ZSE11 humidity sensor or any compatible humidity sensor. domain: automation input: fans: name: Fan Entities description: One or more fans to control based on humidity selector: entity: domain: fan multiple: true humidity_sensor: name: Humidity Sensor description: Humidity sensor entity (e.g., Zooz ZSE11 or compatible sensor) selector: entity: domain: sensor device_class: humidity humidity_threshold: name: Humidity Threshold (%) description: Base humidity percentage threshold default: 60 selector: number: min: 30 max: 90 unit_of_measurement: "%" hysteresis_high: name: High Hysteresis (%) description: Amount above threshold to turn fans ON (prevents rapid cycling) default: 5 selector: number: min: 1 max: 15 unit_of_measurement: "%" hysteresis_low: name: Low Hysteresis (%) description: Amount below threshold to turn fans OFF (prevents rapid cycling) default: 3 selector: number: min: 1 max: 15 unit_of_measurement: "%" turn_on_delay: name: Turn On Delay description: Delay before turning fans on (avoids brief humidity spikes) default: 30 selector: number: min: 0 max: 300 unit_of_measurement: seconds max_runtime_minutes: name: Maximum Runtime (minutes) description: Maximum time fans can run continuously before forced shutdown default: 120 selector: number: min: 15 max: 480 unit_of_measurement: minutes cooldown_minutes: name: Cooldown Period (minutes) description: Minimum time between fan cycles to prevent runaway operation default: 10 selector: number: min: 2 max: 60 unit_of_measurement: minutes mode: restart trigger: - platform: state entity_id: !input humidity_sensor attribute: - platform: state entity_id: !input humidity_sensor variables: fans_entities: !input fans humidity_sensor: !input humidity_sensor base_threshold: !input humidity_threshold high_hysteresis: !input hysteresis_high low_hysteresis: !input hysteresis_low turn_on_threshold: "{{ base_threshold + high_hysteresis }}" turn_off_threshold: "{{ base_threshold - low_hysteresis }}" current_humidity: "{{ states(humidity_sensor) | float(0) }}" any_fan_on: > {{ expand(fans_entities) | selectattr('state', 'eq', 'on') | list | length > 0 }} max_runtime_seconds: "{{ (max_runtime_minutes | int) * 60 }}" action: - choose: # Turn fans ON when humidity exceeds upper threshold - conditions: - condition: template value_template: > {{ current_humidity > turn_on_threshold }} - condition: template value_template: > {{ not any_fan_on }} - condition: template value_template: > {{ states(humidity_sensor) not in ['unavailable', 'unknown'] }} sequence: - delay: seconds: !input turn_on_delay # Re-check humidity after delay - condition: template value_template: > {{ states(humidity_sensor) | float(0) > turn_on_threshold }} - condition: template value_template: > {{ states(humidity_sensor) not in ['unavailable', 'unknown'] }} - service: fan.turn_on target: entity_id: "{{ fans_entities }}" # Set up automatic shutoff timer for runaway prevention - delay: seconds: "{{ max_runtime_seconds }}" - condition: template value_template: > {{ expand(fans_entities) | selectattr('state', 'eq', 'on') | list | length > 0 }} - service: fan.turn_off target: entity_id: "{{ fans_entities }}" # Enforce cooldown period - delay: minutes: !input cooldown_minutes # Turn fans OFF when humidity drops below lower threshold - conditions: - condition: template value_template: > {{ current_humidity < turn_off_threshold }} - condition: template value_template: > {{ any_fan_on }} - condition: template value_template: > {{ states(humidity_sensor) not in ['unavailable', 'unknown'] }} sequence: - service: fan.turn_off target: entity_id: "{{ fans_entities }}" # Enforce cooldown period - delay: minutes: !input cooldown_minutes