renemarc/home-assistant-config

View on GitHub
sensors/calendar.yaml

Summary

Maintainability
Test Coverage
#
# Time & Date
#
# Manipulates time and dates to make them more human-friendly.
#
# Using a date sensor instead of now() inside templates avoids constant updates.
#
# @link https://www.home-assistant.io/integrations/time_date/
#
- platform: time_date
  display_options:
    - 'time'
    - 'date'
    - 'date_time'
    - 'time_date'

- platform: template
  sensors:
    date_friendly:
      friendly_name: "Date (Friendly)"
      icon_template: "mdi:calendar-today"
      friendly_name_template: >-
        {% set date = states('sensor.date') %}
        {% set datetime = strptime(date, '%Y-%m-%d') %}
        {{ datetime.strftime('%A') }}
      value_template: >-
        {% set date = states('sensor.date') %}
        {% set datetime = strptime(date, '%Y-%m-%d') %}
        {% set month = datetime.strftime('%B') %}
        {% set day = datetime.strftime('%d') | int %}

        {{ month }} {{ day }}

    date_long:
      friendly_name: "Date (Long)"
      icon_template: "mdi:calendar-today"
      value_template: >-
        {% set date = states('sensor.date') %}
        {% set datetime = strptime(date, '%Y-%m-%d') %}
        {% set weekday = datetime.strftime('%A') %}
        {% set month = datetime.strftime('%B') %}
        {% set day = datetime.strftime('%d') | int %}
        {%
          set suffix = 'st' if (day % 10 == 1 and day != 11)
          else 'nd' if (day % 10 == 2 and day != 12)
          else 'rd' if (day % 10 == 3 and day != 13)
          else 'th'
        %}

        {{ weekday }} {{ month }} {{ day }}{{ suffix }}

    time_friendly:
      friendly_name: "Time (Friendly)"
      icon_template: "mdi:clock"
      value_template: >-
        {% set hour = states('sensor.time').split(':')[0] | int %}
        {% set minutes = states('sensor.time').split(':')[1] %}

        {{ hour }}:{{ minutes }}

    time_long:
      friendly_name: "Time (Long)"
      icon_template: "mdi:clock"
      value_template: >-
        {% set hour = states('sensor.time').split(':')[0] | int %}
        {% set minute = states('sensor.time').split(':')[1] | int %}

        {% set minute_str = '' %}
        {% if minute == 15 or minute == 45 %}
          {% set minute_str = 'a quarter' %}
        {% elif minute == 30 %}
          {% set minute_str = 'half' %}
        {% else %}
          {% if minute > 30 %}
            {% set minute_str = (60 - minute) | string %}
          {% elif minute != 0 %}
            {% set minute_str = minute | string %}
          {% endif %}

          {% if minute_str %}
            {% if minute > 1 %}
              {% set minute_str = minute_str + ' minutes' %}
            {% else %}
              {% set minute_str = minute_str + ' minute' %}
            {% endif %}
          {% endif %}
        {% endif %}

        {% if minute > 30 %}
          {% set minute_str = minute_str + ' to' %}
          {% set hour = hour + 1 %}
          {% if hour >= 24 %}
            {% set hour = hour - 24 %}
          {% endif %}
        {% elif minute > 0 %}
          {% set minute_str = minute_str + ' past' %}
        {% endif %}

        {% if hour == 0 %}
          {% set hour_str = 'midnight' %}
        {% elif hour == 12 %}
          {% set hour_str = 'noon' %}
        {% elif hour > 12 %}
          {% set hour_str = hour - 12 %}
        {% else %}
          {% set hour_str = hour %}
        {% endif %}

        {% if minute_str %}
          {{ minute_str }} {{ hour_str }}
        {% elif hour != 0 and hour != 12 %}
          {{ hour_str }} O'Clock
        {% else %}
          {{ hour_str }}
        {% endif %}

    time_quarterly:
      friendly_name: "Time (Quarterly)"
      icon_template: "mdi:clock"
      value_template: >-
        {% set hour = states('sensor.time').split(':')[0] | int %}
        {% set minutes = states('sensor.time').split(':')[1] | int %}

        {% if minutes >= 45 %}
          {% set minute = '45' %}
        {% elif minutes >= 30 %}
          {% set minute = '30' %}
        {% elif minutes >= 15 %}
          {% set minute = '15' %}
        {% else %}
          {% set minute = '00' %}
        {% endif %}

        {{ hour }}:{{ minute }}

    after_tomorrow:
      friendly_name: "After Tomorrow"
      icon_template: "mdi:calendar-arrow-right"
      value_template: >-
        {% set date = states('sensor.date') %}
        {% set datetime = strptime(date, '%Y-%m-%d') %}
        {% set timestamp = as_timestamp(datetime) + 2*24*60*60 %}

        {{ timestamp | timestamp_custom('%A') }}


#
# Number of days in a month
#
# Used to calculate remaining bandwidth capacity from ISP.
#
# @see /sensors/isp.yaml
#
- platform: template
  sensors:
    days_in_month:
      friendly_name: "Days in Month"
      icon_template: "mdi:calendar"
      value_template: >-
        {% set date = states('sensor.date') %}
        {% set datetime = strptime(date, '%Y-%m-%d') %}
        {% set month = datetime.month %}
        {% set year = datetime.year %}
        {% set days = 31 if month in [1,3,5,7,8,10,12]
          else 30 if month in [4,6,9,11]
          else 29 if as_timestamp(strptime(year|string + '-02-29', '%Y-%m-%d'))
          else 28
        %}

        {{ days }}

    days_remaining_in_month:
      friendly_name: "Days Remaining in Month"
      icon_template: "mdi:calendar"
      value_template: >-
        {% set days_in_month = states('sensor.days_in_month') | int %}

        {{ days_in_month - now().day }}


#
# Report on the next sun event (risings or settings)
#
- platform: template
  sensors:
    sun_state:
      friendly_name_template: >-
        {% set next_dawn = as_timestamp(state_attr('sun.sun', 'next_dawn')) %}
        {% set next_rising = as_timestamp(state_attr('sun.sun', 'next_rising')) %}
        {% set next_setting = as_timestamp(state_attr('sun.sun', 'next_setting')) %}
        {% set next_dusk = as_timestamp(state_attr('sun.sun', 'next_dusk')) %}

        {% if next_dawn >= next_rising %}
          Is is dawn
        {% elif next_rising >= next_setting %}
          Sun is up
        {% elif next_setting >= next_dusk %}
          It is dusk
        {% else %}
          Sun is down
        {% endif %}
      icon_template: &sun_state_icon >-
        {% set next_dawn = as_timestamp(state_attr('sun.sun', 'next_dawn')) %}
        {% set next_rising = as_timestamp(state_attr('sun.sun', 'next_rising')) %}
        {% set next_setting = as_timestamp(state_attr('sun.sun', 'next_setting')) %}
        {% set next_dusk = as_timestamp(state_attr('sun.sun', 'next_dusk')) %}

        {% if next_dawn >= next_rising %}
          mdi:weather-sunset-up
        {% elif next_rising >= next_setting %}
          mdi:weather-sunny
        {% elif next_setting >= next_dusk %}
          mdi:weather-sunset-down
        {% else %}
          mdi:weather-night
        {% endif %}
      value_template: >-
        {% if is_state('sun.sun', 'above_horizon') %}
          sets at {% set timestamp = as_timestamp(state_attr('sun.sun', 'next_setting')) | timestamp_custom('%H:%M') %} {{ timestamp.lstrip('0') }}
        {% else %}
          rises at {% set timestamp = as_timestamp(state_attr('sun.sun', 'next_rising')) | timestamp_custom('%H:%M') %} {{ timestamp.lstrip('0') }}
        {% endif %}

    #
    # Human-readable state of the sun
    #
    # Output examples:
    #   - Dawn is almost here.
    #   - It is dawn.
    #   - The sun will rise soon.
    #   - The sun is rising.
    #   - The sun will set at around 8.
    #   - The sun will set at around a quarter past 8.
    #   - The sun will set at around 8 and a half.
    #   - The sun will set at around a quarter to 9.
    #   - The sun will set soon.
    #   - The sun is setting.
    #   - It is dusk.
    #   - It will be dark soon.
    #   - The sun will rise in about 7 hours.
    #   - The sun rise in about 7 and a half hours.
    #   - The sun rise in soon.
    #
    sun_state_friendly:
      friendly_name: "Sun"
      icon_template: *sun_state_icon
      value_template: >-
        {% set current = as_timestamp(strptime(states('sensor.time_date'), '%H:%M, %Y-%m-%d')) %}
        {% set next_dawn = as_timestamp(state_attr('sun.sun', 'next_dawn')) %}
        {% set next_rising = as_timestamp(state_attr('sun.sun', 'next_rising')) %}
        {% set next_setting = as_timestamp(state_attr('sun.sun', 'next_setting')) %}
        {% set next_dusk = as_timestamp(state_attr('sun.sun', 'next_dusk')) %}
        {% set next_noon = as_timestamp(state_attr('sun.sun', 'next_noon')) %}
        {% set elevation = state_attr('sun.sun', 'elevation') %}
        {% set elevation_sunrise = 3 %}
        {% set elevation_sunset = 2 %}
        {% set warning_dawn = 30*60 %}
        {% set warning_sunrise = 15*60 %}
        {% set warning_sunset = 30*60 %}
        {% set warning_dusk = 15*60 %}

        {% if (next_dawn - current) <= warning_dawn %}
          Dawn is almost here.

        {% elif next_dawn >= next_rising %}
          {% if (next_rising - current) > warning_sunrise %}
            It is dawn.
          {% else %}
            The sun will rise soon.
          {% endif %}

        {% elif next_rising >= next_setting %}
          {% if next_noon < next_setting and elevation <= elevation_sunrise %}
            The sun is rising.
          {% elif (next_setting - current) > warning_sunset %}
            {% set hour = next_setting|timestamp_custom('%H') | int %}
            {% set minute = next_setting|timestamp_custom('%M') | int %}

            {% set minute_friendly = '' %}
            {% set half = false %}

            {% if minute >= 10 and minute <= 20 %}
              {% set minute_friendly = 'a quarter past ' %}
            {% elif minute > 20 and minute < 40 %}
              {% set half = true %}
            {% elif minute >= 40 and minute <= 50 %}
              {% set minute_friendly = 'a quarter to ' %}
              {% set hour = hour + 1 %}
            {% elif minute > 50 %}
              {% set hour = hour + 1 %}
            {% endif %}

            {% if hour >= 24 %}
              {% set hour = hour - 24 %}
            {% endif %}
            {% if hour == 0 %}
              {% set hour_friendly = 'midnight' %}
            {% elif hour == 12 %}
              {% set hour_friendly = 'noon' %}
            {% elif hour > 12 %}
              {% set hour_friendly = hour - 12 %}
            {% else %}
              {% set hour_friendly = hour %}
            {% endif %}

            {% if half %}
              The sun will set at around {{ hour_friendly }} and a half.
            {% else %}
              The sun will set at around {{ minute_friendly }}{{ hour_friendly }}.
            {% endif %}
          {% elif next_noon > next_setting and elevation <= elevation_sunset %}
            The sun is setting.
          {% else %}
            The sun will set soon.
          {% endif %}

        {% elif next_setting >= next_dusk %}
          {% if (next_dusk - current) > warning_dusk %}
            It is dusk.
          {% else %}
            It will be dark soon.
          {% endif %}

        {% else %}
          {% set diff = ((next_rising - current) / 60 / 60) %}
          {% set hour = diff | int %}
          {% set minute = (diff - hour) | round(2) %}

          {% if hour %}
            {% if minute > 0.66 %}
              {% set hour = hour + 1 %}
            {% elif minute > 0.33 %}
              {% set minute_friendly = ' and a half' %}
            {% endif %}

            The sun will rise in about {{ hour }}{{ minute_friendly }} hour{% if hour > 0 %}s{% endif %}.
          {% else %}
            The sun will rise soon.
          {% endif %}

        {% endif %}