homebridge-tydom 0.23.9 → 0.23.11

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
@@ -51,7 +51,7 @@
51
51
  "private": true,
52
52
  "description": "This file keeps track of which plugins should be installed.",
53
53
  "dependencies": {
54
- "homebridge-tydom": "^0.15.1"
54
+ "homebridge-tydom": "^0.23.9"
55
55
  }
56
56
  }
57
57
  ```
@@ -7,6 +7,7 @@ type ZoneAliases = {
7
7
  night?: number[];
8
8
  };
9
9
  type SecuritySystemSettings = {
10
+ legacy?: boolean;
10
11
  aliases?: ZoneAliases;
11
12
  sensors?: boolean;
12
13
  pin?: string;
@@ -12,13 +12,16 @@ const accessory_1 = require("../helpers/accessory");
12
12
  const tydom_1 = require("../helpers/tydom");
13
13
  const utils_1 = require("../utils");
14
14
  const debug_1 = require("../utils/debug");
15
- const getActiveZones = (alarmData) => alarmData.reduce((soFar, { name, value }) => {
16
- const matches = name.match(/zone([1-8])State/i);
17
- if (matches && value === 'ON') {
18
- soFar.push((0, utils_1.asNumber)(matches[1]));
19
- }
20
- return soFar;
21
- }, []);
15
+ const getActiveZones = (alarmData, settings) => {
16
+ const { legacy } = settings;
17
+ return alarmData.reduce((soFar, { name, value }) => {
18
+ const matches = name.match(!legacy ? /zone([1-8])State/i : /part([1-4])State/i);
19
+ if (matches && value === 'ON') {
20
+ soFar.push((0, utils_1.asNumber)(matches[1]));
21
+ }
22
+ return soFar;
23
+ }, []);
24
+ };
22
25
  const getStateForActiveZones = (activeZones, zoneAliases) => {
23
26
  const { SecuritySystemCurrentState } = hap_1.Characteristic;
24
27
  if (zoneAliases.stay && (0, utils_1.sameArrays)(activeZones, zoneAliases.stay)) {
@@ -29,7 +32,7 @@ const getStateForActiveZones = (activeZones, zoneAliases) => {
29
32
  }
30
33
  return SecuritySystemCurrentState.DISARMED;
31
34
  };
32
- const getStateForAlarmData = (alarmData, zoneAliases) => {
35
+ const getStateForAlarmData = (alarmData, zoneAliases, settings) => {
33
36
  const { SecuritySystemCurrentState } = hap_1.Characteristic;
34
37
  const alarmMode = (0, tydom_1.getTydomDataPropValue)(alarmData, 'alarmMode');
35
38
  const alarmState = (0, tydom_1.getTydomDataPropValue)(alarmData, 'alarmState');
@@ -39,20 +42,20 @@ const getStateForAlarmData = (alarmData, zoneAliases) => {
39
42
  if (alarmMode === 'ON') {
40
43
  return SecuritySystemCurrentState.AWAY_ARM;
41
44
  }
42
- if (alarmMode === 'ZONE') {
43
- const activeZones = getActiveZones(alarmData);
45
+ if (['ZONE', 'PART'].includes(alarmMode)) {
46
+ const activeZones = getActiveZones(alarmData, settings);
44
47
  return getStateForActiveZones(activeZones, zoneAliases);
45
48
  }
46
49
  return SecuritySystemCurrentState.DISARMED;
47
50
  };
48
51
  const setupSecuritySystem = async (accessory, controller) => {
49
52
  const { context } = accessory;
50
- const { client } = controller;
53
+ const { client, log } = controller;
51
54
  const { SecuritySystemTargetState, SecuritySystemCurrentState, StatusTampered, ContactSensorState, On } = hap_1.Characteristic;
52
55
  const { deviceId, endpointId, settings } = context;
53
56
  (0, accessory_1.setupAccessoryInformationService)(accessory, controller);
54
57
  (0, accessory_1.setupAccessoryIdentifyHandler)(accessory, controller);
55
- const { aliases = {}, pin: settingsPin } = settings;
58
+ const { aliases = {}, pin: settingsPin, legacy: isLegacy = false } = settings;
56
59
  // Create separate dedicated sensor extra accessory;
57
60
  if (settings.sensors !== false) {
58
61
  const { accessoryId } = context;
@@ -64,13 +67,32 @@ const setupSecuritySystem = async (accessory, controller) => {
64
67
  };
65
68
  controller.emit('device', extraDevice);
66
69
  }
70
+ let zones = [];
67
71
  const initialData = await (0, tydom_1.getTydomDeviceData)(client, { deviceId, endpointId });
68
- const labelResults = await client.command(`/devices/${deviceId}/endpoints/${endpointId}/cdata?name=label`);
69
- const { zones } = labelResults[0];
72
+ if (!isLegacy) {
73
+ try {
74
+ const labelResults = await client.command(`/devices/${deviceId}/endpoints/${endpointId}/cdata?name=label`);
75
+ zones = labelResults[0].zones;
76
+ }
77
+ catch (err) {
78
+ log.warn(`Failed to query labels for security system`);
79
+ zones = [];
80
+ }
81
+ }
82
+ else {
83
+ log.warn(`Setting up legacy zones`);
84
+ // @NOTE could filter "UNUSED" zones from initialData
85
+ zones = [
86
+ { id: 1, nameCustom: 'Zone 1' },
87
+ { id: 2, nameCustom: 'Zone 2' },
88
+ { id: 3, nameCustom: 'Zone 3' },
89
+ { id: 4, nameCustom: 'Zone 4' }
90
+ ];
91
+ }
70
92
  // Pin code check
71
93
  const pin = env_1.HOMEBRIDGE_TYDOM_PIN ? (0, utils_1.decode)(env_1.HOMEBRIDGE_TYDOM_PIN) : settingsPin;
72
94
  if (!pin) {
73
- controller.log.warn(`Missing pin for device securitySystem, add either {"settings": {"${deviceId}": {"pin": "123456"}}} or HOMEBRIDGE_TYDOM_PIN env var (base64 encoded)`);
95
+ log.warn(`Missing pin for device securitySystem, add either {"settings": {"${deviceId}": {"pin": "123456"}}} or HOMEBRIDGE_TYDOM_PIN env var (base64 encoded)`);
74
96
  }
75
97
  // Add the actual accessory Service
76
98
  const service = (0, accessory_1.addAccessoryService)(accessory, hap_1.Service.SecuritySystem, `${accessory.displayName}`, true);
@@ -81,7 +103,7 @@ const setupSecuritySystem = async (accessory, controller) => {
81
103
  (0, debug_1.debugGet)(SecuritySystemCurrentState, service);
82
104
  try {
83
105
  const data = await (0, tydom_1.getTydomDeviceData)(client, { deviceId, endpointId });
84
- const nextValue = getStateForAlarmData(data, aliases);
106
+ const nextValue = getStateForAlarmData(data, aliases, settings);
85
107
  (0, debug_1.debugGetResult)(SecuritySystemCurrentState, service, nextValue);
86
108
  callback(null, nextValue);
87
109
  }
@@ -111,7 +133,7 @@ const setupSecuritySystem = async (accessory, controller) => {
111
133
  (0, debug_1.debugGet)(SecuritySystemTargetState, service);
112
134
  try {
113
135
  const data = await (0, tydom_1.getTydomDeviceData)(client, { deviceId, endpointId });
114
- const nextValue = getStateForAlarmData(data, aliases);
136
+ const nextValue = getStateForAlarmData(data, aliases, settings);
115
137
  (0, debug_1.debugGetResult)(SecuritySystemTargetState, service, nextValue);
116
138
  callback(null, nextValue);
117
139
  }
@@ -132,10 +154,20 @@ const setupSecuritySystem = async (accessory, controller) => {
132
154
  // Global ON/OFF
133
155
  if ([SecuritySystemTargetState.AWAY_ARM, SecuritySystemTargetState.DISARM].includes(value)) {
134
156
  const tydomValue = value === SecuritySystemTargetState.DISARM ? 'OFF' : 'ON';
135
- await client.put(`/devices/${deviceId}/endpoints/${endpointId}/cdata?name=alarmCmd`, {
136
- value: tydomValue,
137
- pwd: pin
138
- });
157
+ if (!isLegacy) {
158
+ await client.put(`/devices/${deviceId}/endpoints/${endpointId}/cdata?name=alarmCmd`, {
159
+ value: tydomValue,
160
+ pwd: pin
161
+ });
162
+ }
163
+ else {
164
+ for (const zone in [1, 2, 3, 4]) {
165
+ await client.put(`/devices/${deviceId}/endpoints/${endpointId}/cdata?name=partCmd`, {
166
+ value: tydomValue,
167
+ part: zone
168
+ });
169
+ }
170
+ }
139
171
  (0, debug_1.debugSetResult)(SecuritySystemTargetState, service, value, tydomValue);
140
172
  callback();
141
173
  return;
@@ -145,11 +177,21 @@ const setupSecuritySystem = async (accessory, controller) => {
145
177
  const tydomValue = value === SecuritySystemTargetState.DISARM ? 'OFF' : 'ON';
146
178
  const targetZones = value === SecuritySystemTargetState.STAY_ARM ? aliases.stay : aliases.night;
147
179
  if (Array.isArray(targetZones) && targetZones.length > 0) {
148
- await client.put(`/devices/${deviceId}/endpoints/${endpointId}/cdata?name=zoneCmd`, {
149
- value: tydomValue,
150
- pwd: pin,
151
- zones: targetZones
152
- });
180
+ if (!isLegacy) {
181
+ await client.put(`/devices/${deviceId}/endpoints/${endpointId}/cdata?name=zoneCmd`, {
182
+ value: tydomValue,
183
+ pwd: pin,
184
+ zones: targetZones
185
+ });
186
+ }
187
+ else {
188
+ for (const zone in targetZones) {
189
+ await client.put(`/devices/${deviceId}/endpoints/${endpointId}/cdata?name=partCmd`, {
190
+ value: tydomValue,
191
+ part: zone
192
+ });
193
+ }
194
+ }
153
195
  }
154
196
  (0, debug_1.debugSetResult)(SecuritySystemTargetState, service, value, tydomValue);
155
197
  callback();
@@ -347,8 +389,9 @@ const updateSecuritySystem = (accessory, controller, updates, type) => {
347
389
  service.updateCharacteristic(SecuritySystemCurrentState, nextValue);
348
390
  return;
349
391
  }
392
+ case 'PART':
350
393
  case 'ZONE': {
351
- const activeZones = getActiveZones(updates);
394
+ const activeZones = getActiveZones(updates, settings);
352
395
  const nextValue = getStateForActiveZones(activeZones, aliases);
353
396
  (0, debug_1.debugSetUpdate)(SecuritySystemCurrentState, service, nextValue);
354
397
  service.updateCharacteristic(SecuritySystemCurrentState, nextValue);
package/lib/bin/cli.js CHANGED
@@ -4,25 +4,28 @@ Object.defineProperty(exports, "__esModule", { value: true });
4
4
  const fs_1 = require("fs");
5
5
  const tydom_1 = require("../helpers/tydom");
6
6
  const utils_1 = require("../utils");
7
- const [action = 'help', ..._args] = process.argv.slice(2);
8
- console.dir({ action });
7
+ const [action = 'help', ...args] = process.argv.slice(2);
8
+ const [filename] = args;
9
+ console.dir({ action, args });
9
10
  const main = async () => {
10
11
  switch (action) {
11
12
  case 'dump': {
12
- const stdin = (0, fs_1.readFileSync)(process.stdin.fd);
13
+ const stdin = (0, fs_1.readFileSync)(filename || process.stdin.fd);
13
14
  const dump = JSON.parse(stdin.toString('utf8'));
14
15
  const allDevicesConfig = dump['/configs/file'];
15
16
  const allDevicesMeta = dump['/devices/meta'];
16
17
  for (const deviceMeta of allDevicesMeta) {
17
- const signature = (0, tydom_1.getEndpointSignatureFromMetadata)(deviceMeta.endpoints[0].metadata);
18
- const config = allDevicesConfig.endpoints.find((item) => item.id_device === deviceMeta.id);
19
- const hash = `${config === null || config === void 0 ? void 0 : config.first_usage}:${await (0, utils_1.sha256)(signature)}`;
20
- console.dir({ id: config === null || config === void 0 ? void 0 : config.id_device, name: config === null || config === void 0 ? void 0 : config.name, signature, hash });
18
+ for (const endpointMeta of deviceMeta.endpoints) {
19
+ const signature = (0, tydom_1.getEndpointSignatureFromMetadata)(endpointMeta.metadata);
20
+ const config = allDevicesConfig.endpoints.find((item) => item.id_device === deviceMeta.id && item.id_endpoint === endpointMeta.id);
21
+ const hash = `${config === null || config === void 0 ? void 0 : config.first_usage}:${await (0, utils_1.sha256)(signature)}`;
22
+ console.dir({ id: `${deviceMeta.id}.${endpointMeta.id}`, name: config === null || config === void 0 ? void 0 : config.name, signature, hash });
23
+ }
21
24
  }
22
25
  break;
23
26
  }
24
27
  case 'hash': {
25
- const stdin = (0, fs_1.readFileSync)(process.stdin.fd);
28
+ const stdin = (0, fs_1.readFileSync)(filename || process.stdin.fd);
26
29
  const meta = JSON.parse(stdin.toString('utf8'));
27
30
  const metaSignature = (0, tydom_1.getEndpointSignatureFromMetadata)(meta);
28
31
  const hash = (0, utils_1.sha256Sync)(metaSignature);
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  import { EventEmitter } from 'events';
3
- import type { Categories, Logging } from 'homebridge';
3
+ import { Categories, Logging } from 'homebridge';
4
4
  import TydomClient from 'tydom-client';
5
5
  import { TydomHttpMessage, TydomResponse } from 'tydom-client/lib/utils/tydom';
6
6
  import { TydomPlatformConfig } from './platform';
@@ -25,7 +25,8 @@ export default class TydomController extends EventEmitter {
25
25
  private state;
26
26
  private refreshInterval?;
27
27
  constructor(log: Logging, config: TydomPlatformConfig);
28
- getAccessoryId(deviceId: number): string;
28
+ getUniqueId(deviceId: number, endpointId: number): string;
29
+ getAccessoryId(deviceId: number, endpointId: number): string;
29
30
  connect(): Promise<void>;
30
31
  sync(): Promise<{
31
32
  config: TydomConfigResponse;
package/lib/controller.js CHANGED
@@ -43,9 +43,12 @@ class TydomController extends events_1.EventEmitter {
43
43
  this.emit('disconnect');
44
44
  });
45
45
  }
46
- getAccessoryId(deviceId) {
46
+ getUniqueId(deviceId, endpointId) {
47
+ return deviceId === endpointId ? `${deviceId}` : `${deviceId}:${endpointId}`;
48
+ }
49
+ getAccessoryId(deviceId, endpointId) {
47
50
  const { username } = this.config;
48
- return `tydom:${username.slice(6)}:accessories:${deviceId}`;
51
+ return `tydom:${username.slice(6)}:accessories:${this.getUniqueId(deviceId, endpointId)}`;
49
52
  }
50
53
  async connect() {
51
54
  const { hostname, username } = this.config;
@@ -95,6 +98,7 @@ class TydomController extends events_1.EventEmitter {
95
98
  const { endpoints, groups: configGroups } = config;
96
99
  endpoints.forEach((endpoint) => {
97
100
  const { id_endpoint: endpointId, id_device: deviceId, name: deviceName, first_usage: firstUsage } = endpoint;
101
+ const uniqueId = this.getUniqueId(deviceId, endpointId);
98
102
  const { metadata } = (0, tydom_1.getEndpointDetailsFromMeta)(endpoint, meta);
99
103
  const groupId = (0, tydom_1.getEndpointGroupIdFromGroups)(endpoint, groups);
100
104
  const group = groupId ? configGroups.find(({ id }) => id === groupId) : undefined;
@@ -108,7 +112,7 @@ class TydomController extends events_1.EventEmitter {
108
112
  if (excludedDevices.length && (0, utils_1.stringIncludes)(excludedDevices, deviceId)) {
109
113
  return;
110
114
  }
111
- const category = categoryFromSettings || (0, tydom_1.resolveEndpointCategory)({ firstUsage, metadata });
115
+ const category = categoryFromSettings || (0, tydom_1.resolveEndpointCategory)({ firstUsage, metadata, settings: deviceSettings });
112
116
  if (!category) {
113
117
  this.log.warn(`Unsupported firstUsage="${firstUsage}" for endpoint with deviceId="${deviceId}"`);
114
118
  (0, utils_1.debug)({ endpoint });
@@ -120,12 +124,12 @@ class TydomController extends events_1.EventEmitter {
120
124
  if (excludedCategories.length && (0, utils_1.stringIncludes)(excludedCategories, category)) {
121
125
  return;
122
126
  }
123
- if (!this.devices.has(deviceId)) {
127
+ if (!this.devices.has(uniqueId)) {
124
128
  this.log.info(`Adding new device with firstUsage=${(0, utils_1.chalkString)(firstUsage)}, deviceId=${(0, utils_1.chalkNumber)(deviceId)} and endpointId=${(0, utils_1.chalkNumber)(endpointId)}`);
125
- const accessoryId = this.getAccessoryId(deviceId);
129
+ const accessoryId = this.getAccessoryId(deviceId, endpointId);
126
130
  const nameFromSetting = (0, lodash_1.get)(settings, `${deviceId}.name`);
127
131
  const name = nameFromSetting || deviceName;
128
- this.devices.set(deviceId, category);
132
+ this.devices.set(uniqueId, category);
129
133
  const context = {
130
134
  name,
131
135
  category,
@@ -168,27 +172,31 @@ class TydomController extends events_1.EventEmitter {
168
172
  return;
169
173
  }
170
174
  body.forEach((device) => {
175
+ var _a;
171
176
  const { id: deviceId, endpoints } = device;
172
- if (!this.devices.has(deviceId)) {
173
- (0, utils_1.debug)(`${chalk_1.default.bold.yellow('←PUT')}:${chalk_1.default.blue('ignored')} for device id=${(0, utils_1.chalkString)(deviceId)}, endpoints:\n${(0, utils_1.chalkJson)(endpoints)}`);
174
- return;
177
+ for (const endpoint of endpoints) {
178
+ const { id: endpointId, data, cdata } = endpoint;
179
+ const updates = type === 'data' ? data : cdata;
180
+ const uniqueId = this.getUniqueId(deviceId, endpointId);
181
+ if (!this.devices.has(uniqueId)) {
182
+ (0, utils_1.debug)(`${chalk_1.default.bold.yellow('←PUT')}:${chalk_1.default.blue('ignored')} for device id=${(0, utils_1.chalkString)(deviceId)} and endpointId=${(0, utils_1.chalkNumber)(endpointId)}`);
183
+ return;
184
+ }
185
+ const category = (_a = this.devices.get(uniqueId)) !== null && _a !== void 0 ? _a : 1 /* Categories.OTHER */;
186
+ const accessoryId = this.getAccessoryId(deviceId, endpointId);
187
+ (0, utils_1.debug)(`${chalk_1.default.bold.green('←PUT')}:${chalk_1.default.blue('update')} for deviceId=${(0, utils_1.chalkNumber)(deviceId)} and endpointId=${(0, utils_1.chalkNumber)(endpointId)}, updates:\n${(0, utils_1.chalkJson)(updates)}`);
188
+ const context = {
189
+ category,
190
+ deviceId,
191
+ endpointId,
192
+ accessoryId
193
+ };
194
+ this.emit('update', {
195
+ type,
196
+ updates,
197
+ context
198
+ });
175
199
  }
176
- const category = this.devices.get(deviceId);
177
- const { id: endpointId, data, cdata } = endpoints[0];
178
- const updates = type === 'data' ? data : cdata;
179
- const accessoryId = this.getAccessoryId(deviceId);
180
- (0, utils_1.debug)(`${chalk_1.default.bold.green('←PUT')}:${chalk_1.default.blue('update')} for device id=${(0, utils_1.chalkString)(deviceId)}, updates:\n${(0, utils_1.chalkJson)(updates)}`);
181
- const context = {
182
- category,
183
- deviceId,
184
- endpointId,
185
- accessoryId
186
- };
187
- this.emit('update', {
188
- type,
189
- updates,
190
- context
191
- });
192
200
  });
193
201
  }
194
202
  }
@@ -21,7 +21,8 @@ export declare const getEndpointSignatureFromMetadata: (metadata: TydomMetaEleme
21
21
  type ResolveEndpointCategoryOptions = {
22
22
  firstUsage: string;
23
23
  metadata: TydomMetaElement[];
24
+ settings: Record<string, unknown>;
24
25
  };
25
- export declare const resolveEndpointCategory: ({ firstUsage, metadata }: ResolveEndpointCategoryOptions) => Categories | null;
26
+ export declare const resolveEndpointCategory: ({ firstUsage, metadata, settings }: ResolveEndpointCategoryOptions) => Categories | null;
26
27
  export declare const asyncWait: (ms: number) => Promise<void>;
27
28
  export {};
@@ -86,7 +86,10 @@ const LEGACY_SUPPORTED_CATEGORIES_MAP = {
86
86
  };
87
87
  const ENDPOINTS_SIGNATURES_CATEGORIES = {
88
88
  'alarm:0c6e1d33808fa50a0a921502f80d36430dfaeda5abfed2467f9f2b07821e4842': 11 /* Categories.SECURITY_SYSTEM */,
89
- 'alarm:6e33f7ee5e62b58f4e888c91a13fd9b9d868f3751cead5ea1252578ba86523a5': 11 /* Categories.SECURITY_SYSTEM */,
89
+ 'alarm:6e33f7ee5e62b58f4e888c91a13fd9b9d868f3751cead5ea1252578ba86523a5': [
90
+ 11 /* Categories.SECURITY_SYSTEM */,
91
+ { legacy: true }
92
+ ],
90
93
  'alarm:aad768ee0367013a974276117fd5ed4834cc26e4d31acc88d35134731331b0e7': 11 /* Categories.SECURITY_SYSTEM */,
91
94
  'awning:48f43ebab20eba438fa9cc2b6ce44311d3cfb01c5be84bf17599d9c152c348d3': 14 /* Categories.WINDOW_COVERING */,
92
95
  'belmDoor:fb935867933d89b3058f09384f76fd63f3defb18cfb3172f60fa9f4f237f748b': 12 /* Categories.DOOR */,
@@ -96,7 +99,6 @@ const ENDPOINTS_SIGNATURES_CATEGORIES = {
96
99
  'hvac:16804a9994bce28275150db329a9c0b931ef7f20608c1a3d2ff248f58569f0d3': 10 /* Categories.SENSOR */,
97
100
  'hvac:17f933bec8ed29f9b2a2cd5280fb5b64806cf8a1c064c83950e350f491d7cb9f': 9 /* Categories.THERMOSTAT */,
98
101
  'hvac:1bab47d1dd7e898b5dc2e9867b14dfb8bc9272c4cb0b5d1221da962d43a6ffb4': 9 /* Categories.THERMOSTAT */,
99
- 'hvac:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855': 10 /* Categories.SENSOR */,
100
102
  'light:449e2a60377094cde10224cee91d378fb0ae373ae6ceea0ac2cbc1ed011bffa7': 5 /* Categories.LIGHTBULB */,
101
103
  'light:fce45085835f4f2790ea3b17d208b5ace34935444d2535e75ba3f0a2ce86de5f': 5 /* Categories.LIGHTBULB */,
102
104
  'others:449e2a60377094cde10224cee91d378fb0ae373ae6ceea0ac2cbc1ed011bffa7': 5 /* Categories.LIGHTBULB */,
@@ -104,13 +106,20 @@ const ENDPOINTS_SIGNATURES_CATEGORIES = {
104
106
  'shutter:c3fe8e2afa864e1a7a5c6676b4287a7b2f2a886a466baec3df8a1ec4f898ad6c': 14 /* Categories.WINDOW_COVERING */,
105
107
  'window:fb935867933d89b3058f09384f76fd63f3defb18cfb3172f60fa9f4f237f748b': 13 /* Categories.WINDOW */ // @mgcrea (MDO)
106
108
  };
107
- const resolveEndpointCategory = ({ firstUsage, metadata }) => {
109
+ const resolveEndpointCategory = ({ firstUsage, metadata, settings }) => {
108
110
  // Compute device signature
109
111
  const metaSignature = (0, exports.getEndpointSignatureFromMetadata)(metadata);
110
112
  const hash = `${firstUsage}:${(0, utils_1.sha256Sync)(metaSignature)}`;
111
113
  // dir({metaSignature, hash});
112
- if (ENDPOINTS_SIGNATURES_CATEGORIES[hash]) {
113
- return ENDPOINTS_SIGNATURES_CATEGORIES[hash];
114
+ const category = ENDPOINTS_SIGNATURES_CATEGORIES[hash];
115
+ if (category) {
116
+ // Support settings override
117
+ if (Array.isArray(category)) {
118
+ const [_category, overrides] = category;
119
+ Object.assign(settings, overrides);
120
+ return _category;
121
+ }
122
+ return category;
114
123
  }
115
124
  (0, utils_1.debug)(`Unknown hash=${hash} with firstUsage="${firstUsage}"`);
116
125
  // Fallback on legacy resolution
@@ -162,12 +162,13 @@ export type SecuritySystemProduct = {
162
162
  nameCustom?: string;
163
163
  number?: number;
164
164
  };
165
+ export type SecuritySystemLabelCommandResultZone = {
166
+ id: number;
167
+ nameStd?: string;
168
+ nameCustom?: string;
169
+ };
165
170
  export type SecuritySystemLabelCommandResult = {
166
- zones: {
167
- id: number;
168
- nameStd?: string;
169
- nameCustom?: string;
170
- }[];
171
+ zones: SecuritySystemLabelCommandResultZone[];
171
172
  products: SecuritySystemProduct[];
172
173
  };
173
174
  export type SecuritySystemHistoOpenIssuesCommandResult = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "homebridge-tydom",
3
- "version": "0.23.9",
3
+ "version": "0.23.11",
4
4
  "description": "Homebridge plugin to manage Tydom devices by Delta Dore",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",