Created
November 14, 2025 08:54
-
-
Save gytisgreitai/5b44644c93efab7079f8ef7d22575838 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| blueprint: | |
| name: Duty-Cycle Thermostat (Max-Off Protection) | |
| description: > | |
| Thermostat logic with duty cycling when temperature is above threshold: | |
| - If temp >= threshold → switch OFF (start duty cycle) | |
| - If temp < threshold → switch ON immediately | |
| - When above threshold, heating is OFF for X hours, then ON for Y hours, | |
| repeating until temperature drops. | |
| domain: automation | |
| input: | |
| temperature_sensor: | |
| name: Temperature Sensor | |
| selector: | |
| entity: | |
| domain: sensor | |
| heating_switch: | |
| name: Heating Switch | |
| selector: | |
| entity: | |
| domain: switch | |
| threshold: | |
| name: Temperature Threshold (°C) | |
| default: 23 | |
| selector: | |
| number: | |
| min: 5 | |
| max: 35 | |
| step: 0.1 | |
| unit_of_measurement: °C | |
| off_duration: | |
| name: Max OFF duration (hours) | |
| description: Heating will never stay OFF longer than this while above threshold. | |
| default: 2 | |
| selector: | |
| number: | |
| min: 0.1 | |
| max: 12 | |
| step: 0.1 | |
| unit_of_measurement: hours | |
| on_duration: | |
| name: ON duration (hours) during duty cycle | |
| default: 2 | |
| selector: | |
| number: | |
| min: 0.1 | |
| max: 12 | |
| step: 0.1 | |
| unit_of_measurement: hours | |
| mode: restart | |
| trigger: | |
| - platform: state | |
| entity_id: !input heating_switch | |
| to: "off" | |
| for: | |
| hours: !input off_duration | |
| - platform: numeric_state | |
| entity_id: !input temperature_sensor | |
| below: !input threshold | |
| - platform: numeric_state | |
| entity_id: !input temperature_sensor | |
| above: !input threshold | |
| condition: [] | |
| action: | |
| - choose: | |
| # ----------------------------- | |
| # 1) Temperature BELOW threshold | |
| # ----------------------------- | |
| - conditions: | |
| - condition: numeric_state | |
| entity_id: !input temperature_sensor | |
| below: !input threshold | |
| sequence: | |
| - service: switch.turn_on | |
| target: | |
| entity_id: !input heating_switch | |
| # ----------------------------- | |
| # 2) Temperature ABOVE threshold AND switch is ON → turn OFF | |
| # ----------------------------- | |
| - conditions: | |
| - condition: numeric_state | |
| entity_id: !input temperature_sensor | |
| above: !input threshold | |
| - condition: state | |
| entity_id: !input heating_switch | |
| state: "on" | |
| sequence: | |
| - service: switch.turn_off | |
| target: | |
| entity_id: !input heating_switch | |
| # ----------------------------- | |
| # 3) Duty Cycle: OFF for X hours → still hot → ON for Y hours → maybe OFF again | |
| # ----------------------------- | |
| - conditions: | |
| - condition: numeric_state | |
| entity_id: !input temperature_sensor | |
| above: !input threshold | |
| - condition: state | |
| entity_id: !input heating_switch | |
| state: "off" | |
| sequence: | |
| # Turn ON for ON-duration | |
| - service: switch.turn_on | |
| target: | |
| entity_id: !input heating_switch | |
| - delay: | |
| hours: !input on_duration | |
| # If still hot → turn OFF again (cycle restarts) | |
| - condition: numeric_state | |
| entity_id: !input temperature_sensor | |
| above: !input threshold | |
| - service: switch.turn_off | |
| target: | |
| entity_id: !input heating_switch |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment