Yale/August smart locks with WiFi support

This binding integrates some Yale/August locks that are linked to a Yale/August Connect WiFi Bridge.

Support for reading/writing lock bolt state and reading door ajar state as well as battery.

Changelog

Version 0.1

  • Initial release

Version 0.2

  • Fix for access token getting lost

Version 0.3

  • Add support for push messages from server whenever a door/lock is changed. Should give much quicker state updates opposed to the previous infrequent polling.

Version 0.4

  • Fix login regression introduced with 0.3

Resources

https://github.com/seime/openhab2-addons/releases/download/august_alpha4/org.openhab.binding.august-3.4.0-SNAPSHOT.jar

Source code and documentation

Thanks - this is really cool!

Installed under openhab 3, managed to get the bridge installed and discovered a lock. Everything fine for about 15 minutes, after which the bridge went offline with the following message:

Status:

OFFLINE

COMMUNICATION_ERROR

Error fetching data: Error sending request to server: org.eclipse.jetty.client.HttpResponseException: HTTP protocol violation: Authentication challenge without WWW-Authenticate header

Tried to restart openhab, but did not help. Any ideas?

Appears that the session expired very quickly.

Could you enable logs, remove any sensitive data and send them to me via PM?

Regards
Arne

Hi @Casper_Lassenius, the same thing happened to me as well. Found a snag in the code, I updated the linked jar (see top) file with a fix.

Thanks for testing!

Thanks for both the great work and the swift response!

Casper

BTW did you test with some other lock than the Yale Doorman L3? I believe more locks should work, but I have none to test with.

Arne

Yes, the Doorman V2N with the Access module and Wi-Fi bridge. Works like a charm.

Casper

Added a new version that supports push messages from server. This gives more instant response when the lock or door status is changed.

I’d appreciate if you could give it a spin @Casper_Lassenius.

If anyone else is using this binding, feel free to respond to this post so I know if it is working for other locks or users as well - if anyone else is using the binding at all? openHAB system provides close to 0 feedback (by design), but it also leaves developers in the dark regarding usage.

I am giving this a try this evening and I’m having trouble figuring out how to get the lockid. I’ve added the bridge and updated with the validation code from email. I can see from the openhab.log that it has logged in to the August account and has found the correct number of locks, but what do I do from there to find the lockid for each lock (i.e, how do I find the bridge to see the locks it has discovered)?

Thanks,
Jeff

I ended up using the Rest API to trigger a discovery for the binding, then my locks showed up in my Inbox and I was able to add things for them. Getting it all setup with items now, so I’ll report back if I encounter any other issues. Thanks!

Thought I’d take a look about setting this up with my old August Pro (3rd Gen). When I try to save the validation code, I get this error every time:

2023-02-05 21:10:40.640 [ERROR] [st.core.internal.thing.ThingResource] - Exception during HTTP PUT request for update config at 'things/august:account:ed82c29c49/config'
Full Error
java.lang.NullPointerException: null
	at org.openhab.binding.august.internal.comm.PubNubMessageSubscriber.dispose(PubNubMessageSubscriber.java:238) ~[?:?]
	at org.openhab.binding.august.internal.handler.AugustAccountHandler.dispose(AugustAccountHandler.java:234) ~[?:?]
	at org.openhab.core.thing.binding.BaseThingHandler.handleConfigurationUpdate(BaseThingHandler.java:108) ~[?:?]
	at org.openhab.core.thing.internal.ThingRegistryImpl.updateConfiguration(ThingRegistryImpl.java:94) ~[?:?]
	at org.openhab.core.io.rest.core.internal.thing.ThingResource.updateConfiguration(ThingResource.java:505) ~[?:?]
	at jdk.internal.reflect.GeneratedMethodAccessor683.invoke(Unknown Source) ~[?:?]
	at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
	at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
	at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:179) ~[bundleFile:3.4.5]
	at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96) ~[bundleFile:3.4.5]
	at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:201) ~[bundleFile:3.4.5]
	at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:104) ~[bundleFile:3.4.5]
	at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59) ~[bundleFile:3.4.5]
	at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96) ~[bundleFile:3.4.5]
	at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:265) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:225) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:298) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPut(AbstractHTTPServlet.java:234) ~[bundleFile:3.4.5]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:710) ~[bundleFile:3.1.0]
	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:273) ~[bundleFile:3.4.5]
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799) ~[bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:550) ~[bundleFile:9.4.46.v20220331]
	at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:74) ~[bundleFile:?]
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) ~[bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:600) ~[bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235) ~[bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624) ~[bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233) ~[bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440) ~[bundleFile:9.4.46.v20220331]
	at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:294) ~[bundleFile:?]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188) ~[bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501) ~[bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594) ~[bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186) ~[bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355) ~[bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) ~[bundleFile:9.4.46.v20220331]
	at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:90) ~[bundleFile:?]
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.server.Server.handle(Server.java:516) ~[bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487) ~[bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732) [bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479) [bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277) [bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311) [bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105) [bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104) [bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338) [bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315) [bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173) [bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131) [bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:409) [bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883) [bundleFile:9.4.46.v20220331]
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034) [bundleFile:9.4.46.v20220331]
	at java.lang.Thread.run(Thread.java:829) [?:?]

After adding a bridge, the regular discovery should find them if you push the “Scan” button?

Thanks for testing @JustinG.

I seem to have introduced a regression in the 2 factor login when adding async messages.

I posted a new version at the top, let me know if this fixes login.

Regards
Arne

Yep. that was it. Thanks for the quick fix.

Initial testing indicates that it works very well with the August Pro Gen3. I’m delighted by this because the z-wave connection on this lock was starting to get on my nerves (always asleep unless the lock had just been manually used, but what’s the point of a remote connect that requires you to use the lock first?).

I’ll report back after some longer term usage.

Great!

I keep a list of tested devices on the README page, could you confim this is your config?

Cheers

After getting this set up about 12 hours ago things appear to be working correctly for me today and my 3 locks:

  • Yale YR C/D 226/246/256
  • ASL-03 3rd Gen Pro (2 of these)

Thanks!

1 Like

That’s correct.