Human spoken time

I just wanted to share a little project I’ve been working on. I’ve got several automations that inform me, thought my Google speakers, when a certain event has happend. Whenever I call a time it will tell me that something happend at sixteen hours twelve minutes. I prefer a more human approach.

I’ve created a sensor (template) in my split configuration:

# HUMAN SPOKEN TIME
- sensor:
    - name: Human spoken time
      unique_id: human_spoken_time
      state: >
        {% if now().strftime('%-H') | float(0) >= 0 and now().strftime('%-H') | float(0) < 6 %}
          {% set timeofday = "in de nacht" %}

        {% elif now().strftime('%-H') | float(0) >= 6 and now().strftime('%-H') | float(0) < 12 %}
          {% set timeofday = "in de ochtend" %} 

        {% elif now().strftime('%-H') | float(0) >= 12 and now().strftime('%-H') | float(0) < 18 %}
          {% set timeofday = "in de middag" %}

        {% elif now().strftime('%-H') | float(0) >= 18 and now().strftime('%-H') | float(0) < 25 %}
          {% set timeofday = "in de avond" %}
        {% endif %}

        {% if (now().minute | float(0)) == 0 %}
          {{ now().strftime('%-I') }} uur {{ timeofday }}

        {% elif (now().minute | float(0)) == 1 %}
          {{ now().minute }} minuut over {{ now().strftime('%-I') }} {{ timeofday }}

        {% elif (now().minute | float(0)) >= 2 and (now().minute | float(0)) <= 14 %}
          {{ now().minute }} minuten over {{ now().strftime('%-I') }} {{ timeofday }}

        {% elif (now().minute | float(0)) == 15 %}
          kwart over {{ now().strftime('%-I') }} {{ timeofday }}

        {% elif (now().minute | float(0)) >= 16 and (now().minute | float(0)) <= 29 %}
          {{ 30 - now().minute | int(0) }} minuten voor half {{ now().strftime('%-I') | int(0) + 1 }} {{ timeofday }}

        {% elif (now().minute | float(0)) == 30 %}
          {% if (now().strftime('%-I')) | float(0) < 12 %}
            half {{ now().strftime('%-I') | int(0) + 1 }} {{ timeofday }}
          {% elif (now().strftime('%-I')) | float(0) >= 12 %}
            half {{ now().strftime('%-H') | int(0) - 11 }} {{ timeofday }}
          {% endif %}

        {% elif (now().minute | float(0)) == 31 %}
          {% if (now().strftime('%-I')) | float(0) < 12 %}        
            {{ now().minute | int(0) - 30 }} minuut over half {{ now().strftime('%-I') | int(0) + 1 }} {{ timeofday }}       
          {% elif (now().strftime('%-I')) | float(0) >= 12 %}
            {{ now().minute | int(0) - 30 }} minuut over half {{ now().strftime('%-H') | int(0) - 11 }} {{ timeofday }}
          {% endif %}

        {% elif (now().minute | float(0)) >= 32 and (now().minute | float(0)) <= 44 %}
          {% if (now().strftime('%-I'))  | float(0) < 12 %}        
            {{ now().minute | int(0) - 30 }} minuten over half {{ now().strftime('%-I') | int(0) + 1 }} {{ timeofday }}       
          {% elif (now().strftime('%-I')) | float(0) >= 12 %}
            {{ now().minute | int(0) - 30 }} minuten over half {{ now().strftime('%-H') | int(0) - 11 }} {{ timeofday }}
          {% endif %}

        {% elif (now().minute | float(0)) == 45 %}
          {% if (now().strftime('%-I')) | float(0) < 12 %}        
            kwart voor {{ now().strftime('%-I') | int(0) + 1 }} {{ timeofday }}
          {% elif (now().strftime('%-I')) | float(0) >= 12 %}
            kwart voor {{ now().strftime('%-H') | int(0) - 11 }} {{ timeofday }}
          {% endif %}

        {% elif (now().minute | float(0)) >= 46 and (now().minute | float(0)) <=59 %}
          {% if (now().strftime('%-I')) | float(0) < 12 %}        
            {{ 60 - now().minute | int(0) }} minuten voor {{ now().strftime('%-I') | int(0) + 1 }} {{ timeofday }}
          {% elif (now().strftime('%-I')) | float(0) >= 12 %}
          {{ 60 - now().minute | int(0) }} minuten voor {{ now().strftime('%-H') | int(0) - 11 }} {{ timeofday }}
          {% endif %}
        {% endif %}

      icon: >
        {% if now().strftime('%-H') | float(0) >= 0 and now().strftime('%-H') | float(0) <= 6 %}
          mdi:weather-night
        {% elif now().strftime('%-H') | float(0) >= 6 and now().strftime('%-H') | float(0) <= 12 %}
          mdi-weather-sunset
        {% elif now().strftime('%-H') | float(0) >= 12 and now().strftime('%-H') | float(0) <= 18 %}
          mdi:weather-sunny        
        {% elif now().strftime('%-H') | float(0) >= 18 and now().strftime('%-H') | float(0) <= 25 %}
          mdi:weather-sunset
        {% else %}
          mdi:clock
        {% endif %}

And if I call:

service: tts.cloud_say
data:
  entity_id: media_player.woonkamer
  message: De tijd is nu {{ states('sensor.human_spoken_time') }}

then it’ll say the time in a more human way.

Next up is finding a way so I can use this template on a variety of times because it currently only says the current time.

2 Likes

I’ve adapted it for the UK user of HA

- platform: template
  sensors:
    human_time:
      friendly_name: Human spoken time
      icon_template: >-
        {% if now().strftime('%-H') | float >= 0 and now().strftime('%-H') | float <= 6 %}
          mdi:weather-night

        {% elif now().strftime('%-H') | float >= 6 and now().strftime('%-H') | float <= 12 %}
          mdi-weather-sunset

        {% elif now().strftime('%-H') | float >= 12 and now().strftime('%-H') | float <= 18 %}
          mdi:weather-sunny        

        {% elif now().strftime('%-H') | float >= 18 and now().strftime('%-H') | float <= 25 %}
        mdi-weather-sunset

        {% else %}
          mdi:clock

        {% endif %}
      value_template: >-		
		{% if (now().minute | float) == 0 %}
		  {{ now().strftime('%-I') }} o'clock

		{% elif (now().minute | float) == 1 %}
		  {{ now().minute }} minute past {{ now().strftime('%-I') }}

		{% elif (now().minute | float) >= 2 and (now().minute | float) <= 14 %}
		  {{ now().minute }} minutes past {{ now().strftime('%-I') }}

		{% elif (now().minute | float) == 15 %}
		  quarter past {{ now().strftime('%-I') }}

		{% elif (now().minute | float) >= 16 and (now().minute | float) <= 29 %}
		  {{ 30 - now().minute | int }} minutes before half past {{ now().strftime('%-I') }}

		{% elif (now().minute | float) == 30 %}
		  half past {{ now().strftime('%-I') }}

		{% elif (now().minute | float) >= 31 and (now().minute | float) <= 44 %}
		  {{ now().minute | int - 30 }} minutes past half {{ now().strftime('%-I') }}

		{% elif (now().minute | float) == 45 %}
		  quarter to {{ now().strftime('%-I') }}

		{% elif (now().minute | float) >= 46 and (now().minute | float) <=59 %}
		  {{ 60 - now().minute | int }} minutes to {{ now().strftime('%-I') }}

		{% endif %}
3 Likes

I’ve modified both Dutch and UK entities.
The changes are:

  • If it’s the 1st minute or 31st minute it’ll say minuut or minute instead of minuten or minutes.
  • The icon changes representing night (0-6 o’clock), morning (6-12), afternoon (12-18), evening (18-24).

I’ve modified the Dutch entity.

half {{ now().strftime('%-I') | int + 1 }}

This would make it say “Half dertien” if it was 12:30.
I’ve added an additional “if” statement so if it is 12:xx it will subtract 11, making it say “Half één”.

Same goes for:

{{ now().minute | int - 30 }} minuut over half {{ now().strftime('%-I') | int + 1 }}        

It looks interesting. I will try to use it in my native language (Czech language)

1 Like

That’s a nice one, how you say time differs from the Dutch and UK English.

I’m trying to convert this to the new format, unfortunately it’s not working and I can’t figure out why; the icon will show but the it won’t display the time.

sensor:
  - name: Human spoken time
    unique_id: human_spoken_time
    state: >
      {% if (now().minute | float(0)) == 0 %}
        {{ now().strftime('%-I') }} uur
      {% elif (now().minute | float(0)) == 1 %}
        {{ now().minute }} minuut over {{ now().strftime('%-I') }}
      {% elif (now().minute | float(0)) >= 2 and (now().minute | float(0)) <= 14 %}
        {{ now().minute }} minuten over {{ now().strftime('%-I') }}
      {% elif (now().minute | float(0)) == 15 %}
        kwart over {{ now().strftime('%-I') }}
      {% elif (now().minute | float(0)) >= 16 and (now().minute | float(0)) <= 29 %}
        {{ 30 - now().minute | int }} minuten voor half {{ now().strftime('%-I') | int + 1 }}
      {% elif (now().minute | float(0)) == 30 %}
        {% if (now().strftime('%-I')) < 12 %}
          half {{ now().strftime('%-I') | int + 1 }}
        {% elif (now().strftime('%-I')) >= 12 %}
          half {{ now().strftime('%-I') | int - 11 }}
        {% endif %}
      {% elif (now().minute | float(0)) == 31 %}
        {% if (now().strftime('%-I')) < 12 %}        
          {{ now().minute | int - 30 }} minuut over half {{ now().strftime('%-I') | int + 1 }}        
        {% elif (now().strftime('%-I')) >= 12 %}
          {{ now().minute | int - 30 }} minuut over half {{ now().strftime('%-I') | int - 11 }}
        {% endif %}
      {% elif (now().minute | float(0)) >= 31 and (now().minute | float(0)) <= 44 %}
        {{ now().minute | int - 30 }} minuten over half {{ now().strftime('%-I') | int + 1 }}
      {% elif (now().minute | float(0)) == 45 %}
        kwart voor {{ now().strftime('%-I') | int + 1 }}
      {% elif (now().minute | float(0)) >= 46 and (now().minute | float(0)) <=59 %}
        {{ 60 - now().minute | int }} minuten voor {{ now().strftime('%-I') | int + 1 }}
      {% endif %}
    icon: >
      {% if now().strftime('%-H') | float(0) >= 0 and now().strftime('%-H') | float(0) <= 6 %}
        mdi:weather-night
      {% elif now().strftime('%-H') | float(0) >= 6 and now().strftime('%-H') | float(0) <= 12 %}
        mdi-weather-sunset
      {% elif now().strftime('%-H') | float(0) >= 12 and now().strftime('%-H') | float(0) <= 18 %}
        mdi:weather-sunny        
      {% elif now().strftime('%-H') | float(0) >= 18 and now().strftime('%-H') | float(0) <= 25 %}
        mdi:weather-sunset
      {% else %}
        mdi:clock
      {% endif %}```

I’ve made some changes to the Dutch implementation, this entity would say ‘één minuut over half dertien’, that’s now corrected.

Again I’ve made some changes to the Dutch implementation, it will also tell you the time of day ('s ochtends, 's middags, 's avonds or 's nachts).

        {% if now().strftime('%-H') | float(0) >= 0 and now().strftime('%-H') | float(0) < 6 %}
          {% set timeofday = "'s nachts" %}

        {% elif now().strftime('%-H') | float(0) >= 6 and now().strftime('%-H') | float(0) < 12 %}
          {% set timeofday = "'s ochtends" %} 

        {% elif now().strftime('%-H') | float(0) >= 12 and now().strftime('%-H') | float(0) < 18 %}
          {% set timeofday = "'s middags" %}

        {% elif now().strftime('%-H') | float(0) >= 18 and now().strftime('%-H') | float(0) < 25 %}
          {% set timeofday = "'s avonds" %}
        {% endif %}

and the addition of `{{ timeofday }}’ to each “spoken” line.

I’ve made some changes, it still said “twee minuten voor dertien”. I saw in the template I forgot to edit the time between 46 and 59.

I’ve made some changes to the Dutch language:

  • After xx:29 the template wouldn’t function, I’ve added some float(0)'s,
  • There was a problem with 1 PM, fixed that (hopefully).