TTLOCK Integration with HA

I got my TTLock connected to Home Assistant thanks to @xbecomingx

Question. Has anyone figured out how to create an Automation based on the door being unlocked? Or is that too “real time” for this integration.

1 Like

Hi, your tutorial is the only one that I found helpful for me, but currently I am stuck at the step " logout and login using the new user and the same password used for developer account. "
Where should be logging out from? if its the iOS app, I logged out and tried logging in with the developer account and pass, but says unknown user/pass (the iOS app and developer account has the same email, but different passwords, is this the problem)?

  • I installed the ttlock2mqtt addon and configured it with required credentials, i am a but confused here as well, should I also install the MQTT broker add-on? MQTT does not show up in the configuration → integrations, i tried to integrate using the info found the ttlock2mqtt addon but with no success.
    my bad to make this so long to read, i am very new to this and i am so lost.
    need help!!
    EDIT : I was able to get the lock in, thanks to @seba.olah, Great tutorial, its just my interpretation of things were a bit stupid!

This integration is working well for me so far. Thank you for coding it!

I’m finding the huge delays in gateway responses are preventing me from being able to use this very successfully. Is anyone else encountering these lengthy delays, like up to a minute for something to happen (if it even does) after I click “lock” or “unlock”?

Another alternative - requires gateway and uses TT lock API Docker Hub

A restful API for TT lock; handles access tokens and dates

  1. Create an application https://open.ttlock.com/manager
  2. Register a user in the application - returns a prefixed user that you can add to your lock
curl --location -g --request POST 'https://api.ttlock.com/v3/user/register' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'clientId=your id' \
--data-urlencode 'clientSecret=your secret' \
--data-urlencode 'username=lockuser' \
--data-urlencode 'password=your application users password md5 hashed' \
--data-urlencode 'date=1650909361599'

https://currentmillis.com - get the current date

echo "password" | md5 - md5 hash password

  1. Add your new prefixed user to your lock in the TT lock app
  2. Create a Docker container
docker run \
-e CLIENTID='your id' \
-e CLIENTSECRET='your secret' \
-e LOCKID='your lock id' \
-e USER='your prefixed application user' \
-e PASSWORD='your application users password md5 hashed' \
-p 5000:5000 stevendodd/ttlock
  1. Add the following sensor and rest command to configuration.yaml in home assistant

rest:
  - scan_interval: 60
    resource: http://192.168.1.162:8125/123
    sensor:
      - name: "Front Door"
        value_template: "OK"
        json_attributes:
          - "autoLockTime"
          - "electricQuantity"
          - "firmwareRevision"
          - "hardwareRevision"
          - "lockAlias"
          - "modelNum"
          - "passageMode"
          - "passageModeAutoUnlock"
          - "soundVolume"
          - "tamperAlert"
rest_command:
  unlock_door:
    url: "http://192.168.1.162:8125/123/unlock"
    method: get
2 Likes

Hi @stevendodd does this method still have that lock delay as mentioned by @arrows

Maybe a few seconds nothing that’s not tolerable

Looks really interesting, @stevendodd . Thanks! If I can figure out how to run a Docker container in my Home Assistant OS on my Pi, I’ll give it a try. I can skip to step 4 as I already have API access working.

However - I have two TTLOCK locks - would I need to run two separate containers?

Is the IP address for your HA box, your Docker container, or your lock gateway?

Yes you would need to run two containers for two locks; I only implemented it for one; I’ll post the source code later so if you want you can modify.

http://192.168.1.162:8125/123 is the URL of the rest interface running inside the docker container

This is the python script running inside the container - if your locks share the same user it would be very simple to pass the lock ID in the URL

from flask import Flask
from flask import request
import json
import requests
import time
import os
 
tokenExpiryTime = 0

def current_milli_time():
    return round(time.time() * 1000)

def get_token():
    global tokenExpiryTime
    if current_milli_time() > tokenExpiryTime:
        global clientId
        global accessToken
        global lockId

        clientId = os.environ['CLIENTID']
        lockId = os.environ['LOCKID']
        clientSecret = os.environ['CLIENTSECRET']
        user = os.environ['USER']
        password = os.environ['PASSWORD']
      
        data = {"client_id": clientId,
                "client_secret": clientSecret,
                "username": user,
                "password": password
                }
        response = requests.post("https://api.ttlock.com/oauth2/token", data)
            
        if response.status_code == 200:
            accessToken = response.json()["access_token"]
            tokenExpiryTime = int(response.json()["expires_in"])*1000 + current_milli_time() - 25000
        
def handle_users():
    get_token()
    response = requests.get("https://api.ttlock.com/v3/lockRecord/list?clientId=" + clientId + "&accessToken=" + accessToken + "&lockId=" + lockId + "&pageNo=1&pageSize=1&date=" + str(current_milli_time()))
    if response.status_code == 200:
        return(response.json())
    
def handle_unlock():  
    get_token()
    data = {"clientId": clientId,
            "accessToken": accessToken,
            "lockId": lockId,
            "date": current_milli_time()
        }
    
    response = requests.post("https://api.ttlock.com/v3/lock/unlock", data)
            
    if response.status_code == 200:
        return(response.json())


def request_lock():
    get_token()    
    response = requests.get("https://api.ttlock.com/v3/lock/detail?clientId=" + clientId + "&accessToken=" + accessToken + "&lockId=" + lockId + "&date=" + str(current_milli_time()))
         
    if response.status_code == 200:
        return(response.json())


app = Flask(__name__)

@app.route("/",methods = ['GET'])
def hello():
    return('stevendodd/TTLock')

@app.route("/<lock>/unlock",methods = ['POST', 'GET'])
def unlock(lock):
    return handle_unlock()

@app.route("/<lock>/users",methods = ['GET'])
def users(lock):
    return handle_users()

@app.route("/<lock>",methods = ['GET'])
def get_lock(lock):
    return request_lock()

many thanks for your share ,
can you provide with sample that work with docker-compose please

is it correct like this below ?

version: ‘3.3’
services:
ttlock:
environment:
- ‘CLIENTID=your id’
- ‘CLIENTSECRET=your secret’
- ‘LOCKID=your lock id’
- ‘USER=your prefixed application user’
- ‘PASSWORD=your application users password md5 hashed’
ports:
- ‘5000:5000’
image: stevendodd/ttlock

version: "3"

services:
  TTlock:
    container_name: TTlock
    image: stevendodd/ttlock:latest
    ports:
      - "5000:5000/tcp"
    environment:
      - CLIENTID='Your id'
      - CLIENTSECRET='Your secret'
      - LOCKID='..'
      - USER='..'
      - PASSWORD='..'
    restart: unless-stopped

seem to have setup done but getting this error anyone know why

[services.d] done.
2022-05-12 08:26:04 - [ERROR] TTLOCK2MQTT: Exiting script…
Traceback (most recent call last):
File “/ttlock_adapter.py”, line 321, in main
raise ValueError(‘Invalid ttlock client or token.’)
ValueError: Invalid ttlock client or token.

i checked the values and they are right thanks for any help

UPDATE: uninstalled the add on then reinstalled and then worked !!! THANKS to everyone !!!

@goldbe4804 does the TTLock App work with this method.?

yes it does but there is a 60 sec delay so ha to lock is ok for lock/unlock --status update may lag

its seems to have been a bit maybe will see an update :slightly_smiling_face:

3 Likes

Hi,

Thanks for posting, however I am probably being stupid but where you say register a user, is that just the main login for the TTL App on your phone and the same as the password?

Many Thanks

You have to create an admin user to manage your application, it’s different to lock users and different to the login that you use for your application

Thanks for your reply, nearly there now think it’s working.

Just need to add to config.yaml.

Is the port 8125 correct, as the sensor doesn’t seem to be added when I set the IP to the server hosting the docker image?

Thanks again

Many thanks again for your help

From memory the flask Web server runs on port 5000 within the docker; image you would need to map port 8125 to 5000 when you deploy the container.

Thanks for the nice work!

Is there a rest command to lock the door?
Can you get the lock status? (unlock / locked)