So i’ve been reading this thread and as i’m currently debating with myself on what lock to get, i’ve narrowed it down to yale and this other (BG4000 ot BG3000) ttlock based one:
It seems like both can be operated with local bluetooth solutions witch is much more desireble that the cloud, also ttlock seems to be hosted in china?
Coud be a problem in the future, who knows really.
Anyway, my question is, as i run a few bt beacons (mainly because i run/track out phones with Bermuda Bluetooth/BLE Triangulation / Trilateration for HomeAssistant) i would guess using my “normal” beacon config via esphome would work, i usually run ESP32-WROOM (might be misspelled) devices.
Would be cool if anyone could try this.
Found some info here for yale, so it seems possible for this as well i’de guess.
My understanding is that this integration allows to manage the cards/biometrics from home assistant, but currently i am struggling to install the bluetooth proxy. I tried the ESP bluetooth proxy and after months trying i am trying to install GitHub - kind3r/ttlock-sdk-js: JavaScript port of the TTLock Android SDK instead on a pi.
i am running homeassistant on a PC with no bluetooth, so the proxy is the only option for me.
If i can get it to run, i’ll post with the step by step instructions for it
I have been trying all kinds of things for months now.
I tried the ESP-32 based proxy but it wouldn’t work for me.
I tried to install [kind3r][ttlock-sdk-js] on an orangepi 3 i had lying around as i had no raspberry pis but it didn’t work. At that point i had some typescript errors that i thought i had sorted, but i guess it didn’t.
Finally bought a RPI zero w 2 and upon installing the above repo… it seems a lot more promising.
when scanning for locks they now show, but pressing pair isn’t working.
I assume the issue is on:
ttlock-sdk-js/src/device/TTDevice.ts
on line 63:
Object.getOwnPropertyNames(temp).forEach((key) => {
if (!excludedKeys.has(key)) {
const val = Reflect.get(this, key);
if (typeof val != 'undefined' && ((typeof val == "string" && val != "") || typeof val != "string")) {
if ((typeof val) == "object") {
if (val.length && val.length > 0) {
Reflect.set(json, key, val.toString('hex'));
}
} else {
Reflect.set(json, key, val);
}
}
}
});
the problem is the lines:
if (val.length && val.length > 0) {
Reflect.set(json, key, val.toString(‘hex’));
the error is: error TS2339: Property ‘length’ does not exist on type ‘string extends keyof this ? this[keyof this & string] : any’.
I dont know enough of typescript to fix this. I tried to cast the val to any (val as any) or (val) but although they compile, the function to pair does not work
If anybody knows how to fix the code would be greatly appreciated
cd ttlock-sdk-js
sudo nano ./src/device/TTDevice.ts
**Edited to add missing closing } as pointed out by MuzzaM **
replace the file’s content with the following:
'use strict';
import { EventEmitter } from "events";
import { LockType } from "../constant/Lock";
export class TTDevice extends EventEmitter {
id: string = "";
uuid: string = "";
name: string = "";
manufacturer: string = "unknown";
model: string = "unknown";
hardware: string = "unknown";
firmware: string = "unknown";
address: string = "";
rssi: number = 0;
protocolType: number = 0;
protocolVersion: number = 0;
scene: number = 0;
groupId: number = 0;
orgId: number = 0;
lockType: LockType = LockType.UNKNOWN;
isTouch: boolean = false;
isUnlock: boolean = false;
hasEvents: boolean = true;
isSettingMode: boolean = false;
txPowerLevel: number = 0;
batteryCapacity: number = -1;
date: number = 0;
isWristband: boolean = false;
isRoomLock: boolean = false;
isSafeLock: boolean = false;
isBicycleLock: boolean = false;
isLockcar: boolean = false;
isGlassLock: boolean = false;
isPadLock: boolean = false;
isCyLinder: boolean = false;
isRemoteControlDevice: boolean = false;
isDfuMode: boolean = false;
isNoLockService: boolean = false;
remoteUnlockSwitch: number = 0;
disconnectStatus: number = 0;
parkStatus: number = 0;
toJSON(asObject: boolean = false): string | Object {
const json: { [key: string]: any } = {};
const excludedKeys = new Set([
"_eventsCount"
]);
Object.getOwnPropertyNames(this).forEach((key) => {
if (!excludedKeys.has(key)) {
const val = Reflect.get(this, key);
if (val !== undefined && val !== '') {
if (typeof val === "object" && val !== null) {
if (Buffer.isBuffer(val)) {
if (val.length > 0) {
json[key] = val.toString('hex');
}
}
else if(Array.isArray(val)) {
if (val.length > 0) {
json[key] = val.toString();
}
}
else {
json[key] = val;
}
} else {
json[key] = val;
}
}
}
});
return asObject ? json : JSON.stringify(json);
}
}
sudo npm i
sudo npm run server-tool
when its running set the add on configuration to have the gateway to say noble
the ip to the pi IP
the gateway port to 2846
the dateway key to f8b55c272eb007f501560839be1f1e7e
and both user and pass to be admin
Finally on the webUI of the add on press the top right corner and activate the lock. it should show to be paired.
then try to pair. For me it didn’t go through first time. It took a good 20-30 attempts
lt only took the better part of a year… damn
Now… i need multiple proxies because the locks are too far to each other… good times
The locks will only pair to one device at a time. I had to remove them from the app before pairing to Home Assistant.
This was a RPI zero W 2 running the ttlock-sdk-js.
I never got the esp32 version to work unfortunately.
I now still need to do some extra work on this as i have 4 locks fairly far from each other beyond bluetooth range.
im looking at:
Hacking the Pi to add an external antenna
Alter the addon to allow multiple proxies
use regular esp32 to extend the range of the pi.
I’m not sure what will pan out. Adding the antenna seems the simplest, and might work as my house isn’t that big and the locks are just barely out of range.
The other two options might be a bit more useful for the community.
We’ll see how it goes.
I am stubborn and keep at it for a while, but i do have other fights to fight. The cat flaps for example
Just to clarify, removing the lock from the app and doing a factory reset seems to amount to the same. In both cases all the stored access gets wiped and it all has to be done again.
A bit of a pain, but well worth it to get into Home Assistant with offline support
That TTDevice.ts file content you listed is missing the last trailing ’ } ’
by my trial of your process steps.
Just so anybody else runs into the error it produces .
Thanks for the documenting the steps, have not yet completed pairing yet…
OK all done following the instructions above.
Thanks @TheTrueWanderer for documenting this.
A few notes from my testing this install.
I forgot to delete a TTLock HACS cloud integration, and this offline version had similar name which was a bit confusing before I realised.
Remember to turn off the original WIFI Bridge if you are coming from the cloud interface.
Once I set up the Pi4 running the Server I managed to PAIR the lock on the second attempt. I think the key is the order you activate the lock and hit the PAIR button.
From my reading and my own experience you need to activate the lock FIRST (mine ‘spoke’ a message to now enter bluetooth admin or some such words) … Then hit the PAIR button.
Very happy that I can run this OFFLINE.
With the old cloud connection I did use an option to SET Passage Mode between certain hours which was very handy, but this is not provided as far as I can see.
The sensors displayed via MQTT are LOCK/UNLOCK, Battery Level, RSSI.
I did change the Auto Lock from 5s to 59s, so this works.
I also tested the Sound On/OFF feature which worked.
I’ll probably be running this on a PiZero next once I tidy things up and do some more testing.
Just an update to my experience. It seems to work but after restarting the addon it cant read the access controls. I’m not sure if this is a common problem or just me.
Edit: so… this was true, but all of the sudden it started to work. not sure why. Its either a bit flaky, or behaves differently from a cron job and when run manually with a debugger attached. Very odd indeed.
Edit again: even being run as a service it works… but required a restart on the add on and a few tries. Must be what OP referred to bluetooth being unstable
I had my pi zero close to the lock and worked fine but as soon as i put the lock and the pi about 4 to 5 meters away, it doesn’t work anymore. I guess the only real way is to get a pi per lock. I don’t mind that but that will require changes to allow for that.
Looking at ttlock-sdk-js/tree/main/src/scanner/noble/NobleWebsocketBinding.ts
It seems to me that it would be possible to alter the webserver instance with an array and pass a comma separated list of IPs as a quick and dirty way to get this working with multiple proxies. Unfortunately i dont know how to make changes to the dependency an have the addon use it.
Thanks for the instructions! I’ve just moved in to a place with one of these locks and have been struggling to manage it without the very limited app. I saw your post, and grabbed a Pi zero W 2, fresh install, update/upgrade, followed your instructions but get “Error: Cannot find module ‘…/build/Release/bluetooth_hci_socket.node’” when ruinning ‘sudo npm run server-tool’. Am I missing something?
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
pi@rp32z2w:~ $
cut and paste updated TTDevice.ts code into here and SAVE/EXIT
Check file looks OK
cat ./src/device/TTDevice.ts
sudo npm I
pi@rp32z2w:~/ttlock-sdk-js $ sudo npm I
npm WARN deprecated [email protected]: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
npm WARN deprecated [email protected]: This package is no longer supported.
npm WARN deprecated [email protected]: This package is no longer supported.
npm WARN deprecated [email protected]: Rimraf versions prior to v4 are no longer supported
npm WARN deprecated [email protected]: This package is no longer supported.
npm WARN deprecated [email protected]: Glob versions prior to v9 are no longer supported
npm WARN deprecated [email protected]: Glob versions prior to v9 are no longer supported
npm WARN deprecated [email protected]: TSLint has been deprecated in favor of ESLint. Please see Roadmap: TSLint -> ESLint · Issue #4534 · palantir/tslint · GitHub for more information.
I must admit i didn’t pay any attention to what bitness OS i installed.
I have another pi on the way to try to connect multiple gateways to the addon and i’ll try to pay a bit more attention on the next install
I think a small change on ttlock-sdk-js might allow for that although i have absolutely no idea how to deploy it. I don’t really know how docker works
but we’ll cross that bridge when we reach it