homebridge-ttlock-accesscode 2.0.0-beta.6 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,42 +13,85 @@
13
13
  <p align="center">
14
14
  <a href="https://github.com/ZeliardM/homebridge-ttlock-accesscode/blob/latest/LICENSE"><img src="https://img.shields.io/npm/l/homebridge-ttlock-accesscode?color=yellow" alt="mit license"></a>
15
15
  <a href="https://www.npmjs.com/package/homebridge-ttlock-accesscode/v/latest"><img src="https://img.shields.io/npm/v/homebridge-ttlock-accesscode/latest?label=npm%40latest&color=blue" alt="latest npm version"></a>
16
+ <a href="https://www.npmjs.com/package/homebridge-ttlock-accesscode/v/beta"><img src="https://img.shields.io/npm/v/homebridge-ttlock-accesscode/beta?label=npm%40beta&color=red" alt="beta npm version"></a>
16
17
  <a href="https://www.npmjs.com/package/homebridge-ttlock-accesscode/v/latest"><img src="https://img.shields.io/npm/dt/homebridge-ttlock-accesscode?color=brightgreen" alt="npm downloads total"></a>
17
- <a href="https://www.paypal.me/ZeliardM/USD/"><img src="https://img.shields.io/badge/donate-paypal-orange" alt="donate"></a>
18
- <a href="https://github.com/sponsors/ZeliardM"><img src="https://img.shields.io/badge/donate-github-orange" alt="donate"></a>
18
+ <a href="https://www.paypal.me/ZeliardM/USD/"><img src="https://img.shields.io/badge/donate-paypal-orange" alt="donate paypal"></a>
19
+ <a href="https://github.com/sponsors/ZeliardM"><img src="https://img.shields.io/badge/donate-github-orange" alt="donate github"></a>
19
20
  </p>
20
21
 
21
- <div align="center">
22
+ This is a [Homebridge](https://github.com/homebridge/homebridge) plug-in based for integrating TTLock smart locks with the TTLock Cloud API.
22
23
 
23
- >## PLEASE READ!!!
24
- >HomeKey Support is not physically possible with TTLock Readers, but Access Code Features are working in HomeKit.
24
+ This plug-in lets you control TTLock locks in the Apple Home app with lock/unlock status, control, and access code management if supported.
25
25
 
26
- </div>
26
+ ## Requirements
27
+ - Homebridge Supported Versions: 1.8.0 and 2.0.0-beta.0 or later.
28
+ - Node.js Supported Versions: 20, 22, and 24.
29
+ - TTLock Smart Lock.
30
+ - TTLock Gateway for non-Wi-Fi locks.
31
+ - Remote Unlock enabled in the TTLock mobile app.
32
+ - TTLock Open API account with an approved OAUTH2.0 App.
27
33
 
28
- This is a [Homebridge](https://github.com/homebridge/homebridge) plug-in based for integrating TTLock smart locks with the TTLock Cloud API.
34
+ ## Current Supported and Tested Devices
35
+ - I have tested this plug-in with a G2 Gateway setup and TTLock lock access code features in Apple Home. More lock models and gateway setups are expected to work, but may vary by TTLock firmware and account setup.
29
36
 
30
37
  ## Features
31
-
32
38
  - Get the status of your TTLock devices.
33
39
  - Lock and unlock your TTLock devices.
34
- - Manage passcodes for your TTLock devices.
35
-
36
- ## Requirements
37
-
38
- 1. TTLock Smart Lock
39
- 2. A Gateway (If your lock does not have built-in Wi-Fi, I purchased a TTLock G2 Gateway off Amazon.)
40
- 3. Remote Unlock must be enabled through the TTLock App locally within bluetooth or Wi-Fi rnage of your lock.
41
- 4. You must create a TTLock Open API Account. This is not the username and password that will be used in the setting in the plug-in, this is for creating an OAUTH2.0 App with the TTLock Cloud API for the plug-in to get access to your TTLock Devices.
42
-
43
- ## Setup
44
-
45
- 1. Create an account in the [TTLock Cloud API](https://euopen.ttlock.com/register).
46
- 2. Create your OAUTH2.0 App, give it a name, icon, select the 'App' option, and a short description.</br>
47
- *This may take a few days to be approved by their Development Team.*
48
- 3. Once approved, you will need the *client_id* and *client_secret* from the app.
49
- 4. Setup the TTLock Mobile App, create an account in the Mobile App, setup and install your lock(s).</br>
50
- *If your Lock is not Wi-Fi Capable, make sure you setup your Gateway as well and have it close enough to your Lock for the Gateway to pick up the Lock in the Mobile App.*
51
- 5. Once you have your Mobile App Username and Password, and the client_id and client_secret, you can setup the plug-in in Homebridge.
52
-
53
- ## IMPORTANT
54
- I have only tested this with a G2 Gateway.
40
+ - Manage passcodes for your TTLock devices in Apple Home.
41
+ - Automatic API usage protection with adaptive polling.
42
+ - Periodic discovery and offline recovery handling.
43
+
44
+ ## Installation
45
+ - Install from the Homebridge UI or with npm.
46
+ - After installing, configure your TTLock credentials and API App values, then restart Homebridge.
47
+
48
+ ```bash
49
+ npm install -g homebridge-ttlock-accesscode
50
+ ```
51
+
52
+ ## Configuration Notes
53
+ - Create an account in the [TTLock Cloud API](https://euopen.ttlock.com/register)
54
+ - Create your OAUTH2.0 App, approval may take a few days.
55
+ - Use your TTLock mobile app username/password and OAUTH2.0 App client_id and client_secret in the plugin settings.
56
+ - For non-Wi-Fi locks, make sure your gateway is online and near the lock.
57
+ - The default settings are tuned for TTLock's monthly API limits.
58
+ - Polling is automatically slowed when monthly allowance gets lower.
59
+
60
+ ## Access Code Notes
61
+ - Access code support is exposed through the Apple Home App.
62
+ - Existing passcodes are loaded from TTLock and mapped into the Apple Home App.
63
+ - Add/Delete/List/Read flows are handled through the Apple Home App.
64
+
65
+ ## Example Configuration
66
+ ```json
67
+ {
68
+ "bridge": {
69
+ "name": "Homebridge",
70
+ "username": "11:22:33:AA:BB:CC",
71
+ "port": 12345,
72
+ "pin": "001-02-003"
73
+ },
74
+ "description": "This is an example configuration file.",
75
+ "platforms": [
76
+ {
77
+ "platform": "TTLockAccessCode",
78
+ "name": "TTLockAccessCode",
79
+ "clientId": "YourClientID",
80
+ "clientSecret": "YourClientSecret",
81
+ "username": "YourUsername",
82
+ "password": "YourPassword",
83
+ "totalApiCallsPerMonth": 30000,
84
+ "pollingInterval": 300,
85
+ "discoveryPollingInterval": 12,
86
+ "offlineInterval": 7,
87
+ "waitTimeUpdate": 100
88
+ }
89
+ ],
90
+ "accessories": []
91
+ }
92
+ ```
93
+
94
+ ## Known Limitations
95
+ - Apple HomeKey is not supported by TTLock readers.
96
+ - Gateway-dependent locks will return gateway-offline conditions if the gateway is unavailable.
97
+ - TTLock Cloud API limits and behavior can change without notice.
@@ -2,6 +2,7 @@
2
2
  "pluginAlias": "TTLockAccessCode",
3
3
  "pluginType": "platform",
4
4
  "singular": true,
5
+ "strictValidation": true,
5
6
  "headerDisplay": "TTLock Access Code Plugin.<p>Follow the [README](https://github.com/ZeliardM/homebridge-ttlock-accesscode/blob/latest/README.md) for configuration instructions and then click \"Save\" to get started.</p>",
6
7
  "footerDisplay": "",
7
8
  "schema": {
@@ -50,20 +51,20 @@
50
51
  "title": "Total API Calls Per Month",
51
52
  "type": "integer",
52
53
  "description": "Total number of TTLock API calls allowed per month (used to automatically adjust polling).",
53
- "default": 100000,
54
- "minimum": 100000
54
+ "default": 30000,
55
+ "minimum": 30000
55
56
  },
56
57
  "pollingInterval": {
57
58
  "title": "Polling Interval (seconds)",
58
59
  "type": "integer",
59
60
  "description": "How often to check device status in the background (seconds)",
60
- "default": 90
61
+ "default": 300
61
62
  },
62
63
  "discoveryPollingInterval": {
63
64
  "title": "Discovery Polling Interval (hours)",
64
65
  "type": "integer",
65
66
  "description": "How often to discover new devices in the background (hours)",
66
- "default": 6
67
+ "default": 12
67
68
  },
68
69
  "offlineInterval": {
69
70
  "title": "Offline Interval (days)",
@@ -1,6 +1,28 @@
1
1
  import type { Logging } from 'homebridge';
2
2
  import { UsageTracker } from './usageTracker.js';
3
3
  import { FeatureInfo, Passcode, SysInfo, TTLockDevice } from '../devices/deviceTypes.js';
4
+ export declare enum TTLockApiErrorCategory {
5
+ AuthExpired = "AuthExpired",
6
+ AuthInvalid = "AuthInvalid",
7
+ BudgetExhausted = "BudgetExhausted",
8
+ ClientInvalidRequest = "ClientInvalidRequest",
9
+ InvalidResponse = "InvalidResponse",
10
+ NetworkTransient = "NetworkTransient",
11
+ RateLimited = "RateLimited",
12
+ ServerTransient = "ServerTransient",
13
+ Unknown = "Unknown"
14
+ }
15
+ export declare class TTLockApiError extends Error {
16
+ readonly category: TTLockApiErrorCategory;
17
+ readonly retryable: boolean;
18
+ readonly endpoint?: string | undefined;
19
+ readonly statusCode?: number | undefined;
20
+ readonly errcode?: number | undefined;
21
+ readonly cause?: unknown | undefined;
22
+ wasLogged: boolean;
23
+ constructor(message: string, category: TTLockApiErrorCategory, retryable: boolean, endpoint?: string | undefined, statusCode?: number | undefined, errcode?: number | undefined, cause?: unknown | undefined);
24
+ get authRelated(): boolean;
25
+ }
4
26
  export declare class TTLockApi {
5
27
  private log;
6
28
  private clientId;
@@ -10,12 +32,26 @@ export declare class TTLockApi {
10
32
  refreshToken: string | null;
11
33
  private tokenMutex;
12
34
  private usageTracker;
35
+ private authUsername;
36
+ private authPassword;
37
+ private readonly requestTimeoutMs;
38
+ private readonly maxRetries;
13
39
  constructor(log: Logging, clientId: string, clientSecret: string, usageTracker?: UsageTracker);
14
40
  private encryptPassword;
15
41
  authenticate(username: string, password: string): Promise<void>;
16
- private refreshTokenIfNeeded;
42
+ private authenticateWithPassword;
43
+ private refreshTokenIfNeededLocked;
44
+ private recoverAuthentication;
17
45
  private makeAuthenticatedRequest;
18
- private handleError;
46
+ private logApiError;
47
+ private isGatewayOfflineError;
48
+ private normalizeApiResponseError;
49
+ private normalizeError;
50
+ private looksAuthError;
51
+ private looksRateLimitError;
52
+ private getRetryDelayMs;
53
+ private sleep;
54
+ private isObject;
19
55
  getDevices(): Promise<TTLockDevice[]>;
20
56
  getDeviceDetails(lockId: string): Promise<Partial<SysInfo>>;
21
57
  getSysInfo(lockId: string): Promise<Partial<SysInfo>>;