Schlage Connect Locks - HA Integration Needs Attention

Yes it is, don’t name it map because map is a filter.

Sorry, i left out half the equation…

          {% set mapper = { 'sensor.frontdoor_action': 'states.sensor.frontdoor_code',
                            'sensor.backdoor_action' : 'states.sensor.backdoor_code',
                            'sensor.garagedoor_code' : 'states.sensor.garagedoor_code' } %}
           {{ trigger.to_state.attributes.friendly_name }} unlocked by {{ states(mapper[trigger.entity_id]) }}
1 Like

Sorry, One last change, maybe??

          {% set mapper = { 'sensor.frontdoor_action': 'states.sensor.frontdoor_code',
                            'sensor.backdoor_action' : 'states.sensor.backdoor_code',
                            'sensor.garagedoor_code' : 'states.sensor.garagedoor_code' } %}
           {{ trigger.to_state.attributes.friendly_name }} unlocked by {{ states(mapper[trigger.entity_id]) }}

Should it be?

          {% set mapper = { 'sensor.frontdoor_action': 'sensor.frontdoor_code.state',
                            'sensor.backdoor_action' : 'sensor.backdoor_code.state',
                            'sensor.garagedoor_code' : 'sensor.garagedoor_code.state' } %}
           {{ trigger.to_state.attributes.friendly_name }} unlocked by {{ states(mapper[trigger.entity_id]) }}

Nope, remove the state, the state() method on the mapper object will pull the state out of the entity_id w/o the .state on it.

To clarify:

This

{{ states.sensor.frontdoor_code.state }}

is the same as

{{ states('sensor.frontdoor_code') }}

Just noticed another typo, this should work:

          {% set mapper = { 'sensor.frontdoor_action': 'sensor.frontdoor_code',
                            'sensor.backdoor_action' : 'sensor.backdoor_code',
                            'sensor.garagedoor_code' : 'sensor.garagedoor_code' } %}
          {{ trigger.to_state.attributes.friendly_name }} unlocked by {{ states(mapper[trigger.entity_id]) }}
1 Like

Well darn, I went to post my package file and found that I was limited to 32,000 characters, but had 90,000+ haha. I’ll have to get my github figured out. Post coming soon.

I have the following working now thanks to everyone’s help @nalipaz @petro @firstof9 @hejman08 (door codes/alarm levels)

  • Scheduled codes @nalipaz (and the majority of the foundation)
  • One Time user code with a random code created for you
  • Fix for the ‘0000’ not clearing codes on my locks, sets a random code instead
  • Notification when a code is used including who opened what door with timestamp, used names already set up with UI.
  • Works with Schalge BE469 and FE599, but I beleive it works with Yale, just not tested to verify
3 Likes

I’ll play around, but states(mapper… is returning unknown, but the sensor is defintiely being updated. I’ll check and report back. I tried adding state to the end just in case and it make no difference either. :slight_smile:

I’m excited to be finally posting this. This is mostly based on the original post by @nalipaz, but then added some sensors for door codes that I found on a post by @hejman08. Then a lot of templating help from @firstof9 @petro, I think I’ve gotten something that will be useful for many people with Schlage Locks. I believe that most if not all of this will work with Yale or other zwave locks as well, but of course cannot confirm.

I have two Schlage BE469 deadbolts and an FE599 lock. The FE599 is a bit different. Setting and clearing of codes works just great though, the door unlock notification is a bit flaky, but generally works as well.

I tried to put as many comments as possible to make it clear on what to change if you wanted to name your locks differently. Additionally, if you only have one deadbolt, it’s fairly obvious what to remove and what to keep.

I don’t have a need for 30 codes, so I broke it down to 18 (18 also happens to be the max codes for the FE599)

I wanted to have an area for Family codes, one for workers, and then I set up 3 codes as one time use. A random code will be set and will automatically clear when used. Not sure how often I’ll actually use it , but it was a fun lesson. Also I wanted to be notified who unlocked a door. I made almost no changes to the scheduled codes. This allows you to set a start and end date for a code, and it will automatically clear when the time is up. That’s all @nalipaz. :slight_smile:

The only thing I’d like to come back to maybe in the future would the the scheduled, reoccurring on a specific day, like, maybe a code works M-F only from 8am-5pm, or just on Tuesdays, etc. And maybe the option to disable a code when people are home. These don’t seem too crazy to implement, just more than I wanted to get into at the moment.

https://github.com/ptdalen/home-assistant/blob/master/packages/door_locks.yaml

10 Likes

Nice work! Doing something about the Schlage lock integration has been on my radar for awhile. Looks like you’ve tackled it successfully. I’ll test shortly!

1 Like

In order to use the schlage connect lock with HA, do I need a separate piece of hardware? Like a usb dongle adapter? Or can I just use HA and the lock with No other hardware needed?

I’m an absolute noob when it comes to making the changes needed to HA to get the lock working. Should I start a new thread?

@R0tten you will need a zwave usb dongle connected to your HA to control the Schlage Connect which is a zwave lock.

Needs a lot of work, but wanted to post a preview of possible more automation for changing schalge zwave confiig settings. Need to figure out the best way to do this, might put this in a card using the new lovelace UI?

Anyway, this is not at all formatted correctly, but the concept, is this is an input select for each of the possible zwave configuration options. Above each one I just put the general outline for what will be the zwave.set_config_parameter for each one.

The input selects are the correct options pulled from the zwave xml config file.

input_selects

  lock_zwave_option_3:
      name: Enable or disable the beeper.
      options:
          - Disable Beeper
          - Enable Beeper

  lock_zwave_option_4:
      name: Prevents all user codes from unlocking the deadbolt
      options:
          - Disable Vacation Mode
          - Enable Vacation Mode
		  
  lock_zwave_option_5:
      name: Press the Outside Schlage Button to lock the deadbolt
      options:
          - Disable Lock & Leave
          - Enable Lock & Leave
			
  lock_zwave_option_7:
      name: Alarm sounds based on door activity
      options:
          - Alarm Off
          - Activity
          - Tamper
          - Forced Entry
		  
  lock_zwave_option_8:
      name: Activity Alarm Sensitivity
      options:
          - Most Sensitive
          - Medium/high Sensitivity
          - Medium Sensitivity
          - Medium/low Sensitivity
          - Least Sensitivity

  lock_zwave_option_9:
      name: Tamper Alarm Sensitivity
      options:
          - Most Sensitive
          - Medium/high Sensitivity
          - Medium Sensitivity
          - Medium/low Sensitivity
          - Least Sensitivity

  lock_zwave_option_10:
      name: Forced Entry Alarm Sensitivity
      options:
          - Most Sensitive
          - Medium/high Sensitivity
          - Medium Sensitivity
          - Medium/low Sensitivity
          - Least Sensitivity

  lock_zwave_option_11:
      name: Disable Local Alarm Controls
      options:
          - Disable local alarm controls
          - Enable local alarm controls

  lock_zwave_option_15:
      name: Auto lock
      options:
          - Disable auto lock
          - Enable auto lock

  lock_zwave_option_16:
      name: User code pin length (changing Lenth erases all codes)
      options:
          - 4
          - 5
          - 6
          - 7
          - 8


automation examples
- alias: Set Schlage Zwave Options
  trigger:
    - platform: state
      entity_id: input_boolean.save_lock_1_settings
      to: on
  action:
    service: zwave.set_config_parameter
    data_template: {
      "node_id": 99,
      "parameter": 3,
      "value": "{{states.input_select.lock_zwave_option_3.state}}"
      }
 and th enext one
delay
and the next one, etc

I think that this will end up having multiple calls to set all zwave parameters, but maybe with a delay between each parameter.  Setting the parameters seems to be a bit hit or miss in general (at least for me)
zwave.set_config_parameter commands to be used (needs a bit of work.  Want it to be as dynamic as possible)
{"node_id": XX, "parameter": 3, "value": "input_select.lock_zwave_option_3"}

{"node_id": XX, "parameter": 4, "value": "input_select.lock_zwave_option_4"}
		  
{"node_id": XX, "parameter": 5, "value": "input_select.lock_zwave_option_5"}
			
{"node_id": XX, "parameter": 7, "value": "input_select.lock_zwave_option_4"}
		  
{"node_id": XX, "parameter": 8, "value": "input_select.lock_zwave_option_8"}

{"node_id": XX, "parameter": 9, "value": "input_select.lock_zwave_option_9"}

{"node_id": XX, "parameter": 10, "value": "input_select.lock_zwave_option_10"}

{"node_id": XX, "parameter": 11, "value": "input_select.lock_zwave_option_11"}

{"node_id": XX, "parameter": 15, "value": "input_select.lock_zwave_option_15"}

{"node_id": XX, "parameter": 16, "value": "input_select.lock_zwave_option_16"}
1 Like

So this works

{
      "node_id": 82,
      "parameter": 7,
      "value":  "Tamper"
      }

But this does not

{
      "node_id": 82,
      "parameter": 7,
      "value": "{{states.input_select.lock_zwave_option_7.state}}"
      }

But the second one shows proper in the template test area.

Any thoughts?

Literally I can copy the output from the template test area into the services and it works

Great work! I’m using Yale B1L locks (YRD110) and have tweaked your code to suit my needs.

Out of curiosity: why do you check HA uptime before sending a notification? Are the lock states unpredictable in the first few seconds of uptime?

I just add HA uptime to any automations that send notifications. I often got “false” messages when I restarted HA, or worse my wife would get a false message :-). Just more of a safetly precaution for me.

1 Like

What exactly needs to be replaced to make this work with our locks ?

If you have a look at this

I commented pretty heavily on what needs to be changed and where. Should be pretty easy to follow. A significant portion of this was from @nalipaz initial post, but I added a lot of other sensors from other posts in the community as well

This part its not clear for me:

Entities need to be named to match your lock name. In this case
front, back, garage based on “lock.lock_front_door_lock”, etc

For example ALL parts where front is located for the name of our lock ?

For example my back door lock is has this entity name in HA

lock.lock_back_door_lock
and my front is named
lock.lock_front_door_lock

If you’re have different names you either need to rename your locks (entities) or make a lot of changes in the yaml to match your name. It’s your choice, but for many renaming your locks is the easiest.

Edit the reason for the naming is that the input booleans, and several other items in the script just parse the name of the lock. For example

input_boolean.door_keypad_1_back_switch

relys on lock.lock_back_door_lock. It actually parses the name of the input boolean and pulls the word “BACK” to use elsewhere in the script then uses that here

            {% set object_id = trigger.to_state.object_id %}
            {% set lock_name = "_".join(object_id.split("_")[3:-1]) %}
            {% set lock_id = 'lock_' ~ lock_name ~ '_door_lock' %}
            {{ states['lock'][lock_id].attributes.node_id }}

lock_id ends up being the name of your lock

1 Like

Hi , thanks for the explanation

Here is the place to change it right ? In my case what it should be ?

Seems that the system adds _locked to the end of the name there…

I renamed mine in the entity registry file here is what mine looks like for all sensors

Make sure to stop HA, make the changes, then start ha

lock.lock_front_door_lock:
  name:
  platform: zwave
  unique_id: 82-7205759541934535
sensor.lock_front_door_deadbolt_alarm_type:
  name:
  platform: zwave
  unique_id: 82-720575953453505345
sensor.lock_front_door_deadbolt_alarm_level:
  name:
  platform: zwave
  unique_id: 82-72057536469705361
sensor.lock_front_door_deadbolt_sourcenodeid:
  name:
  platform: zwave
  unique_id: 82-72057536346705377
sensor.lock_front_door_deadbolt_access_control:
  name:
  platform: zwave
  unique_id: 82-7205757698419705489
sensor.lock_front_door_deadbolt_burglar:
  name:
  platform: zwave
  unique_id: 82-720575956969685
sensor.lock_front_door_deadbolt_power_management:
  name:
  platform: zwave
  unique_id: 82-72057596796965521
sensor.lock_front_door_deadbolt_system:
  name:
  platform: zwave
  unique_id: 82-720575956796937

Of course make sure any other sensors or automations you have match the new names.

These names will work with the package file I have

I’ve been using the script for a few days now, and am experiencing some odd behaviour when using the one-time-use codes. It seems the automation to delete the one-time-use codes is running in response to unknown events that are not door unlocks.

Looking at the relevant automation:

  - alias: Keypad clear code after one time use code is used for 16 through 18
    trigger:
      - platform: numeric_state
        entity_id:
          - sensor.lock_front_door_deadbolt_alarm_level
          - sensor.lock_back_door_deadbolt_alarm_level
          - sensor.lock_garage_door_lock_alarm_level
        above: 15
        below: 19
    condition:
    - condition: numeric_state
      entity_id: sensor.ha_runtime_in_minutes
      above: 1
    action:
      - service: script.turn_on
        data_template:
          entity_id: >
            {% set code_slot = trigger.to_state.state %}
            {{ 'script.door_keypad_' ~ code_slot ~ '_delete' }}

(I’ve removed comments for brevity.)
It appears that the automation will trigger when the alarm level is in the correct range. However, the alarm level will be in that range for a few different events: door lock, door unlock, and even setting the code in the first place. Shouldn’t the action type also be a condition of the automation, to make sure the door is actually being unlocked?

Something like:

  - alias: Keypad clear code after one time use code is used for 16 through 18
    trigger:
    - platform: numeric_state
      entity_id:
        - sensor.front_door_deadbolt_alarm_level
        - sensor.back_door_deadbolt_alarm_level
        - sensor.garage_door_lock_alarm_level
      above: 15
      below: 19
    condition:
    - condition: and
        conditions:
        - condition: or
          conditions:
            - condition: state
              entity_id: sensor.frontdoor_action
              state: 'Keypad Unlock'
            - condition: state
              entity_id: sensor.backdoor_action
              state: 'Keypad Unlock'
            - condition: state
              entity_id: sensor.garagedoor_action
              state: 'Keypad Unlock'
        - condition: numeric_state
          entity_id: sensor.ha_runtime_in_minutes
          above: 1
    action:
      - service: script.turn_on
        data_template:
          entity_id: >
            {% set code_slot = trigger.to_state.state %}
            {{ 'script.door_keypad_' ~ code_slot ~ '_delete' }}