ELK M1 Interface

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.

- id: keypad_code_entered
  alias: "Keypad code entered"
  initial_state: 'on'
  trigger:
    - platform: state
      entity_id:
        - sensor.elkm1_keypad_001
        - sensor.elkm1_keypad_002
        - sensor.elkm1_keypad_003
  condition:
    condition: template
    value_template: "{{ trigger.from_state.attributes['last_user_time'] != trigger.to_state.attributes['last_user_time'] }}"
  action:
    service: persistent_notification.create
    data_template:
      title: "Keypad triggered"
      message: >-
        {%- set a = trigger.to_state.attributes %}
        {%- if trigger.to_state.attributes['last_user'] %}
          User "{{ a['last_user_name'] }}" entered valid code at
        {%- else %}
          Invalid code "{{ trigger.to_state.attributes['code'] }}" entered at
        {%- endif %}
        keypad {{ a['index'] }} ({{ a['friendly_name'] }})

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.

Thoughts?

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 … :sunglasses:

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.

@BioSehnsucht Curious how you did this before, can you share an example?

@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.

This may be a problem : Accessing entity registry values in an Automation

TL;DR : Apparently you cannot currently access the unique_id from Jinja

Yah. I figured that. Instead of the keypad index (on which the entity_id is currently computed) the actually entity_id could be stored.

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 :smiley:

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.

Thoughts?

Regarding users, no matter which user arms or disarms, value is always changed_by_user:1. Am I doing something wrong?

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

Entering codes from physical keypad produces desired results. Thanks

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?

@stipex it looks like it is not possible.

Are you running the latest code? https://github.com/gwww/ha-elkm1/tree/refactor has the latest. There will be a couple more changes in this area. See my last couple of posts on this list.

I expect the code to be posted shortly.

Thankfully I found this "Elk M1 interface project! I’ve been running HomeAssistant for a week on a ubuntu VM. So far I am very impressed with the work you guys have done!
Thank you for this latest code in “refactor”, it fixed the problems I’ve been having with displaying the correct temperatures from the Elk. I’m in Canada and we use Celsius temperatures and before I added your refactor update, the temperatures on all sensors and control panels where displayed incorrectly! Thank you!!

The only issue I have now is the furnace control thermostat. We have a TR40-RS485 that controls the furnace and AC. https://www.smarthome-products.com/productspecs/TR40-Manual.pdf

Here’s what I see in HASS -

current temp should display 23C
heat set point should display 23C
cooling set point should display 27C

Maybe there is something I am doing wrong but I appreciate any input!

Probably a double conversion somewhere in the code or HASS. The heat_setpoint and cool_setpoint are set as you say, but target_temp_high and target_temp_low are what are shown in the UI and clearly wrong. Same for current temperature.

23C is 73.4F. 23F is -5C. Converting from 73.4F to celcius, then to celcius again (when it already is) gets us these wrong numbers.

Ahhhhhh! Well I decided to try https://github.com/gwww/ha-elkm1/tree/refactor with my old config and I was greeted with two things:

elk:// changed to socket://

plc: changed to x10:

And now, none of my “enabled: false” statements took for output and task so now I have several hundred outputs and tasks. lol

Looks like the Area / keypad disappeared from my configuration as well. Well it didn’t disappear, it’s now showing as “area_2”? hmmmm what did i miss in this thread?