Schlage BE469 and zwave2mqtt

Summary

I’ve migrated my Z-Wave setup a few different times. I started with SmartThings, tried using Home Assistant’s Z-Wave implementation a few years back, switched back to SmartThings, and finally settled on something I’m happy with: zwave2mqtt running in Docker. It’s on a separate Pi with an AEON Z-Stick, so I can restart Home Assistant without impacting the Z-Wave network.

Everything was pretty quick and painless to migrate over from SmartThings, minus the Schlage BE469. It’s an older model and has been a pain in the ass. The pairing was easy enough, i.e. reset to factory defaults and do a secure pair. The locking and unlocking was easy enough. However, getting the lock to correctly report if it was locked or unlocked was driving me nuts. The Z-Wave value will show a “True” or “False” for if the lock was engaged, but that’s only for Z-Wave. Manually unlocking it will report a “Manual Unlock” event, but the lock still shows that it’s locked.

The TL;DR is that a used a Node-RED automation to update an input_boolean based on the last Z-Wave or physical lock status, and then a lock template is used on top of that.

Implementation

The first part is the MQTT integration. You’ll end up with two entities that are used, although the names might vary depending on how you have them saved in zwave2mqtt:

lock.lock_front_door_zwave
sensor.lock_front_door_alarm_access_control

The top is the actual Z-Wave entity for the lock. The bottom is the status when something changes. If you look at the values sensor.lock_front_door_alarm_access_control you’ll see the following:

Clear
Manual Lock Operation
Manual Unlock Operation
Keypad Lock Operation
Keypad Unlock Operation
Auto Lock
Lock Jammed
Keypad Disabled
New Program Code Entered

Basically, when any of those happen, it’ll send the corresponding event and then go back to the Clear status. The only ones I care about are the Lock and Unlock events.

The first step is to create the input_boolean that will act as the lock state:

input_boolean:
  lock_front_door_switch:
    name: "Lock Front Door Virtual Switch"

Easy enough. Restart Home Assistant and it’ll show up in your entities. The next step is to create a Node-RED flow that flips the input_boolean based on the last lock event. For example, if it’s locked via Z-Wave then the input is “True”. If you then manually unlock it, that event will flip it to “False” even though the lock still reports “True”. Here’s a screenshot for reference:

lock
And here’s the Node-RED flow that you can import:

[{"id":"43493c42.9ae3d4","type":"comment","z":"bc59819c.4843c","name":"Virtual Switch for Front Door","info":"","x":260,"y":460,"wires":[]},{"id":"a2443d88.8f0e8","type":"server-state-changed","z":"bc59819c.4843c","name":"Front Lock Physical","server":"744f1fa7.a5248","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.lock_front_door_alarm_access_control","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"x":110,"y":520,"wires":[["7fa5288f.93bea8"]]},{"id":"7fa5288f.93bea8","type":"switch","z":"bc59819c.4843c","name":"Status","property":"payload","propertyType":"msg","rules":[{"t":"regex","v":"\\b(Locked|Manual Lock Operation|Keypad Lock Operation)\\b","vt":"str","case":true},{"t":"regex","v":"\\b(Unlocked|Manual Unlock Operation|Keypad Unlock Operation)\\b","vt":"str","case":true}],"checkall":"false","repair":false,"outputs":2,"x":290,"y":520,"wires":[["ff125c26.dce92"],["10171d2e.f85b63"]]},{"id":"ff125c26.dce92","type":"api-call-service","z":"bc59819c.4843c","name":"Locked","server":"744f1fa7.a5248","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_on","entityId":"input_boolean.lock_front_door_switch","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":440,"y":520,"wires":[[]]},{"id":"10171d2e.f85b63","type":"api-call-service","z":"bc59819c.4843c","name":"Unlocked","server":"744f1fa7.a5248","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_off","entityId":"input_boolean.lock_front_door_switch","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":440,"y":580,"wires":[[]]},{"id":"b8a3dc21.11046","type":"server-state-changed","z":"bc59819c.4843c","name":"Front Lock Zwave","server":"744f1fa7.a5248","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"lock.lock_front_door_zwave","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"x":110,"y":580,"wires":[["8d9efd09.a37db"]]},{"id":"8d9efd09.a37db","type":"function","z":"bc59819c.4843c","name":"Status","func":"var lockState = msg.data.new_state.attributes.value;\n\nif (lockState == \"true\") {\n    msg.payload = \"Locked\";\n}\n\nelse if (lockState == \"false\") {\n    msg.payload = \"Unlocked\";\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":270,"y":580,"wires":[["7fa5288f.93bea8"]]},{"id":"744f1fa7.a5248","type":"server","z":"","name":"Home Assistant","legacy":false,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":false}]

The next step is to create the lock template that leverages the input_boolean for the status, and the Z-Wave lock for control:

lock:
  - platform: template
    name: 'Lock Front Door'
    value_template: "{{ is_state('input_boolean.lock_front_door_switch', 'on') }}"
    lock:
      service: lock.lock
      data:
        entity_id: lock.lock_front_door_zwave
    unlock:
      service: lock.unlock
      data:
        entity_id: lock.lock_front_door_zwave

Once again, restart Home Assistant for it to appear. You should end up with this assuming everything was configured correctly:
lock2
Hope this helps!

1 Like