Add humidity-controlled fan blueprint with hysteresis and safety features
Includes support for multiple fans, configurable thresholds with hysteresis to prevent flip-flopping, and runaway prevention mechanisms with max runtime and cooldown periods. Optimized for Zooz ZSE11 and compatible humidity sensors. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
		
							
								
								
									
										163
									
								
								humidity-controlled-fan.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								humidity-controlled-fan.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,163 @@
 | 
			
		||||
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
 | 
			
		||||
		Reference in New Issue
	
	Block a user