Extracting Event Data from Schlage ZWave Deadbolt to Useful Entity State

I’m brainfarting here and struggling to find a way to extract some event data to a single entity value. I.e. “User 1 Unlocked”, “User 1 Locked”, “User 2 Unlocked”, “User 2 Locked”, etc.

A lot of what I’ve found in the community is several years old now and doesn’t seem to work with the new Z-wave JS. I’m not sure if the event data is polling differently or if I’m making some mistake.

Should I be using an automation or an entity template?

What I’ve tried is:

      breezeway_door_code:
        friendly_name: 'Breezeway Door Code'
        value_template: >
                          {% if is_state_attr("lock.breezway_door_deadbolt", "lock_status", "Unlocked with Keypad by user 1") %} 
                            U1
                          {% elif is_state_attr("lock.breezway_door_deadbolt", "lock_status", "Unlocked with Keypad by user 2") %} 
                            U2
                          {% elif is_state_attr("lock.breezway_door_deadbolt", "lock_status", "Locked with Keypad by user 1") %} 
                            L1
                          {% elif is_state_attr("lock.breezway_door_deadbolt", "lock_status", "Locked with Keypad by user 2") %} 
                            L2
                          {% endif %}

This returns nothing so I’m obviously not extracting the right information or it simply doesn’t exist as a state. Given what I see in the event information, the info coming in from Zwave_JS isn’t a state.

Below is what I see in the event data and all I’d like to do is have an entity that creates a unique value where U = “Label: keypad unlock operation”, L = “label: keypad lock operation”, and 1 = “userid: 1”, 2 = “userid: 2”, etc… So the entity value would be if “User 1 locked” = L1 and if “User 3 unlocked” = U3.

{
    "event_type": "zwave_js_event",
    "data": {
        "type": "notification",
        "domain": "zwave_js",
        "node_id": 11,
        "home_id": 4145725559,
        "device_id": "cf5bbe35ec36a434c4e49769db54c717",
        "label": "Keypad unlock operation",
        "parameters": {
            "userId": 2
        }
    },
    "origin": "LOCAL",
    "time_fired": "2021-03-14T14:59:07.196811+00:00",
    "context": {
        "id": "c89801868df24dab1f63d769df0d89c1",
        "parent_id": null,
        "user_id": null
    }
}
Event 0 fired 10:58 AM:
{
    "event_type": "zwave_js_event",
    "data": {
        "type": "notification",
        "domain": "zwave_js",
        "node_id": 11,
        "home_id": 4145725559,
        "device_id": "cf5bbe35ec36a434c4e49769db54c717",
        "label": "Keypad lock operation",
        "parameters": {
            "userId": 1
        }
    },
    "origin": "LOCAL",
    "time_fired": "2021-03-14T14:58:48.928060+00:00",
    "context": {
        "id": "697230cd44b818898ead85bf3ca0ddd3",
        "parent_id": null,
        "user_id": null
    }

The frontend device Id for the lock is “breezeway_door_deadbolt”

Thanks!

1 Like

It would be possible to set an input_text entity to the appropriate value via an automation that monitors zwave_js_event events. However, if there’s already a lock entity (lock.breezeway_door_deadbolt ???) that exists, you might want to take a look at all of its attributes. Maybe there’s already something there you could use. I.e., go to the STATES tab of the Developer Tools page, and look for the entity that represents the lock. What does it show for its attributes?

I think that is where the problem exists with my initial code try. Under states for lock.breezeway_door_deadbolt, I only see ‘locked’ or ‘unlocked.’ With attributes, it only shows it’s friendly name. I will need to pull the data from the events, but I’m unsure how to write this.

I am perplexed why this event data isn’t also an attribute within the entity, but I think that has to do with the ZwaveJS database.

I’m dealing with the same problem (that’s how I found this thread - I was hoping someone else had done the legwork!). I’ve gone through all the entities created with zwavejs and I can’t find any that pertain to user info.

With the old zwave integration the lock status and user was reported as an attribute on the lock entity. The method to use those attributes is what you are seeing in the forums. It won’t work with zwavejs.

Unless/until zwavejs entities are updated to include this info (and it doesn’t look like they will be - see git link) we’re stuck doing exactly what Phil suggested. I’ll put something together tomorrow and post it here.

2 Likes

That would be awesome! Thank you.

This should get you started. I think I have all the events covered here.

- id: lock_side_door_status_update
  alias: '[Lock] Side Door Status Update'
  description: Update side door lock status.
  trigger:
    - platform: event
      event_type: zwave_js_event
      event_data:
        node_id: 52
        label: Keypad unlock operation

    - platform: event
      event_type: zwave_js_event
      event_data:
        node_id: 52
        label: Keypad lock operation

    - platform: event
      event_type: zwave_js_event
      event_data:
        node_id: 52
        label: RF unlock operation

    - platform: event
      event_type: zwave_js_event
      event_data:
        node_id: 52
        label: RF lock operation

    - platform: event
      event_type: zwave_js_event
      event_data:
        node_id: 52
        label: Manual unlock operation

    - platform: event
      event_type: zwave_js_event
      event_data:
        node_id: 52
        label: Manual lock operation

  action:
    - service: input_text.set_value
      data:
        entity_id: input_text.side_door_lock_status
        value: >
          {% set users = ['Jason','Sheri','Dawn'] %}
          {% set userID = trigger.event.data.parameters['userId']|int -1 %}
          {% set user = 'Keypad' if userID == null else users[userID] %}
          {% if trigger.event.data.label == 'Manual unlock operation' %} Unlocked (Manual)
          {% elif trigger.event.data.label == 'Manual unlock operation' %} Locked (Manual)
          {% elif trigger.event.data.label == 'RF unlock operation' %} Unlocked (Hassio)
          {% elif trigger.event.data.label == 'RF lock operation' %} Locked (Hassio)
          {% elif trigger.event.data.label == 'Keypad unlock operation' %} Unlocked ({{ user }})
          {% elif trigger.event.data.label == 'Keypad lock operation' %} Locked ({{ user }})
          {% else %} Unknown
          {% endif %}else user }})
          {% else %} Unknown
          {% endif %}

One way would be to set an input_text entity via an automation. If you don’t like it showing up as an input_text in the UI, you could always then create a template sensor from the input text entity.

automation:
  - trigger:
      - platform: event
        event_type: zwave_js_event
    condition:
      - >
          {{ trigger.event.data.node_id == 11 and
             trigger.event.data.label.startswith('Keypad') and
             trigger.event.data.label.endswith('operation') }}
    action:
      - service: input_text.set_value
        target:
          entity_id: input_text.LOCK
        data:
          value: >
            {{ 'U' if trigger.event.data.label.count('unlock') > 0 else 'L' -}}
            {{ trigger.event.data.parameters.userId }}
2 Likes

HA! I think we were posting at the same time! Your trigger/condition is a little more compact though, I’ll be using that thanks!

Event triggers, especially the event_data parameter, can be a bit tricky and not always work the way one would expect, so I find it’s better to test event data in the condition.

Yours does a lot more. I guess it ultimately depends on what the OP wants. But now he’s got two examples of how to start. :smiley:

I was able to shorten it up a bit more. I don’t believe there would be any unwanted events that end with “lock operation” so this would cover it.

- id: lock_side_door_status_update
  alias: '[Lock] Side Door Status Update'
  description: Update side door lock status.
  trigger:
    - platform: event
      event_type: zwave_js_event

  condition: "{{ trigger.event.data.node_id == 52 and trigger.event.data.label.endswith('lock operation') }}"

  action:
    - service: input_text.set_value
      data:
        entity_id: input_text.side_door_lock_status
        value: >
          {% set users = ['Jason','Sheri','Dawn'] %}
          {% set userID = trigger.event.data.parameters['userId'] %}
          {% set user = 'Keypad' if userID == null else users[userID|int -1] %}
          {% if trigger.event.data.label == 'Manual unlock operation' %} Unlocked (Manual)
          {% elif trigger.event.data.label == 'Manual lock operation' %} Locked (Manual)
          {% elif trigger.event.data.label == 'RF unlock operation' %} Unlocked (Hassio)
          {% elif trigger.event.data.label == 'RF lock operation' %} Locked (Hassio)
          {% elif trigger.event.data.label == 'Keypad unlock operation' %} Unlocked ({{ user }})
          {% elif trigger.event.data.label == 'Keypad lock operation' %} Locked ({{ user }})
          {% else %} Unknown
          {% endif %}
3 Likes

This is awesome! I see now how you extracted the event data. It’s implemented and doing everything I’m looking for it to do thanks to you and @pnbruckner!

1 Like

Here’s another automation you might find useful for your lock. It changes the lock’s internal alarm mode with the house alarm mode.

Disarmed -> No chips (no alarm)
Armed Home -> Chirps when door opened
Armed Night/Away - Changes to forced entry mode.

Lock Alarm Mode Automation
- id: lock_side_door_alarm_mode
  alias: "[Lock] Side Door Alarm Mode"
  description: Set side door lock alarm mode.
  initial_state: true
  mode: queued
  trigger:
    - platform: state
      entity_id: alarm_control_panel.alarmo
      to:
        - armed_home
        - armed_night
        - armed_away
        - disarmed
  condition:
    - condition: or
      alias: Make sure door lock entity is connected (zwave).
      conditions:
        - condition: state
          entity_id: lock.side_door_lock
          state: locked
        - condition: state
          entity_id: lock.side_door_lock
          state: unlocked
  action:
    - choose:
        - conditions:
            - condition: state
              entity_id: alarm_control_panel.alarmo
              state: disarmed
          sequence:
            - service: zwave_js.set_config_parameter
              data:
                parameter: Alarm Mode
                value: Alarm Off
              target:
                entity_id: lock.side_door_lock
        - conditions:
            - condition: state
              entity_id: alarm_control_panel.alarmo
              state: armed_home
          sequence:
            - service: zwave_js.set_config_parameter
              data:
                parameter: Alarm Mode
                value: Alert
              target:
                entity_id: lock.side_door_lock
        - conditions:
            - condition: or
              conditions:
                - condition: state
                  entity_id: alarm_control_panel.alarmo
                  state: armed_night
                - condition: state
                  entity_id: alarm_control_panel.alarmo
                  state: armed_away
          sequence:
            - service: zwave_js.set_config_parameter
              data:
                parameter: Alarm Mode
                value: Forced Entry
              target:
                entity_id: lock.side_door_lock
2 Likes

I made one correction as it looks like a small typo in the even data for the “Locked (Manual)” The event data was duplicated from the “Unlocked (Manual)” Changed ‘unlock’ to ‘lock’

  action:
    - service: input_text.set_value
      data:
        entity_id: input_text.side_door_lock_status
        value: >
          {% set users = ['Jason','Sheri','Dawn'] %}
          {% set userID = trigger.event.data.parameters['userId'] %}
          {% set user = 'Keypad' if userID == null else users[userID|int -1] %}
          {% if trigger.event.data.label == 'Manual unlock operation' %} Unlocked (Manual)
          {% elif trigger.event.data.label == 'Manual lock operation' %} Locked (Manual)
          {% elif trigger.event.data.label == 'RF unlock operation' %} Unlocked (Hassio)
          {% elif trigger.event.data.label == 'RF lock operation' %} Locked (Hassio)
          {% elif trigger.event.data.label == 'Keypad unlock operation' %} Unlocked ({{ user }})
          {% elif trigger.event.data.label == 'Keypad lock operation' %} Locked ({{ user }})
          {% else %} Unknown
          {% endif %}

You are absolutely correct, I had to make the same correction in my config and forgot to make the change here. I’ve updated it now. Good catch!

1 Like

I found this automation useful, it also works for a Kwikset 888 and it may work for a 910 too (need to test this). I wanted to share some updates here for others, on the latest HA update two things changed, the event_type and event_label. I also changed the “else” line to be a catch all.

- alias: Alarm - Front Door Lock Sensor Updater
  id: 'alarm_-_front_door_lock_sensor_updater'
  initial_state: true
  trigger:
  - platform: event
    event_type: zwave_js_notification
  condition:
  - condition: template
    value_template: '{{ trigger.event.data.node_id == 66 and trigger.event.data.command_class_name == ''Notification'' }}'
  action:
  - service: input_text.set_value
    data:
      entity_id: input_text.front_door_lock_status
      value: >
        {% set users = ['Chris','Violet','Pat or Bob','Melanie','Amelia'] %}
        {% set userID = trigger.event.data.parameters['userId'] %}
        {% set user = 'Keypad' if userID == null else users[userID|int -1] %}
        {% if trigger.event.data.event_label == 'Manual unlock operation' %} Manual Unlock
        {% elif trigger.event.data.event_label == 'Manual lock operation' %} Manual Lock
        {% elif trigger.event.data.event_label == 'RF unlock operation' %} RF Unlock
        {% elif trigger.event.data.event_label == 'RF lock operation' %} RF Lock
        {% elif trigger.event.data.event_label == 'Keypad unlock operation' %} Keypad Unlock ({{ user }})
        {% elif trigger.event.data.event_label == 'Keypad lock operation' %} Keypad Lock ({{ user }})
        {% else %} {{trigger.event.data.event_label}}
        {% endif %}

Thank you! I meant to post an update last week when I saw these changes with the core update. You caught them all.

To summarize for those just catching up, because of the “Breaking ZwaveJS changes” on core-2021.04.00, Zwave_JS_event changed to Zwave_JS_notification and the “label” tag changed to “event_label”

Cheers!

For some reason when I lock/unlock through Home Assistant, there is no event created. Events are only generated when I manually interact with the lock. Is this expected? If not, does anyone know why that would be? I basically never see the “RF (un)lock operation” event_label. I was able to see that with the sensor before moving to zwavejs2mqtt.

What event topic are you listening to?

I subscribed to zwave_js_notification and when I manually lock the door I see an event with event_label ‘Manual lock operation’. But, if I unlock or lock in Home Assistant, no zwave_js_notification event is fired at all.

Interesting. On my end, I see “RF lock operation” or “RF unlock operation” under event_label like you stated. Are you viewing the event data from the Developer Tools ->Events tab when you subscribe to zwave_js_notification?

What events are fired if you lock/unlock via the keypad?

Also, when you moved to zwaveJS2mqtt, did you update the ZwaveJS integration with the proper server address? It should look something like this when you go to Integrations->ZwaveJS->configure.