my family and other logged in users can enter a text, and play it over the intercom pushing the execute button. What I would like to do is create an automation that writes the message and user to a line in a text file.
I know we can use the notify.file service, but am not sure how to log the user that pushed the button for the script.
trying this, but neither of the automations trigger:
- alias: 'Forward intercom messages to filed_intercom_messages'
id: 'Forward intercom messages to filed_intercom_messages'
trigger:
platform: state
entity_id: script.intercom_text_message
to: 'on'
condition: []
action:
service: notify.filed_intercom_messages
data_template:
message: >
Script state: {{ as_timestamp(now()) | timestamp_custom('%d %b: %X') }}: {{ states('input_text.message')}}
played on {{states('input_select.intercom')}} in {{states('input_select.intercom_language')}}
- alias: 'Call Service Event (Script) text message'
id: 'Call Service Event (Script) test message'
trigger:
platform: event
event_type: call_service
event_data:
domain: script
condition:
condition: template
value_template: >
{{ trigger.event.data.entity_id == script.intercom_text_message}}
action:
service: notify.filed_intercom_messages
data_template:
message: >
Event call: {{ as_timestamp(now()) | timestamp_custom('%d %b: %X') }}: {{ states('input_text.message')}}
played on {{states('input_select.intercom')}} in {{states('input_select.intercom_language')}}
if I trigger manually the action is performed and files are written.
Somehow I cant get the script execution toi trigger the automations? Could use some help / tips…
please have a look? @petro and @pnbruckner might I ask you directly?
taking the condition out completely makes the file being written. I need a condition though, because now it will write to the file upon each script execution
tried this too, and thought it worked, but now nothing is written anymore…:
- alias: 'Call Service Event (Script) text message'
id: 'Call Service Event (Script) test message'
trigger:
platform: event
event_type: call_service
event_data:
domain: script
condition:
condition: template
value_template: >
{{ trigger.event.data.entity_id in ['script.intercom_text_message']}}
action:
service: notify.filed_intercom_messages
data_template:
message: >
Event call: {{ as_timestamp(now()) | timestamp_custom('%d %b: %X') }}: {{ states('input_text.message')}}
played on {{states('input_select.intercom')}} in {{states('input_select.intercom_language')}}
replacing the trigger notation in the template editor with the actual state:
You’d have to play around with the context object from a trigger. I haven’t investigated the rules for it yet, but it does get populated and there is a field for user. It’s only available on state objects. So I don’t know if it’s accessible from an event trigger.
trigger.to_state.context.user_id
You’d then have to check it against the user_id’s for each user.
o great, will investigate! once I get the base automations to behave as I want… btw where is this documented, so I can investigate…?
could you see why this:
- alias: 'Call Service Event (Script) text message'
id: 'Call Service Event (Script) test message'
trigger:
platform: event
event_type: call_service
event_data:
domain: script
condition:
condition: template
value_template: >
{{ trigger.event.data.entity_id == 'script.intercom_text_message'}}
action:
service: notify.filed_intercom_messages
data_template:
message: >
Event call: {{ as_timestamp(now()) | timestamp_custom('%d %b: %X') }}: {{ states('input_text.message')}}
played on {{states('input_select.intercom')}} in {{states('input_select.intercom_language')}}
doesn’t trigger?
would this be a reason to use the state trigger automation and focus on getting that to work? Since I get this in the logs:
Error rendering data template: UndefinedError: 'dict object' has no attribute 'to_state'
I fear it won’t work with the event trigger as you already suspected.
taking the to: ‘on’ out of the state trigger automation looks promising:
- alias: 'Forward intercom messages to filed_intercom_messages'
id: 'Forward intercom messages to filed_intercom_messages'
trigger:
platform: state
entity_id: script.intercom_text_message
condition: []
action:
service: notify.filed_intercom_messages
data_template:
message: >
Script state: {{ as_timestamp(now()) | timestamp_custom('%d %b: %X') }}: {{ states('input_text.message')}}
played on {{states('input_select.intercom')}} in {{states('input_select.intercom_language')}} by
{{trigger.to_state.context.user_id}}
results in:
Script state: 06 Nov: 14:36:20: testing for trigger.to_state.context.user_id
played on Office in Nl by
3a8d4c2-redacted-2f67356b63
! Cool. now I need to find a mapper for the id’s
Could you explain why the state trigger on the script won’t work using a state: ‘on’, but does work without a state defined? Suppose it now triggers on an attribute or maybe the last_changed?
this indicates though it triggers on last_triggered:
Script state triggered on <state script.intercom_text_message=off; last_triggered=2019-11-06T14:42:53.679379+01:00, friendly_name=Intercom text message, custom_ui_state_card=state-card-custom-ui, action_name=Announce, icon=mdi:text-to-speech @ 2019-11-06T14:42:56.710785+01:00>: 06 Nov: 14:42:56: testing for trigger.to_state
played on Office in En by
3a8d4c-redacted-356b63
tested by:
action:
service: notify.filed_intercom_messages
data_template:
message: >
Script state triggered on {{trigger.to_state}}: {{ as_timestamp(now()) | timestamp_custom('%d %b: %X') }}: {{ states('input_text.message')}}
played on {{states('input_select.intercom')}} in {{states('input_select.intercom_language')}} by
{{trigger.to_state.context.user_id}}
continuing on the context.user_id: I suppose we couldn’t use context.user_name, or maybe context.user? That would be much easier and not force me to use a mapper for the id’s.
The only options avialable from context are: user_id, parent_id, and id. Go into your users and create a map from your user name to your user_id. The user id is displayed in the ui for each user.
EDIT:
You may be able to access this information from a python_script. I don’t know off the top of my head. There has to be an object somewhere in the software that contains user information.
ok thanks Petro, will do. where can I read up on this? Can’t find it in the docs just yet.
this works fine for now, will add more user_id’s too come and create a true mapper for that:
action:
service: notify.filed_intercom_messages
data_template:
message: >
{% set message = states('input_text.message') %}
{% set device = states('input_select.intercom') %}
{% set language = states('input_select.intercom_language') %}
{% set id = trigger.to_state.context.user_id %}
{% set time = as_timestamp(now()) | timestamp_custom('%d %b: %X') %}
{% set user = 'Marius' if id == '3a8d-redacted-6b63' else id %}
{{time}}: {{user}} played "{{message}}" on {{device}} in {{language}}
so, this is cool, got a working messaging log in my Ha setup now for all family members
- alias: 'Forward intercom messages to filed intercom messages'
id: 'Forward intercom messages to filed intercom messages'
trigger:
platform: state
entity_id: script.intercom_text_message
condition: []
action:
service: notify.filed_intercom_messages
data_template:
message: >
{% set message = states('input_text.message') %}
{% set device = states('input_select.intercom') %}
{% set language = states('input_select.intercom_language') %}
{% set id = trigger.to_state.context.user_id %}
{% set time = as_timestamp(now()) | timestamp_custom('%d %b: %X') %}
{% set user = {'3a8d-redacted-b63':'Marius',
'ed40-redacted-68af0':'Wife',
'579-redacted-9d9':'Daughter1',
'425-redacted-a1fa66':'Daughter2',
'3297-redacted-c0fe7a':'Daughter3',
'734fc2-redacted-74a6a':'Daughter4'} %}
{% set user = user[id] if id in user else id %}
{{time}}: {{user}} played "{{message}}" on {{device}} in {{language}}
If only I could find a way how to move the mapper to the secrets file… don’t like all the user_id out in the open…
{% set message = states('input_text.message') %}
{% set device = states('input_select.intercom') %}
{% set language = states('input_select.intercom_language') %}
{% set id = trigger.to_state.context.user_id %}
{% set time = as_timestamp(now()) | timestamp_custom('%d %b: %X') %}
{% set user = states.person | selectattr('attributes.user_id', 'eq', id) | list | first %}
{{time}}: {{user.id}} played "{{message}}" on {{device}} in {{language}}
that looks promising, but, after setting up all my persons (hadn’t used that before), the template doesn’t show me a name for the user, in the {{user.id}} part. No matter which attribute I use, it isn’t displayed. If only {{user}} is used, it shows all attributes of that particular person.
if I enter
{{states.person.marijn.attributes.friendly_name}}
in the template editor, it reveals the name I am looking for.
How could I change your template to use that?
{% set message = states('input_text.message') %}
{% set device = states('input_select.intercom') %}
{% set language = states('input_select.intercom_language') %}
{% set id = trigger.to_state.context.user_id %}
{% set time = as_timestamp(now()) | timestamp_custom('%d %b: %X') %}
{% set user = states.person | selectattr('attributes.user_id', 'eq', id) | list | first %}
{% set user = user.attributes.friendly_name %}
{{time}}: {{user}} played "{{message}}" on {{device}} in {{language}}
could you explain what:
{% set user = states.person | selectattr('attributes.user_id', 'eq', id) | list | first %}
does, especially the last 2 filters?
using:
{% set user = states.person | selectattr('attributes.user_id', 'eq', id) | first %}
seems to give me the same correct result, though I am not sure why…