Automation Blueprint fails to run if a variable sensor is unavailable

I am trying to make a HVAC automation that is customisedto my needs and also to learn!

It relies on an external wireless Bluetooth temperature sensor - occasionally it becomes ‘unavailable’ . Iwould want to know when this happens especially if it was a prolonged outage.

If the sensor becomes unavailable the whole automation fails to run at all.
I would wish it to fail gracefully and post a notification in HA (and/or log)
However, the automation doesn’t get as far as getting to the action testnig if the sensor is unavailable to then make a UI notification.

I assume that is because my complex variable section fails - is there any way around this? Thanks for any assistance.

  - if: 
      - condition: template
        value_template: "{{ states(temp_sensor) == 'unavailable' }}"
    then: 
      - service: notify.persistent_notification
        data: 
          message: HVAC remote temperature sensor unavailable - HVAC automation halted until resolved
      - stop: "Stop running the rest of the sequence"
    else: 
        - service: climate.set_temperature
          data:
            temperature: '{{calc_target[1]}}'

Full code:

Summary
blueprint:
  name: HVAC automation
  description: Adjust HVAC (utilising remote sensor) setting acceptable ranges varying at time of day
  domain: automation

  input:
    hvac_unit:
      name: HVAC device
      description: Select desired climate decive
      selector:
        entity:
          filter:
            - domain: climate
    temp_sensor:
      name: Temperature sensor
      description: Select desired temperature sensor (could be the from the HVAC or a wireless one elsewhere in the room e.g. zigbee)
      selector:
        entity:
          filter:
            - domain: sensor

    morning_start_time:
      name:  ' '
      description: '# ☀️ Morining start time ☀️'
      default: '07:00:00'
      selector:
        time: {}
    morning_low_temp:
      name: ' '
      description: '🥶 Morning low temperature 🥶'
      default: 20
      selector:
        number:
          min: 12
          max: 24
          step: 0.5
          unit_of_measurement: "°C"
          mode: slider
    morning_high_temp:
      name: ' '
      description: '🥵 Morning high temperature 🥵'
      default: 24
      selector:
        number:
          min: 18
          max: 28
          step: 0.5
          unit_of_measurement: "°C"
          mode: slider

    day_start_time:
      name:  ' '
      description: '# 🏢 Day start time 🏢'
      default: '09:00:00'
      selector:
        time: {}
    day_low_temp:
      name: ' '
      description: '🥶 Day low temperature 🥶'
      default: 18
      selector:
        number:
          min: 12
          max: 24
          step: 0.5
          unit_of_measurement: "°C"
          mode: slider
    day_high_temp:
      name: ' '
      description: '🥵 Day high temperature 🥵'
      default: 26
      selector:
        number:
          min: 18
          max: 28
          step: 0.5
          unit_of_measurement: "°C"
          mode: slider

    evening_start_time:
      name: ' '
      description: '# 🌇 Evening start time 🌇'
      default: '18:00:00'      
      selector:
        time: {}
    evening_low_temp:
      name: ' '
      description: '🥶 Evening low temperature 🥶'
      default: 20
      selector:
        number:
          min: 12
          max: 24
          step: 0.5
          unit_of_measurement: "°C"
          mode: slider
    evening_high_temp:
      name: ' '
      description: '🥵 Evening high temperature 🥵'
      default: 24
      selector:
        number:
          min: 18
          max: 28
          step: 0.5
          unit_of_measurement: "°C"
          mode: slider

    night_start_time:
      name: ' '
      description: '# 🌙 Night start time 🌙'
      default: '23:30:00'
      selector:
        time: {}
    night_low_temp:
      name: ' '
      description: '🥶 Night low temperature 🥶'
      default: 18.5
      selector:
        number:
          min: 12
          max: 24
          step: 0.5
          unit_of_measurement: "°C"
          mode: slider
    night_high_temp:
      name: ' '
      description: '🥵 Night high temperature 🥵'
      default: 25
      selector:
        number:
          min: 18
          max: 28
          step: 0.5
          unit_of_measurement: "°C"
          mode: slider

    low_temp_target_offset:
      name: ' '
      description: |
        # 🥶 Offset for low target temp 🥶
        e.g. if the low temperature is set to 20 and this is set to -2 then the HVAC will not kick in until 18°C 
      default: '-0.5'
      selector:
        number:
          min: -3
          max: 0
          step: 0.5
          unit_of_measurement: "°C"
          mode: slider
    high_temp_target_offset:
      name: ' '
      description: |
        # 🥵 Offset for high target temp 🥵
        e.g. if the high temperature is set to 24 and this is set to 2 then the HVAC will not kick in until 26°C 
      default: '0.5'
      selector:
        number:
          min: 0
          max: 3
          step: 0.5
          unit_of_measurement: "°C"
          mode: slider
    within_range_mode:
      name: ' '
      description: When the temperature is within range what mode should the HVAC operate?
      default: "Fan only"
      selector:
        select:
          options:
            - label: Auto
              value: auto
            - label: Dry
              value: dry
            - label: Fan only
              value: fan_only
            - label: "Off"
              value: "off"
          mode: dropdown
    high_mode:
      name: ' '
      description: 🥵When the temperature is high what mode should the HVAC operate?🥵
      default: "Cool"
      selector:
        select:
          options:
            - label: Cool
              value: cool
            - label: Auto
              value: auto
            - label: Dry
              value: dry
            - label: Fan only
              value: fan_only
            - label: "Off"
              value: "off"
          mode: dropdown
    low_mode:
      name: ' '
      description: 🥶 When the temperature is low what mode should the HVAC operate? 🥶
      default: "Heat"
      selector:
        select:
          options:
            - label: Heat
              value: heat
            - label: Auto
              value: auto
            - label: "Off"
              value: "off"
          mode: dropdown
    fan_mode_morning:
      name: ' '
      description: What fan mode to use during morning
      default: "Auto"
      selector:
        select:
          options:
            - label: Quiet
              value: Quiet
            - label: Low
              value: low
            - label: Medium
              value: medium
            - label: High
              value: high
            - label: Auto
              value: auto
          mode: dropdown
    fan_mode_day:
      name: ' '
      description: What fan mode to use during day
      default: "Auto"
      selector:
        select:
          options:
            - label: Quiet
              value: Quiet
            - label: Low
              value: low
            - label: Medium
              value: medium
            - label: High
              value: high
            - label: Auto
              value: auto
          mode: dropdown
    fan_mode_evening:
      name: ' '
      description: What fan mode to use during evening
      default: "Auto"
      selector:
        select:
          options:
            - label: Quiet
              value: Quiet
            - label: Low
              value: low
            - label: Medium
              value: medium
            - label: High
              value: high
            - label: Auto
              value: auto
          mode: dropdown
    fan_mode_night:
      name: ' '
      description: What fan mode to use during night
      default: "Auto"
      selector:
        select:
          options:
            - label: Quiet
              value: Quiet
            - label: Low
              value: low
            - label: Medium
              value: medium
            - label: High
              value: high
            - label: Auto
              value: auto
          mode: dropdown

trigger:
  - platform: time_pattern
    minutes: "/15"

variables:
  hvac_unit: !input hvac_unit
  temp_sensor: !input temp_sensor
  temp_sensor_value: "{{ states(temp_sensor) }}"

  fan_mode_morning: !input fan_mode_morning
  fan_mode_day: !input fan_mode_day
  fan_mode_evening: !input fan_mode_evening
  fan_mode_night: !input fan_mode_night

  within_range_mode: !input within_range_mode
  low_mode: !input low_mode
  high_mode: !input high_mode

  morning_start_time: !input morning_start_time
  day_start_time: !input day_start_time
  evening_start_time: !input evening_start_time
  night_start_time: !input night_start_time

  morning_low_temp: !input morning_low_temp
  day_low_temp: !input day_low_temp
  evening_low_temp: !input evening_low_temp
  night_low_temp: !input night_low_temp

  morning_high_temp: !input morning_high_temp
  day_high_temp: !input day_high_temp
  evening_high_temp: !input evening_high_temp
  night_high_temp: !input night_high_temp

  time_attribute: >
    {% set a = today_at(morning_start_time) %}
    {% set b = today_at(day_start_time) %}
    {% set c = today_at(evening_start_time) %}
    {% set d = today_at(night_start_time) %}
    {% set now = now() %}

    {% set map = {
    a < now <= b: ['morning', morning_low_temp, morning_high_temp, fan_mode_morning],
    b < now <= c: [ 'day', day_low_temp, day_high_temp, fan_mode_day],
    c < now <= d: ['evening', evening_low_temp, evening_high_temp, fan_mode_evening],
    d < now or a > now: ['night', night_low_temp, night_high_temp, fan_mode_night] } %}
    {{ map.get(True) }}
  
  avg_target_temp: "{{ ((time_attribute[1] + time_attribute[2]) / 2) | round(0, default=0) }}"
  low_temp_target_offset: !input low_temp_target_offset
  low_target_temp: "{{ (time_attribute[1] + low_temp_target_offset) | round(1, default=0) }}"
  high_temp_target_offset: !input high_temp_target_offset
  high_target_temp: "{{ (time_attribute[2] + high_temp_target_offset) | round(1, default=0) }}"

  calc_target: >
    {% set map = {
    low_target_temp <= temp_sensor_value <= high_target_temp: ['withinrange', avg_target_temp, within_range_mode],
    low_target_temp > temp_sensor_value: ['low', time_attribute[1], low_mode ],
    high_target_temp < temp_sensor_value: ['high', time_attribute[2], high_mode ] } %}
    {{ map.get(True) }}
    
action:

#debugging message (remove later)
  - if:
      - condition: template
        value_template: "{{ now().minute == 0 }}"
    then:
      - service: notify.persistent_notification
        data: 
          message: it is {{ time_attribute[0] }} and the low temp is set as {{ time_attribute[1] }} and the high temp is set as {{ time_attribute[2] }}. Status is {{ calc_target[0] }}. Calc mode is {{ calc_target[2] }}

  - if: 
      - condition: template
        value_template: "{{ states(temp_sensor) == 'unavailable' }}"
    then: 
      - service: notify.persistent_notification
        data: 
          message: HVAC remote temperature sensor unavailable - HVAC automation halted until resolved
      - stop: "Stop running the rest of the sequence"
    else: 
        - service: climate.set_temperature
          data:
            temperature: '{{calc_target[1]}}'
          target:
            entity_id: !input 'hvac_unit'
        - service: climate.set_hvac_mode
          data:
            hvac_mode: '{{ calc_target[2] }}'
          target:
            entity_id: !input 'hvac_unit'
        - service: climate.set_fan_mode
          data:
            fan_mode: '{{ time_attribute[3] }}'
          target:
            entity_id: !input 'hvac_unit'

You could define your variables in your else instead of up top.

Use the float filter like this

"{{ calc_target[1] | float(-1) })"

This converts the number from the text it is stored as and provides a default when it is not available.
In your code, if the value is less than 0, assume it is unavailable and don’t use it in calculations and send your notification. You can use default filter the same way with against the entity if that works better.

It is best to cast numbers to float or int anyway then you are more sure of what you get. Otherwise unavailable is often just broken automation when it’s looking for a number.