Let me first say, I’m moving my way up the stack. Started with elkm1-lib, then hass integration. I have spent almost no time on automations. That said…
What is possible in automations such that changed_by_* are not attributes at all on the alarm_control_panel?
Right now they are an aberration compared with the rest of the hass code. Those are the only attributes that are shown that are not “native” to the hass component.
So my challenge to everyone is this. Can you come up with a way to get the automation you are looking for, without “standing on your head”, using only native attributes?
Is it possible that when a system is armed/disarmed that triggers the automation which then goes and grabs “last_user” from the keypad, which then grabs the “name” from users?
IMO the more attributes available the better. Attributes give me more information to work with, to trigger automations or to filter events.
I can’t speak of hass automation since I do all my automations in Node Red. When I have it trigger on a state change of a device, all the attributes of said device get sent as a json payload through my flows. If some attributes are not a part of this entity I have to add additionnal queries back to hass to obtain the values and include them in my automation. It sounds simple but it adds complexity to the process.
I don’t use the changed_by* attributes yet in my automations but I think that in a situation where you have multiple keypads it would make sense to have the changed_by* attributes on the alarm_panel entity so you directly know on which keypad the action took place without going through each keypad entities to figure out which one did the change and extract the values from there.
Perhaps it might be better. Perhaps it is breaking the model of the device. Perhaps something else
First, all the attributes from the ElkM1 are represented and available. No question (unless I’ve missed one).
What we are talking about is storing attributes from one component, say a keypad, on another component, say an alarm_control_panel.
What if… the trigger for the automation is on a keypad? From that you get the area, the user, and of course the time (of the trigger). From there you can pull the arm status for the area. And, if you want something other than arm status you could pull that.
So, back to my throwdown challenge… can we create the automation without creating cross component attributes?
It looks like changed_by on the alarm_control_panel entity worked just fine. @gwww I agree we can likely pull together the automations we want by using some automation logic. I’ll let you know if I run into any cases that won’t work or are prohibitively complicated. Thank you again for all of your work on this component.
- id: notify_alarm_disarmed
alias: "Notify Jim who disarmed"
hide_entity: True
trigger:
- platform: state
entity_id: alarm_control_panel.elkm1_area_001
from: 'pending'
to: 'disarmed'
- platform: state
entity_id: alarm_control_panel.elkm1_area_001
from: 'triggered'
to: 'disarmed'
action:
service: notify.haas_notifier_jshank_pixel
data_template:
title: "Alarm Disarmed"
message: '{{ states.alarm_control_panel.elkm1_area_001.attributes["changed_by"].split(" ")[0] }} disarmed the alarm'
I think what @Gwww is hoping for is that we can figure out a pattern where we can do something like :
“({{ states.alarm_control_panel.elkm1_keypad_{{states.alarm_control_panel.elkm1_area_001.attributes.changed_by_keypad}}.attributes.friendly_name) accessed by {{ states.alarm_control_panel.elkm1_keypad_{{states.alarm_control_panel.elkm1_area_001.attributes.changed_by_keypad}}.attributes.last_user_name }}”
Or in other words, look up the keypad using the changed_by_keypad and then get the user name / etc from there.
If we can make it work, then we avoid duplicating information, and keep information as much as possible only on the entities it is relevant to.
However I don’t know enough about the automation scripting/templating to know if you can perform such lookups in a template “code” (you could certainly do it with proper code in AppDaemon). Also, there might be a gotcha with the formatting (since currently we’re zero-padding the entity names so they are sorted nice and pretty in the entity list in order, but the changed_by_keypad likely lacks that, so even if it worked it might not work … ). Again in AppDaemon this would be trivial to work around, but in template “code” I’m not sure how to do it. It might all be doable but I don’t know that part of HASS well enough to say.
I can say that in our usage of the Elk at my office, we do have multiple keypads (technically M1KAM RFID readers), and thus do have a need as @mathd postulated for being able to get who accessed / etc an area. We post that to our internal chat system. So one way or the other, this will be getting solved in a functional fashion
Let me start with a proposal for device_state_attributes…
On the alarm_control_panel (area in Elk terms), all keypad attributes will be removed except one: the index of the keypad that last entered a code on its keypad. So, user index, user name, keypad name would not be attributes.
Why? Because automations can support everything with them. I tried to figure out how to get rid of the keypad index too, but have not figured out how (yet).
Here’s the automation:
- id: alarm_panel_status
alias: "Alarm panel arm/disarm"
initial_state: 'on'
trigger:
- platform: state
entity_id: alarm_control_panel.elkm1_area_001
to: 'armed_night'
for:
seconds: 1.5
- platform: state
entity_id: alarm_control_panel.elkm1_area_001
to: 'disarmed'
condition:
condition: template
value_template: "{{ trigger.to_state.attributes.changed_by_keypad > 0 }}"
action:
service: persistent_notification.create
data_template:
title: "Alarm arm/disarm"
message: >-
{%- set keypad_num = trigger.to_state.attributes.changed_by_keypad %}
{%- set keypad = "sensor.elkm1_keypad_{:03d}".format(keypad_num) %}
Alarm has been set to {{ trigger.to_state.attributes.state }}
by "{{ state_attr(keypad, 'last_user_name') }}"
({{ state_attr(keypad, 'last_user') }})
at {{ state_attr(keypad, 'last_user_time') }}.
Of course you can put in your own action.
I have also created an automation when for keypad code is entered.
Here’s the output of the two automations when entering a valid code on a keypad:
User "Glenn" entered valid code at keypad 1 (Lower Hall)
Alarm has been set to armed_night by "Glenn" (1) at 2018-09-10T03:22:17.537389+00:00.
Alarm has been set to disarmed by "Glenn" (1) at 2018-09-10T03:23:25.976835+00:00.
So, I propose that the keypad attributes will be removed from alarm_control_panel.
Requires a lot more lines of code but honestly I don’t feel it matters as long as it works, since it’s something you would copy and paste and modify if necessary, not something you have to remember how to do from scratch. And we’d of course have such examples in the documentation.
That example shows some template coding possibilities I hadn’t yet taken the time to learn were possible …
I’ll try to test this out with our use case ASAP and ensure it works, but as long as we can get the keypad number and then use it to reference the keypad entity as you show, I don’t foresee any problems - all things will be solvable.
@gwww Here’s a snippet of our existing way of handling this (there’s more for other areas):
sensor:
- platform: template
sensors:
elk_area_1_last_user_at:
value_template: '{{ states.alarm_control_panel.elkm1_area_001.attributes["Last User At"] }}'
friendly_name: 'ELK Area 1 last accessed at'
automation:
- alias: 'Main Area Accessed'
trigger:
platform: state
entity_id: sensor.elk_area_1_last_user_at
action:
- service: notify.stride
data_template:
message: "Main Area ({{ states.alarm_control_panel.elkm1_area_001.attributes.last_keypad_name }}) accessed by {{ states.alarm_control_panel.elk_area_001.attributes['Last User Name'] }}"
the template sensor nonsense is because I couldn’t get triggering on attributes to work (perhaps this works now) so I had to create the fake sensor from an attribute then trigger on it.
Well, you still have to create a “fake” sensor to track an attribute change in the current hass.
Overall it’s not much different in lines of “code” if you take into account the attribute sensor and the automation bit. The formatting I used broke it into multiple lines. I also see you are using a template too.
There’s a new issue popping up (look for another Elk thread on the forum) around unique_id vs entity_id. It seems that entities are supposed to create a unique_id not an entity_id. I googling around to try and figure out the “right” answer. Not much clarity on what is right. I’ve played around a wee bit today, switched to creating the unique_id and let hass create the entity_id. Seems to work except the entity_id names are all the default names from the library. But entity_ids can be edited.
So, warning that to get integrated into hass we may need to change to unique_id. Simple code change. Bigger impacts for automations, etc. Might also impact how the keypad is linked to the alarm_control_panel.
That should work fine. If someone manages to rename their entity ID between the event occuring and the automation firing, they only have themselves to blame
This of course assumes we can look up the entity_id from within HASS itself, but if it’s not doable with some built in functionality, worst case we can track that ourselves (similar to the old discovered devices code would be one way).
@BioSehnsucht Appears doable to have entity_id as the changed_by_keypad. Still need to test further.
Hey all, another breaking change. This is big(ish). First, still investigating, but looks like to be latest hass compatible the entity_id should be generated by hass. The Elk hass code should be generating a unique_id.
What does this mean? The Elk-hass code would generate a unique_id for each entity. The unique_id would look just like the entity_id does today. For example a unique_id would be something such as sensor.elkm1_zone_001. The hass-generated entity_id would be something like sensor.zone001.
With this change all your entity_ids will change. However, you are now able to edit your entity_ids to be what you want (within reason).
Thanks to @lddubeau for point the entity_id/unique_id usage. I had an inkling that what was in the Elk-hass code was not correct but did not have details until today.
If arming/disarming through hass the API to the Elk always uses keypad 1. Can’t change that. If arming/disarming through a physical keypad it should be the actual keypad number. If its not then I will look into it.
As to user, the user number should match the code entered. Or 0 for invalid code.
After rebooting, sometimes I get users, sometimes not. Currently, output is changed_by (blank, no value), changed_by_user:0, changed_by_time:0, changed_by_keypad:0. Arming and disarming doesn’t change these values. I will keep testing and reporting back. Cheers
To expand, codes from physical keypads work correctly. But if armed or disarmed via HASS, changed_by still shows last code entered via physical keypad, and not code entered in HASS
Arming and disarming with different users isn’t being displayed correctly. I have test with Android app M1 Touch, and the Elk logs show the different users arming and disarming, but not the case in HA. HA only shows users with codes entered on physical keypad. Is there a way to update last user no matter where code is entered?