Hi all,
I just wanted to post my setup using Telegram to send notifications about calendar events and general home information.
The samples below show notifications about:
- Home Assistant has booted up,
- Nobody detected at home, but some devices are left on,
- Notify of an upcoming calendar event (before it happens),
- Calendar reminder with actionable “remind me in X minutes”.
Example from below with remind me later buttons:
To start with, we define a telegram bot to be able to message with.
There are many guides to setting this up, it’s as simple as sending a message to an existing Telegram Bot called BotFather. One thing they all seemed to miss though, is that you need to send a message to your bot before it can interact with you. So once you’ve got your bot and sent it a message (this can be in private or a group chat with housemates/family) you then need the chat id.
So we define the bot in configuration.yaml
, giving our api_key
from BotFather and the chat_id
we want to be able to communicate with (this can be a list).
telegram_bot:
- platform: polling
api_key: 2764xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
allowed_chat_ids:
- xyxyxyxy
Then we set up a HA notification service using the telegram platform, I named mine onplus because it’s communicating mainly with my phone and the chat_id is that of me<->bot. This chat_id
must be in the list of allowed chats above.
notify:
- name: oneplus
platform: telegram
chat_id: xyxyxyxy
Starting with a simple automation then (this indentation and synax is from a separate automations.yaml
), this triggers when HA starts and sends a message using the notify service we set up.
- id: 'telegramboot'
alias: 'Telegram bot to notify on boot'
trigger:
- event: start
platform: homeassistant
condition: []
action:
- service: notify.oneplus
data:
message: Home Assistant on Pi booted
Slightly more complex now, if all the devices that I track (device_tracker) are not_home
, check to see if any of the major devices in the home are left on. If a device is on, send a message. This results in a few false positives due to devices dropping out of wifi or whatever, but it’s not bad. You could extend this with some interactivity like in the later examples (you could add a “turn off” button, for instance). My main devices are a Harmony Hub for the TV and a Wake-On-LAN switch for my computer, generally these devices should be off when nobody is home.
- id: 'telegramawayelectronics'
alias: 'Telegram bot to notify nobody home and electronics on'
trigger:
- entity_id: group.all_devices
from: home
platform: state
to: not_home
condition:
- condition: or
conditions:
- condition: state
entity_id: remote.harmony_hub
state: 'on'
- condition: state
entity_id: switch.computer
state: 'on'
action:
- data:
message: Nobody home, but device(s) have been left on.
service: notify.oneplus
Now I want to get a notification the night before the bins are due for collection. I could never get the calendar offset to work properly in HA and I wanted to keep the bin event in the right day/time. You could create an extra hidden calendar just for this, but I wanted to be able to see the same events on my phone and edit them easily. So I had to make an intermediate sensor to be the middle-man between the calendar and the automation. I wrote about this in another thread.
Basically, it checks the start and end time of the next event in a calendar and turns itself on and off depending on whether it’s starting in the next 6 hours. You may also need the date__time
sensor included just below. This code sample is extracted from my sensors.yaml
, so the syntax and indentation may vary for you.
- platform: template
sensors:
bins_out_offset:
friendly_name: "Bins out offset"
value_template: >
{% if as_timestamp(states.calendar.house.attributes.start_time) - as_timestamp(strptime(states.sensor.date__time.state, "%Y-%m-%d, %H:%M" ) ) < 21600 and as_timestamp(states.calendar.house.attributes.end_time) > as_timestamp(strptime(states.sensor.date__time.state, "%Y-%m-%d, %H:%M" ) ) %}on{% else %}off{% endif %}
- platform: time_date
display_options:
- 'date_time'
Now the sensor is set up to switch on/off with 6 hours notice (change the 21600 for a different amount of seconds), we can send a notification when the state turns on.
Here I also include an inline_keyboard
with actionable buttons. I provide some clean text to display and then a command I want to execute when they’re pressed. Back in automations.yaml
now.
- id: 'telegrambinsout'
alias: 'Telegram bot to remind to put bins out'
trigger:
- entity_id: sensor.bins_out_offset
platform: state
to: 'on'
condition: []
action:
- service: notify.oneplus
data_template:
message: '{{ states.calendar.house.attributes.message }}'
data:
inline_keyboard:
- '30 Minutes:/30m, 1 Hour:/1h, 3 Hours:/3h'
- 'No reminder:/removekeyboard'
This gives us the below result:
Now we need to handle the button presses, so firstly if we don’t want a reminder, we can just get rid of the keyboard from taking up so much space. The trigger is setup to handle the /removekeyboard
command from above. The action first notifies telegram that we have handled the command, and then it edits the previous message to provide an empty inline_keyboard
.
- id: 'telegramremoveinline'
alias: 'Telegram callback to remove keyboard'
hide_entity: true
trigger:
platform: event
event_type: telegram_callback
event_data:
data: '/removekeyboard'
action:
- service: telegram_bot.answer_callback_query
data_template:
callback_query_id: '{{ trigger.event.data.id }}'
message: 'OK'
- service: telegram_bot.edit_replymarkup
data_template:
message_id: '{{ trigger.event.data.message.message_id }}'
chat_id: '{{ trigger.event.data.user_id }}'
inline_keyboard: []
The OK to Telegram shows up like the following (with different text):
Handling the reminder commands are very similar. It is triggered when the specific command button is pressed. The action this time does the same as above, but then has a delay according to which button was pressed. After the delay, another message is sent with using the same message text as before and using the same keyboard again.
- id: 'telegramrepeat30m'
alias: 'Telegram callback to repeat message in 30 minutes'
hide_entity: true
trigger:
platform: event
event_type: telegram_callback
event_data:
data: '/30m'
action:
- service: telegram_bot.answer_callback_query
data_template:
callback_query_id: '{{ trigger.event.data.id }}'
message: 'OK, reminding you in 30 minutes'
- service: telegram_bot.edit_replymarkup
data_template:
message_id: '{{ trigger.event.data.message.message_id }}'
chat_id: '{{ trigger.event.data.user_id }}'
inline_keyboard: []
- delay: '00:30:00'
- service: notify.oneplus
data_template:
message: '{{ trigger.event.data.message.text }}'
data:
inline_keyboard:
- '30 Minutes:/30m, 1 Hour:/1h, 3 Hours:/3h'
- 'No reminder:/removekeyboard'
Another of the same commands, but with a 1 hour delay instead.
- id: 'telegramrepeat1h'
alias: 'Telegram callback to repeat message in 1 hour'
hide_entity: true
trigger:
platform: event
event_type: telegram_callback
event_data:
data: '/1h'
action:
- service: telegram_bot.answer_callback_query
data_template:
callback_query_id: '{{ trigger.event.data.id }}'
message: 'OK, reminding you in 1 hour'
- service: telegram_bot.edit_replymarkup
data_template:
message_id: '{{ trigger.event.data.message.message_id }}'
chat_id: '{{ trigger.event.data.user_id }}'
inline_keyboard: []
- delay: '01:00:00'
- service: notify.oneplus
data_template:
message: '{{ trigger.event.data.message.text }}'
data:
inline_keyboard:
- '30 Minutes:/30m, 1 Hour:/1h, 3 Hours:/3h'
- 'No reminder:/removekeyboard'
Using this same pattern, you can add a keyboard to the previous examples and be able to turn off a device without leaving Telegram. These “remind me” automations are reusable since they resend the same message text as was sent before.
You can interact with the chat bot via text too. The above commands (/30m
, /1h
) can all be typed, the buttons are just a fancy way of doing it. So you can have a command /homestatus
and have HA reply with the temperature and a list of devices that are on, for example. It could also include actionable things like turn all lights off.
Also, once setup, the Telegram bot can be used by more than just HA. For example you can use a command line to send a message:
curl -s "https://api.telegram.org/bot$KEY/sendMessage?chat_id=$CHATID&disable_web_page_preview=1&text=$TEXT"