homebridge-easy-mqtt 1.2.0-beta.0 → 1.2.0-beta.2

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.
Files changed (46) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/README.md +6 -8
  3. package/config.schema.json +12 -26
  4. package/dist/accessory/abstract/base.d.ts +20 -10
  5. package/dist/accessory/abstract/base.js +92 -4
  6. package/dist/accessory/abstract/base.js.map +1 -1
  7. package/dist/accessory/abstract/statusActive.d.ts +4 -7
  8. package/dist/accessory/abstract/statusActive.js +12 -22
  9. package/dist/accessory/abstract/statusActive.js.map +1 -1
  10. package/dist/accessory/lock.d.ts +3 -6
  11. package/dist/accessory/lock.js +51 -60
  12. package/dist/accessory/lock.js.map +1 -1
  13. package/dist/accessory/onoff/lightbulb.d.ts +9 -17
  14. package/dist/accessory/onoff/lightbulb.js +51 -76
  15. package/dist/accessory/onoff/lightbulb.js.map +1 -1
  16. package/dist/accessory/onoff/onoff.d.ts +4 -5
  17. package/dist/accessory/onoff/onoff.js +28 -29
  18. package/dist/accessory/onoff/onoff.js.map +1 -1
  19. package/dist/accessory/onoff/outlet.d.ts +1 -5
  20. package/dist/accessory/onoff/outlet.js +9 -41
  21. package/dist/accessory/onoff/outlet.js.map +1 -1
  22. package/dist/accessory/onoff/switch.js.map +1 -1
  23. package/dist/accessory/security.d.ts +2 -7
  24. package/dist/accessory/security.js +44 -81
  25. package/dist/accessory/security.js.map +1 -1
  26. package/dist/accessory/temperatureSensor.d.ts +1 -2
  27. package/dist/accessory/temperatureSensor.js +6 -8
  28. package/dist/accessory/temperatureSensor.js.map +1 -1
  29. package/dist/homebridge/platform.js +7 -6
  30. package/dist/homebridge/platform.js.map +1 -1
  31. package/dist/homebridge-ui/public/index.html +2 -2
  32. package/dist/homebridge-ui/public/ui.js +1 -1
  33. package/dist/i18n/en.d.ts +11 -8
  34. package/dist/i18n/en.js +53 -50
  35. package/dist/i18n/en.js.map +1 -1
  36. package/dist/i18n/i18n.d.ts +11 -8
  37. package/dist/i18n/template.d.ts +11 -8
  38. package/dist/model/enums.d.ts +23 -0
  39. package/dist/model/enums.js +25 -0
  40. package/dist/model/enums.js.map +1 -1
  41. package/dist/model/mqtt.d.ts +3 -3
  42. package/dist/model/mqtt.js.map +1 -1
  43. package/dist/model/types.d.ts +8 -7
  44. package/dist/tools/primitive.d.ts +3 -3
  45. package/dist/tools/primitive.js.map +1 -1
  46. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  All notable changes to homebridge-dummy will be documented in this file.
4
4
 
5
- ## 1.2.0-beta.0 (2025-08-26)
5
+ ## 1.2.0-beta.1 (2025-08-??)
6
6
 
7
7
  ### HELP NEEDED! (no coding experience required)
8
8
 
@@ -11,8 +11,18 @@ Would you like to see Homebridge Easy MQTT in your language? Please consider [ge
11
11
  ### Added
12
12
  - Security System accessory type
13
13
 
14
+ ### Fixed
15
+ - Allow raw strings in mqtt messages
16
+ - Changing accessory type cleans up old Homebridge accessories
17
+
14
18
  ### Changed
15
19
  - Updated dev dependencies
20
+ - Significant under-the-hood refactoring to speed future development
21
+ - Removed in-use setter topic for outlet since it is not user modifyable
22
+ - Deprecated inconsistent LockMechanism topic names
23
+ - topicGetLockCurrentState -> topicGetCurrentLockState
24
+ - topicGetLockTargetState -> topicGetTargetLockState
25
+ - topicSetTargetState -> topicSetTargetLockState
16
26
 
17
27
  ## 1.1.0 (2025-08-20)
18
28
 
package/README.md CHANGED
@@ -50,9 +50,9 @@ Using the Homebridge Config UI is the easiest way to set up this plugin. However
50
50
  "options": "string"
51
51
  },
52
52
  "topicGetStatusActive": "string",
53
- "topicGetLockCurrentState": "string",
54
- "topicGetLockTargetState": "string",
55
- "topicSetTargetState": "string",
53
+ "topicGetCurrentLockState": "string",
54
+ "topicGetTargetLockState": "string",
55
+ "topicSetTargetLockState": "string",
56
56
  "topicGetOn": "string",
57
57
  "topicSetOn": "string",
58
58
  "valueStatusActive": "string",
@@ -107,15 +107,14 @@ You may define topics using a JSONPath dot notation to assist the parser in find
107
107
  - `topicSetSaturation` - (Optional) For setting the saturation setting of the lightbulb
108
108
 
109
109
  - LockMechanism
110
- - `topicGetLockCurrentState` - The current state of the lock, i.e. locked/unlocked
111
- - `topicGetLockTargetState` - The target (i.e. desired) state of the lock
112
- - `topicSetTargetState` - For setting the target (i.e. desired) state of the lock
110
+ - `topicGetCurrentLockState` - The current state of the lock, i.e. locked/unlocked
111
+ - `topicGetTargetLockState` - The target (i.e. desired) state of the lock
112
+ - `topicSetTargetLockState` - For setting the target (i.e. desired) state of the lock
113
113
 
114
114
  - Outlet
115
115
  - `topicGetOn` - The current state of the outlet, i.e. on/off
116
116
  - `topicSetOn` - For setting the state of the outlet
117
117
  - `topicGetOutletInUse` - (Optional) Whether or not the outlet is currently being used
118
- - `topicSetOutletInUse` - (Optional) For setting whether the outlet is currently being used
119
118
 
120
119
  - SecuitySystem
121
120
  - `topicGetCurrentSecurityState` — The current state of the system
@@ -152,7 +151,6 @@ As with Topics, you will need to populate the appropriate values based on the ty
152
151
  - `valueOn` - Turned on, e.g. "true", or "1", or "On"
153
152
  - `valueOff` - Turned off, e.g. "false", or "0", or "Off"
154
153
  - `valueOutletInUse` - Currently being used, e.g. "true", or "1", or "On"
155
- - `valueOutletNotInUse` - Currently not being used, e.g. "false", or "0", or "Off"
156
154
 
157
155
  - SecuritySystem
158
156
  - `valueArmStay` — (Optional) system armed in stay mode, e.g. "SA" or "stay"
@@ -122,17 +122,17 @@
122
122
  "type": "string",
123
123
  "title": "${config.title.topicSetSaturation}"
124
124
  },
125
- "topicGetLockCurrentState": {
125
+ "topicGetCurrentLockState": {
126
126
  "type": "string",
127
- "title": "${config.title.topicGetLockCurrentState}"
127
+ "title": "${config.title.topicGetCurrentLockState}"
128
128
  },
129
- "topicGetLockTargetState": {
129
+ "topicGetTargetLockState": {
130
130
  "type": "string",
131
- "title": "${config.title.topicGetLockTargetState}"
131
+ "title": "${config.title.topicGetTargetLockState}"
132
132
  },
133
- "topicSetTargetState": {
133
+ "topicSetTargetLockState": {
134
134
  "type": "string",
135
- "title": "${config.title.topicSetTargetState}"
135
+ "title": "${config.title.topicSetTargetLockState}"
136
136
  },
137
137
  "topicGetOn": {
138
138
  "type": "string",
@@ -146,10 +146,6 @@
146
146
  "type": "string",
147
147
  "title": "${config.title.topicGetOutletInUse}"
148
148
  },
149
- "topicSetOutletInUse": {
150
- "type": "string",
151
- "title": "${config.title.topicSetOutletInUse}"
152
- },
153
149
  "topicGetCurrentTemperature": {
154
150
  "type": "string",
155
151
  "title": "${config.title.topicGetCurrentTemperature}"
@@ -176,8 +172,7 @@
176
172
  },
177
173
  "valueStatusActive": {
178
174
  "type": "string",
179
- "title": "${config.title.valueStatusActive}",
180
- "description": "${config.description.valueStatusActive}"
175
+ "title": "${config.title.valueStatusActive}"
181
176
  },
182
177
  "valueLockStateSecured": {
183
178
  "type": "string",
@@ -203,10 +198,6 @@
203
198
  "type": "string",
204
199
  "title": "${config.title.valueOutletInUse}"
205
200
  },
206
- "valueOutletNotInUse": {
207
- "type": "string",
208
- "title": "${config.title.valueOutletNotInUse}"
209
- },
210
201
  "valueArmStay": {
211
202
  "type": "string",
212
203
  "title": "${config.title.valueArmStay}"
@@ -344,9 +335,9 @@
344
335
  "type": "fieldset",
345
336
  "notitle": "true",
346
337
  "items": [
347
- "accessories[].topicGetLockCurrentState",
348
- "accessories[].topicGetLockTargetState",
349
- "accessories[].topicSetTargetState"
338
+ "accessories[].topicGetCurrentLockState",
339
+ "accessories[].topicGetTargetLockState",
340
+ "accessories[].topicSetTargetLockState"
350
341
  ],
351
342
  "condition": {
352
343
  "functionBody": "return model.accessories?.[arguments[1]]?.info?.type === 'LockMechanism';"
@@ -384,8 +375,7 @@
384
375
  "type": "fieldset",
385
376
  "notitle": "true",
386
377
  "items": [
387
- "accessories[].topicGetOutletInUse",
388
- "accessories[].topicSetOutletInUse"
378
+ "accessories[].topicGetOutletInUse"
389
379
  ],
390
380
  "condition": {
391
381
  "functionBody": "return model.accessories?.[arguments[1]]?.info?.type === 'Outlet';"
@@ -485,10 +475,6 @@
485
475
  {
486
476
  "key": "accessories[].valueOutletInUse",
487
477
  "flex": "0 0 25%"
488
- },
489
- {
490
- "key": "accessories[].valueOutletNotInUse",
491
- "flex": "0 0 25%"
492
478
  }
493
479
  ]
494
480
  },
@@ -550,7 +536,7 @@
550
536
  "items": [
551
537
  {
552
538
  "key": "accessories[].valueStatusActive",
553
- "flex": "0 0 50%"
539
+ "flex": "0 0 25%"
554
540
  }
555
541
  ]
556
542
  }
@@ -1,12 +1,7 @@
1
- import { PlatformAccessory } from 'homebridge';
1
+ import { Characteristic, CharacteristicGetHandler, CharacteristicSetHandler, CharacteristicValue, PlatformAccessory, PrimitiveTypes, Service, WithUUID } from 'homebridge';
2
+ import { CharacteristicKey } from '../../model/enums.js';
2
3
  import { AccessoryConfig, CharacteristicType, ServiceType } from '../../model/types.js';
3
4
  import { Log } from '../../tools/log.js';
4
- import { Primitive } from '../../tools/primitive.js';
5
- export type TopicHandler = {
6
- topic: string;
7
- handler: ((topic: string, value: Primitive) => Promise<void>);
8
- };
9
- export declare function makeHandler(topic: string, handler: (topic: string, value: Primitive) => Promise<void>): TopicHandler;
10
5
  export declare abstract class MQTTAccessory<C extends AccessoryConfig> {
11
6
  protected readonly Service: ServiceType;
12
7
  protected readonly Characteristic: CharacteristicType;
@@ -14,12 +9,27 @@ export declare abstract class MQTTAccessory<C extends AccessoryConfig> {
14
9
  protected readonly config: C;
15
10
  protected readonly log: Log;
16
11
  private readonly mqttClient;
12
+ private readonly properties;
13
+ private readonly topicHandlers;
14
+ protected readonly accessoryService: Service;
17
15
  constructor(Service: ServiceType, Characteristic: CharacteristicType, accessory: PlatformAccessory, config: C, log: Log, caller: string);
18
16
  private onMQTTConnect;
19
- protected abstract get topicHandlers(): TopicHandler[];
17
+ protected abstract getAccessoryService(): Service;
18
+ protected bind(constructor: WithUUID<{
19
+ new (): Characteristic;
20
+ }>, getTopic: keyof C, getHandler: CharacteristicGetHandler, setTopic?: keyof C | undefined, setHandler?: CharacteristicSetHandler | undefined): void;
21
+ protected abstract addTopicHandlers(): void;
22
+ protected addTopicHandler(topicKey: keyof C, handler: (topic: string, value: PrimitiveTypes) => Promise<void>, assert?: boolean): void;
20
23
  protected get name(): string;
21
- protected publish(topic: string, value: Primitive): void;
24
+ protected getRawValue(property: keyof C, assert?: boolean): string | undefined;
25
+ protected getPrimitiveValue(property: keyof C, assert?: boolean): PrimitiveTypes | undefined;
26
+ protected publish(topic: string, value: PrimitiveTypes): void;
22
27
  teardown(): void;
23
- protected assert(...keys: (keyof any)[]): boolean;
28
+ protected get(key: CharacteristicKey): CharacteristicValue;
29
+ protected set(key: CharacteristicKey, value: CharacteristicValue): void;
30
+ protected assert(...keys: (keyof C)[]): boolean;
31
+ protected assertNumber(value: PrimitiveTypes, error: string): boolean;
32
+ protected onUpdate(key: CharacteristicKey, value: CharacteristicValue, logString?: string | undefined): boolean;
33
+ protected onSet(key: CharacteristicKey, value: CharacteristicValue, publish: PrimitiveTypes, topic: keyof C, logString: string | undefined): void;
24
34
  protected logIfDesired(message: string, ...parameters: string[]): void;
25
35
  }
@@ -1,10 +1,9 @@
1
1
  import { PLATFORM_NAME } from '../../homebridge/settings.js';
2
+ import { AccessoryType } from '../../model/enums.js';
2
3
  import { MQTT } from '../../model/mqtt.js';
3
4
  import getVersion from '../../tools/version.js';
4
5
  import { assert } from '../../tools/validation.js';
5
- export function makeHandler(topic, handler) {
6
- return { topic, handler };
7
- }
6
+ import { toPrimitive } from '../../tools/primitive.js';
8
7
  export class MQTTAccessory {
9
8
  Service;
10
9
  Characteristic;
@@ -12,6 +11,9 @@ export class MQTTAccessory {
12
11
  config;
13
12
  log;
14
13
  mqttClient;
14
+ properties = {};
15
+ topicHandlers = [];
16
+ accessoryService;
15
17
  constructor(Service, Characteristic, accessory, config, log, caller) {
16
18
  this.Service = Service;
17
19
  this.Characteristic = Characteristic;
@@ -30,25 +32,111 @@ export class MQTTAccessory {
30
32
  .setCharacteristic(Characteristic.SerialNumber, config.info.serialNumber ?? `${PLATFORM_NAME}:${name}`)
31
33
  .setCharacteristic(Characteristic.Model, config.info.model ?? caller)
32
34
  .setCharacteristic(Characteristic.FirmwareRevision, config.info.version ?? getVersion());
35
+ this.accessoryService = this.getAccessoryService();
36
+ for (const type of Object.values(AccessoryType)) {
37
+ const existingService = accessory.getService(Service[type]);
38
+ if (existingService && type !== config.info.type) {
39
+ accessory.removeService(existingService);
40
+ }
41
+ }
42
+ this.addTopicHandlers();
33
43
  }
34
44
  async onMQTTConnect() {
35
45
  this.topicHandlers.forEach(topicHandler => {
36
46
  this.mqttClient?.subscribe(topicHandler.topic, topicHandler.handler);
37
47
  });
38
48
  }
49
+ bind(constructor, getTopic, getHandler, setTopic = undefined, setHandler = undefined) {
50
+ if (this.config[getTopic] === undefined && (setTopic === undefined || setHandler === undefined || this.config[setTopic] !== undefined)) {
51
+ for (const characteristic of this.accessoryService.characteristics) {
52
+ if (characteristic.UUID === constructor.UUID) {
53
+ this.accessoryService.removeCharacteristic(characteristic);
54
+ break;
55
+ }
56
+ }
57
+ return;
58
+ }
59
+ const characteristic = this.accessoryService.getCharacteristic(constructor);
60
+ if (this.config[getTopic] !== undefined) {
61
+ characteristic.onGet(getHandler);
62
+ }
63
+ if (setTopic !== undefined && setHandler !== undefined && this.config[setTopic] !== undefined) {
64
+ characteristic.onSet(setHandler);
65
+ }
66
+ }
67
+ addTopicHandler(topicKey, handler, assert = true) {
68
+ if (!topicKey.toString().startsWith('topic')) {
69
+ throw new Error(`Trying to fetch topic with unexpected property name '${topicKey.toString()}'`);
70
+ }
71
+ if (assert && !this.assert(topicKey)) {
72
+ return;
73
+ }
74
+ const topic = this.config[topicKey];
75
+ if (topic === undefined) {
76
+ return;
77
+ }
78
+ this.topicHandlers.push({ topic: topic, handler });
79
+ }
39
80
  get name() {
40
81
  return this.config.info.name;
41
82
  }
83
+ getRawValue(property, assert = true) {
84
+ if (!property.toString().startsWith('value')) {
85
+ throw new Error(`Trying to fetch value with unexpected property name '${property.toString()}'`);
86
+ }
87
+ if (assert && !this.assert(property)) {
88
+ return;
89
+ }
90
+ return this.config[property];
91
+ }
92
+ getPrimitiveValue(property, assert = true) {
93
+ const stringValue = this.getRawValue(property, assert);
94
+ return stringValue ? toPrimitive(stringValue) : undefined;
95
+ }
42
96
  publish(topic, value) {
43
97
  this.mqttClient?.publish(topic, value);
44
98
  }
45
99
  teardown() {
46
100
  this.mqttClient?.teardown();
47
101
  }
48
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
102
+ get(key) {
103
+ return this.properties[key];
104
+ }
105
+ set(key, value) {
106
+ this.properties[key] = value;
107
+ }
49
108
  assert(...keys) {
50
109
  return assert(this.log, this.name, this.config, ...keys);
51
110
  }
111
+ assertNumber(value, error) {
112
+ if (typeof value === 'number') {
113
+ return true;
114
+ }
115
+ this.log.error(error, this.name, `'${value}'`);
116
+ return false;
117
+ }
118
+ onUpdate(key, value, logString = undefined) {
119
+ if (value === this.get(key)) {
120
+ return false;
121
+ }
122
+ this.set(key, value);
123
+ this.accessoryService.updateCharacteristic(this.Characteristic[key], value);
124
+ if (logString) {
125
+ this.logIfDesired(logString);
126
+ }
127
+ return true;
128
+ }
129
+ onSet(key, value, publish, topic, logString) {
130
+ if (!this.assert(topic)) {
131
+ return;
132
+ }
133
+ if (logString && value !== this.get(key)) {
134
+ this.logIfDesired(logString);
135
+ }
136
+ this.set(key, value);
137
+ this.accessoryService.updateCharacteristic(this.Characteristic[key], value);
138
+ this.publish(this.config[topic], publish);
139
+ }
52
140
  logIfDesired(message, ...parameters) {
53
141
  if (this.config.disableLogging) {
54
142
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/accessory/abstract/base.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE7D,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAK3C,OAAO,UAAU,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AAInD,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,OAA2D;IACpG,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,OAAgB,aAAa;IAKZ;IACA;IACA;IACA;IACA;IAPJ,UAAU,CAAmB;IAE9C,YACqB,OAAoB,EACpB,cAAkC,EAClC,SAA4B,EAC5B,MAAS,EACT,GAAQ,EAC3B,MAAc;QALK,YAAO,GAAP,OAAO,CAAa;QACpB,mBAAc,GAAd,cAAc,CAAoB;QAClC,cAAS,GAAT,SAAS,CAAmB;QAC5B,WAAM,GAAN,MAAM,CAAG;QACT,QAAG,GAAH,GAAG,CAAK;QAI3B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;QAE9B,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,IAAI,CAAC,UAAU,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;YAClF,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;QAC5B,CAAC;QAED,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,oBAAoB,CAAE;aAChD,iBAAiB,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC;aAC5C,iBAAiB,CAAC,cAAc,CAAC,cAAc,EAAE,IAAI,CAAC;aACtD,iBAAiB,CAAC,cAAc,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC;aACxF,iBAAiB,CAAC,cAAc,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,YAAY,IAAI,GAAG,aAAa,IAAI,IAAI,EAAE,CAAC;aACtG,iBAAiB,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC;aACpE,iBAAiB,CAAC,cAAc,CAAC,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,UAAU,EAAE,CAAC,CAAC;IAC7F,CAAC;IAEO,KAAK,CAAC,aAAa;QACzB,IAAI,CAAC,aAAa,CAAC,OAAO,CAAE,YAAY,CAAC,EAAE;YACzC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;QACvE,CAAC,CAAC,CAAC;IACL,CAAC;IAID,IAAc,IAAI;QAChB,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;IAC/B,CAAC;IAES,OAAO,CAAC,KAAa,EAAE,KAAgB;QAC/C,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACzC,CAAC;IAEM,QAAQ;QACb,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAED,8DAA8D;IACpD,MAAM,CAAC,GAAG,IAAmB;QACrC,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;IAC3D,CAAC;IAES,YAAY,CAAC,OAAe,EAAE,GAAG,UAAoB;QAE7D,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;YAC/B,OAAO;QACT,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,UAAU,CAAC,CAAC;IACrD,CAAC;CACF"}
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/accessory/abstract/base.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,10 @@
1
- import { PlatformAccessory, Service } from 'homebridge';
2
- import { MQTTAccessory, TopicHandler } from './base.js';
1
+ import { PlatformAccessory } from 'homebridge';
2
+ import { MQTTAccessory } from './base.js';
3
3
  import { CharacteristicType, StatusActiveConfig, ServiceType } from '../../model/types.js';
4
4
  import { Log } from '../../tools/log.js';
5
5
  export declare abstract class StatusActiveAccessory<C extends StatusActiveConfig = StatusActiveConfig> extends MQTTAccessory<C> {
6
- protected readonly accessoryService: Service;
7
- private statusActive;
8
6
  constructor(Service: ServiceType, Characteristic: CharacteristicType, accessory: PlatformAccessory, config: C, log: Log, className: string);
9
- protected abstract getAccessoryService(): Service;
10
- protected get topicHandlers(): TopicHandler[];
11
- private onStatusActiveUpdate;
7
+ protected addTopicHandlers(): void;
12
8
  private getStatusActive;
9
+ private onStatusActiveUpdate;
13
10
  }
@@ -1,39 +1,29 @@
1
- import { makeHandler, MQTTAccessory } from './base.js';
1
+ import { MQTTAccessory } from './base.js';
2
2
  import { strings } from '../../i18n/i18n.js';
3
- import { toPrimitive } from '../../tools/primitive.js';
3
+ import { CharacteristicKey } from '../../model/enums.js';
4
4
  export class StatusActiveAccessory extends MQTTAccessory {
5
- accessoryService;
6
- statusActive = true;
7
5
  constructor(Service, Characteristic, accessory, config, log, className) {
8
6
  super(Service, Characteristic, accessory, config, log, className);
9
- this.accessoryService = this.getAccessoryService();
10
- this.accessoryService.getCharacteristic(Characteristic.StatusActive)
11
- .onGet(this.getStatusActive.bind(this));
7
+ this.set(CharacteristicKey.StatusActive, true);
8
+ this.bind(Characteristic.StatusActive, 'topicGetStatusActive', this.getStatusActive.bind(this));
12
9
  }
13
- get topicHandlers() {
14
- return [
15
- ...(this.config.topicGetStatusActive ? [makeHandler(this.config.topicGetStatusActive, this.onStatusActiveUpdate.bind(this))] : []),
16
- ];
10
+ addTopicHandlers() {
11
+ this.addTopicHandler('topicGetStatusActive', this.onStatusActiveUpdate.bind(this), false);
12
+ }
13
+ async getStatusActive() {
14
+ return this.get(CharacteristicKey.StatusActive);
17
15
  }
18
16
  async onStatusActiveUpdate(topic, value) {
19
- if (!this.assert('valueStatusActive')) {
20
- return;
21
- }
22
- const statusActive = value === toPrimitive(this.config.valueStatusActive);
23
- if (statusActive === this.statusActive) {
17
+ const statusActive = value === this.getPrimitiveValue('valueStatusActive');
18
+ if (!this.onUpdate(CharacteristicKey.StatusActive, statusActive)) {
24
19
  return;
25
20
  }
26
- this.statusActive = statusActive;
27
- this.accessoryService.updateCharacteristic(this.Characteristic.StatusActive, this.statusActive);
28
- if (this.statusActive) {
21
+ if (statusActive) {
29
22
  this.logIfDesired(strings.accessory.statusActive);
30
23
  }
31
24
  else {
32
25
  this.log.warning(strings.accessory.statusInactive, this.name);
33
26
  }
34
27
  }
35
- async getStatusActive() {
36
- return this.statusActive;
37
- }
38
28
  }
39
29
  //# sourceMappingURL=statusActive.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"statusActive.js","sourceRoot":"","sources":["../../../src/accessory/abstract/statusActive.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAgB,MAAM,WAAW,CAAC;AAErE,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAK7C,OAAO,EAAa,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAElE,MAAM,OAAgB,qBAAyE,SAAQ,aAAgB;IAClG,gBAAgB,CAAU;IAErC,YAAY,GAAwB,IAAI,CAAC;IAEjD,YACE,OAAoB,EACpB,cAAkC,EAClC,SAA4B,EAC5B,MAAS,EACT,GAAQ,EACR,SAAiB;QAEjB,KAAK,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC;QAElE,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAEnD,IAAI,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,cAAc,CAAC,YAAY,CAAC;aACjE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5C,CAAC;IAID,IAAc,aAAa;QACzB,OAAO;YACL,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,oBAAoB,EAAE,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA,CAAC,CAAC,EAAE,CAAC;SAClI,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,oBAAoB,CAAC,KAAa,EAAE,KAAgB;QAEhE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,CAAC;YACtC,OAAO;QACT,CAAC;QAED,MAAM,YAAY,GAAG,KAAK,KAAK,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;QAC1E,IAAI,YAAY,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;YACvC,OAAO;QACT,CAAC;QAED,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAEhG,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACpD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,eAAe;QAC3B,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;CACF"}
1
+ {"version":3,"file":"statusActive.js","sourceRoot":"","sources":["../../../src/accessory/abstract/statusActive.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAKzD,MAAM,OAAgB,qBAAyE,SAAQ,aAAgB;IAErH,YAAY,OAAoB,EAAE,cAAkC,EAAE,SAA4B,EAAE,MAAS,EAAE,GAAQ,EAAE,SAAiB;QACxI,KAAK,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC;QAElE,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QAE/C,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,sBAAsB,EAAE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAClG,CAAC;IAES,gBAAgB;QACxB,IAAI,CAAC,eAAe,CAAC,sBAAsB,EAAE,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;IAC5F,CAAC;IAEO,KAAK,CAAC,eAAe;QAC3B,OAAO,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAClD,CAAC;IAEO,KAAK,CAAC,oBAAoB,CAAC,KAAa,EAAE,KAAqB;QAErE,MAAM,YAAY,GAAG,KAAK,KAAK,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,CAAC;QAC3E,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,YAAY,EAAE,YAAY,CAAC,EAAE,CAAC;YACjE,OAAO;QACT,CAAC;QAED,IAAI,YAAY,EAAE,CAAC;YACjB,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACpD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;CACF"}
@@ -1,21 +1,18 @@
1
1
  import { PlatformAccessory, Service } from 'homebridge';
2
- import { TopicHandler } from './abstract/base.js';
3
2
  import { StatusActiveAccessory } from './abstract/statusActive.js';
4
3
  import { CharacteristicType, LockMechanismConfig, ServiceType } from '../model/types.js';
5
4
  import { Log } from '../tools/log.js';
6
5
  export declare class LockMechanismAccessory extends StatusActiveAccessory<LockMechanismConfig> {
7
- private currentState;
8
- private targetState;
9
6
  constructor(Service: ServiceType, Characteristic: CharacteristicType, accessory: PlatformAccessory, config: LockMechanismConfig, log: Log);
10
7
  protected getAccessoryService(): Service;
11
- get topicHandlers(): TopicHandler[];
8
+ addTopicHandlers(): void;
12
9
  private getCurrentState;
13
10
  private getTargetState;
14
11
  private onCurrentStateUpdate;
15
12
  private onTargetStateUpdate;
16
- private setTargetState;
17
- private valueFromTargetState;
13
+ private onSetTargetState;
18
14
  private currentStateFromValue;
19
15
  private targetStateFromValue;
16
+ private valueFromTargetState;
20
17
  private stringForState;
21
18
  }
@@ -1,119 +1,110 @@
1
- import { makeHandler } from './abstract/base.js';
2
1
  import { StatusActiveAccessory } from './abstract/statusActive.js';
3
2
  import { strings } from '../i18n/i18n.js';
4
- import { toPrimitive } from '../tools/primitive.js';
3
+ import { CharacteristicKey } from '../model/enums.js';
5
4
  export class LockMechanismAccessory extends StatusActiveAccessory {
6
- currentState;
7
- targetState;
8
5
  constructor(Service, Characteristic, accessory, config, log) {
9
6
  super(Service, Characteristic, accessory, config, log, LockMechanismAccessory.name);
10
- this.currentState = this.Characteristic.LockCurrentState.UNKNOWN;
11
- this.targetState = this.Characteristic.LockTargetState.SECURED;
7
+ this.set(CharacteristicKey.LockCurrentState, Characteristic.LockCurrentState.UNKNOWN);
8
+ this.set(CharacteristicKey.LockTargetState, Characteristic.LockTargetState.SECURED);
12
9
  this.accessoryService.getCharacteristic(this.Characteristic.LockCurrentState)
13
10
  .onGet(this.getCurrentState.bind(this));
14
11
  this.accessoryService.getCharacteristic(this.Characteristic.LockTargetState)
15
12
  .onGet(this.getTargetState.bind(this))
16
- .onSet(this.setTargetState.bind(this));
13
+ .onSet(this.onSetTargetState.bind(this));
17
14
  }
18
15
  getAccessoryService() {
19
16
  return this.accessory.getService(this.Service.LockMechanism) || this.accessory.addService(this.Service.LockMechanism);
20
17
  }
21
- get topicHandlers() {
22
- const topicHandlers = super.topicHandlers;
23
- if (!this.assert('topicGetLockCurrentState', 'topicGetLockTargetState')) {
24
- return topicHandlers;
25
- }
26
- topicHandlers.push(makeHandler(this.config.topicGetLockCurrentState, this.onCurrentStateUpdate.bind(this)));
27
- topicHandlers.push(makeHandler(this.config.topicGetLockTargetState, this.onTargetStateUpdate.bind(this)));
28
- return topicHandlers;
18
+ addTopicHandlers() {
19
+ super.addTopicHandlers();
20
+ if (this.config.topicGetLockCurrentState !== undefined && this.config.topicGetCurrentLockState === undefined) {
21
+ this.addTopicHandler('topicGetLockCurrentState', this.onCurrentStateUpdate.bind(this));
22
+ }
23
+ else {
24
+ this.addTopicHandler('topicGetCurrentLockState', this.onCurrentStateUpdate.bind(this));
25
+ }
26
+ if (this.config.topicGetLockTargetState !== undefined && this.config.topicGetTargetLockState === undefined) {
27
+ this.addTopicHandler('topicGetLockTargetState', this.onCurrentStateUpdate.bind(this));
28
+ }
29
+ else {
30
+ this.addTopicHandler('topicGetTargetLockState', this.onCurrentStateUpdate.bind(this));
31
+ }
29
32
  }
30
33
  async getCurrentState() {
31
- return this.currentState;
34
+ return this.get(CharacteristicKey.LockCurrentState);
32
35
  }
33
36
  async getTargetState() {
34
- return this.targetState;
37
+ return this.get(CharacteristicKey.LockTargetState);
35
38
  }
36
39
  async onCurrentStateUpdate(topic, value) {
37
40
  const current = this.currentStateFromValue(value);
38
- if (current === this.currentState) {
41
+ if (current <= this.Characteristic.LockTargetState.SECURED) {
42
+ this.onUpdate(CharacteristicKey.LockTargetState, current);
43
+ }
44
+ if (!this.onUpdate(CharacteristicKey.LockCurrentState, current)) {
39
45
  return;
40
46
  }
41
- this.currentState = current;
42
- this.accessoryService.updateCharacteristic(this.Characteristic.LockCurrentState, this.currentState);
43
- this.targetState = this.currentState;
44
- this.accessoryService.updateCharacteristic(this.Characteristic.LockTargetState, this.targetState);
45
- if (this.currentState === this.Characteristic.LockCurrentState.JAMMED) {
46
- this.log.error(this.stringForState(this.currentState), this.name);
47
+ if (current === this.Characteristic.LockCurrentState.JAMMED) {
48
+ this.log.error(this.stringForState(current), this.name);
47
49
  }
48
50
  else {
49
- this.logIfDesired(this.stringForState(this.currentState));
51
+ this.logIfDesired(this.stringForState(current));
50
52
  }
51
53
  }
52
54
  async onTargetStateUpdate(topic, value) {
53
55
  const target = this.targetStateFromValue(value);
54
- if (target === this.targetState) {
55
- return;
56
- }
57
- this.targetState = target;
58
- this.accessoryService.updateCharacteristic(this.Characteristic.LockTargetState, this.targetState);
59
- this.logIfDesired(this.stringForState(this.targetState, true));
56
+ this.onUpdate(CharacteristicKey.LockTargetState, target, this.stringForState(target, true));
60
57
  }
61
- async setTargetState(value) {
62
- if (!this.assert('topicSetTargetState')) {
63
- return;
64
- }
58
+ async onSetTargetState(value) {
65
59
  const target = this.valueFromTargetState(value);
66
60
  if (target === undefined) {
67
- this.log.error(strings.lock.badTarget, this.name, value);
68
61
  return;
69
62
  }
70
- if (this.targetState !== value) {
71
- this.logIfDesired(this.stringForState(value, true));
72
- }
73
- this.targetState = value;
74
- this.accessoryService.updateCharacteristic(this.Characteristic.LockTargetState, this.targetState);
75
- this.publish(this.config.topicSetTargetState, target);
76
- }
77
- valueFromTargetState(value) {
78
- if (value === undefined || !this.assert('valueLockStateSecured', 'valueLockStateUnsecured')) {
79
- return undefined;
63
+ if (this.config.topicSetTargetState !== undefined && this.config.topicSetTargetLockState === undefined) {
64
+ this.onSet(CharacteristicKey.LockTargetState, value, target, 'topicSetTargetState', this.stringForState(value, true));
80
65
  }
81
- switch (value) {
82
- case this.Characteristic.LockTargetState.SECURED:
83
- return toPrimitive(this.config.valueLockStateSecured);
84
- case this.Characteristic.LockTargetState.UNSECURED:
85
- return toPrimitive(this.config.valueLockStateUnsecured);
86
- default:
87
- return undefined;
66
+ else {
67
+ this.onSet(CharacteristicKey.LockTargetState, value, target, 'topicSetTargetLockState', this.stringForState(value, true));
88
68
  }
89
69
  }
90
70
  currentStateFromValue(value) {
91
- if (value === undefined || !this.assert('valueLockStateSecured', 'valueLockStateUnsecured')) {
71
+ if (value === undefined) {
92
72
  return this.Characteristic.LockCurrentState.UNKNOWN;
93
73
  }
94
74
  switch (value) {
95
- case toPrimitive(this.config.valueLockStateSecured):
75
+ case this.getPrimitiveValue('valueLockStateSecured'):
96
76
  return this.Characteristic.LockCurrentState.SECURED;
97
- case toPrimitive(this.config.valueLockStateUnsecured):
77
+ case this.getPrimitiveValue('valueLockStateUnsecured'):
98
78
  return this.Characteristic.LockCurrentState.UNSECURED;
99
- case toPrimitive(this.config.valueLockStateJammed):
79
+ case this.getPrimitiveValue('valueLockStateJammed', false):
100
80
  return this.Characteristic.LockCurrentState.JAMMED;
101
81
  default:
102
82
  return this.Characteristic.LockCurrentState.UNKNOWN;
103
83
  }
104
84
  }
105
85
  targetStateFromValue(value) {
106
- if (value === undefined || !this.assert('valueLockStateSecured', 'valueLockStateUnsecured')) {
86
+ if (value === undefined) {
107
87
  return this.Characteristic.LockTargetState.SECURED;
108
88
  }
109
89
  switch (value) {
110
- case toPrimitive(this.config.valueLockStateUnsecured):
90
+ case this.getPrimitiveValue('valueLockStateUnsecured'):
111
91
  return this.Characteristic.LockTargetState.UNSECURED;
112
- case toPrimitive(this.config.valueLockStateSecured):
92
+ case this.getPrimitiveValue('valueLockStateSecured'):
113
93
  default:
114
94
  return this.Characteristic.LockTargetState.SECURED;
115
95
  }
116
96
  }
97
+ valueFromTargetState(value) {
98
+ switch (value) {
99
+ case this.Characteristic.LockTargetState.SECURED:
100
+ return this.getPrimitiveValue('valueLockStateSecured');
101
+ case this.Characteristic.LockTargetState.UNSECURED:
102
+ return this.getPrimitiveValue('valueLockStateUnsecured');
103
+ default:
104
+ this.log.error(strings.lock.badTarget, this.name, `'${value}'`);
105
+ return undefined;
106
+ }
107
+ }
117
108
  stringForState(state, future = false) {
118
109
  switch (state) {
119
110
  case this.Characteristic.LockCurrentState.SECURED: