@homebridge-plugins/homebridge-august 3.3.0-beta.0 → 3.3.0-beta.1
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/CHANGELOG.md +19 -14
- package/CLAUDE.md +48 -0
- package/README.md +39 -27
- package/config.schema.json +47 -3
- package/dist/Platform.HAP.d.ts +139 -20
- package/dist/Platform.HAP.d.ts.map +1 -1
- package/dist/Platform.HAP.js +732 -46
- package/dist/Platform.HAP.js.map +1 -1
- package/dist/connectivity-manager.d.ts +3 -3
- package/dist/connectivity-manager.d.ts.map +1 -1
- package/dist/connectivity-manager.js +14 -57
- package/dist/connectivity-manager.js.map +1 -1
- package/dist/devices/device.d.ts +16 -5
- package/dist/devices/device.d.ts.map +1 -1
- package/dist/devices/device.js +75 -18
- package/dist/devices/device.js.map +1 -1
- package/dist/devices/device.test.d.ts +2 -0
- package/dist/devices/device.test.d.ts.map +1 -0
- package/dist/devices/device.test.js +294 -0
- package/dist/devices/device.test.js.map +1 -0
- package/dist/devices/lock.d.ts +3 -3
- package/dist/devices/lock.d.ts.map +1 -1
- package/dist/devices/lock.js +41 -41
- package/dist/devices/lock.js.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/platform.matter.d.ts +26 -18
- package/dist/platform.matter.d.ts.map +1 -1
- package/dist/platform.matter.js +95 -76
- package/dist/platform.matter.js.map +1 -1
- package/dist/settings.d.ts +1 -0
- package/dist/settings.d.ts.map +1 -1
- package/package.json +37 -32
- package/test/connectivity-manager.test.ts +592 -0
- package/test/platform.matter.test.ts +660 -0
- package/test/platform.polling.test.ts +5 -5
- package/test/{platform.hap.test.ts → platform.test.ts} +23 -23
- package/.github/FUNDING.yml +0 -4
- package/.github/ISSUE_TEMPLATE/bug-report.yml +0 -97
- package/.github/ISSUE_TEMPLATE/config.yml +0 -8
- package/.github/ISSUE_TEMPLATE/feature-request.yml +0 -38
- package/.github/ISSUE_TEMPLATE/support-request.yml +0 -85
- package/.github/ISSUE_TEMPLATE.md +0 -48
- package/.github/PULL_REQUEST_TEMPLATE/pull_request.md +0 -27
- package/.github/copilot-instructions.md +0 -200
- package/.github/dependabot.yml +0 -17
- package/.github/labeler.yml +0 -38
- package/.github/npm-version-script-esm.js +0 -97
- package/.github/workflows/release.yml +0 -169
- package/.github/workflows/stale.yml +0 -12
- package/SECURITY.md +0 -19
- package/branding/Homebridge_x_August.svg +0 -32
- package/branding/icon.png +0 -0
- package/dist/Platform.Base.d.ts +0 -288
- package/dist/Platform.Base.d.ts.map +0 -1
- package/dist/Platform.Base.js +0 -797
- package/dist/Platform.Base.js.map +0 -1
- package/dist/package.json +0 -85
- package/docs/.nojekyll +0 -1
- package/docs/assets/hierarchy.js +0 -1
- package/docs/assets/highlight.css +0 -22
- package/docs/assets/icons.js +0 -18
- package/docs/assets/icons.svg +0 -1
- package/docs/assets/main.js +0 -60
- package/docs/assets/navigation.js +0 -1
- package/docs/assets/search.js +0 -1
- package/docs/assets/style.css +0 -1633
- package/docs/hierarchy.html +0 -1
- package/docs/index.html +0 -44
- package/docs/modules.html +0 -1
- package/docs/variables/default.html +0 -1
- package/eslint.config.js +0 -47
- package/test/device.test.ts +0 -384
- package/vitest.config.ts +0 -8
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
// Create a simplified test implementation that mimics the updateCharacteristic behavior
|
|
3
|
+
class MockDeviceWithCharacteristics {
|
|
4
|
+
accessory = { context: {}, displayName: 'Test Lock' };
|
|
5
|
+
debugLog = vi.fn();
|
|
6
|
+
debugWarnLog = vi.fn();
|
|
7
|
+
infoLog = vi.fn();
|
|
8
|
+
async updateCharacteristic(Service, ServiceName, Characteristic, CharacteristicValue, CharacteristicName, Value, StatusMatch, StatusDoesNotMatch) {
|
|
9
|
+
if (CharacteristicValue === undefined) {
|
|
10
|
+
await this.debugLog(`${CharacteristicName}: ${CharacteristicValue}`);
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
const contextKey = `${ServiceName}${CharacteristicName}`;
|
|
14
|
+
await this.debugWarnLog(`context before: ${this.accessory.context[contextKey]}`);
|
|
15
|
+
const contextBefore = this.accessory.context[contextKey];
|
|
16
|
+
this.accessory.context[contextKey] = CharacteristicValue;
|
|
17
|
+
await this.debugWarnLog(`context after: ${this.accessory.context[contextKey]}`);
|
|
18
|
+
await this.debugLog(`updateCharacteristic ${CharacteristicName}: ${CharacteristicValue} (${CharacteristicValue === Value ? StatusMatch : StatusDoesNotMatch})`);
|
|
19
|
+
if (contextBefore !== CharacteristicValue) {
|
|
20
|
+
// Value actually changed - push update to HomeKit
|
|
21
|
+
Service.updateCharacteristic(Characteristic, CharacteristicValue);
|
|
22
|
+
// Only log state change messages when we had a prior known value (not initial discovery)
|
|
23
|
+
if (contextBefore !== undefined && StatusMatch && StatusDoesNotMatch) {
|
|
24
|
+
await this.infoLog(`was ${CharacteristicValue === Value ? StatusMatch : StatusDoesNotMatch}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// Create a simplified test implementation that mimics the statusCode behavior
|
|
31
|
+
class MockDevice {
|
|
32
|
+
debugLog = vi.fn();
|
|
33
|
+
debugErrorLog = vi.fn();
|
|
34
|
+
/**
|
|
35
|
+
* Check if error is a network timeout or session expiration that requires session refresh
|
|
36
|
+
* Handles 502 Bad Gateway, 401 Unauthorized, 503 Service Unavailable, and network timeouts
|
|
37
|
+
*/
|
|
38
|
+
isTimeoutError(error) {
|
|
39
|
+
// Check for august-yale TimeoutError by name (stable contract — works regardless
|
|
40
|
+
// of message format changes) and Node.js network timeouts by message
|
|
41
|
+
if (error.name === 'TimeoutError' || error.message?.includes('ETIMEDOUT')) {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
// Check for status codes that indicate session expiration or temporary server issues
|
|
45
|
+
// 502 Bad Gateway - typically indicates session has expired or server issues
|
|
46
|
+
// 503 Service Unavailable - temporary server issues
|
|
47
|
+
// 401 Unauthorized - session has expired
|
|
48
|
+
if (error.statusCode && (error.statusCode === 502 || error.statusCode === 503 || error.statusCode === 401)) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
// Check for error messages containing these status codes (from tiny-json-http error format)
|
|
52
|
+
// Format: "POST failed with: 502" or "GET failed with: 401"
|
|
53
|
+
if (error.message) {
|
|
54
|
+
const sessionErrorPatterns = [
|
|
55
|
+
/failed with: 502/i,
|
|
56
|
+
/failed with: 503/i,
|
|
57
|
+
/failed with: 401/i,
|
|
58
|
+
/Bad Gateway/i,
|
|
59
|
+
/Service Unavailable/i,
|
|
60
|
+
/Unauthorized/i,
|
|
61
|
+
];
|
|
62
|
+
return sessionErrorPatterns.some(pattern => pattern.test(error.message));
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
async statusCode(action, error) {
|
|
67
|
+
const statusCodeString = error.message || ''; // Convert statusCode to a string, handle undefined/null
|
|
68
|
+
// Check if the error is an AggregateError or doesn't contain a status code
|
|
69
|
+
if (error.constructor?.name === 'AggregateError' || !/^\d{3}/.test(statusCodeString)) {
|
|
70
|
+
await this.debugErrorLog(`${action} failed with ${error.constructor?.name || 'Error'}: ${statusCodeString}`);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const statusCode = statusCodeString.slice(0, 3);
|
|
74
|
+
const logMap = {
|
|
75
|
+
100: `Command successfully sent, statusCode: ${statusCodeString}`,
|
|
76
|
+
200: `Request successful, statusCode: ${statusCodeString}`,
|
|
77
|
+
400: `Bad Request, statusCode: ${statusCodeString}`,
|
|
78
|
+
429: `Too Many Requests, exceeded the number of requests allowed for a given time window, statusCode: ${statusCodeString}`,
|
|
79
|
+
};
|
|
80
|
+
const logMessage = logMap[statusCode]
|
|
81
|
+
?? `Unknown statusCode: ${statusCodeString}, Submit Bugs Here: https://tinyurl.com/AugustYaleBug`;
|
|
82
|
+
await this.debugLog(logMessage);
|
|
83
|
+
if (!logMap[statusCode]) {
|
|
84
|
+
await this.debugErrorLog(`failed ${action}, Error: ${error}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
describe('statusCode error handling', () => {
|
|
89
|
+
let mockDevice;
|
|
90
|
+
beforeEach(() => {
|
|
91
|
+
mockDevice = new MockDevice();
|
|
92
|
+
});
|
|
93
|
+
describe('isTimeoutError method', () => {
|
|
94
|
+
it('should detect august-yale TimeoutError by error.name', () => {
|
|
95
|
+
const error = { message: 'Request timed out after 30000ms', name: 'TimeoutError' };
|
|
96
|
+
expect(mockDevice.isTimeoutError(error)).toBe(true);
|
|
97
|
+
});
|
|
98
|
+
it('should detect august-yale TimeoutError regardless of message content', () => {
|
|
99
|
+
const error = { message: 'anything', name: 'TimeoutError' };
|
|
100
|
+
expect(mockDevice.isTimeoutError(error)).toBe(true);
|
|
101
|
+
});
|
|
102
|
+
it('should detect ETIMEDOUT network errors', () => {
|
|
103
|
+
const error = { message: 'ETIMEDOUT connection timed out' };
|
|
104
|
+
expect(mockDevice.isTimeoutError(error)).toBe(true);
|
|
105
|
+
});
|
|
106
|
+
it('should detect 502 Bad Gateway status code', () => {
|
|
107
|
+
const error = { message: 'POST failed with: 502', statusCode: 502 };
|
|
108
|
+
expect(mockDevice.isTimeoutError(error)).toBe(true);
|
|
109
|
+
});
|
|
110
|
+
it('should detect 502 in error message', () => {
|
|
111
|
+
const error = { message: 'POST failed with: 502' };
|
|
112
|
+
expect(mockDevice.isTimeoutError(error)).toBe(true);
|
|
113
|
+
});
|
|
114
|
+
it('should detect 503 Service Unavailable status code', () => {
|
|
115
|
+
const error = { message: 'GET failed with: 503', statusCode: 503 };
|
|
116
|
+
expect(mockDevice.isTimeoutError(error)).toBe(true);
|
|
117
|
+
});
|
|
118
|
+
it('should detect 503 in error message', () => {
|
|
119
|
+
const error = { message: 'Service Unavailable' };
|
|
120
|
+
expect(mockDevice.isTimeoutError(error)).toBe(true);
|
|
121
|
+
});
|
|
122
|
+
it('should detect 401 Unauthorized status code', () => {
|
|
123
|
+
const error = { message: 'POST failed with: 401', statusCode: 401 };
|
|
124
|
+
expect(mockDevice.isTimeoutError(error)).toBe(true);
|
|
125
|
+
});
|
|
126
|
+
it('should detect 401 in error message', () => {
|
|
127
|
+
const error = { message: 'Unauthorized access' };
|
|
128
|
+
expect(mockDevice.isTimeoutError(error)).toBe(true);
|
|
129
|
+
});
|
|
130
|
+
it('should detect Bad Gateway in error message', () => {
|
|
131
|
+
const error = { message: 'Bad Gateway' };
|
|
132
|
+
expect(mockDevice.isTimeoutError(error)).toBe(true);
|
|
133
|
+
});
|
|
134
|
+
it('should return false for non-timeout errors', () => {
|
|
135
|
+
const error = { message: '404 Not Found' };
|
|
136
|
+
expect(mockDevice.isTimeoutError(error)).toBe(false);
|
|
137
|
+
});
|
|
138
|
+
it('should return false for 400 Bad Request', () => {
|
|
139
|
+
const error = { message: '400 Bad Request', statusCode: 400 };
|
|
140
|
+
expect(mockDevice.isTimeoutError(error)).toBe(false);
|
|
141
|
+
});
|
|
142
|
+
it('should return false for 429 Too Many Requests', () => {
|
|
143
|
+
const error = { message: '429 Too Many Requests', statusCode: 429 };
|
|
144
|
+
expect(mockDevice.isTimeoutError(error)).toBe(false);
|
|
145
|
+
});
|
|
146
|
+
it('should return false for empty message', () => {
|
|
147
|
+
const error = { message: '' };
|
|
148
|
+
expect(mockDevice.isTimeoutError(error)).toBe(false);
|
|
149
|
+
});
|
|
150
|
+
it('should return false for errors with non-timeout name', () => {
|
|
151
|
+
const error = { message: 'something failed', name: 'Error' };
|
|
152
|
+
expect(mockDevice.isTimeoutError(error)).toBe(false);
|
|
153
|
+
});
|
|
154
|
+
it('should not match 401 in non-HTTP status contexts', () => {
|
|
155
|
+
const error = { message: 'Expected 4012 records but found 401' };
|
|
156
|
+
expect(mockDevice.isTimeoutError(error)).toBe(false);
|
|
157
|
+
});
|
|
158
|
+
it('should not match 502 in non-HTTP status contexts', () => {
|
|
159
|
+
const error = { message: 'Lock ID 50234 not found' };
|
|
160
|
+
expect(mockDevice.isTimeoutError(error)).toBe(false);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
describe('statusCode method', () => {
|
|
164
|
+
it('should handle standard HTTP status codes', async () => {
|
|
165
|
+
await mockDevice.statusCode('test action', { message: '400 Bad Request' });
|
|
166
|
+
expect(mockDevice.debugLog).toHaveBeenCalledWith('Bad Request, statusCode: 400 Bad Request');
|
|
167
|
+
expect(mockDevice.debugErrorLog).not.toHaveBeenCalled();
|
|
168
|
+
});
|
|
169
|
+
it('should handle AggregateError specifically', async () => {
|
|
170
|
+
await mockDevice.statusCode('refreshStatus', {
|
|
171
|
+
message: 'Multiple errors occurred',
|
|
172
|
+
constructor: { name: 'AggregateError' },
|
|
173
|
+
});
|
|
174
|
+
expect(mockDevice.debugErrorLog).toHaveBeenCalledWith('refreshStatus failed with AggregateError: Multiple errors occurred');
|
|
175
|
+
expect(mockDevice.debugLog).not.toHaveBeenCalled();
|
|
176
|
+
});
|
|
177
|
+
it('should handle error with empty message', async () => {
|
|
178
|
+
await mockDevice.statusCode('refreshStatus', { message: '' });
|
|
179
|
+
expect(mockDevice.debugErrorLog).toHaveBeenCalledWith('refreshStatus failed with Object: ');
|
|
180
|
+
expect(mockDevice.debugLog).not.toHaveBeenCalled();
|
|
181
|
+
});
|
|
182
|
+
it('should handle error message without numeric status code', async () => {
|
|
183
|
+
await mockDevice.statusCode('refreshStatus', { message: 'Network connection failed' });
|
|
184
|
+
expect(mockDevice.debugErrorLog).toHaveBeenCalledWith('refreshStatus failed with Object: Network connection failed');
|
|
185
|
+
expect(mockDevice.debugLog).not.toHaveBeenCalled();
|
|
186
|
+
});
|
|
187
|
+
it('should handle 429 Too Many Requests status code', async () => {
|
|
188
|
+
await mockDevice.statusCode('test action', { message: '429 Too Many Requests' });
|
|
189
|
+
expect(mockDevice.debugLog).toHaveBeenCalledWith('Too Many Requests, exceeded the number of requests allowed for a given time window, statusCode: 429 Too Many Requests');
|
|
190
|
+
expect(mockDevice.debugErrorLog).not.toHaveBeenCalled();
|
|
191
|
+
});
|
|
192
|
+
it('should handle unknown numeric status codes', async () => {
|
|
193
|
+
await mockDevice.statusCode('test action', { message: '503 Service Unavailable' });
|
|
194
|
+
expect(mockDevice.debugLog).toHaveBeenCalledWith('Unknown statusCode: 503 Service Unavailable, Submit Bugs Here: https://tinyurl.com/AugustYaleBug');
|
|
195
|
+
expect(mockDevice.debugErrorLog).toHaveBeenCalledWith('failed test action, Error: [object Object]');
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
describe('updateCharacteristic', () => {
|
|
200
|
+
let device;
|
|
201
|
+
let mockService;
|
|
202
|
+
const CHARACTERISTIC = 'LockCurrentState';
|
|
203
|
+
beforeEach(() => {
|
|
204
|
+
device = new MockDeviceWithCharacteristics();
|
|
205
|
+
mockService = {
|
|
206
|
+
updateCharacteristic: vi.fn(),
|
|
207
|
+
};
|
|
208
|
+
});
|
|
209
|
+
it('should skip HomeKit update when CharacteristicValue is undefined', async () => {
|
|
210
|
+
await device.updateCharacteristic(mockService, 'LockMechanism', CHARACTERISTIC, undefined, 'LockCurrentState');
|
|
211
|
+
expect(mockService.updateCharacteristic).not.toHaveBeenCalled();
|
|
212
|
+
expect(device.debugLog).toHaveBeenCalledWith('LockCurrentState: undefined');
|
|
213
|
+
});
|
|
214
|
+
describe('initial state discovery (no prior context)', () => {
|
|
215
|
+
it('should push value to HomeKit on first update', async () => {
|
|
216
|
+
await device.updateCharacteristic(mockService, 'LockMechanism', CHARACTERISTIC, 0, 'LockCurrentState', 1, 'Locked', 'Unlocked');
|
|
217
|
+
expect(mockService.updateCharacteristic).toHaveBeenCalledWith(CHARACTERISTIC, 0);
|
|
218
|
+
});
|
|
219
|
+
it('should NOT log info message on initial discovery', async () => {
|
|
220
|
+
await device.updateCharacteristic(mockService, 'LockMechanism', CHARACTERISTIC, 0, 'LockCurrentState', 1, 'Locked', 'Unlocked');
|
|
221
|
+
expect(device.infoLog).not.toHaveBeenCalled();
|
|
222
|
+
});
|
|
223
|
+
it('should store the value in context for future comparisons', async () => {
|
|
224
|
+
await device.updateCharacteristic(mockService, 'LockMechanism', CHARACTERISTIC, 0, 'LockCurrentState', 1, 'Locked', 'Unlocked');
|
|
225
|
+
expect(device.accessory.context.LockMechanismLockCurrentState).toBe(0);
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
describe('subsequent updates with unchanged value', () => {
|
|
229
|
+
it('should NOT push to HomeKit when value has not changed', async () => {
|
|
230
|
+
// Seed context as if a previous update occurred
|
|
231
|
+
device.accessory.context.LockMechanismLockCurrentState = 1;
|
|
232
|
+
await device.updateCharacteristic(mockService, 'LockMechanism', CHARACTERISTIC, 1, 'LockCurrentState', 1, 'Locked', 'Unlocked');
|
|
233
|
+
expect(mockService.updateCharacteristic).not.toHaveBeenCalled();
|
|
234
|
+
});
|
|
235
|
+
it('should NOT log info message when value has not changed', async () => {
|
|
236
|
+
device.accessory.context.LockMechanismLockCurrentState = 1;
|
|
237
|
+
await device.updateCharacteristic(mockService, 'LockMechanism', CHARACTERISTIC, 1, 'LockCurrentState', 1, 'Locked', 'Unlocked');
|
|
238
|
+
expect(device.infoLog).not.toHaveBeenCalled();
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
describe('genuine state change', () => {
|
|
242
|
+
it('should push to HomeKit when value changes', async () => {
|
|
243
|
+
device.accessory.context.LockMechanismLockCurrentState = 1;
|
|
244
|
+
await device.updateCharacteristic(mockService, 'LockMechanism', CHARACTERISTIC, 0, 'LockCurrentState', 1, 'Locked', 'Unlocked');
|
|
245
|
+
expect(mockService.updateCharacteristic).toHaveBeenCalledWith(CHARACTERISTIC, 0);
|
|
246
|
+
});
|
|
247
|
+
it('should log "was Unlocked" when lock changes from secured to unsecured', async () => {
|
|
248
|
+
device.accessory.context.LockMechanismLockCurrentState = 1;
|
|
249
|
+
await device.updateCharacteristic(mockService, 'LockMechanism', CHARACTERISTIC, 0, 'LockCurrentState', 1, 'Locked', 'Unlocked');
|
|
250
|
+
expect(device.infoLog).toHaveBeenCalledWith('was Unlocked');
|
|
251
|
+
});
|
|
252
|
+
it('should log "was Locked" when lock changes from unsecured to secured', async () => {
|
|
253
|
+
device.accessory.context.LockMechanismLockCurrentState = 0;
|
|
254
|
+
await device.updateCharacteristic(mockService, 'LockMechanism', CHARACTERISTIC, 1, 'LockCurrentState', 1, 'Locked', 'Unlocked');
|
|
255
|
+
expect(device.infoLog).toHaveBeenCalledWith('was Locked');
|
|
256
|
+
});
|
|
257
|
+
it('should update context to new value', async () => {
|
|
258
|
+
device.accessory.context.LockMechanismLockCurrentState = 1;
|
|
259
|
+
await device.updateCharacteristic(mockService, 'LockMechanism', CHARACTERISTIC, 0, 'LockCurrentState', 1, 'Locked', 'Unlocked');
|
|
260
|
+
expect(device.accessory.context.LockMechanismLockCurrentState).toBe(0);
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
describe('contact sensor state changes', () => {
|
|
264
|
+
it('should log "was Closed" when door changes to closed', async () => {
|
|
265
|
+
device.accessory.context.ContactSensorContactSensorState = 1;
|
|
266
|
+
await device.updateCharacteristic(mockService, 'ContactSensor', 'ContactSensorState', 0, 'ContactSensorState', 1, 'Opened', 'Closed');
|
|
267
|
+
expect(device.infoLog).toHaveBeenCalledWith('was Closed');
|
|
268
|
+
});
|
|
269
|
+
it('should log "was Opened" when door changes to open', async () => {
|
|
270
|
+
device.accessory.context.ContactSensorContactSensorState = 0;
|
|
271
|
+
await device.updateCharacteristic(mockService, 'ContactSensor', 'ContactSensorState', 1, 'ContactSensorState', 1, 'Opened', 'Closed');
|
|
272
|
+
expect(device.infoLog).toHaveBeenCalledWith('was Opened');
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
describe('updates without StatusMatch/StatusDoesNotMatch', () => {
|
|
276
|
+
it('should push to HomeKit but not log info when no status strings provided', async () => {
|
|
277
|
+
device.accessory.context.BatteryBatteryLevel = 90;
|
|
278
|
+
await device.updateCharacteristic(mockService, 'Battery', 'BatteryLevel', 85, 'BatteryLevel');
|
|
279
|
+
expect(mockService.updateCharacteristic).toHaveBeenCalledWith('BatteryLevel', 85);
|
|
280
|
+
expect(device.infoLog).not.toHaveBeenCalled();
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
describe('startup simulation (seeded context matches API response)', () => {
|
|
284
|
+
it('should not push to HomeKit or log when seeded context matches first API value', async () => {
|
|
285
|
+
// Simulate constructor seeding: accessory.context.LockMechanismLockCurrentState ??= SECURED
|
|
286
|
+
device.accessory.context.LockMechanismLockCurrentState = 1;
|
|
287
|
+
// First API response returns same state (SECURED = 1)
|
|
288
|
+
await device.updateCharacteristic(mockService, 'LockMechanism', CHARACTERISTIC, 1, 'LockCurrentState', 1, 'Locked', 'Unlocked');
|
|
289
|
+
expect(mockService.updateCharacteristic).not.toHaveBeenCalled();
|
|
290
|
+
expect(device.infoLog).not.toHaveBeenCalled();
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
//# sourceMappingURL=device.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device.test.js","sourceRoot":"","sources":["../../src/devices/device.test.ts"],"names":[],"mappings":"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"}
|
package/dist/devices/lock.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CharacteristicValue, PlatformAccessory } from 'homebridge';
|
|
2
|
-
import type {
|
|
2
|
+
import type { AugustPlatform } from '../Platform.HAP.js';
|
|
3
3
|
import type { device, devicesConfig, lockDetails, lockEvent, lockStatus } from '../settings.js';
|
|
4
4
|
import { deviceBase } from './device.js';
|
|
5
5
|
/**
|
|
@@ -8,7 +8,7 @@ import { deviceBase } from './device.js';
|
|
|
8
8
|
* Each accessory may expose multiple services of different service types.
|
|
9
9
|
*/
|
|
10
10
|
export declare class LockMechanism extends deviceBase {
|
|
11
|
-
readonly platform:
|
|
11
|
+
readonly platform: AugustPlatform;
|
|
12
12
|
private LockMechanism?;
|
|
13
13
|
private Battery;
|
|
14
14
|
private ContactSensor?;
|
|
@@ -18,7 +18,7 @@ export declare class LockMechanism extends deviceBase {
|
|
|
18
18
|
lockUpdateInProgress: boolean;
|
|
19
19
|
doLockUpdate: any;
|
|
20
20
|
private pubnubUnsubscribe?;
|
|
21
|
-
constructor(platform:
|
|
21
|
+
constructor(platform: AugustPlatform, accessory: PlatformAccessory, device: device & devicesConfig);
|
|
22
22
|
/**
|
|
23
23
|
* Parse the device status from the August api
|
|
24
24
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/devices/lock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAW,MAAM,YAAY,CAAA;AAEjF,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/devices/lock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAW,MAAM,YAAY,CAAA;AAEjF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAU/F,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC;;;;GAIG;AACH,qBAAa,aAAc,SAAQ,UAAU;IAsCzC,QAAQ,CAAC,QAAQ,EAAE,cAAc;IApCnC,OAAO,CAAC,aAAa,CAAC,CAKrB;IAED,OAAO,CAAC,OAAO,CAMd;IAED,OAAO,CAAC,aAAa,CAAC,CAIrB;IAGD,SAAS,EAAG,SAAS,CAAA;IACrB,UAAU,EAAG,UAAU,CAAA;IACvB,WAAW,EAAG,WAAW,CAAA;IAGzB,oBAAoB,EAAE,OAAO,CAAA;IAC7B,YAAY,EAAE,GAAG,CAAA;IAKjB,OAAO,CAAC,iBAAiB,CAAC,CAAY;gBAG3B,QAAQ,EAAE,cAAc,EACjC,SAAS,EAAE,iBAAiB,EAC5B,MAAM,EAAE,MAAM,GAAG,aAAa;IAiIhC;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAqElC;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAkDvC;;;;;;;;;;;OAWG;IACG,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAqBpC;;;;;;OAMG;IACG,YAAY,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ3D;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAuDlC;;OAEG;IACG,4BAA4B,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB7C,kBAAkB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBnE,OAAO,CAAC,uBAAuB,CAAC,CAAY;IAI5C,OAAO,CAAC,YAAY,CAAC,CAAQ;IAEvB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IA+CtC;;;;OAIG;IACH,0BAA0B,IAAI,IAAI;CA0BnC"}
|
package/dist/devices/lock.js
CHANGED
|
@@ -37,7 +37,7 @@ export class LockMechanism extends deviceBase {
|
|
|
37
37
|
// Initialize Lock Mechanism Service
|
|
38
38
|
if (device.lock?.hide_lock) {
|
|
39
39
|
if (this.LockMechanism?.Service) {
|
|
40
|
-
this.
|
|
40
|
+
this.debugLog('Removing Lock Mechanism Service');
|
|
41
41
|
this.LockMechanism.Service = accessory.getService(this.hap.Service.LockMechanism);
|
|
42
42
|
accessory.removeService(this.LockMechanism.Service);
|
|
43
43
|
accessory.context.LockMechanism = {};
|
|
@@ -67,7 +67,7 @@ export class LockMechanism extends deviceBase {
|
|
|
67
67
|
// Initialize Contact Sensor Service
|
|
68
68
|
if (device.lock?.hide_contactsensor) {
|
|
69
69
|
if (this.ContactSensor?.Service) {
|
|
70
|
-
this.
|
|
70
|
+
this.debugLog('Removing Conact Sensor Service');
|
|
71
71
|
this.ContactSensor.Service = accessory.getService(this.hap.Service.ContactSensor);
|
|
72
72
|
accessory.removeService(this.ContactSensor.Service);
|
|
73
73
|
accessory.context.ContactSensor = {};
|
|
@@ -142,7 +142,7 @@ export class LockMechanism extends deviceBase {
|
|
|
142
142
|
}
|
|
143
143
|
catch (e) {
|
|
144
144
|
await this.statusCode('pushChanges', e);
|
|
145
|
-
await this.
|
|
145
|
+
await this.errorLog(`doLockUpdate pushChanges: ${e.message ?? e}`);
|
|
146
146
|
}
|
|
147
147
|
this.lockUpdateInProgress = false;
|
|
148
148
|
});
|
|
@@ -152,14 +152,14 @@ export class LockMechanism extends deviceBase {
|
|
|
152
152
|
* Parse the device status from the August api
|
|
153
153
|
*/
|
|
154
154
|
async parseStatus() {
|
|
155
|
-
await this.
|
|
155
|
+
await this.debugLog('parseStatus');
|
|
156
156
|
const retryCount = 1;
|
|
157
157
|
if (this.lockStatus) {
|
|
158
158
|
if (this.lockStatus.state) {
|
|
159
159
|
// Lock Mechanism
|
|
160
160
|
this.platform.augustConfig?.addSimpleProps(this.lockStatus);
|
|
161
161
|
if (this.LockMechanism && (this.lockStatus.state.unlocking || this.lockStatus.state.locking)) {
|
|
162
|
-
await this.
|
|
162
|
+
await this.warnLog(`LockCurrentState: ${this.LockMechanism.LockCurrentState}, locking/unlocking parseStatus`
|
|
163
163
|
+ ` lockStatus: ${JSON.stringify(this.lockStatus)}`);
|
|
164
164
|
}
|
|
165
165
|
if (!this.device.lock?.hide_lock && this.LockMechanism?.Service && (this.lockStatus.state.locked !== this.lockStatus.state.unlocked)) {
|
|
@@ -172,11 +172,11 @@ export class LockMechanism extends deviceBase {
|
|
|
172
172
|
this.LockMechanism.LockTargetState = this.LockMechanism.LockCurrentState;
|
|
173
173
|
}
|
|
174
174
|
if (this.LockMechanism.LockCurrentState === this.hap.Characteristic.LockCurrentState.UNKNOWN) {
|
|
175
|
-
await this.
|
|
175
|
+
await this.warnLog(`LockCurrentState: ${this.LockMechanism.LockCurrentState}, (UNKNOWN) parseStatus`
|
|
176
176
|
+ ` lockStatus: ${JSON.stringify(this.lockStatus)}`);
|
|
177
177
|
}
|
|
178
|
-
await this.
|
|
179
|
-
await this.
|
|
178
|
+
await this.debugLog(`LockCurrentState: ${this.LockMechanism.LockCurrentState}`);
|
|
179
|
+
await this.debugLog(`LockTargetState: ${this.LockMechanism.LockTargetState}`);
|
|
180
180
|
}
|
|
181
181
|
// Contact Sensor
|
|
182
182
|
if (!this.device.lock?.hide_contactsensor && this.ContactSensor?.Service) {
|
|
@@ -190,25 +190,25 @@ export class LockMechanism extends deviceBase {
|
|
|
190
190
|
: this.lockStatus.doorState?.includes('closed')
|
|
191
191
|
? this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED
|
|
192
192
|
: this.ContactSensor.ContactSensorState;
|
|
193
|
-
await this.
|
|
193
|
+
await this.debugLog(`ContactSensorState: ${this.ContactSensor.ContactSensorState}`);
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
196
|
else {
|
|
197
|
-
await this.
|
|
197
|
+
await this.debugWarnLog(`lockStatus state: ${JSON.stringify(this.lockStatus)}`);
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
200
|
if (this.lockDetails) {
|
|
201
201
|
// BatteryLevel
|
|
202
202
|
this.Battery.BatteryLevel = Math.min(Math.max(Number((this.lockDetails.battery * 100).toFixed()), 0), 100);
|
|
203
|
-
await this.
|
|
203
|
+
await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`);
|
|
204
204
|
// StatusLowBattery
|
|
205
205
|
this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 15
|
|
206
206
|
? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW
|
|
207
207
|
: this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
208
|
-
await this.
|
|
208
|
+
await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
209
209
|
// Firmware Version
|
|
210
210
|
if (this.accessory.context.currentFirmwareVersion !== this.lockDetails.currentFirmwareVersion) {
|
|
211
|
-
await this.
|
|
211
|
+
await this.warnLog(`Firmware Version changed to Current Firmware Version: ${this.lockDetails.currentFirmwareVersion}`);
|
|
212
212
|
this.accessory
|
|
213
213
|
.getService(this.hap.Service.AccessoryInformation)
|
|
214
214
|
.setCharacteristic(this.hap.Characteristic.HardwareRevision, this.lockDetails.currentFirmwareVersion)
|
|
@@ -223,15 +223,15 @@ export class LockMechanism extends deviceBase {
|
|
|
223
223
|
* Parse the device status from the August api
|
|
224
224
|
*/
|
|
225
225
|
async parseEventStatus() {
|
|
226
|
-
await this.
|
|
226
|
+
await this.debugLog('parseEventStatus');
|
|
227
227
|
const retryCount = 1;
|
|
228
228
|
if (this.lockEvent) {
|
|
229
229
|
if (this.lockEvent.state) {
|
|
230
|
-
this.
|
|
230
|
+
this.debugLog(`lockEvent: ${JSON.stringify(this.lockEvent)}`);
|
|
231
231
|
// Lock Mechanism
|
|
232
232
|
this.platform.augustConfig?.addSimpleProps(this.lockEvent);
|
|
233
233
|
if (this.LockMechanism && (this.lockEvent.state.unlocking || this.lockEvent.state.locking)) {
|
|
234
|
-
await this.
|
|
234
|
+
await this.debugLog(`is ${this.lockEvent.state.unlocking ? 'Unlocking' : this.lockEvent.state.locking ? 'Locking' : ''}, parseEventStatus`
|
|
235
235
|
+ ` lockEventState: ${JSON.stringify(this.lockEvent.state)}`);
|
|
236
236
|
return;
|
|
237
237
|
}
|
|
@@ -245,11 +245,11 @@ export class LockMechanism extends deviceBase {
|
|
|
245
245
|
this.LockMechanism.LockTargetState = this.LockMechanism.LockCurrentState;
|
|
246
246
|
}
|
|
247
247
|
if (this.LockMechanism.LockCurrentState === this.hap.Characteristic.LockCurrentState.UNKNOWN) {
|
|
248
|
-
await this.
|
|
248
|
+
await this.warnLog(`LockCurrentState: ${this.LockMechanism.LockCurrentState}, (UNKNOWN) parseEventStatus`
|
|
249
249
|
+ ` lockEvent: ${JSON.stringify(this.lockEvent)}`);
|
|
250
250
|
}
|
|
251
|
-
await this.
|
|
252
|
-
await this.
|
|
251
|
+
await this.debugLog(`LockCurrentState: ${this.LockMechanism.LockCurrentState}`);
|
|
252
|
+
await this.debugLog(`LockTargetState: ${this.LockMechanism.LockTargetState}`);
|
|
253
253
|
}
|
|
254
254
|
// Contact Sensor
|
|
255
255
|
if (!this.device.lock?.hide_contactsensor && this.ContactSensor?.Service) {
|
|
@@ -263,11 +263,11 @@ export class LockMechanism extends deviceBase {
|
|
|
263
263
|
: this.lockEvent.doorState === 'closed'
|
|
264
264
|
? this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED
|
|
265
265
|
: this.ContactSensor.ContactSensorState;
|
|
266
|
-
await this.
|
|
266
|
+
await this.debugLog(`ContactSensorState: ${this.ContactSensor.ContactSensorState}`);
|
|
267
267
|
}
|
|
268
268
|
}
|
|
269
269
|
else {
|
|
270
|
-
await this.
|
|
270
|
+
await this.debugWarnLog(`lovckEvent state: ${JSON.stringify(this.lockStatus)}`);
|
|
271
271
|
}
|
|
272
272
|
}
|
|
273
273
|
}
|
|
@@ -285,11 +285,11 @@ export class LockMechanism extends deviceBase {
|
|
|
285
285
|
*/
|
|
286
286
|
async refreshStatus() {
|
|
287
287
|
if (this.deviceRefreshRate === 0) {
|
|
288
|
-
await this.
|
|
288
|
+
await this.debugLog(`(refreshStatus) deviceRefreshRate: ${this.deviceRefreshRate}`);
|
|
289
289
|
return;
|
|
290
290
|
}
|
|
291
291
|
if (!this.platform.connectivity) {
|
|
292
|
-
await this.
|
|
292
|
+
await this.debugLog('(refreshStatus) connectivity not initialized — skipping');
|
|
293
293
|
return;
|
|
294
294
|
}
|
|
295
295
|
const lockDetails = await this.platform.connectivity.execute(`refreshStatus ${this.accessory.displayName}`, client => client.details(this.device.lockId));
|
|
@@ -308,7 +308,7 @@ export class LockMechanism extends deviceBase {
|
|
|
308
308
|
* (which would re-fetch).
|
|
309
309
|
*/
|
|
310
310
|
async applyRefresh(lockDetails) {
|
|
311
|
-
await this.
|
|
311
|
+
await this.debugSuccessLog(`(applyRefresh) lockDetails: ${JSON.stringify(lockDetails)}`);
|
|
312
312
|
this.lockDetails = lockDetails;
|
|
313
313
|
this.lockStatus = lockDetails.LockStatus;
|
|
314
314
|
await this.parseStatus();
|
|
@@ -319,22 +319,22 @@ export class LockMechanism extends deviceBase {
|
|
|
319
319
|
*/
|
|
320
320
|
async pushChanges() {
|
|
321
321
|
if (!this.LockMechanism) {
|
|
322
|
-
await this.
|
|
322
|
+
await this.errorLog(`lockTargetState: ${JSON.stringify(this.LockMechanism)}`);
|
|
323
323
|
return;
|
|
324
324
|
}
|
|
325
325
|
const targetState = this.LockMechanism.LockTargetState;
|
|
326
326
|
const currentState = this.LockMechanism.LockCurrentState;
|
|
327
327
|
if (targetState === currentState) {
|
|
328
|
-
await this.
|
|
328
|
+
await this.debugLog(`No changes, LockTargetState: ${targetState}, LockCurrentState: ${currentState}`);
|
|
329
329
|
this.LockMechanism.LockTargetState = currentState === this.hap.Characteristic.LockCurrentState.SECURED
|
|
330
330
|
? this.hap.Characteristic.LockTargetState.SECURED
|
|
331
331
|
: this.hap.Characteristic.LockTargetState.UNSECURED;
|
|
332
332
|
await this.updateHomeKitCharacteristics();
|
|
333
333
|
return;
|
|
334
334
|
}
|
|
335
|
-
await this.
|
|
335
|
+
await this.debugLog(`Making API call - Target: ${targetState}, Current: ${currentState}`);
|
|
336
336
|
if (!this.platform.connectivity) {
|
|
337
|
-
await this.
|
|
337
|
+
await this.errorLog('pushChanges: connectivity not initialized');
|
|
338
338
|
return;
|
|
339
339
|
}
|
|
340
340
|
try {
|
|
@@ -358,19 +358,19 @@ export class LockMechanism extends deviceBase {
|
|
|
358
358
|
await client.lock(this.device.lockId);
|
|
359
359
|
}
|
|
360
360
|
}, { throwOnOffline: true });
|
|
361
|
-
await this.
|
|
361
|
+
await this.successLog(`Sending request to August API: ${targetState === 1 ? 'Locked' : 'Unlocked'}`);
|
|
362
362
|
await this.updateHomeKitCharacteristics();
|
|
363
363
|
}
|
|
364
364
|
catch (e) {
|
|
365
365
|
await this.statusCode('pushChanges', e);
|
|
366
|
-
await this.
|
|
366
|
+
await this.errorLog(`pushChanges: ${e.message ?? e}`);
|
|
367
367
|
}
|
|
368
368
|
}
|
|
369
369
|
/**
|
|
370
370
|
* Updates the status for each of the HomeKit Characteristics
|
|
371
371
|
*/
|
|
372
372
|
async updateHomeKitCharacteristics() {
|
|
373
|
-
await this.
|
|
373
|
+
await this.debugLog('updateHomeKitCharacteristics');
|
|
374
374
|
// Lock Mechanism
|
|
375
375
|
if (!this.device.lock?.hide_lock && this.LockMechanism?.Service) {
|
|
376
376
|
// LockTargetState
|
|
@@ -392,10 +392,10 @@ export class LockMechanism extends deviceBase {
|
|
|
392
392
|
async setLockTargetState(value) {
|
|
393
393
|
if (this.LockMechanism) {
|
|
394
394
|
if (this.LockMechanism.LockTargetState !== this.LockMechanism.LockCurrentState) {
|
|
395
|
-
await this.
|
|
395
|
+
await this.debugLog(`Set LockTargetState: ${value}`);
|
|
396
396
|
}
|
|
397
397
|
else {
|
|
398
|
-
await this.
|
|
398
|
+
await this.debugLog(`No changes, LockTargetState: ${this.LockMechanism.LockTargetState},`
|
|
399
399
|
+ ` LockCurrentState: ${this.LockMechanism.LockCurrentState}`);
|
|
400
400
|
}
|
|
401
401
|
this.accessory.context.LockMechanismLockTargetState = this.LockMechanism.LockTargetState = value;
|
|
@@ -412,7 +412,7 @@ export class LockMechanism extends deviceBase {
|
|
|
412
412
|
// platform.connectivity's August (which is for HTTP only).
|
|
413
413
|
pubnubAugust;
|
|
414
414
|
async subscribeAugust() {
|
|
415
|
-
await this.
|
|
415
|
+
await this.debugLog('subscribeAugust');
|
|
416
416
|
await this.platform.augustCredentials();
|
|
417
417
|
if (this.config.credentials) {
|
|
418
418
|
// Clean up any previous subscription before creating a new one.
|
|
@@ -436,15 +436,15 @@ export class LockMechanism extends deviceBase {
|
|
|
436
436
|
this.pubnubStatusUnsubscribe = this.pubnubAugust.onPubNubStatus((status) => {
|
|
437
437
|
const category = status?.category;
|
|
438
438
|
if (category === 'PNConnectedCategory' || category === 'PNReconnectedCategory') {
|
|
439
|
-
this.
|
|
439
|
+
this.debugLog(`PubNub status: ${category} — signalling connectivity recovery`);
|
|
440
440
|
this.platform.connectivity?.onPubNubReconnect();
|
|
441
441
|
}
|
|
442
442
|
else if (category === 'PNNetworkDownCategory' || category === 'PNDisconnectedCategory') {
|
|
443
|
-
this.
|
|
443
|
+
this.debugLog(`PubNub status: ${category}`);
|
|
444
444
|
}
|
|
445
445
|
});
|
|
446
446
|
this.pubnubUnsubscribe = await this.pubnubAugust.subscribe(this.device.lockId, async (AugustEvent, timestamp) => {
|
|
447
|
-
await this.
|
|
447
|
+
await this.debugLog(`AugustEvent: ${JSON.stringify(AugustEvent)}, ${JSON.stringify(timestamp)}`);
|
|
448
448
|
// Update HomeKit
|
|
449
449
|
this.lockEvent = AugustEvent;
|
|
450
450
|
await this.parseEventStatus();
|
|
@@ -452,7 +452,7 @@ export class LockMechanism extends deviceBase {
|
|
|
452
452
|
});
|
|
453
453
|
}
|
|
454
454
|
else {
|
|
455
|
-
await this.
|
|
455
|
+
await this.errorLog('subscribeAugust: No credentials');
|
|
456
456
|
}
|
|
457
457
|
}
|
|
458
458
|
/**
|
|
@@ -466,7 +466,7 @@ export class LockMechanism extends deviceBase {
|
|
|
466
466
|
this.pubnubStatusUnsubscribe();
|
|
467
467
|
}
|
|
468
468
|
catch (e) {
|
|
469
|
-
this.
|
|
469
|
+
this.debugLog(`Error tearing down PubNub status listener: ${e.message || e}`);
|
|
470
470
|
}
|
|
471
471
|
this.pubnubStatusUnsubscribe = undefined;
|
|
472
472
|
}
|
|
@@ -475,7 +475,7 @@ export class LockMechanism extends deviceBase {
|
|
|
475
475
|
this.pubnubUnsubscribe();
|
|
476
476
|
}
|
|
477
477
|
catch (e) {
|
|
478
|
-
this.
|
|
478
|
+
this.debugLog(`Error tearing down PubNub subscription: ${e.message || e}`);
|
|
479
479
|
}
|
|
480
480
|
this.pubnubUnsubscribe = undefined;
|
|
481
481
|
}
|
|
@@ -484,7 +484,7 @@ export class LockMechanism extends deviceBase {
|
|
|
484
484
|
this.pubnubAugust.destroy();
|
|
485
485
|
}
|
|
486
486
|
catch (e) {
|
|
487
|
-
this.
|
|
487
|
+
this.debugLog(`Error destroying PubNub August instance: ${e.message || e}`);
|
|
488
488
|
}
|
|
489
489
|
this.pubnubAugust = undefined;
|
|
490
490
|
}
|