homebridge-ttlock-accesscode 2.0.0-beta.7 → 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 +69 -27
- package/config.schema.json +5 -4
- package/dist/api/ttlockApi.d.ts +38 -2
- package/dist/api/ttlockApi.js +222 -96
- package/dist/api/ttlockApi.js.map +1 -1
- package/dist/api/usageTracker.d.ts +1 -1
- package/dist/api/usageTracker.js +27 -13
- package/dist/api/usageTracker.js.map +1 -1
- package/dist/config.js +3 -3
- package/dist/config.js.map +1 -1
- package/dist/devices/accessoryInformation.js +4 -2
- package/dist/devices/accessoryInformation.js.map +1 -1
- package/dist/devices/baseDevice.d.ts +12 -8
- package/dist/devices/baseDevice.js +164 -67
- package/dist/devices/baseDevice.js.map +1 -1
- package/dist/devices/create.js +2 -15
- package/dist/devices/create.js.map +1 -1
- package/dist/devices/descriptorHelpers.js +12 -15
- package/dist/devices/descriptorHelpers.js.map +1 -1
- package/dist/devices/deviceManager.d.ts +3 -2
- package/dist/devices/deviceManager.js +28 -4
- package/dist/devices/deviceManager.js.map +1 -1
- package/dist/devices/deviceTypes.d.ts +6 -4
- package/dist/devices/homekitLock.d.ts +15 -0
- package/dist/devices/homekitLock.js +148 -98
- package/dist/devices/homekitLock.js.map +1 -1
- package/dist/platform.d.ts +3 -0
- package/dist/platform.js +71 -14
- package/dist/platform.js.map +1 -1
- package/dist/utils.js +6 -2
- package/dist/utils.js.map +1 -1
- package/package.json +5 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deviceManager.js","sourceRoot":"","sources":["../../src/devices/deviceManager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAM3C,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,YAAY,EAAE,CAAC;AAErD,MAAM,CAAC,OAAO,OAAO,aAAa;
|
|
1
|
+
{"version":3,"file":"deviceManager.js","sourceRoot":"","sources":["../../src/devices/deviceManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { Characteristic, CharacteristicValue, WithUUID } from 'homebridge';
|
|
2
|
-
import type HomeKitDevice from './baseDevice.js';
|
|
3
2
|
import type TTLockAccessCodePlatform from '../platform.js';
|
|
4
3
|
export type TTLockDevice = Lock;
|
|
5
4
|
export interface SysInfo {
|
|
@@ -31,14 +30,17 @@ export interface Passcode {
|
|
|
31
30
|
}
|
|
32
31
|
export interface DescriptorContext {
|
|
33
32
|
platform: TTLockAccessCodePlatform;
|
|
34
|
-
device:
|
|
33
|
+
device: SysInfo;
|
|
34
|
+
alias: string;
|
|
35
35
|
}
|
|
36
36
|
export interface CharacteristicDescriptor {
|
|
37
37
|
type: WithUUID<new () => Characteristic>;
|
|
38
38
|
name?: string;
|
|
39
39
|
writable?: boolean;
|
|
40
40
|
syncGroup?: string;
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
debouncePolls?: number;
|
|
42
|
+
syncHomeKitValueAfterSet?: boolean;
|
|
43
|
+
getInitial(context: DescriptorContext): CharacteristicValue;
|
|
44
|
+
getCurrent(context: DescriptorContext): CharacteristicValue;
|
|
43
45
|
applySet?(value: CharacteristicValue, context: DescriptorContext): Promise<void | string>;
|
|
44
46
|
}
|
|
@@ -11,6 +11,21 @@ export default class HomeKitDeviceLock extends HomeKitDevice {
|
|
|
11
11
|
protected getServiceTypes(): WithUUID<typeof Service>[];
|
|
12
12
|
protected buildDescriptors(service: Service): CharacteristicDescriptor[];
|
|
13
13
|
private getAccessCodeSupportedConfiguration;
|
|
14
|
+
private getAccessCodeService;
|
|
15
|
+
private setLockBusy;
|
|
16
|
+
private ensurePasscodesLoaded;
|
|
17
|
+
private refreshPasscodes;
|
|
18
|
+
private getPasscodeIdentifier;
|
|
19
|
+
private encodePasscodeIdentifier;
|
|
20
|
+
private findPasscodeByIdentifier;
|
|
21
|
+
private buildPasscodeResponseRecord;
|
|
22
|
+
private parseOperationType;
|
|
23
|
+
private parseIdentifierRequest;
|
|
24
|
+
private parsePasscodeRequest;
|
|
25
|
+
private buildListResponse;
|
|
26
|
+
private buildReadResponse;
|
|
27
|
+
private buildAddResponse;
|
|
28
|
+
private buildDeleteResponse;
|
|
14
29
|
private setAccessCodeControlPoint;
|
|
15
30
|
private getConfigurationState;
|
|
16
31
|
protected updateAllServicesAndCharacteristics(forceUpdate: boolean): Promise<void>;
|
|
@@ -2,6 +2,8 @@ import pkg from 'ber-tlv';
|
|
|
2
2
|
import HomeKitDevice from './baseDevice.js';
|
|
3
3
|
import { buildAccessCodeDescriptors, buildBatteryDescriptors, buildLockDescriptors, } from './descriptorHelpers.js';
|
|
4
4
|
const { TlvFactory } = pkg;
|
|
5
|
+
class AccessCodeProtocolError extends Error {
|
|
6
|
+
}
|
|
5
7
|
export default class HomeKitDeviceLock extends HomeKitDevice {
|
|
6
8
|
ttlockDevice;
|
|
7
9
|
hasPasscode;
|
|
@@ -26,7 +28,7 @@ export default class HomeKitDeviceLock extends HomeKitDevice {
|
|
|
26
28
|
const C = this.platform.Characteristic;
|
|
27
29
|
if (service.UUID === this.platform.Service.LockMechanism.UUID) {
|
|
28
30
|
return buildLockDescriptors(C, async (value, context) => {
|
|
29
|
-
await this.deviceManager.controlDevice(context.device.
|
|
31
|
+
await this.deviceManager.controlDevice(context.device.device_id, 'state', value);
|
|
30
32
|
});
|
|
31
33
|
}
|
|
32
34
|
if (service.UUID === this.platform.Service.Battery.UUID) {
|
|
@@ -34,7 +36,7 @@ export default class HomeKitDeviceLock extends HomeKitDevice {
|
|
|
34
36
|
}
|
|
35
37
|
if (service.UUID === this.platform.Service.AccessCode.UUID) {
|
|
36
38
|
return buildAccessCodeDescriptors(C, () => this.getAccessCodeSupportedConfiguration(), async (value, context) => {
|
|
37
|
-
return await this.setAccessCodeControlPoint(context.device
|
|
39
|
+
return await this.setAccessCodeControlPoint(context.device, value);
|
|
38
40
|
}, () => this.getConfigurationState());
|
|
39
41
|
}
|
|
40
42
|
return [];
|
|
@@ -53,129 +55,177 @@ export default class HomeKitDeviceLock extends HomeKitDevice {
|
|
|
53
55
|
}
|
|
54
56
|
return Buffer.concat(tlvBuffer).toString('base64') ?? 'AQEBAgEGAwEJBAEK';
|
|
55
57
|
}
|
|
58
|
+
getAccessCodeService() {
|
|
59
|
+
return this.homebridgeAccessory.getService(this.platform.Service.AccessCode) ?? undefined;
|
|
60
|
+
}
|
|
61
|
+
setLockBusy(busy) {
|
|
62
|
+
this.lockBusy = busy;
|
|
63
|
+
const accessCodeService = this.getAccessCodeService();
|
|
64
|
+
if (accessCodeService) {
|
|
65
|
+
accessCodeService
|
|
66
|
+
.getCharacteristic(this.platform.Characteristic.ConfigurationState)
|
|
67
|
+
.updateValue(this.getConfigurationState());
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async ensurePasscodesLoaded(device) {
|
|
71
|
+
if (Array.isArray(device.passcodes)) {
|
|
72
|
+
return device.passcodes;
|
|
73
|
+
}
|
|
74
|
+
device.passcodes = await this.deviceManager.managePasscodes(device.device_id, 'get');
|
|
75
|
+
return device.passcodes;
|
|
76
|
+
}
|
|
77
|
+
async refreshPasscodes(device) {
|
|
78
|
+
device.passcodes = await this.deviceManager.managePasscodes(device.device_id, 'get');
|
|
79
|
+
return device.passcodes;
|
|
80
|
+
}
|
|
81
|
+
getPasscodeIdentifier(passcode) {
|
|
82
|
+
return BigInt(passcode.index);
|
|
83
|
+
}
|
|
84
|
+
encodePasscodeIdentifier(identifier) {
|
|
85
|
+
let hex = identifier.toString(16);
|
|
86
|
+
if (hex.length % 2 !== 0) {
|
|
87
|
+
hex = `0${hex}`;
|
|
88
|
+
}
|
|
89
|
+
return hex;
|
|
90
|
+
}
|
|
91
|
+
findPasscodeByIdentifier(passcodes, identifier) {
|
|
92
|
+
return passcodes.find(passcode => this.getPasscodeIdentifier(passcode) === identifier);
|
|
93
|
+
}
|
|
94
|
+
buildPasscodeResponseRecord(passcode) {
|
|
95
|
+
const identifierValue = this.encodePasscodeIdentifier(this.getPasscodeIdentifier(passcode));
|
|
96
|
+
const identifier = TlvFactory.serialize(TlvFactory.primitiveTlv('01', identifierValue)).toString('hex');
|
|
97
|
+
const accessCode = TlvFactory.serialize(TlvFactory.primitiveTlv('02', Buffer.from(passcode.passcode).toString('hex'))).toString('hex');
|
|
98
|
+
const flags = TlvFactory.serialize(TlvFactory.primitiveTlv('03', '00')).toString('hex');
|
|
99
|
+
const status = TlvFactory.serialize(TlvFactory.primitiveTlv('04', '00')).toString('hex');
|
|
100
|
+
return TlvFactory.serialize(TlvFactory.primitiveTlv('03', identifier + accessCode + flags + status)).toString('hex');
|
|
101
|
+
}
|
|
102
|
+
parseOperationType(decodedTlv) {
|
|
103
|
+
if (decodedTlv.length === 0) {
|
|
104
|
+
throw new AccessCodeProtocolError('Empty AccessCodeControlPoint request');
|
|
105
|
+
}
|
|
106
|
+
return Number(decodedTlv[0].value.toString('hex'));
|
|
107
|
+
}
|
|
108
|
+
parseIdentifierRequest(element, requestType) {
|
|
109
|
+
const request = TlvFactory.parse(element.value);
|
|
110
|
+
if (request.length === 0) {
|
|
111
|
+
throw new AccessCodeProtocolError(`${requestType} request is missing its passcode index`);
|
|
112
|
+
}
|
|
113
|
+
const identifier = request[0].value.toString('hex');
|
|
114
|
+
if (!identifier) {
|
|
115
|
+
throw new AccessCodeProtocolError(`${requestType} request contained an empty passcode index`);
|
|
116
|
+
}
|
|
117
|
+
return BigInt(`0x${identifier}`);
|
|
118
|
+
}
|
|
119
|
+
parsePasscodeRequest(element) {
|
|
120
|
+
const request = TlvFactory.parse(element.value);
|
|
121
|
+
if (request.length === 0) {
|
|
122
|
+
throw new AccessCodeProtocolError('Add request is missing the passcode payload');
|
|
123
|
+
}
|
|
124
|
+
return request[0].value.toString();
|
|
125
|
+
}
|
|
126
|
+
async buildListResponse(device) {
|
|
127
|
+
const passcodes = await this.ensurePasscodesLoaded(device);
|
|
128
|
+
const records = passcodes.map(passcode => {
|
|
129
|
+
this.log.debug(`Passcode ${passcode.passcode} found on ${this.name}`);
|
|
130
|
+
return this.buildPasscodeResponseRecord(passcode);
|
|
131
|
+
});
|
|
132
|
+
return `010101${records.join('0000')}`;
|
|
133
|
+
}
|
|
134
|
+
async buildReadResponse(device, decodedTlv) {
|
|
135
|
+
const passcodes = await this.ensurePasscodesLoaded(device);
|
|
136
|
+
const records = decodedTlv.slice(1).map((element) => {
|
|
137
|
+
const passcodeIdentifier = this.parseIdentifierRequest(element, 'Read');
|
|
138
|
+
const passcode = this.findPasscodeByIdentifier(passcodes, passcodeIdentifier);
|
|
139
|
+
if (!passcode) {
|
|
140
|
+
throw new AccessCodeProtocolError(`Passcode identifier ${passcodeIdentifier.toString()} was not found for read`);
|
|
141
|
+
}
|
|
142
|
+
this.log.debug(`Reading passcode ${passcode.passcode} on ${this.name}`);
|
|
143
|
+
return this.buildPasscodeResponseRecord(passcode);
|
|
144
|
+
});
|
|
145
|
+
return `010102${records.join('0000')}`;
|
|
146
|
+
}
|
|
147
|
+
async buildAddResponse(device, decodedTlv) {
|
|
148
|
+
const records = [];
|
|
149
|
+
for (const element of decodedTlv.slice(1)) {
|
|
150
|
+
const newPassCode = this.parsePasscodeRequest(element);
|
|
151
|
+
const cachedPasscodes = await this.ensurePasscodesLoaded(device);
|
|
152
|
+
let passcode = cachedPasscodes.find(existing => existing.passcode === newPassCode);
|
|
153
|
+
if (!passcode) {
|
|
154
|
+
this.log.info(`Adding new passcode ${newPassCode} to ${this.name}`);
|
|
155
|
+
const newPasscode = await this.deviceManager
|
|
156
|
+
.managePasscodes(device.device_id, 'add', newPassCode);
|
|
157
|
+
const refreshedPasscodes = await this.refreshPasscodes(device);
|
|
158
|
+
passcode = refreshedPasscodes.find(existing => existing.passcode_id === newPasscode.keyboardPwdId.toString()
|
|
159
|
+
|| existing.passcode === newPassCode);
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
this.log.debug(`Passcode ${newPassCode} already exists on ${this.name}`);
|
|
163
|
+
}
|
|
164
|
+
if (!passcode) {
|
|
165
|
+
throw new AccessCodeProtocolError(`Passcode ${newPassCode} was not available after add`);
|
|
166
|
+
}
|
|
167
|
+
records.push(this.buildPasscodeResponseRecord(passcode));
|
|
168
|
+
}
|
|
169
|
+
return `010103${records.join('0000')}`;
|
|
170
|
+
}
|
|
171
|
+
async buildDeleteResponse(device, decodedTlv) {
|
|
172
|
+
if (decodedTlv.length < 2) {
|
|
173
|
+
throw new AccessCodeProtocolError('Delete request is missing the target passcode index');
|
|
174
|
+
}
|
|
175
|
+
const passcodes = await this.ensurePasscodesLoaded(device);
|
|
176
|
+
const deletePasscodeIdentifier = this.parseIdentifierRequest(decodedTlv[1], 'Delete');
|
|
177
|
+
const passcode = this.findPasscodeByIdentifier(passcodes, deletePasscodeIdentifier);
|
|
178
|
+
if (!passcode) {
|
|
179
|
+
throw new AccessCodeProtocolError(`Passcode identifier ${deletePasscodeIdentifier.toString()} was not found for delete`);
|
|
180
|
+
}
|
|
181
|
+
this.log.info(`Deleting passcode ${passcode.passcode} on ${this.name}`);
|
|
182
|
+
await this.deviceManager.managePasscodes(device.device_id, 'delete', passcode.passcode_id);
|
|
183
|
+
await this.refreshPasscodes(device);
|
|
184
|
+
return `010105${this.buildPasscodeResponseRecord(passcode)}`;
|
|
185
|
+
}
|
|
56
186
|
async setAccessCodeControlPoint(device, value) {
|
|
187
|
+
this.setLockBusy(true);
|
|
57
188
|
try {
|
|
58
|
-
this.lockBusy = true;
|
|
59
|
-
this.isUpdating = true;
|
|
60
189
|
const decodedTlv = TlvFactory.parse(Buffer.from(String(value), 'base64').toString('hex'));
|
|
61
190
|
this.log.debug(`Decoded TLV for AccessCodeControlPoint on ${this.name}:`, decodedTlv);
|
|
62
|
-
let responseTlv = '';
|
|
63
|
-
let response = '';
|
|
64
191
|
let requestType = '';
|
|
65
|
-
let
|
|
66
|
-
switch (
|
|
192
|
+
let responseTlv = '';
|
|
193
|
+
switch (this.parseOperationType(decodedTlv)) {
|
|
67
194
|
case 1: {
|
|
68
195
|
requestType = 'List';
|
|
69
|
-
responseTlv =
|
|
70
|
-
device.passcodes.forEach((pc, index) => {
|
|
71
|
-
identifier = TlvFactory.serialize(TlvFactory.primitiveTlv('01', String(pc.index).padStart(2, '0'))).toString('hex');
|
|
72
|
-
accessCode = TlvFactory.serialize(TlvFactory.primitiveTlv('02', Buffer.from(pc.passcode).toString('hex'))).toString('hex');
|
|
73
|
-
flags = TlvFactory.serialize(TlvFactory.primitiveTlv('03', '00')).toString('hex');
|
|
74
|
-
status = TlvFactory.serialize(TlvFactory.primitiveTlv('04', '00')).toString('hex');
|
|
75
|
-
this.log.debug(`Passcode ${pc.passcode} found on ${this.name}`);
|
|
76
|
-
responseTlv += TlvFactory.serialize(TlvFactory.primitiveTlv('03', identifier + accessCode + flags + status)).toString('hex') + (index !== (device.passcodes.length - 1) ? '0000' : '');
|
|
77
|
-
});
|
|
78
|
-
response = Buffer.from(responseTlv, 'hex').toString('base64');
|
|
196
|
+
responseTlv = await this.buildListResponse(device);
|
|
79
197
|
break;
|
|
80
198
|
}
|
|
81
199
|
case 2: {
|
|
82
200
|
requestType = 'Read';
|
|
83
|
-
responseTlv =
|
|
84
|
-
if (device.passcodes.length > 0) {
|
|
85
|
-
for (let index = 1; index < decodedTlv.length; ++index) {
|
|
86
|
-
const element = decodedTlv[index];
|
|
87
|
-
const readReq = TlvFactory.parse(element.value);
|
|
88
|
-
if (readReq.length > 0) {
|
|
89
|
-
const passcodeIndexHex = readReq[0].value.toString('hex');
|
|
90
|
-
const passcodeIndex = parseInt(passcodeIndexHex, 16);
|
|
91
|
-
const pc = device.passcodes[passcodeIndex];
|
|
92
|
-
if (pc) {
|
|
93
|
-
this.log.debug(`Reading passcode ${pc.passcode} on ${this.name}`);
|
|
94
|
-
identifier = TlvFactory.serialize(TlvFactory.primitiveTlv('01', String(pc.index).padStart(2, '0'))).toString('hex');
|
|
95
|
-
accessCode = TlvFactory.serialize(TlvFactory.primitiveTlv('02', Buffer.from(pc.passcode).toString('hex'))).toString('hex');
|
|
96
|
-
flags = TlvFactory.serialize(TlvFactory.primitiveTlv('03', '00')).toString('hex');
|
|
97
|
-
status = TlvFactory.serialize(TlvFactory.primitiveTlv('04', '00')).toString('hex');
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
responseTlv += TlvFactory.serialize(TlvFactory.primitiveTlv('03', identifier + accessCode + flags + status)).toString('hex') + (index !== (decodedTlv.length - 1) ? '0000' : '');
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
response = Buffer.from(responseTlv, 'hex').toString('base64');
|
|
201
|
+
responseTlv = await this.buildReadResponse(device, decodedTlv);
|
|
104
202
|
break;
|
|
105
203
|
}
|
|
106
204
|
case 3: {
|
|
107
205
|
requestType = 'Add';
|
|
108
|
-
responseTlv =
|
|
109
|
-
for (let index = 1; index < decodedTlv.length; index++) {
|
|
110
|
-
const addReq = TlvFactory.parse(decodedTlv[index].value);
|
|
111
|
-
if (addReq.length > 0) {
|
|
112
|
-
const newPassCodeHex = addReq[0];
|
|
113
|
-
const newPassCode = newPassCodeHex.value.toString();
|
|
114
|
-
let pc = device.passcodes.find(p => p.passcode === newPassCode);
|
|
115
|
-
if (!pc) {
|
|
116
|
-
this.log.info(`Adding new passcode ${newPassCode} to ${this.name}`);
|
|
117
|
-
try {
|
|
118
|
-
const newPc = await this.deviceManager
|
|
119
|
-
.managePasscodes(device.device_id, 'add', newPassCode);
|
|
120
|
-
device.passcodes = await this.deviceManager.managePasscodes(device.device_id, 'get');
|
|
121
|
-
pc = device.passcodes.find((p) => p.passcode_id === newPc.keyboardPwdId.toString() ||
|
|
122
|
-
p.passcode === newPassCode);
|
|
123
|
-
}
|
|
124
|
-
catch (err) {
|
|
125
|
-
this.log.error(`Failed to add passcode ${newPassCode} to ${this.name}`, err);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
129
|
-
this.log.debug(`Passcode ${newPassCode} already exists on ${this.name}`);
|
|
130
|
-
}
|
|
131
|
-
if (pc) {
|
|
132
|
-
identifier = TlvFactory.serialize(TlvFactory.primitiveTlv('01', String(pc.index).padStart(2, '0'))).toString('hex');
|
|
133
|
-
accessCode = TlvFactory.serialize(TlvFactory.primitiveTlv('02', Buffer.from(pc.passcode).toString('hex'))).toString('hex');
|
|
134
|
-
flags = TlvFactory.serialize(TlvFactory.primitiveTlv('03', '00')).toString('hex');
|
|
135
|
-
status = TlvFactory.serialize(TlvFactory.primitiveTlv('04', '00')).toString('hex');
|
|
136
|
-
responseTlv += TlvFactory.serialize(TlvFactory.primitiveTlv('03', identifier + accessCode + flags + status)).toString('hex') + (index !== (decodedTlv.length - 1) ? '0000' : '');
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
response = Buffer.from(responseTlv, 'hex').toString('base64');
|
|
206
|
+
responseTlv = await this.buildAddResponse(device, decodedTlv);
|
|
141
207
|
break;
|
|
142
208
|
}
|
|
143
209
|
case 5: {
|
|
144
210
|
requestType = 'Delete';
|
|
145
|
-
responseTlv =
|
|
146
|
-
const deleteReq = TlvFactory.parse(decodedTlv[1].value);
|
|
147
|
-
if (deleteReq.length > 0) {
|
|
148
|
-
const deletePassCodeIndexHex = deleteReq[0].value.toString('hex');
|
|
149
|
-
const deletePassCodeIndex = parseInt(deletePassCodeIndexHex, 16);
|
|
150
|
-
const pc = device.passcodes[deletePassCodeIndex];
|
|
151
|
-
if (pc) {
|
|
152
|
-
this.log.info(`Deleting passcode ${pc.passcode} on ${this.name}`);
|
|
153
|
-
await this.deviceManager.managePasscodes(device.device_id, 'delete', pc.passcode_id);
|
|
154
|
-
device.passcodes = await this.deviceManager.managePasscodes(device.device_id, 'get');
|
|
155
|
-
identifier = TlvFactory.serialize(TlvFactory.primitiveTlv('01', String(pc.index).padStart(2, '0'))).toString('hex');
|
|
156
|
-
accessCode = TlvFactory.serialize(TlvFactory.primitiveTlv('02', Buffer.from(pc.passcode).toString('hex'))).toString('hex');
|
|
157
|
-
flags = TlvFactory.serialize(TlvFactory.primitiveTlv('03', '00')).toString('hex');
|
|
158
|
-
status = TlvFactory.serialize(TlvFactory.primitiveTlv('04', '00')).toString('hex');
|
|
159
|
-
responseTlv += TlvFactory.serialize(TlvFactory.primitiveTlv('03', identifier + accessCode + flags + status)).toString('hex');
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
response = Buffer.from(responseTlv, 'hex').toString('base64');
|
|
211
|
+
responseTlv = await this.buildDeleteResponse(device, decodedTlv);
|
|
163
212
|
break;
|
|
164
213
|
}
|
|
214
|
+
default:
|
|
215
|
+
throw new AccessCodeProtocolError(`Unsupported AccessCodeControlPoint operation: ${this.parseOperationType(decodedTlv)}`);
|
|
165
216
|
}
|
|
166
217
|
this.log.info(`Access Code Control ${requestType} Request completed for ${this.name}`);
|
|
167
|
-
return
|
|
218
|
+
return Buffer.from(responseTlv, 'hex').toString('base64');
|
|
168
219
|
}
|
|
169
220
|
catch (error) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
221
|
+
if (error instanceof AccessCodeProtocolError) {
|
|
222
|
+
this.log.warn(`Invalid AccessCodeControlPoint request on ${this.name}: ${error.message}`);
|
|
223
|
+
return '';
|
|
224
|
+
}
|
|
225
|
+
throw error;
|
|
174
226
|
}
|
|
175
227
|
finally {
|
|
176
|
-
this.
|
|
177
|
-
this.isUpdating = false;
|
|
178
|
-
this.updateEmitter.emit('updateComplete');
|
|
228
|
+
this.setLockBusy(false);
|
|
179
229
|
}
|
|
180
230
|
}
|
|
181
231
|
getConfigurationState() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"homekitLock.js","sourceRoot":"","sources":["../../src/devices/homekitLock.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"homekitLock.js","sourceRoot":"","sources":["../../src/devices/homekitLock.ts"],"names":[],"mappings":"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"}
|
package/dist/platform.d.ts
CHANGED
|
@@ -27,13 +27,16 @@ export default class TTLockAccessCodePlatform implements DynamicPlatformPlugin {
|
|
|
27
27
|
taskQueue: TaskQueue;
|
|
28
28
|
private readonly homekitDevicesById;
|
|
29
29
|
private deviceDiscoveredHandler?;
|
|
30
|
+
private discoveryInterval?;
|
|
30
31
|
private platformInitialization;
|
|
32
|
+
private usageTierChangedHandler?;
|
|
31
33
|
constructor(log: Logging, config: PlatformConfig, api: API);
|
|
32
34
|
private setupDeviceEventEmitter;
|
|
33
35
|
initializePlatform(): Promise<void>;
|
|
34
36
|
private logInitializationDetails;
|
|
35
37
|
private verifyEnvironment;
|
|
36
38
|
private didFinishLaunching;
|
|
39
|
+
private startTTLockApiWithRetry;
|
|
37
40
|
private setupPeriodicDiscovery;
|
|
38
41
|
private discoverDevices;
|
|
39
42
|
private periodicDeviceDiscovery;
|
package/dist/platform.js
CHANGED
|
@@ -26,7 +26,9 @@ export default class TTLockAccessCodePlatform {
|
|
|
26
26
|
taskQueue;
|
|
27
27
|
homekitDevicesById = new Map();
|
|
28
28
|
deviceDiscoveredHandler;
|
|
29
|
+
discoveryInterval;
|
|
29
30
|
platformInitialization;
|
|
31
|
+
usageTierChangedHandler;
|
|
30
32
|
constructor(log, config, api) {
|
|
31
33
|
this.log = log;
|
|
32
34
|
this.api = api;
|
|
@@ -53,9 +55,16 @@ export default class TTLockAccessCodePlatform {
|
|
|
53
55
|
if (!this.isShuttingDown) {
|
|
54
56
|
this.isShuttingDown = true;
|
|
55
57
|
}
|
|
58
|
+
if (this.discoveryInterval) {
|
|
59
|
+
clearInterval(this.discoveryInterval);
|
|
60
|
+
this.log.debug('Cleared periodic device discovery interval');
|
|
61
|
+
}
|
|
62
|
+
if (this.deviceDiscoveredHandler) {
|
|
63
|
+
deviceEventEmitter.off('deviceDiscovered', this.deviceDiscoveredHandler);
|
|
64
|
+
}
|
|
56
65
|
this.log.debug('Stopping all polling tasks');
|
|
57
66
|
for (const device of this.homekitDevicesById.values()) {
|
|
58
|
-
await device.stopPolling();
|
|
67
|
+
await device.stopPolling(true);
|
|
59
68
|
}
|
|
60
69
|
this.log.debug('Waiting for tasks to complete');
|
|
61
70
|
try {
|
|
@@ -64,7 +73,7 @@ export default class TTLockAccessCodePlatform {
|
|
|
64
73
|
catch (error) {
|
|
65
74
|
this.log.error('Error while waiting for task queue to empty during shutdown:', error);
|
|
66
75
|
}
|
|
67
|
-
this.stopTTLockApi();
|
|
76
|
+
await this.stopTTLockApi();
|
|
68
77
|
});
|
|
69
78
|
}
|
|
70
79
|
setupDeviceEventEmitter(mode, discoveredDeviceIds) {
|
|
@@ -125,7 +134,11 @@ export default class TTLockAccessCodePlatform {
|
|
|
125
134
|
async didFinishLaunching() {
|
|
126
135
|
this.log.debug('Finished launching');
|
|
127
136
|
try {
|
|
128
|
-
await this.
|
|
137
|
+
const apiStarted = await this.startTTLockApiWithRetry();
|
|
138
|
+
if (!apiStarted) {
|
|
139
|
+
this.log.warn('TTLock API did not start before shutdown; skipping device manager startup');
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
129
142
|
this.log.debug('Initializing DeviceManager');
|
|
130
143
|
this.deviceManager = new DeviceManager(this);
|
|
131
144
|
this.log.debug('DeviceManager initialized');
|
|
@@ -138,6 +151,25 @@ export default class TTLockAccessCodePlatform {
|
|
|
138
151
|
this.log.error('An error occurred during startup:', error);
|
|
139
152
|
}
|
|
140
153
|
}
|
|
154
|
+
async startTTLockApiWithRetry() {
|
|
155
|
+
let attempt = 0;
|
|
156
|
+
while (!this.isShuttingDown) {
|
|
157
|
+
try {
|
|
158
|
+
await this.startTTLockApi();
|
|
159
|
+
if (attempt > 0) {
|
|
160
|
+
this.log.info('TTLock API startup recovered after retries');
|
|
161
|
+
}
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
attempt++;
|
|
166
|
+
const delayMs = Math.min(5 * 60 * 1000, Math.pow(2, Math.min(attempt, 8)) * 1000);
|
|
167
|
+
this.log.error(`TTLock API startup attempt ${attempt} failed; retrying in ${Math.floor(delayMs / 1000)}s:`, error);
|
|
168
|
+
await new Promise(resolve => setTimeout(resolve, delayMs));
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
141
173
|
setupPeriodicDiscovery(discoveredDeviceIds) {
|
|
142
174
|
this.log.debug('Setting up periodic device discovery');
|
|
143
175
|
this.setupDeviceEventEmitter('periodicDiscovery', discoveredDeviceIds);
|
|
@@ -145,7 +177,7 @@ export default class TTLockAccessCodePlatform {
|
|
|
145
177
|
await this.periodicDeviceDiscovery(discoveredDeviceIds);
|
|
146
178
|
};
|
|
147
179
|
const deferredDiscoveryTask = deferAndCombine(discoveryTask, this.config.advancedOptions.waitTimeUpdate);
|
|
148
|
-
setInterval(() => {
|
|
180
|
+
this.discoveryInterval = setInterval(() => {
|
|
149
181
|
try {
|
|
150
182
|
this.taskQueue.addTask(deferredDiscoveryTask);
|
|
151
183
|
}
|
|
@@ -190,6 +222,7 @@ export default class TTLockAccessCodePlatform {
|
|
|
190
222
|
return;
|
|
191
223
|
}
|
|
192
224
|
this.periodicDeviceDiscovering = true;
|
|
225
|
+
let discoverySucceeded = false;
|
|
193
226
|
discoveredDeviceIds.clear();
|
|
194
227
|
this.log.debug('Cleared discoveredDeviceIds set before discovery.');
|
|
195
228
|
try {
|
|
@@ -209,13 +242,19 @@ export default class TTLockAccessCodePlatform {
|
|
|
209
242
|
this.log.debug('Error reserving budget for periodic discovery', error);
|
|
210
243
|
}
|
|
211
244
|
await this.deviceManager.discoverDevices();
|
|
245
|
+
discoverySucceeded = true;
|
|
212
246
|
}
|
|
213
247
|
}
|
|
214
248
|
catch (error) {
|
|
215
249
|
this.log.error('Error during periodic device discovery:', error);
|
|
216
250
|
}
|
|
217
251
|
finally {
|
|
218
|
-
|
|
252
|
+
if (discoverySucceeded) {
|
|
253
|
+
this.handleOfflineDevices(discoveredDeviceIds);
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
this.log.warn('Skipping offline accessory reconciliation because periodic discovery did not complete successfully');
|
|
257
|
+
}
|
|
219
258
|
this.periodicDeviceDiscovering = false;
|
|
220
259
|
this.periodicDeviceDiscoveryEmitter.emit('periodicDeviceDiscoveryComplete');
|
|
221
260
|
this.log.debug('Finished periodic device discovery');
|
|
@@ -283,15 +322,18 @@ export default class TTLockAccessCodePlatform {
|
|
|
283
322
|
const existingDevice = this.homekitDevicesById.get(device.sys_info.device_id);
|
|
284
323
|
if (existingDevice) {
|
|
285
324
|
if (!existingDevice.isUpdating) {
|
|
286
|
-
|
|
325
|
+
const comingOnline = existingDevice.ttlockDevice.offline && !device.offline;
|
|
326
|
+
existingDevice.ttlockDevice.sys_info = device.sys_info;
|
|
327
|
+
existingDevice.ttlockDevice.feature_info = device.feature_info;
|
|
328
|
+
existingDevice.ttlockDevice.last_seen = device.last_seen;
|
|
329
|
+
existingDevice.ttlockDevice.offline = device.offline;
|
|
330
|
+
if (comingOnline) {
|
|
287
331
|
this.log.debug(`Device [${device.sys_info.device_id}] was offline and is now online. Updating and starting polling.`);
|
|
288
|
-
existingDevice.
|
|
289
|
-
existingDevice.updateAfterPeriodicDiscovery();
|
|
332
|
+
existingDevice.updateAfterPeriodicDiscovery(true);
|
|
290
333
|
existingDevice.startPolling();
|
|
291
334
|
}
|
|
292
335
|
else {
|
|
293
336
|
this.log.debug(`Updating existing HomeKit device [${device.sys_info.device_id}].`);
|
|
294
|
-
existingDevice.ttlockDevice = device;
|
|
295
337
|
existingDevice.updateAfterPeriodicDiscovery();
|
|
296
338
|
}
|
|
297
339
|
}
|
|
@@ -308,8 +350,12 @@ export default class TTLockAccessCodePlatform {
|
|
|
308
350
|
await this.foundDevice(device);
|
|
309
351
|
}
|
|
310
352
|
updateAccessoryStatus(accessory, lastSeen, offline) {
|
|
353
|
+
const offlineStatusChanged = accessory.context.offline !== offline;
|
|
311
354
|
accessory.context.lastSeen = lastSeen;
|
|
312
355
|
accessory.context.offline = offline;
|
|
356
|
+
if (offlineStatusChanged) {
|
|
357
|
+
this.api.updatePlatformAccessories([accessory]);
|
|
358
|
+
}
|
|
313
359
|
}
|
|
314
360
|
async startTTLockApi() {
|
|
315
361
|
this.log.debug('Starting TTLock API');
|
|
@@ -318,12 +364,21 @@ export default class TTLockAccessCodePlatform {
|
|
|
318
364
|
this.log.debug('TTLock API process started successfully');
|
|
319
365
|
}
|
|
320
366
|
catch (error) {
|
|
367
|
+
await this.stopTTLockApi();
|
|
321
368
|
this.log.error(`Error starting TTLock API process: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
322
369
|
throw error;
|
|
323
370
|
}
|
|
324
371
|
}
|
|
325
|
-
stopTTLockApi() {
|
|
372
|
+
async stopTTLockApi() {
|
|
326
373
|
this.log.debug('Stopping TTLock API');
|
|
374
|
+
if (this.usageTracker) {
|
|
375
|
+
if (this.usageTierChangedHandler) {
|
|
376
|
+
this.usageTracker.off('tierChanged', this.usageTierChangedHandler);
|
|
377
|
+
this.usageTierChangedHandler = undefined;
|
|
378
|
+
}
|
|
379
|
+
await this.usageTracker.stop();
|
|
380
|
+
this.usageTracker = undefined;
|
|
381
|
+
}
|
|
327
382
|
if (this.ttLockApi) {
|
|
328
383
|
this.log.debug('TTLock API process found, attempting to kill the process');
|
|
329
384
|
this.ttLockApi = undefined;
|
|
@@ -340,14 +395,16 @@ export default class TTLockAccessCodePlatform {
|
|
|
340
395
|
this.usageTracker = new UsageTracker(this.api, this.log, this.config.totalApiCallsPerMonth);
|
|
341
396
|
await this.usageTracker.init();
|
|
342
397
|
this.log.debug('UsageTracker initialized');
|
|
343
|
-
this.
|
|
398
|
+
this.usageTierChangedHandler = () => {
|
|
344
399
|
this.log.info('API usage tier changed — recalculating polling intervals...');
|
|
345
400
|
void this.reschedulePolling();
|
|
346
|
-
}
|
|
401
|
+
};
|
|
402
|
+
this.usageTracker.on('tierChanged', this.usageTierChangedHandler);
|
|
347
403
|
}
|
|
348
404
|
catch (err) {
|
|
349
405
|
this.log.error('Failed to initialize usage tracker', err);
|
|
350
406
|
this.usageTracker = undefined;
|
|
407
|
+
this.usageTierChangedHandler = undefined;
|
|
351
408
|
}
|
|
352
409
|
this.log.debug('Initializing TTLockApi...');
|
|
353
410
|
this.ttLockApi = new TTLockApi(this.log, this.config.clientId, this.config.clientSecret, this.usageTracker);
|
|
@@ -426,12 +483,12 @@ export default class TTLockAccessCodePlatform {
|
|
|
426
483
|
if (!this.configuredAccessories.has(accessory.UUID)) {
|
|
427
484
|
this.log.debug(`Platform Accessory ${accessory.displayName} is not in configuredAccessories, adding it.`);
|
|
428
485
|
this.configuredAccessories.set(accessory.UUID, accessory);
|
|
486
|
+
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
|
|
487
|
+
this.log.debug(`Platform Accessory ${accessory.displayName} registered with Homebridge.`);
|
|
429
488
|
}
|
|
430
489
|
else {
|
|
431
490
|
this.log.debug(`Platform Accessory ${accessory.displayName} is already in configuredAccessories.`);
|
|
432
491
|
}
|
|
433
|
-
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
|
|
434
|
-
this.log.debug(`Platform Accessory ${accessory.displayName} registered with Homebridge.`);
|
|
435
492
|
}
|
|
436
493
|
configureAccessory(accessory) {
|
|
437
494
|
this.log.debug(`Configuring Platform Accessory: [${accessory.displayName}] UUID: ${accessory.UUID}`);
|