Link a thermostat to the day/night cycle

This automation blueprint links a thermostat (any “climate” device) to the day/night cycle. You set a temperature for sunrise/sunset and one each for the middle of the day and night. The automation will then interpolate between those in a nice curve.

Example:

image

It also allows you to set a maximum and minimum temperature, so you can have extended periods at the middle of the day/night with those. Example:

image

Note: It triggers on sun.elevation changes, so you may need to enable (and hide) that on the “Sun” integration. The sun’s elevation is not used, but I liked that trigger better than a dub “every 1 minute” one.

Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.

blueprint:
  name: Day Cycle Temperature
  description: Makes a climate controller's temperature follow the day cycle
  domain: automation
  input:
    climate_controller:
      name: Climate Controller
      description: This climate controller's temperature will be synchronized with the day/night cycle.
      selector:
        target:
          entity:
            - domain: climate
    base_temp:
      name: Base temperature
      description: The temperature at sunrise and sunset.
      selector:
        number:
          min: 0
          max: 100
          step: 0.25
          unit_of_measurement: "°C"
          mode: slider
    max_temp:
      name: Maximum temperature
      description: Hard limit for the temperature.
      selector:
        number:
          min: 0
          max: 100
          step: 0.25
          unit_of_measurement: "°C"
          mode: slider
    min_temp:
      name: Minimum temperature
      description: Hard limit for the temperature.
      selector:
        number:
          min: 0
          max: 100
          step: 0.25
          unit_of_measurement: "°C"
          mode: slider
    noon_temp:
      name: Temperature at noon
      description: The temperature in the middle of the day. (May be higher/lower than the maximum/minimum temperature.)
      selector:
        number:
          min: 0
          max: 100
          step: 0.25
          unit_of_measurement: "°C"
          mode: slider
    midnight_temp:
      name: Temperature at midnight
      description: The temperature in the middle of the night. (May be higher/lower than the maximum/minimum temperature.)
      selector:
        number:
          min: 0
          max: 100
          step: 0.25
          unit_of_measurement: "°C"
          mode: slider

trigger:
  - platform: state
    entity_id:
      - sensor.sun_solar_elevation
  - platform: homeassistant
    event: start
condition: []

action:
  - variables:
      dayt: !input noon_temp
      nightt: !input midnight_temp
      sett: !input base_temp
      attday: "{{ dayt - sett }}"
      attnight: "{{ nightt - sett }}"
      maxt: !input max_temp
      mint: !input min_temp
      temp: >-
        {% set sr = state_attr('sun.sun','next_rising')|as_timestamp - today_at()|as_timestamp %}
        {% set sr = sr - [86400, 0][sr < 86400] %}
        {% set ss = state_attr('sun.sun','next_setting')|as_timestamp - today_at()|as_timestamp %}
        {% set ss = ss - [86400, 0][ss < 86400] %}
        {% set n = now()|as_timestamp - today_at()|as_timestamp %}
        {% set n = n + [0, 86400][n < sr] %}
        {% set dl = ss - sr if ss > sr else 86400 - (sr - ss) %}
        {% set se = ((-1, sin(pi * ((n - ss) / (dl - 86400), (n - sr) / dl)[ss > n > sr]), 1)|sort)[1] %}
        {{ ((mint, [sett - se * attnight, sett + se * attday][se > 0], maxt)|sort)[1]  }}
  - service: climate.set_temperature
    metadata: {}
    data:
      temperature: "{{temp}}"
    target: !input climate_controller
mode: single

Thanks to @Troon for the math.