Schlage Encode Wifi

great man! that lock is the only smart device not compatible with my home assistant set up.
I can’t wait to be able to use a NFC tag to open the door with :heart_eyes:

Thanks for the work, and updates!

Just need someone who is able to develop this… I can help with the findings but I’m no programmer capable of making this an integration.

1 Like

Can you share your findings?
Any bash or powershell scripts you can share?

I have not looked inside the lock but I’m tempted to consider replacing the original control board with an ESP32 or equivalent and a small servo controller. Consider that a lock is a very simple device. It moves a bar back and forth and senses the movement.

I would also like to add a solar panel on the door. I expect that unless the doorway is used a lot, or us in a dark location, a solar panel should be able to keep batteries charged.

I just got one of these as well. I went with the WiFi since I don’t have any z-wave devices and didn’t want to add any just for this lock. I’d really love to just be able to see the door status and don’t really care about the lock/unlock from HA right now. One of the routes I tried to go down was to get the lock into the Ring app with the hopes that it would then show up there. To do this I had to pair it with the Amazon Key app. The lock now shows up in the Ring App but does not show as an entity for the Ring integration. Any thoughts on how to get this? It could be a round about way to see the lock in HA.

Maybe there’s hope.
https://theresnomon.co/the-current-state-of-api-access-to-your-schlage-encode-locks-7e981f404501

5 Likes

As proper integration isn’t available I thought I would share a solution I’m working on using Alexa integration with Home Assistant. Allowing Home Assistant to lock the door.
Basically, you use a virtual switch in Home Assistant to change the state of a virtual Home Assistant sensor that Alexa monitors. When Alexa sees the state of that sensor change (i.e. to closed) you have an Alexa routine lock the door.
You don’t need an Amazon Alexa device to use this BTW, just the Alexa app and Amazon account on your Android (maybe iOS device too).

This is the virtual switch, which when in the ‘off’ state will trigger the sensor to change to ‘closed’ and the Alexa Routine. Add this to your configuration.xml.

  front_door_lock_alexa_switch:
    name: Front Door Lock HA Switch
    icon: mdi:door-closed-lock

This is the virtual sensor which Alexa will watch.

- platform: template
    sensors:
      front_door_lock_ha_alexa_switch_sensor:
        friendly_name: "Front Door Lock HA Switch State Sensor"
        device_class: door
        value_template: '{{ is_state("input_boolean.front_door_lock_alexa_switch","on") }}'

Next enable Home Assistant Cloud, Alexa Integration and ensure that the Front Door Lock HA Switch State Sensor is synced to Alexa.

Configure the Schlage Encode integration within the Alexa app on your mobile device.
Setup a Routine in the Alexa to Lock the Front Door when it sees the “Front Door Lock HA Switch State Sensor” in the Closed state.

One problem I’m still working on is that this only works once as Front Door Lock HA Switch and Sensor won’t automatically open again if the front door is actually unlocked. You will need an Automation in Home Assistant to change the virtual switch back to the On state (Sensor Open) every x seconds or something. Or maybe Alexa changes the HA switch state back to Open when is see’s it was open. Not sure yet, but wanted to share my progress as is.

For now the workaround is this automation which reset the switch (effectively turning it into a momentary switch) 10 seconds after it is used.
Add this Automation via the HA GUI using this yaml.

alias: Reset Front Door Lock Switch State
description: 'Resets switch after 10 seconds so it can be reused'
mode: single
trigger:
  - platform: state
    entity_id: input_boolean.front_door_lock_alexa_switch
    to: 'off'
    for: 00:00:10
condition: []
action:
  - service: input_boolean.turn_on
    target:
      entity_id: input_boolean.front_door_lock_alexa_switch

P.S. Thanks to @MarVin for the idea

If you still have this info can you send it to me. I have a pretty strong background with AWS.

Cheers!

2 Likes

Going to bump just because this would be very useful. The Encode is a really great, easy to use lock and I’d love to integrate it into my HA install.

2 Likes

FYI I sent in a suggestion / question to Schlage on their website about local API access and got this reply:

Thank you for contacting Schlage Support to suggest local API support. Unfortunately, although we love the idea, we aren’t able to add it to our development calendar at this point due to competing priorities. If or when that changes, we’ll reach out with more information. We appreciate your insights and suggestions, keep sending them our way!

I still suggest everyone does it to make their opinion heard on the matter.

3 Likes

I tried using mitmproxy between my phone’s Schlage app and the internet, but I couldn’t capture the lock status nor lock change requests. #16 mentions web sockets are used for communication, so maybe mitmproxy is having trouble with those, even though it says web sockets are supported. If anyone has instructions for sniffing the lock status or lock change request traffic, I’d love to see them!

Regarding #31 and #47, Yonomi is closed to indvidual developers (which is the TL;DR of the blogpost in #47). I think something like Nabu Casa would have to step in, get the Yonomi integration working, and then HA would integrate with Nabu Casa.

I’m not sure if this has already been discussed anywhere, but Schlage does (at least now) have a developer portal, specifically listing Schlage Home devices as an API integration option.

https://developer.allegion.com/developer/en/index.html

I’ve requested access and they are supposed to review the request within 24 hours.

3 Likes

Nice! Just requested as well.
Thanks for pointing that out!

April 2019 - feb 2022 and still stuck. I wish I could go back in time and not have bought this lock. I almost wish I could put an esp32 in to turn the thumb and still have the pad work.

Thanks all for still trying

1 Like

@dmrichards26 or @bluk did either of you gain access to the developer portal? Schlage is coming out with a similar version this spring that is compatible with Apple Home Key and I am hoping to replace my current lock with that one.
Here’s a link with more info if anyone is interested: CES 2022: Schlage Introduces Encode Plus Deadbolt With Support for Apple’s Home Key Feature - MacRumors

1 Like

My request status is still at “requested”. Will update when approved or not. Strange as it stated the response/approval would be quick.

1 Like

I still have not gained access either. Like @bluk, my account sits at the “requested” state. I have reached our to Allegion today and hope I’ll be able to get in touch with someone who can help.

1 Like

I made some progress discovering API end points and documenting for myself and others.

Get lock status API

bearer="" # authentication from AWS
api_key="" # maybe hardcoded into app?
curl -vv -H "content-type: application/json" -H "x-api-key: $api_key" -H "authorization: Bearer $bearer" -H "accept-encoding: gzip" -H "user-agent: okhttp/3.8.0" "https://api.allegion.yonomi.cloud/v1/devices?archetype=lock"

Returns lots of info! lock state; battery change date, level; alarm settings; firmware version; wifi signal strength, mac address; users associated with lock; and more. I’m too lazy to properly redact it to paste a sample; sorry.

Lock/Unlock API

value=1 # lock
value=0 # unlock
bearer="" # authentication from AWS
api_key="" # maybe hardcoded into app?
lock_device_id="" # uuid from get lock status response
curl -vv -H "content-type: application/json" -H "x-api-key: $api_key" -H "authorization: Bearer $bearer" -H "accept-encoding: gzip" -H "user-agent: okhttp/3.8.0" -d '{"attributes":{"lockState":$value}}' -X PUT "https://api.allegion.yonomi.cloud/v1/devices/$lock_device_id"

Method

  1. I used a random site to get the Schlage Home APK from the play store onto a computer
  2. I used apk-mitm to remove the certificate pinning in the APK
  3. I installed the patched APK onto an android phone
  4. I used mitmproxy to intercept the requests
    a. start mitmproxy on computer
    b. configure android phone to use proxy
    c. install cert (http://mitm.it) on android phone
  5. I made a few requests

More Notes

  • This should be enough to put together a very crude initial proof-of-concept integration
  • Bearer auth token
    • I’m pretty sure this is available via mitmproxy without having to patch an app to avoid certificate pinning. This would mean hoops to jump through to get it and put it in an HA config file, but very doable (kinda like what’s had to happen with Nest integration in the past)
    • Not sure how long this token is good for. I though I saw somewhere that it was 3600 units. Units were defined, and now I can’t find the response that included that expiration information. Who knows.
    • Would be nice to figure out how to do the auth for real, using the username and password users use with the app. I think @mcnutter1 post #40 in this thread got the closest. Not quite enough there for me to reproduce, though.
  • api key
    • I’m thinking this might be hardcoded into the app. I didn’t see it an auth responses. I didn’t want to start trying other values
    • The way I currently know how to get this involves the apk-mitm certificate pinning patching. Can surely find it in the packaged apps somewhere, but I don’t know how to do that.
    • It might be enough for someone to figure this out everytime a new app version drops (if that’s even necessary)
    • shasum -a512 - “108826$api_key” is 3ea4e400bb5706aff440274d9bc1bff77efa0aa2a32e9541b7ee0d3428c4c681fa30d0fc33675541a5e762ff0375d242373d329bc770c80ed54efac93d42a1c1. would be nice to know if it matches other people.
  • the lock status appears to update in the app with websockets in addition to the conventional HTTP lock status request above. For example, when I have the app open on my phone and I issue a curl (un)lock request, the phone updates quickly. mitmproxy didn’t show me these requests (yet?) so I don’t know how they work.
8 Likes

No worries, I’ll help out here. Here is a schema with all the parameters returned and their possible values:

{
  "type": "object",
  "properties": {
    "lockState": {
      "enum": [
        "Unlocked",
        "Locked",
        "Jammed",
        "Unknown"
      ],
      "type": "string",
      "description": "Constants used to indicate the state of the device."
    },
    "batteryState": {
      "enum": [
        "Normal",
        "Low",
        "CriticallyLow",
        "Unknown"
      ],
      "type": "string",
      "description": "Potential set of values that can be assigned to battery state."
    },
    "modelName": {
      "type": "string",
      "description": "Human readable model name to present to users",
      "nullable": true
    },
    "serialNumber": {
      "type": "string",
      "description": "Serial number of the device",
      "nullable": true
    },
    "percentageBatteryLevel": {
      "type": "integer",
      "description": "Battery level in percentage\r\nNote: This value has been known to be unreliable",
      "format": "int32",
      "nullable": true
    },
    "connected": {
      "type": "boolean",
      "description": "Boolean to check if the device's most recent heartbeat indicates it was connected"
    },
    "lastConnectedToCloud": {
      "type": "string",
      "description": "Timestamp when the device was last connected to the cloud.",
      "format": "date-time",
      "nullable": true
    },
    "lastUpdated": {
      "type": "string",
      "description": "Timestamp when the device was last updated",
      "format": "date-time"
    },
    "created": {
      "type": "string",
      "description": "Timestamp when the device was created",
      "format": "date-time"
    },
    "accessCodeLength": {
      "type": "integer",
      "description": "Access code length of the lock. Ranges from 4-8 digit. It will be null if no accessCodes created in lock.",
      "format": "int32",
      "nullable": true
    },
    "timezoneOffset": {
      "type": "string",
      "description": "Timezone of the lock.",
      "nullable": true
    },
    "id": {
      "type": "string",
      "description": "Device unique identification.",
      "format": "uuid"
    },
    "name": {
      "type": "string",
      "description": "Device friendly name.",
      "nullable": true
    },
    "type": {
      "type": "string",
      "description": "Device factory model type.",
      "nullable": true
    }
  },
  "additionalProperties": false,
  "description": "Detailed dto to be returned from the api"
}
4 Likes