homebridge-plugin-klares4 1.1.7-beta1

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 (65) hide show
  1. package/CHANGELOG.md +238 -0
  2. package/LICENSE +21 -0
  3. package/README.md +495 -0
  4. package/config.schema.json +801 -0
  5. package/dist/accessories/cover-accessory.d.ts +26 -0
  6. package/dist/accessories/cover-accessory.d.ts.map +1 -0
  7. package/dist/accessories/cover-accessory.js +134 -0
  8. package/dist/accessories/cover-accessory.js.map +1 -0
  9. package/dist/accessories/gate-accessory.d.ts +20 -0
  10. package/dist/accessories/gate-accessory.d.ts.map +1 -0
  11. package/dist/accessories/gate-accessory.js +70 -0
  12. package/dist/accessories/gate-accessory.js.map +1 -0
  13. package/dist/accessories/light-accessory.d.ts +20 -0
  14. package/dist/accessories/light-accessory.d.ts.map +1 -0
  15. package/dist/accessories/light-accessory.js +81 -0
  16. package/dist/accessories/light-accessory.js.map +1 -0
  17. package/dist/accessories/scenario-accessory.d.ts +17 -0
  18. package/dist/accessories/scenario-accessory.d.ts.map +1 -0
  19. package/dist/accessories/scenario-accessory.js +59 -0
  20. package/dist/accessories/scenario-accessory.js.map +1 -0
  21. package/dist/accessories/sensor-accessory.d.ts +28 -0
  22. package/dist/accessories/sensor-accessory.d.ts.map +1 -0
  23. package/dist/accessories/sensor-accessory.js +141 -0
  24. package/dist/accessories/sensor-accessory.js.map +1 -0
  25. package/dist/accessories/thermostat-accessory.d.ts +25 -0
  26. package/dist/accessories/thermostat-accessory.d.ts.map +1 -0
  27. package/dist/accessories/thermostat-accessory.js +228 -0
  28. package/dist/accessories/thermostat-accessory.js.map +1 -0
  29. package/dist/accessories/zone-accessory.d.ts +22 -0
  30. package/dist/accessories/zone-accessory.d.ts.map +1 -0
  31. package/dist/accessories/zone-accessory.js +99 -0
  32. package/dist/accessories/zone-accessory.js.map +1 -0
  33. package/dist/debug-capture.d.ts +45 -0
  34. package/dist/debug-capture.d.ts.map +1 -0
  35. package/dist/debug-capture.js +294 -0
  36. package/dist/debug-capture.js.map +1 -0
  37. package/dist/index.d.ts +4 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +7 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/log-levels.d.ts +28 -0
  42. package/dist/log-levels.d.ts.map +1 -0
  43. package/dist/log-levels.js +48 -0
  44. package/dist/log-levels.js.map +1 -0
  45. package/dist/mqtt-bridge.d.ts +33 -0
  46. package/dist/mqtt-bridge.d.ts.map +1 -0
  47. package/dist/mqtt-bridge.js +397 -0
  48. package/dist/mqtt-bridge.js.map +1 -0
  49. package/dist/platform.d.ts +90 -0
  50. package/dist/platform.d.ts.map +1 -0
  51. package/dist/platform.js +517 -0
  52. package/dist/platform.js.map +1 -0
  53. package/dist/settings.d.ts +3 -0
  54. package/dist/settings.d.ts.map +1 -0
  55. package/dist/settings.js +6 -0
  56. package/dist/settings.js.map +1 -0
  57. package/dist/types.d.ts +284 -0
  58. package/dist/types.d.ts.map +1 -0
  59. package/dist/types.js +81 -0
  60. package/dist/types.js.map +1 -0
  61. package/dist/websocket-client.d.ts +69 -0
  62. package/dist/websocket-client.d.ts.map +1 -0
  63. package/dist/websocket-client.js +1068 -0
  64. package/dist/websocket-client.js.map +1 -0
  65. package/package.json +63 -0
@@ -0,0 +1,26 @@
1
+ import type { CharacteristicValue, PlatformAccessory } from 'homebridge';
2
+ import type { Lares4Platform } from '../platform';
3
+ import type { KseniaCover } from '../types';
4
+ /**
5
+ * Cover Accessory Handler
6
+ * Handles HomeKit WindowCovering service for Ksenia Lares4 covers/shutters
7
+ */
8
+ export declare class CoverAccessory {
9
+ private readonly platform;
10
+ private readonly accessory;
11
+ private service;
12
+ device: KseniaCover;
13
+ private targetPosition;
14
+ private currentPosition;
15
+ private positionState;
16
+ private readonly maxSeconds;
17
+ private moveInterval?;
18
+ constructor(platform: Lares4Platform, accessory: PlatformAccessory);
19
+ setTargetPosition(value: CharacteristicValue): Promise<void>;
20
+ getTargetPosition(): Promise<CharacteristicValue>;
21
+ getCurrentPosition(): Promise<CharacteristicValue>;
22
+ getPositionState(): Promise<CharacteristicValue>;
23
+ private simulateMovement;
24
+ updateStatus(newDevice: KseniaCover): void;
25
+ }
26
+ //# sourceMappingURL=cover-accessory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cover-accessory.d.ts","sourceRoot":"","sources":["../../src/accessories/cover-accessory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAW,MAAM,YAAY,CAAC;AAClF,OAAO,KAAK,EAAE,cAAc,EAAgB,MAAM,aAAa,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAe,MAAM,UAAU,CAAC;AAEzD;;;GAGG;AACH,qBAAa,cAAc;IAUnB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAV9B,OAAO,CAAC,OAAO,CAAU;IAClB,MAAM,EAAE,WAAW,CAAC;IAC3B,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,YAAY,CAAC,CAAiC;gBAGjC,QAAQ,EAAE,cAAc,EACxB,SAAS,EAAE,iBAAiB;IAsDpC,iBAAiB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAoC5D,iBAAiB,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAIjD,kBAAkB,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAIlD,gBAAgB,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAI7D,OAAO,CAAC,gBAAgB;IAoDjB,YAAY,CAAC,SAAS,EAAE,WAAW,GAAG,IAAI;CAmCpD"}
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CoverAccessory = void 0;
4
+ /**
5
+ * Cover Accessory Handler
6
+ * Handles HomeKit WindowCovering service for Ksenia Lares4 covers/shutters
7
+ */
8
+ class CoverAccessory {
9
+ constructor(platform, accessory) {
10
+ this.platform = platform;
11
+ this.accessory = accessory;
12
+ this.targetPosition = 0;
13
+ this.currentPosition = 0;
14
+ this.positionState = 2; // 2 = stopped
15
+ this.device = accessory.context.device;
16
+ this.currentPosition = this.device.status?.position ?? 0;
17
+ this.targetPosition = this.device.status?.position ?? 0;
18
+ this.maxSeconds = this.platform.config.maxSeconds ?? 30;
19
+ const accessoryInfoService = this.accessory.getService(this.platform.Service.AccessoryInformation);
20
+ if (accessoryInfoService) {
21
+ accessoryInfoService
22
+ .setCharacteristic(this.platform.Characteristic.Manufacturer, 'Ksenia')
23
+ .setCharacteristic(this.platform.Characteristic.Model, 'Lares4 Cover')
24
+ .setCharacteristic(this.platform.Characteristic.SerialNumber, this.device.id)
25
+ .setCharacteristic(this.platform.Characteristic.FirmwareRevision, '2.0.0');
26
+ }
27
+ this.service =
28
+ this.accessory.getService(this.platform.Service.WindowCovering) ??
29
+ this.accessory.addService(this.platform.Service.WindowCovering);
30
+ this.service.setCharacteristic(this.platform.Characteristic.Name, this.device.name);
31
+ this.service
32
+ .getCharacteristic(this.platform.Characteristic.CurrentPosition)
33
+ .onGet(this.getCurrentPosition.bind(this));
34
+ this.service
35
+ .getCharacteristic(this.platform.Characteristic.PositionState)
36
+ .onGet(this.getPositionState.bind(this));
37
+ this.service
38
+ .getCharacteristic(this.platform.Characteristic.TargetPosition)
39
+ .onSet(this.setTargetPosition.bind(this))
40
+ .onGet(this.getTargetPosition.bind(this));
41
+ const safeCurrentPosition = isNaN(this.currentPosition) ? 0 : this.currentPosition;
42
+ const safeTargetPosition = isNaN(this.targetPosition) ? 0 : this.targetPosition;
43
+ this.service.setCharacteristic(this.platform.Characteristic.CurrentPosition, safeCurrentPosition);
44
+ this.service.setCharacteristic(this.platform.Characteristic.TargetPosition, safeTargetPosition);
45
+ this.service.setCharacteristic(this.platform.Characteristic.PositionState, this.positionState);
46
+ }
47
+ async setTargetPosition(value) {
48
+ const targetPosition = value;
49
+ if (targetPosition === this.currentPosition) {
50
+ return;
51
+ }
52
+ this.targetPosition = targetPosition;
53
+ try {
54
+ if (targetPosition > this.currentPosition) {
55
+ this.positionState = 1; // Opening
56
+ }
57
+ else {
58
+ this.positionState = 0; // Closing
59
+ }
60
+ this.service.updateCharacteristic(this.platform.Characteristic.PositionState, this.positionState);
61
+ await this.platform.wsClient?.moveCover(this.device.id, targetPosition);
62
+ this.platform.log.info(`${this.device.name}: Moving to ${targetPosition}%`);
63
+ this.simulateMovement(targetPosition);
64
+ }
65
+ catch (error) {
66
+ this.platform.log.error(`Cover control error ${this.device.name}:`, error instanceof Error ? error.message : String(error));
67
+ throw new this.platform.api.hap.HapStatusError(-70402 /* this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
68
+ }
69
+ }
70
+ async getTargetPosition() {
71
+ return isNaN(this.targetPosition) ? 0 : this.targetPosition;
72
+ }
73
+ async getCurrentPosition() {
74
+ return isNaN(this.currentPosition) ? 0 : this.currentPosition;
75
+ }
76
+ async getPositionState() {
77
+ return this.positionState;
78
+ }
79
+ simulateMovement(targetPosition) {
80
+ // Clear any existing movement simulation to prevent concurrent intervals
81
+ if (this.moveInterval) {
82
+ clearInterval(this.moveInterval);
83
+ this.moveInterval = undefined;
84
+ this.platform.log.debug(`${this.device.name}: Cancelled previous movement simulation`);
85
+ }
86
+ const startPosition = this.currentPosition;
87
+ const distance = Math.abs(targetPosition - startPosition);
88
+ const direction = targetPosition > startPosition ? 1 : -1;
89
+ const stepSize = this.platform.config.coverStepSize ?? 5;
90
+ const totalTime = (distance / 100) * (this.maxSeconds * 1000);
91
+ const stepTime = totalTime / (distance / stepSize);
92
+ let currentStep = 0;
93
+ const totalSteps = Math.ceil(distance / stepSize);
94
+ this.moveInterval = setInterval(() => {
95
+ currentStep++;
96
+ if (currentStep >= totalSteps) {
97
+ this.currentPosition = targetPosition;
98
+ this.positionState = 2; // Stopped
99
+ this.service.updateCharacteristic(this.platform.Characteristic.CurrentPosition, this.currentPosition);
100
+ this.service.updateCharacteristic(this.platform.Characteristic.PositionState, this.positionState);
101
+ this.platform.log.debug(`${this.device.name}: Movement completed to ${targetPosition}%`);
102
+ clearInterval(this.moveInterval);
103
+ this.moveInterval = undefined;
104
+ }
105
+ else {
106
+ this.currentPosition = Math.min(100, Math.max(0, startPosition + direction * stepSize * currentStep));
107
+ this.service.updateCharacteristic(this.platform.Characteristic.CurrentPosition, this.currentPosition);
108
+ }
109
+ }, stepTime);
110
+ }
111
+ updateStatus(newDevice) {
112
+ this.device = newDevice;
113
+ if (this.device.status?.position !== this.currentPosition) {
114
+ this.currentPosition = this.device.status?.position ?? 0;
115
+ this.targetPosition = this.device.status?.position ?? 0;
116
+ this.service.updateCharacteristic(this.platform.Characteristic.CurrentPosition, this.currentPosition);
117
+ this.service.updateCharacteristic(this.platform.Characteristic.TargetPosition, this.targetPosition);
118
+ }
119
+ switch (this.device.status?.state) {
120
+ case 'opening':
121
+ this.positionState = 1;
122
+ break;
123
+ case 'closing':
124
+ this.positionState = 0;
125
+ break;
126
+ default:
127
+ this.positionState = 2; // stopped
128
+ }
129
+ this.service.updateCharacteristic(this.platform.Characteristic.PositionState, this.positionState);
130
+ this.platform.log.debug(`Updated cover state ${this.device.name}: ${this.currentPosition}%`);
131
+ }
132
+ }
133
+ exports.CoverAccessory = CoverAccessory;
134
+ //# sourceMappingURL=cover-accessory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cover-accessory.js","sourceRoot":"","sources":["../../src/accessories/cover-accessory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { CharacteristicValue, PlatformAccessory } from 'homebridge';
2
+ import type { Lares4Platform } from '../platform';
3
+ import type { KseniaGate } from '../types';
4
+ /**
5
+ * Gate Accessory Handler
6
+ * Handles HomeKit Switch service for Ksenia Lares4 monostable gates (GATE/M)
7
+ * Gates are exposed as momentary switches that trigger on press
8
+ */
9
+ export declare class GateAccessory {
10
+ private readonly platform;
11
+ private readonly accessory;
12
+ private service;
13
+ device: KseniaGate;
14
+ private autoOffTimeout?;
15
+ constructor(platform: Lares4Platform, accessory: PlatformAccessory);
16
+ setOn(value: CharacteristicValue): Promise<void>;
17
+ getOn(): Promise<CharacteristicValue>;
18
+ updateDevice(device: KseniaGate): void;
19
+ }
20
+ //# sourceMappingURL=gate-accessory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-accessory.d.ts","sourceRoot":"","sources":["../../src/accessories/gate-accessory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAW,MAAM,YAAY,CAAC;AAClF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C;;;;GAIG;AACH,qBAAa,aAAa;IAMlB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAN9B,OAAO,CAAC,OAAO,CAAU;IAClB,MAAM,EAAE,UAAU,CAAC;IAC1B,OAAO,CAAC,cAAc,CAAC,CAAiB;gBAGnB,QAAQ,EAAE,cAAc,EACxB,SAAS,EAAE,iBAAiB;IA8BpC,KAAK,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqChD,KAAK,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAK3C,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;CAIhD"}
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GateAccessory = void 0;
4
+ /**
5
+ * Gate Accessory Handler
6
+ * Handles HomeKit Switch service for Ksenia Lares4 monostable gates (GATE/M)
7
+ * Gates are exposed as momentary switches that trigger on press
8
+ */
9
+ class GateAccessory {
10
+ constructor(platform, accessory) {
11
+ this.platform = platform;
12
+ this.accessory = accessory;
13
+ this.device = accessory.context.device;
14
+ const accessoryInfoService = this.accessory.getService(this.platform.Service.AccessoryInformation);
15
+ if (accessoryInfoService) {
16
+ accessoryInfoService
17
+ .setCharacteristic(this.platform.Characteristic.Manufacturer, 'Ksenia')
18
+ .setCharacteristic(this.platform.Characteristic.Model, 'Lares4 Gate')
19
+ .setCharacteristic(this.platform.Characteristic.SerialNumber, this.device.id)
20
+ .setCharacteristic(this.platform.Characteristic.FirmwareRevision, '2.0.0');
21
+ }
22
+ this.service =
23
+ this.accessory.getService(this.platform.Service.Switch) ??
24
+ this.accessory.addService(this.platform.Service.Switch);
25
+ this.service.setCharacteristic(this.platform.Characteristic.Name, this.device.name);
26
+ this.service
27
+ .getCharacteristic(this.platform.Characteristic.On)
28
+ .onSet(this.setOn.bind(this))
29
+ .onGet(this.getOn.bind(this));
30
+ // Initialize as OFF
31
+ this.service.setCharacteristic(this.platform.Characteristic.On, false);
32
+ }
33
+ async setOn(value) {
34
+ const on = value;
35
+ if (!on) {
36
+ // User turned OFF manually, just acknowledge
37
+ return;
38
+ }
39
+ try {
40
+ // Clear any existing timeout
41
+ if (this.autoOffTimeout) {
42
+ clearTimeout(this.autoOffTimeout);
43
+ }
44
+ // Send momentary ON command to gate
45
+ await this.platform.wsClient?.toggleGate(this.device.id);
46
+ this.platform.log.info(`${this.device.name}: Gate activated`);
47
+ // Auto-off after 500ms to simulate momentary press
48
+ this.autoOffTimeout = setTimeout(() => {
49
+ this.service.updateCharacteristic(this.platform.Characteristic.On, false);
50
+ this.platform.log.debug(`${this.device.name}: Auto-off triggered`);
51
+ }, 500);
52
+ }
53
+ catch (error) {
54
+ this.platform.log.error(`Gate control error ${this.device.name}:`, error instanceof Error ? error.message : String(error));
55
+ // Reset to OFF on error
56
+ this.service.updateCharacteristic(this.platform.Characteristic.On, false);
57
+ throw new this.platform.api.hap.HapStatusError(-70402 /* this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
58
+ }
59
+ }
60
+ async getOn() {
61
+ // Gates are always "off" in terms of state (momentary switch)
62
+ return false;
63
+ }
64
+ updateDevice(device) {
65
+ this.device = device;
66
+ this.accessory.context.device = device;
67
+ }
68
+ }
69
+ exports.GateAccessory = GateAccessory;
70
+ //# sourceMappingURL=gate-accessory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-accessory.js","sourceRoot":"","sources":["../../src/accessories/gate-accessory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { CharacteristicValue, PlatformAccessory } from 'homebridge';
2
+ import type { Lares4Platform } from '../platform';
3
+ import type { KseniaLight } from '../types';
4
+ /**
5
+ * Light Accessory Handler
6
+ * Handles HomeKit Lightbulb service for Ksenia Lares4 lights
7
+ */
8
+ export declare class LightAccessory {
9
+ private readonly platform;
10
+ private readonly accessory;
11
+ private service;
12
+ device: KseniaLight;
13
+ constructor(platform: Lares4Platform, accessory: PlatformAccessory);
14
+ setOn(value: CharacteristicValue): Promise<void>;
15
+ getOn(): Promise<CharacteristicValue>;
16
+ setBrightness(value: CharacteristicValue): Promise<void>;
17
+ getBrightness(): Promise<CharacteristicValue>;
18
+ updateStatus(newDevice: KseniaLight): void;
19
+ }
20
+ //# sourceMappingURL=light-accessory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"light-accessory.d.ts","sourceRoot":"","sources":["../../src/accessories/light-accessory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAW,MAAM,YAAY,CAAC;AAClF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAe,MAAM,UAAU,CAAC;AAEzD;;;GAGG;AACH,qBAAa,cAAc;IAKnB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAL9B,OAAO,CAAC,OAAO,CAAU;IAClB,MAAM,EAAE,WAAW,CAAC;gBAGN,QAAQ,EAAE,cAAc,EACxB,SAAS,EAAE,iBAAiB;IAkCpC,KAAK,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBhD,KAAK,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAIrC,aAAa,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IA6BxD,aAAa,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAInD,YAAY,CAAC,SAAS,EAAE,WAAW,GAAG,IAAI;CAmBpD"}
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LightAccessory = void 0;
4
+ /**
5
+ * Light Accessory Handler
6
+ * Handles HomeKit Lightbulb service for Ksenia Lares4 lights
7
+ */
8
+ class LightAccessory {
9
+ constructor(platform, accessory) {
10
+ this.platform = platform;
11
+ this.accessory = accessory;
12
+ this.device = accessory.context.device;
13
+ const accessoryInfoService = this.accessory.getService(this.platform.Service.AccessoryInformation);
14
+ if (accessoryInfoService) {
15
+ accessoryInfoService
16
+ .setCharacteristic(this.platform.Characteristic.Manufacturer, 'Ksenia')
17
+ .setCharacteristic(this.platform.Characteristic.Model, 'Lares4 Light')
18
+ .setCharacteristic(this.platform.Characteristic.SerialNumber, this.device.id)
19
+ .setCharacteristic(this.platform.Characteristic.FirmwareRevision, '2.0.0');
20
+ }
21
+ this.service =
22
+ this.accessory.getService(this.platform.Service.Lightbulb) ??
23
+ this.accessory.addService(this.platform.Service.Lightbulb);
24
+ this.service.setCharacteristic(this.platform.Characteristic.Name, this.device.name);
25
+ this.service
26
+ .getCharacteristic(this.platform.Characteristic.On)
27
+ .onSet(this.setOn.bind(this))
28
+ .onGet(this.getOn.bind(this));
29
+ if (this.device.status?.dimmable) {
30
+ this.service
31
+ .getCharacteristic(this.platform.Characteristic.Brightness)
32
+ .onSet(this.setBrightness.bind(this))
33
+ .onGet(this.getBrightness.bind(this));
34
+ }
35
+ }
36
+ async setOn(value) {
37
+ const on = value;
38
+ try {
39
+ await this.platform.wsClient?.switchLight(this.device.id, on);
40
+ this.device.status.on = on;
41
+ this.platform.log.info(`${this.device.name}: ${on ? 'On' : 'Off'}`);
42
+ }
43
+ catch (error) {
44
+ this.platform.log.error(`Light control error ${this.device.name}:`, error instanceof Error ? error.message : String(error));
45
+ throw new this.platform.api.hap.HapStatusError(-70402 /* this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
46
+ }
47
+ }
48
+ async getOn() {
49
+ return this.device.status?.on ?? false;
50
+ }
51
+ async setBrightness(value) {
52
+ const brightness = value;
53
+ if (!this.device.status?.dimmable) {
54
+ return;
55
+ }
56
+ try {
57
+ await this.platform.wsClient?.dimLight(this.device.id, brightness);
58
+ this.device.status.brightness = brightness;
59
+ this.device.status.on = brightness > 0;
60
+ this.service.updateCharacteristic(this.platform.Characteristic.On, this.device.status.on);
61
+ this.platform.log.info(`${this.device.name}: Brightness ${brightness}%`);
62
+ }
63
+ catch (error) {
64
+ this.platform.log.error(`Dimmer error ${this.device.name}:`, error instanceof Error ? error.message : String(error));
65
+ throw new this.platform.api.hap.HapStatusError(-70402 /* this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
66
+ }
67
+ }
68
+ async getBrightness() {
69
+ return this.device.status?.brightness ?? (this.device.status?.on ? 100 : 0);
70
+ }
71
+ updateStatus(newDevice) {
72
+ this.device = newDevice;
73
+ this.service.updateCharacteristic(this.platform.Characteristic.On, this.device.status?.on ?? false);
74
+ if (this.device.status?.dimmable && this.device.status?.brightness !== undefined) {
75
+ this.service.updateCharacteristic(this.platform.Characteristic.Brightness, this.device.status.brightness);
76
+ }
77
+ this.platform.log.debug(`Updated light state ${this.device.name}: ${this.device.status?.on ? 'ON' : 'OFF'}`);
78
+ }
79
+ }
80
+ exports.LightAccessory = LightAccessory;
81
+ //# sourceMappingURL=light-accessory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"light-accessory.js","sourceRoot":"","sources":["../../src/accessories/light-accessory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { PlatformAccessory, CharacteristicValue } from 'homebridge';
2
+ import type { Lares4Platform } from '../platform';
3
+ import type { KseniaScenario } from '../types';
4
+ /**
5
+ * Scenario Accessory Handler
6
+ * Handles HomeKit Switch service for Ksenia Lares4 scenarios
7
+ */
8
+ export declare class ScenarioAccessory {
9
+ private readonly platform;
10
+ private readonly accessory;
11
+ private service;
12
+ readonly device: KseniaScenario;
13
+ constructor(platform: Lares4Platform, accessory: PlatformAccessory, device: KseniaScenario);
14
+ setOn(value: CharacteristicValue): Promise<void>;
15
+ getOn(): Promise<CharacteristicValue>;
16
+ }
17
+ //# sourceMappingURL=scenario-accessory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scenario-accessory.d.ts","sourceRoot":"","sources":["../../src/accessories/scenario-accessory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAElF,OAAO,KAAK,EAAE,cAAc,EAAgB,MAAM,aAAa,CAAC;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C;;;GAGG;AACH,qBAAa,iBAAiB;IAKtB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAL9B,OAAO,CAAC,OAAO,CAAU;IACzB,SAAgB,MAAM,EAAE,cAAc,CAAC;gBAGlB,QAAQ,EAAE,cAAc,EACxB,SAAS,EAAE,iBAAiB,EAC7C,MAAM,EAAE,cAAc;IA0Bb,KAAK,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAkChD,KAAK,IAAI,OAAO,CAAC,mBAAmB,CAAC;CAIrD"}
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ScenarioAccessory = void 0;
4
+ /**
5
+ * Scenario Accessory Handler
6
+ * Handles HomeKit Switch service for Ksenia Lares4 scenarios
7
+ */
8
+ class ScenarioAccessory {
9
+ constructor(platform, accessory, device) {
10
+ this.platform = platform;
11
+ this.accessory = accessory;
12
+ this.device = device;
13
+ const accessoryInfoService = this.accessory.getService(this.platform.Service.AccessoryInformation);
14
+ if (accessoryInfoService) {
15
+ accessoryInfoService
16
+ .setCharacteristic(this.platform.Characteristic.Manufacturer, 'Ksenia')
17
+ .setCharacteristic(this.platform.Characteristic.Model, 'Lares4 Scenario')
18
+ .setCharacteristic(this.platform.Characteristic.SerialNumber, device.id);
19
+ }
20
+ this.service =
21
+ this.accessory.getService(this.platform.Service.Switch) ??
22
+ this.accessory.addService(this.platform.Service.Switch);
23
+ this.service.setCharacteristic(this.platform.Characteristic.Name, device.name);
24
+ this.service
25
+ .getCharacteristic(this.platform.Characteristic.On)
26
+ .onSet(this.setOn.bind(this))
27
+ .onGet(this.getOn.bind(this));
28
+ }
29
+ async setOn(value) {
30
+ const isOn = value;
31
+ if (isOn) {
32
+ try {
33
+ if (!this.platform.wsClient) {
34
+ throw new Error('WebSocket client not initialized');
35
+ }
36
+ await this.platform.wsClient.triggerScenario(this.device.id);
37
+ this.platform.log.info(`Scenario ${this.device.name} executed`);
38
+ const autoOffDelay = this.platform.config.scenarioAutoOffDelay ?? 500;
39
+ setTimeout(() => {
40
+ if (this.service) {
41
+ this.service.updateCharacteristic(this.platform.Characteristic.On, false);
42
+ this.platform.log.debug(`Scenario ${this.device.name} automatically turned off after ${autoOffDelay}ms`);
43
+ }
44
+ }, autoOffDelay);
45
+ }
46
+ catch (error) {
47
+ this.platform.log.error(`Scenario execution error ${this.device.name}:`, error instanceof Error ? error.message : String(error));
48
+ throw new this.platform.api.hap.HapStatusError(-70402 /* this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
49
+ }
50
+ }
51
+ // Do nothing for "off" - scenarios are momentary
52
+ }
53
+ async getOn() {
54
+ // Scenarios don't have persistent state, always return false
55
+ return false;
56
+ }
57
+ }
58
+ exports.ScenarioAccessory = ScenarioAccessory;
59
+ //# sourceMappingURL=scenario-accessory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scenario-accessory.js","sourceRoot":"","sources":["../../src/accessories/scenario-accessory.ts"],"names":[],"mappings":";;;AAKA;;;GAGG;AACH,MAAa,iBAAiB;IAI1B,YACqB,QAAwB,EACxB,SAA4B,EAC7C,MAAsB;QAFL,aAAQ,GAAR,QAAQ,CAAgB;QACxB,cAAS,GAAT,SAAS,CAAmB;QAG7C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,MAAM,oBAAoB,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAClD,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,oBAAoB,CAC7C,CAAC;QACF,IAAI,oBAAoB,EAAE,CAAC;YACvB,oBAAoB;iBACf,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,YAAY,EAAE,QAAQ,CAAC;iBACtE,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,KAAK,EAAE,iBAAiB,CAAC;iBACxE,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,YAAY,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QACjF,CAAC;QAED,IAAI,CAAC,OAAO;YACR,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC;gBACvD,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAE5D,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QAE/E,IAAI,CAAC,OAAO;aACP,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;aAClD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aAC5B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACtC,CAAC;IAEM,KAAK,CAAC,KAAK,CAAC,KAA0B;QACzC,MAAM,IAAI,GAAG,KAAgB,CAAC;QAE9B,IAAI,IAAI,EAAE,CAAC;YACP,IAAI,CAAC;gBACD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;oBAC1B,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;gBACxD,CAAC;gBACD,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBAC7D,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,CAAC;gBAEhE,MAAM,YAAY,GACb,IAAI,CAAC,QAAQ,CAAC,MAAuB,CAAC,oBAAoB,IAAI,GAAG,CAAC;gBACvE,UAAU,CAAC,GAAS,EAAE;oBAClB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;wBACf,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;wBAC1E,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CACnB,YAAY,IAAI,CAAC,MAAM,CAAC,IAAI,mCAAmC,YAAY,IAAI,CAClF,CAAC;oBACN,CAAC;gBACL,CAAC,EAAE,YAAY,CAAC,CAAC;YACrB,CAAC;YAAC,OAAO,KAAc,EAAE,CAAC;gBACtB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CACnB,4BAA4B,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,EAC/C,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACzD,CAAC;gBACF,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,4EAE7C,CAAC;YACN,CAAC;QACL,CAAC;QACD,iDAAiD;IACrD,CAAC;IAEM,KAAK,CAAC,KAAK;QACd,6DAA6D;QAC7D,OAAO,KAAK,CAAC;IACjB,CAAC;CACJ;AAvED,8CAuEC"}
@@ -0,0 +1,28 @@
1
+ import type { CharacteristicValue, PlatformAccessory } from 'homebridge';
2
+ import type { Lares4Platform } from '../platform';
3
+ import type { KseniaSensor } from '../types';
4
+ /**
5
+ * Sensor Accessory Handler
6
+ * Handles HomeKit sensor services for Ksenia Lares4 sensors
7
+ */
8
+ export declare class SensorAccessory {
9
+ private readonly platform;
10
+ private readonly accessory;
11
+ private service;
12
+ device: KseniaSensor;
13
+ constructor(platform: Lares4Platform, accessory: PlatformAccessory);
14
+ private createSensorService;
15
+ private createTemperatureSensor;
16
+ private createHumiditySensor;
17
+ private createLightSensor;
18
+ private createMotionSensor;
19
+ private createContactSensor;
20
+ getCurrentTemperature(): Promise<CharacteristicValue>;
21
+ getCurrentHumidity(): Promise<CharacteristicValue>;
22
+ getCurrentLightLevel(): Promise<CharacteristicValue>;
23
+ getMotionDetected(): Promise<CharacteristicValue>;
24
+ getContactState(): Promise<CharacteristicValue>;
25
+ private getSensorTypeLabel;
26
+ updateStatus(newDevice: KseniaSensor): void;
27
+ }
28
+ //# sourceMappingURL=sensor-accessory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sensor-accessory.d.ts","sourceRoot":"","sources":["../../src/accessories/sensor-accessory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAW,MAAM,YAAY,CAAC;AAClF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,UAAU,CAAC;AAE3D;;;GAGG;AACH,qBAAa,eAAe;IAKpB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAL9B,OAAO,CAAC,OAAO,CAAU;IAClB,MAAM,EAAE,YAAY,CAAC;gBAGP,QAAQ,EAAE,cAAc,EACxB,SAAS,EAAE,iBAAiB;IAsBjD,OAAO,CAAC,mBAAmB;IAiB3B,OAAO,CAAC,uBAAuB;IAY/B,OAAO,CAAC,oBAAoB;IAY5B,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,mBAAmB;IAYd,qBAAqB,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAMrD,kBAAkB,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAMlD,oBAAoB,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAMpD,iBAAiB,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAIjD,eAAe,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAK5D,OAAO,CAAC,kBAAkB;IAiBnB,YAAY,CAAC,SAAS,EAAE,YAAY,GAAG,IAAI;CAwCrD"}