[HOWTO] Simulate a native device when it is not supported by an app - example with ttlock

In this thread, @Shiki asked me to write a tutorial about how I combine a number of features to make a customised virtual device which behaves as if it were natively supported by an app, without having to code your own app or script.

Specifically, there is no app for ttlock, which is the web platform for many many locks, keypads and other security devices out there on the market. Two branded ones that I know of are Ruveno and Simpled, but you can see many examples and designs on AliExpress. Note that for this guide you will need the ttlock gateway too, and I assume you already have the ttlock app and gateway configured and working with your lock.

We need to use the ttlock web api. Sign up for a developer account at https://euopen.ttlock.com/login (or, your correct region address). In the management area, create a new application. Give it a name, logo, description and choose the type of Web. It will take a few days for it to be approved. Once it is approved, revisit the application in the management screen and take note of the client id and secret provided to you. Here is what mine looks like:

While waiting for your application to be approved, install the Device Capabilities app on your Homey. Create a new device and choose the Advanced Virtual Device from Device Capabilities. Create it as an empty device and choose a name and icon. https://www.svgrepo.com/ is a great place to get icons if you don’t like any of the built in ones:



After the device is created, right click and go to repair. The developer of this app has built the customisations into the repair menu. For this tutorial we’ll add a switch which will be the control to lock and unlock it, as well as be updated to match the state of the lock. We’ll also add the battery level. See the screen shots for their configuration. Be sure to set the device class to Lock


After saving you should have a device that looks something like this. You can of course add more things later, but lets keep it simple for now.

Now for the fun part with the flows, assuming your app has now been approved. Before you start, make sure you have these things to hand, ready to copy and paste from. Or, as I have done, store them in text variables.

  • Your ttlock api client id
  • Your ttlock api secret
  • Your ttlock app username
  • Your ttlock phone app password, as an md5 hash (you can use https://www.md5hashgenerator.com/ to create it)

Also have the ttlock web api documentation handy, here https://euopen.ttlock.com/document/doc?urlName=cloud%2Foauth2%2FgetAccessTokenEn.html

Create a new advanced flow. There will be two main parts to the flow, one part that fetches the oauth token and lockid, and other parts that use the token and lock id. I’m relatively new to flows so there may be better ways to achieve some of these things, but what I have works. I have chosen to fetch the oauth token and lock id once per day and store it in a variable rather than fetch it all the time. This is my flow that does that:

You should be able to see the URL formatting, but it looks like this:
https://euapi.ttlock.com/oauth2/token?clientId=&clientSecret=&username=&password=
Note that these are url encoded. The @ symbol is %40. You can use this website to url encode things but it is probably only going to be the @ symbol if your app login uses an email address.

Obviously, the url used is from the api documentation, where there are also plenty of curl based examples. Do note that when fetching the lock id, I also search by specifying the name I gave it in the app. Your name may be different.

The homey script in these flows simply gets an epoch date which must be passed and be accurate within 5 minutes:

So, now we have everything needed to call any of the api methods in the documentation. Probably the most useful ones are all under gateway api section. Here is my flow which reacts to the lock and unlock buttons of the advanced device created earlier:

The other thing is to update the actual state of the lock, and the battery level. Here is my flow that does that (I actually have a text field for state too). Note that I only call the api once at a time, as I have found the gateway can fail with a “busy” message otherwise:


Hopefully that is enough to allow someone to do more with ttlock, or any other api for a device that isn’t natively supported by an app. Here is my final device:

If this was useful, I do something similar with a Solis solar inverter, using Node-Red as a middle man to handle the modbus queries, including setting the overnight battery charge rate based on Solcast solar forecasting. I could also do a tutorial on that.

8 Likes

Nice how-to, mostly for someone starting with Device Capabilities, well done !