I’ve built this the last few days. I’ve put most of my configuration in separate yaml files for readability and manageability.
To start: I have a few template sensors for the server time. In templates, the noew() function triggers the template every time it changes, which is every minute. My hour sensor only changes once an hour, reducing the number of triggers!
in config/sensors/servertime.yaml:
# A simple sensor to get the server date and time available
# See https://www.home-assistant.io/integrations/time_date/
- platform: time_date
display_options:
- "time"
- "date"
- "date_time"
- "date_time_utc"
- "date_time_iso"
- "time_date"
- "time_utc"
and in config/templates/servertime.yaml:
# The sensor.date itself can be found here: ~/config/sensors/servertime
- sensor:
- unique_id: current_hour
name: current_hour
state: "{{ states('sensor.time').split(':')[0] }}"
- unique_id: current_minute
name: current_minute
state: " {{ states('sensor.time').split(':')[1] }}"
- unique_id: current_year
name: current_year
state: " {{ states('sensor.date').split('-')[0] }}"
- unique_id: current_month
name: current_month
state: " {{ states('sensor.date').split('-')[1] }}"
- unique_id: current_day
name: current_day
state: " {{ states('sensor.date').split('-')[2] }}"
I mix my automations in separate files and via UI (the ones in a separate file are not editable by the UI, but can be seen and en/disabled via the UI).
In config/automations/tell_time.yaml
- id: telltime
alias: telltime
description: Tells the current time
trigger:
- platform: conversation
command:
- what time is it
condition: []
action:
- set_conversation_response: >-
{% from 'fuzzy_time.jinja' import zeg_tijd, say_time %}
It is {{ say_time(states("sensor.current_hour")|int, states("sensor.current_minute")|int,1) }}
mode: single
In the UI it looks like this:
NOTE: The macro expects integers, while the sensors return strings! That’s why the integer filter (‘|int’) is needed
This uses a jinja template (aka macro) to say the time in ‘fuzzy’ format, but you can also use a more formal message:
action:
- set_conversation_response: >-
The current time is {{ states("sensor.current_hour") }} {{states("sensor.current_minute") }}
To get fuzzy time, I’ve built these templates.
In config/custom_templates/fuzzy_time.yaml:
{% macro zeg_tijd(hour,min,mode=0) %}
{% set am=" 's ochtends" %}
{% set pm=" 's middags" %}
{% set hour12 = hour % 12 %}
{% set hour12 = 12 if hour12 == 0 else hour12 %}
{% set nexthour = 1 + hour % 12 %}
{% set om = am if hour < 12 else pm %}
{% set om = "" if mode == 0 else om %}
{%- if hour > 23 or hour < 0 %} een ongeldig uur!
{% elif min > 59 or min < 0 %} een ongeldig aantal minuten!
{% elif min == 59 and hour == 23 %}1 minuut voor middernacht
{% elif min > 45 and hour == 23 %}{{ 60-min }} voor middernacht
{% elif min == 0 and hour == 0 %}precies middernacht
{% elif min == 1 and hour == 0 %}1 minuut na middernacht
{% elif min < 15 and hour == 0 %}{{min}} minuten na middernacht
{% elif min > 45 %}{{ 60 - min }} voor {{nexthour}}{{ om }}
{% elif min == 45 %} kwart voor {{ nexthour }}{{ om }}
{% elif min > 30 %} {{min - 30 }} over half {{ nexthour }}{{ om }}
{% elif min == 30 %} half {{ nexthour }}{{ om }}
{% elif min > 15 %} {{ 30 - min }} voor half {{ nexthour }}{{ om }}
{% elif min == 15 %} kwart over {{ hour12 }}{{ om }}
{% elif min > 0 %} {{ min }} over {{ hour12 }}{{ om }}
{% endif %}
{% endmacro %}
{% macro say_time(hour,min,mode=0) %}
{% set am=" A M" %}
{% set pm=" P M" %}
{% set hour12 = hour % 12 %}
{% set hour12 = 12 if hour12 == 0 else hour12 %}
{% set nexthour = 1 + hour % 12 %}
{% set om = am if hour < 12 else pm %}
{% set om = "" if mode == 0 else om %}
{%- if hour > 23 or hour < 0 %} invalidg hour!
{% elif min > 59 or min < 0 %} invalid minute!
{% elif min == 59 and hour == 23 %}1 minute before midnight
{% elif min > 45 and hour == 23 %}{{ 60-min }} minutes before midnight
{% elif min == 0 and hour == 0 %}midnight on the dot
{% elif min == 1 and hour == 0 %}1 minute after midnight
{% elif min < 15 and hour == 0 %}{{min}} minutes after midnight
{% elif min > 45 %}{{ 60 - min }} to {{nexthour}}{{ om }}
{% elif min == 45 %} a quarter to {{ nexthour }}{{ om }}
{% elif min > 30 %} {{min - 30 }} past {{ hour12 }} thirty {{ om }}
{% elif min == 30 %} half past {{ nexthour }}{{ om }}
{% elif min == 15 %} a quarter past {{ hour12 }}{{ om }}
{% elif min > 0 %} {{ min }} past {{ hour12 }}{{ om }}
{% endif %}
{% endmacro %}
Both the dutch and english versions are in this file. You can add or remove the AM/PM suffix by using the mode switch. This defaults to 0, which omits the AM/PM suffix.
I’m not a native English speaker, so there is room for improvement
Hope this helps!
Marcel