Caution
VERY EXPERIMENTAL. This software can operate a physical door lock. Hardware validation is incomplete, and passing automated tests does not establish safe production operation. It must not be treated as the only means of entering or securing a property. Test only while physically present with a working mechanical key, keypad, or other manual fallback.
This repository merges the newer Home Assistant packaging and interface work from PiexlPuck/hass-addons with compatible reliability changes from RK392/hass-addons and the RK392 TTLock SDK v0.3.34.
The public project and repository name is TT-LockStar-HA-integration. Its Home Assistant add-on slug is tt-lockstar-ha-integration.
Home Assistant treats a changed slug as a different add-on. Installations made under the legacy tt-lockstar-ha-intergration or upstream ttlock-hass-integration slug will not automatically inherit add-on data or configuration. Back up and explicitly migrate add-on data before replacing an existing installation.
Read MERGE_NOTES.md before building, installing, pairing, or operating a lock.
Detailed release and supervised hardware-test history is in UPDATE_NOTES.md.
- Add-on version:
0.1.0-alpha.64 - Home Assistant stage:
experimental - Development branch:
main - Target: Home Assistant on Linux
- Verified image: Home Assistant Alpine Linux,
amd64 - Frontend production build: successful before the final package rename; renamed packaged assets verified in the final Docker image
- Backend JavaScript syntax checks: successful
- SDK v0.3.34 compile and method inspection: successful
- Real Bluetooth adapter and lock test: discovery, battery, time, magnetic contact, operation-log reads, unlock, and lock have worked with raw HCI. Native BlueZ has one physically verified round trip without an add-on restart. ESPHome through the dedicated Craft proxy has completed physically confirmed lock and unlock commands. The alpha.58 prepared unlock reused a verified live command channel and completed the authenticated command in 659 milliseconds; the user physically confirmed the closed door was unlocked. Alpha.60 exposed that same bounded read-only preparation lease as a Home Assistant MQTT button. Alpha.61 corrects the shared-feed address-type handoff and suppresses unsolicited startup metadata connections before further preparation testing.
- Alpha.57 adds explicit read-only hardware-feature discovery and persists the authoritative current SDK lock snapshot so auto-lock, sound, PIN, card, passage-mode, and remote-unlock commands do not look unsupported after a direct ESPHome restart. Live validation restored the complete feature set, auto-lock
0, and sound on after an add-on-only restart without contacting the lock again. Biometric enrollment remains last and unvalidated. - Production readiness: not ready
Development priority is core discovery, evidence-backed state, reliable lock/unlock, settings, PINs, and cards. Biometric fingerprint enrollment and management remain unvalidated and are intentionally last in the implementation and hardware-test order.
Compatibility is claimed only for the user's M302 lock running firmware 6.4.43.24052101. That value was read from this physical lock on 2026-07-13 through the dedicated read-only COMM_READ_DEVICE_INFO request using the Craft ESPHome proxy. No other lock model or M302 firmware is claimed as tested.
The source repository may be stored or edited on Windows, but the deployable add-on image is Linux-native and was built with Docker Desktop's Linux engine.
This add-on communicates locally with a TTLock-compatible lock using a selectable Bluetooth transport. raw_hci is the default because it passed the supervised physical test; dbus uses maintained @stoprocent/noble 2.5.5; bluez bypasses Noble with a native BlueZ D-Bus adapter; and esphome_proxy uses the native API of one or more existing ESPHome Bluetooth proxies. All non-default paths remain experimental.
- A direct USB/onboard Bluetooth adapter is required for
raw_hci,dbus, andbluez;esphome_proxyinstead requires a local ESPHome device with active Bluetooth connections and remote GATT caching enabled. - The adapter is selected with
bluetooth_adapter, normallyhci0orhci1. - The transport is selected with
bluetooth_transport:raw_hciby default, Noble-backeddbus, nativebluez, or localesphome_proxy. esphome_proxy_hostsis a comma-separated list of native API endpoints such as192.168.1.30:6053,192.168.1.55:6053. No TTLock Cloud or G2 gateway is used by this transport.- ESPHome proxy support currently accepts native API endpoints without an API password or Noise encryption key. Keep those endpoints on a trusted local network; encrypted proxy credentials are not implemented yet.
- With
esphome_advertisement_source: home_assistant(the default), Home Assistant retains the ESPHome advertisement subscription and TT LockStar consumes the supportedbluetooth/subscribe_advertisementsWebSocket feed. The add-on's direct ESPHome clients remain connection-only for active scan mode and GATT. The legacydirectsource is retained only for bounded diagnostics and can displace Home Assistant's proxy stream. - The add-on explicitly requests active scanning whenever it connects to a proxy. The proxy must expose scanner state/mode control in addition to active connections and remote GATT caching.
- A TTLock G2 gateway is not a transport for this add-on and remains a separate TTLock app/cloud path.
- Simultaneous access from the G2, TTLock app, and this add-on may cause Bluetooth contention or failed operations.
Do not reset, unpair, or initialize an existing production lock until its current ownership/pairing data and recovery path are understood. A reset could disrupt the existing TTLock app or gateway relationship.
- Dedicated read-only firmware-revision request using
COMM_READ_DEVICE_INFO/FIRMWARE_REVISION - Capability-discoverable WebSocket command API covering the pinned SDK's supported high-level operations
- Local lock and unlock commands
- Multiple-lock discovery and management
- PIN, IC card, and fingerprint management
- Lock sound and auto-lock settings up to 300 seconds
- Cached credentials and operation logs with manual refresh
- Optional automatic operation-log fetching
- Lock clock read and synchronization controls
- Home Assistant MQTT discovery for confirmed lock state, passive advertised-state diagnostics, battery, signal level, and lock time
- BLE connection serialization and bounded connection recovery; physical lock and unlock payloads are executed exactly once per confirmed request and are never automatically retried
- Bounded read-only connection preparation for latency-sensitive supervised workflows
- Home Assistant Ingress interface
The generic command API, its exact-confirmation rules, and the intentionally excluded low-level SDK internals are documented in API_COMMANDS.md.
- Home Assistant OS or a supervised Linux installation capable of running local add-ons
- Direct Bluetooth adapter visible to the Home Assistant host, or a local ESPHome proxy configured for active connections and remote GATT caching
- Host networking and Bluetooth permissions supplied by the add-on configuration; host D-Bus is also required for the experimental D-Bus transport
- MQTT broker for Home Assistant discovery, state reporting, and control
- A manual means of entry during every test
Only the amd64 image has been built and inspected during this merge. The manifest also declares aarch64, but that architecture still needs a native image build and hardware test.
This project uses Semantic Versioning:
0.1.0-alpha.N: active development; incomplete and potentially breaking0.1.0-beta.N: feature-complete candidate undergoing supervised hardware testing0.1.0-rc.N: release candidate with no known blocking defects0.1.0: first experimental release considered usable for careful manual operation0.MINOR.PATCH: pre-1.0 development; minor releases may still contain breaking changes1.0.0: reserved for a documented, migration-aware release with sustained hardware validation
Git release tags use the matching vVERSION form, beginning with v0.1.0-alpha.1.
Open the repository root in Visual Studio Code and run Dev Containers: Reopen in Container. The development container uses Home Assistant's current app-development image with Node.js 24, Python 3.13, ShellCheck, and the Home Assistant Supervisor tooling.
From Terminal > Run Task, use Start Home Assistant to start the local development instance at http://localhost:7123/. The remaining tasks install, start, rebuild, and follow logs for tt-lockstar-ha-integration.
The container covers local builds and non-hardware tests. Bluetooth and physical lock validation must still run on the supervised Linux test host with a manual entry method available.
- Keep the existing TTLock app/G2 path and a manual entry method available.
- Install the add-on without resetting or pairing the production lock.
- Confirm the intended local Bluetooth adapter is visible to Home Assistant.
- Import known-good existing lock data if a safe source is available.
- Leave automatic operation-log fetching disabled initially.
- Test status reads while physically at the door.
- Test one lock and one unlock command with the door open.
- Verify the TTLock app, G2 gateway, keypad, and mechanical entry method still work.
- Observe reliability before enabling automations.
Do not connect this experimental add-on to unattended auto-unlock, facial-recognition, presence, or geofence automations.
The validated local amd64 build command is:
docker build \
--platform linux/amd64 \
--tag tt-lockstar-ha-integration:0.1.0-alpha.64 \
./tt-lockstar-ha-integrationBuilding an image does not validate Bluetooth behavior. Final testing must occur on the Home Assistant Linux host with its real adapter and lock.
- The project is unofficial and is not affiliated with TTLock or Home Assistant.
- The experimental
Advertised Lock Statesensor exposes the SDK's passiveisUnlockadvertisement bit. A supervised manual test returned the same clear bit while the bolt was physically locked and unlocked, proving it is not a continuous bolt-position field. Automations must use evidence-backed confirmed state, not this diagnostic sensor or its raw-payload signature. - There is no upstream automated test suite.
- Lock pairing material, administrative data, credentials, and operation logs are stored in add-on data and may be included in backups. Protect both.
- Do not expose the add-on API or Ingress service directly to the internet.
- Native Bluetooth behavior depends on adapter hardware, driver support, signal quality, D-Bus, and host networking.
- Raw HCI remains the default and the native
bluezoption remains available. Native BlueZ removes only the target's host-unpaired cache after disconnect so each wake can provide a fresh connection object; host-paired devices are preserved. It also keeps discovery active for command connections and shortens only the safely bounded native retry path. These latency changes still require supervised physical validation. - Alpha.48 reuses an ESPHome GATT service/MTU cache after the first successful discovery and automatically retries uncached after a cached failure. The optimization does not bypass TTLock authentication or response checks and remains pending supervised timing validation.
- The image installs both transports, compiles the raw-HCI native binding, explicitly builds the pinned TTLock SDK commit, and then runs the fail-closed patch step.
npm audit --omit=devreports 7 moderate, 7 high, and 2 critical findings. Most high/critical findings are inherited through the legacy raw-HCI build/install dependency chain. There is no safe automatic upgrade for the pinned runtime; keep the add-on local-only and do not usenpm audit fix --force.- Generated frontend assets are committed because the Home Assistant add-on image copies the prebuilt interface.
- Original add-on and SDK: Emanuel Posescu (
kind3r) - Home Assistant packaging and interface base:
PiexlPuck/hass-addons - Reliability changes and SDK v0.3.34:
RK392/hass-addonsandRK392/ttlock-sdk-js - Local merge and Docker validation: Chad Shipman
The upstream histories are preserved in the merge commit. See MERGE_NOTES.md for the selected changes and validation record.
This project remains licensed under the GNU General Public License v3.0. The original license and author attribution are retained in LICENSE.md. Modified versions and redistributed builds must continue to comply with the GPL.