homebridge-securitysystem 12.0.0 → 13.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/.github/workflows/bump-version.yml +1 -1
  2. package/.gitignore +127 -0
  3. package/AGENTS.md +7 -7
  4. package/CHANGELOG.md +30 -0
  5. package/config.schema.json +1 -145
  6. package/package.json +1 -1
  7. package/src/constants/default-constant.ts +0 -3
  8. package/src/constants/switch-uuid-constant.ts +0 -2
  9. package/src/handlers/sensor-handler.ts +0 -22
  10. package/src/handlers/state-handler.ts +0 -17
  11. package/src/handlers/trip-handler.ts +0 -3
  12. package/src/homekit/homekit-registrar.ts +1 -6
  13. package/src/homekit/service-factory.ts +0 -11
  14. package/src/interfaces/options-interface.ts +0 -19
  15. package/src/interfaces/service-registry-interface.ts +0 -4
  16. package/src/interfaces/system-state-interface.ts +0 -2
  17. package/src/security-system.ts +2 -14
  18. package/src/services/configuration-service.ts +0 -33
  19. package/src/services/event-bus-service.ts +1 -1
  20. package/src/tests/conditions.test.ts +0 -1
  21. package/src/tests/mqtt-service.test.ts +0 -1
  22. package/src/tests/server-service.test.ts +0 -1
  23. package/src/tests/state-handler.test.ts +14 -65
  24. package/src/tests/switch-handler.test.ts +2 -6
  25. package/src/tests/trip-handler.test.ts +7 -11
  26. package/src/timers/timer-manager.ts +0 -17
  27. package/src/types/mode-type.ts +1 -1
  28. package/dist/conditions/already-triggered-condition.d.ts +0 -10
  29. package/dist/conditions/already-triggered-condition.js +0 -22
  30. package/dist/conditions/already-triggered-condition.js.map +0 -1
  31. package/dist/conditions/arming-in-progress-condition.d.ts +0 -10
  32. package/dist/conditions/arming-in-progress-condition.js +0 -21
  33. package/dist/conditions/arming-in-progress-condition.js.map +0 -1
  34. package/dist/conditions/arming-lock-condition.d.ts +0 -13
  35. package/dist/conditions/arming-lock-condition.js +0 -50
  36. package/dist/conditions/arming-lock-condition.js.map +0 -1
  37. package/dist/conditions/condition.d.ts +0 -22
  38. package/dist/conditions/condition.js +0 -19
  39. package/dist/conditions/condition.js.map +0 -1
  40. package/dist/conditions/double-knock-condition.d.ts +0 -24
  41. package/dist/conditions/double-knock-condition.js +0 -73
  42. package/dist/conditions/double-knock-condition.js.map +0 -1
  43. package/dist/conditions/not-armed-condition.d.ts +0 -10
  44. package/dist/conditions/not-armed-condition.js +0 -26
  45. package/dist/conditions/not-armed-condition.js.map +0 -1
  46. package/dist/conditions/trigger-already-running-condition.d.ts +0 -10
  47. package/dist/conditions/trigger-already-running-condition.js +0 -21
  48. package/dist/conditions/trigger-already-running-condition.js.map +0 -1
  49. package/dist/constants/default-constant.d.ts +0 -27
  50. package/dist/constants/default-constant.js +0 -30
  51. package/dist/constants/default-constant.js.map +0 -1
  52. package/dist/constants/homekit-constant.d.ts +0 -4
  53. package/dist/constants/homekit-constant.js +0 -5
  54. package/dist/constants/homekit-constant.js.map +0 -1
  55. package/dist/constants/switch-uuid-constant.d.ts +0 -23
  56. package/dist/constants/switch-uuid-constant.js +0 -24
  57. package/dist/constants/switch-uuid-constant.js.map +0 -1
  58. package/dist/handlers/sensor-handler.d.ts +0 -20
  59. package/dist/handlers/sensor-handler.js +0 -66
  60. package/dist/handlers/sensor-handler.js.map +0 -1
  61. package/dist/handlers/state-handler.d.ts +0 -52
  62. package/dist/handlers/state-handler.js +0 -213
  63. package/dist/handlers/state-handler.js.map +0 -1
  64. package/dist/handlers/switch-handler.d.ts +0 -35
  65. package/dist/handlers/switch-handler.js +0 -134
  66. package/dist/handlers/switch-handler.js.map +0 -1
  67. package/dist/handlers/trip-handler.d.ts +0 -51
  68. package/dist/handlers/trip-handler.js +0 -198
  69. package/dist/handlers/trip-handler.js.map +0 -1
  70. package/dist/homekit/homekit-registrar.d.ts +0 -19
  71. package/dist/homekit/homekit-registrar.js +0 -156
  72. package/dist/homekit/homekit-registrar.js.map +0 -1
  73. package/dist/homekit/service-factory.d.ts +0 -9
  74. package/dist/homekit/service-factory.js +0 -124
  75. package/dist/homekit/service-factory.js.map +0 -1
  76. package/dist/index.d.ts +0 -3
  77. package/dist/index.js.map +0 -1
  78. package/dist/interfaces/condition-context-interface.d.ts +0 -16
  79. package/dist/interfaces/condition-context-interface.js +0 -2
  80. package/dist/interfaces/condition-context-interface.js.map +0 -1
  81. package/dist/interfaces/hap-types-interface.d.ts +0 -9
  82. package/dist/interfaces/hap-types-interface.js +0 -2
  83. package/dist/interfaces/hap-types-interface.js.map +0 -1
  84. package/dist/interfaces/mqtt-status-payload-interface.d.ts +0 -6
  85. package/dist/interfaces/mqtt-status-payload-interface.js +0 -2
  86. package/dist/interfaces/mqtt-status-payload-interface.js.map +0 -1
  87. package/dist/interfaces/options-interface.d.ts +0 -103
  88. package/dist/interfaces/options-interface.js +0 -2
  89. package/dist/interfaces/options-interface.js.map +0 -1
  90. package/dist/interfaces/persisted-state-interface.d.ts +0 -6
  91. package/dist/interfaces/persisted-state-interface.js +0 -2
  92. package/dist/interfaces/persisted-state-interface.js.map +0 -1
  93. package/dist/interfaces/service-registry-interface.d.ts +0 -33
  94. package/dist/interfaces/service-registry-interface.js +0 -2
  95. package/dist/interfaces/service-registry-interface.js.map +0 -1
  96. package/dist/interfaces/system-state-interface.d.ts +0 -15
  97. package/dist/interfaces/system-state-interface.js +0 -2
  98. package/dist/interfaces/system-state-interface.js.map +0 -1
  99. package/dist/schemas/arming-lock-schema.d.ts +0 -10
  100. package/dist/schemas/arming-lock-schema.js +0 -12
  101. package/dist/schemas/arming-lock-schema.js.map +0 -1
  102. package/dist/schemas/error-schema.d.ts +0 -4
  103. package/dist/schemas/error-schema.js +0 -7
  104. package/dist/schemas/error-schema.js.map +0 -1
  105. package/dist/schemas/mode-request-schema.d.ts +0 -10
  106. package/dist/schemas/mode-request-schema.js +0 -18
  107. package/dist/schemas/mode-request-schema.js.map +0 -1
  108. package/dist/schemas/status-response-schema.d.ts +0 -7
  109. package/dist/schemas/status-response-schema.js +0 -10
  110. package/dist/schemas/status-response-schema.js.map +0 -1
  111. package/dist/schemas/trip-mode-request-schema.d.ts +0 -9
  112. package/dist/schemas/trip-mode-request-schema.js +0 -24
  113. package/dist/schemas/trip-mode-request-schema.js.map +0 -1
  114. package/dist/security-system.d.ts +0 -22
  115. package/dist/security-system.js +0 -154
  116. package/dist/security-system.js.map +0 -1
  117. package/dist/services/audio-service.d.ts +0 -21
  118. package/dist/services/audio-service.js +0 -113
  119. package/dist/services/audio-service.js.map +0 -1
  120. package/dist/services/command-service.d.ts +0 -16
  121. package/dist/services/command-service.js +0 -65
  122. package/dist/services/command-service.js.map +0 -1
  123. package/dist/services/configuration-service.d.ts +0 -25
  124. package/dist/services/configuration-service.js +0 -218
  125. package/dist/services/configuration-service.js.map +0 -1
  126. package/dist/services/event-bus-service.d.ts +0 -12
  127. package/dist/services/event-bus-service.js +0 -17
  128. package/dist/services/event-bus-service.js.map +0 -1
  129. package/dist/services/mqtt-service.d.ts +0 -16
  130. package/dist/services/mqtt-service.js +0 -97
  131. package/dist/services/mqtt-service.js.map +0 -1
  132. package/dist/services/server-service.d.ts +0 -28
  133. package/dist/services/server-service.js +0 -275
  134. package/dist/services/server-service.js.map +0 -1
  135. package/dist/services/storage-service.d.ts +0 -14
  136. package/dist/services/storage-service.js +0 -70
  137. package/dist/services/storage-service.js.map +0 -1
  138. package/dist/services/webhook-service.d.ts +0 -16
  139. package/dist/services/webhook-service.js +0 -68
  140. package/dist/services/webhook-service.js.map +0 -1
  141. package/dist/tests/conditions.test.d.ts +0 -1
  142. package/dist/tests/conditions.test.js +0 -148
  143. package/dist/tests/conditions.test.js.map +0 -1
  144. package/dist/tests/mqtt-service.test.d.ts +0 -1
  145. package/dist/tests/mqtt-service.test.js +0 -167
  146. package/dist/tests/mqtt-service.test.js.map +0 -1
  147. package/dist/tests/server-service.test.d.ts +0 -1
  148. package/dist/tests/server-service.test.js +0 -187
  149. package/dist/tests/server-service.test.js.map +0 -1
  150. package/dist/tests/state-handler.test.d.ts +0 -1
  151. package/dist/tests/state-handler.test.js +0 -273
  152. package/dist/tests/state-handler.test.js.map +0 -1
  153. package/dist/tests/switch-handler.test.d.ts +0 -1
  154. package/dist/tests/switch-handler.test.js +0 -267
  155. package/dist/tests/switch-handler.test.js.map +0 -1
  156. package/dist/tests/trip-handler.test.d.ts +0 -1
  157. package/dist/tests/trip-handler.test.js +0 -289
  158. package/dist/tests/trip-handler.test.js.map +0 -1
  159. package/dist/timers/timer-manager.d.ts +0 -34
  160. package/dist/timers/timer-manager.js +0 -132
  161. package/dist/timers/timer-manager.js.map +0 -1
  162. package/dist/types/event-payload-map-type.d.ts +0 -14
  163. package/dist/types/event-payload-map-type.js +0 -2
  164. package/dist/types/event-payload-map-type.js.map +0 -1
  165. package/dist/types/event-type.d.ts +0 -38
  166. package/dist/types/event-type.js +0 -17
  167. package/dist/types/event-type.js.map +0 -1
  168. package/dist/types/mode-type.d.ts +0 -4
  169. package/dist/types/mode-type.js +0 -2
  170. package/dist/types/mode-type.js.map +0 -1
  171. package/dist/types/origin-type.d.ts +0 -9
  172. package/dist/types/origin-type.js +0 -11
  173. package/dist/types/origin-type.js.map +0 -1
  174. package/dist/types/security-state-type.d.ts +0 -11
  175. package/dist/types/security-state-type.js +0 -13
  176. package/dist/types/security-state-type.js.map +0 -1
  177. package/dist/types/service-result-type.d.ts +0 -4
  178. package/dist/types/service-result-type.js +0 -2
  179. package/dist/types/service-result-type.js.map +0 -1
  180. package/dist/utils/arming-util.d.ts +0 -19
  181. package/dist/utils/arming-util.js +0 -24
  182. package/dist/utils/arming-util.js.map +0 -1
  183. package/dist/utils/state-util.d.ts +0 -8
  184. package/dist/utils/state-util.js +0 -29
  185. package/dist/utils/state-util.js.map +0 -1
  186. package/sounds/README +0 -22
  187. package/sounds/de-DE/current-away.mp3 +0 -0
  188. package/sounds/de-DE/current-home.mp3 +0 -0
  189. package/sounds/de-DE/current-night.mp3 +0 -0
  190. package/sounds/de-DE/current-off.mp3 +0 -0
  191. package/sounds/de-DE/current-triggered.mp3 +0 -0
  192. package/sounds/de-DE/current-warning.mp3 +0 -0
  193. package/sounds/de-DE/target-away.mp3 +0 -0
  194. package/sounds/de-DE/target-home.mp3 +0 -0
  195. package/sounds/de-DE/target-night.mp3 +0 -0
  196. package/sounds/en-US/current-away.mp3 +0 -0
  197. package/sounds/en-US/current-home.mp3 +0 -0
  198. package/sounds/en-US/current-night.mp3 +0 -0
  199. package/sounds/en-US/current-off.mp3 +0 -0
  200. package/sounds/en-US/current-triggered.mp3 +0 -0
  201. package/sounds/en-US/current-warning.mp3 +0 -0
  202. package/sounds/en-US/target-away.mp3 +0 -0
  203. package/sounds/en-US/target-home.mp3 +0 -0
  204. package/sounds/en-US/target-night.mp3 +0 -0
  205. package/src/services/audio-service.ts +0 -133
@@ -1,213 +0,0 @@
1
- import { SecurityState } from '../types/security-state-type.js';
2
- import { OriginType } from '../types/origin-type.js';
3
- import { stateToMode, capitalise } from '../utils/state-util.js';
4
- import { modeToState } from '../utils/state-util.js';
5
- import { EventType } from '../types/event-type.js';
6
- import { getArmingSeconds } from '../utils/arming-util.js';
7
- /**
8
- * Manages the core security-system state machine: arming, triggering, and resetting.
9
- * Cross-handler side effects are signalled via the event bus so that this class has
10
- * no direct dependencies on TripHandler or SwitchHandler.
11
- */
12
- export class StateHandler {
13
- services;
14
- state;
15
- options;
16
- Characteristic;
17
- log;
18
- bus;
19
- storageService;
20
- audio;
21
- timers;
22
- sensorHandler;
23
- constructor(services, state, options, Characteristic, log, bus, storageService, audio, timers, sensorHandler) {
24
- this.services = services;
25
- this.state = state;
26
- this.options = options;
27
- this.Characteristic = Characteristic;
28
- this.log = log;
29
- this.bus = bus;
30
- this.storageService = storageService;
31
- this.audio = audio;
32
- this.timers = timers;
33
- this.sensorHandler = sensorHandler;
34
- }
35
- // ── Public API ─────────────────────────────────────────────────────────────
36
- setCurrentState(state, origin) {
37
- this.sensorHandler.resetArmingMotionSensor();
38
- this.audio.play('current', state);
39
- if (this.state.currentState === state) {
40
- this.log.warn('Current mode (Already set)');
41
- return;
42
- }
43
- this.state.currentState = state;
44
- this.services.mainService.setCharacteristic(this.Characteristic.SecuritySystemCurrentState, state);
45
- this.logMode('Current', state);
46
- this.handleCurrentStateChange(origin);
47
- this.storageService.save(this.state);
48
- }
49
- updateTargetState(state, origin, delay) {
50
- // Same-target re-call: "confirm this mode externally; apply it now"
51
- if (state === this.state.targetState && this.state.currentState !== SecurityState.TRIGGERED) {
52
- if (state === this.state.currentState) {
53
- return { success: true };
54
- }
55
- if (this.state.isArming) {
56
- this.timers.clearArmTimer();
57
- this.state.isArming = false;
58
- }
59
- this.setCurrentState(state, origin);
60
- return { success: true };
61
- }
62
- const reason = this.getBadTargetStateReason(state);
63
- if (reason !== null) {
64
- return { success: false, reason };
65
- }
66
- this.state.targetState = state;
67
- this.logMode('Target', state);
68
- if (origin === OriginType.INTERNAL || origin === OriginType.EXTERNAL) {
69
- this.services.mainService.updateCharacteristic(this.Characteristic.SecuritySystemTargetState, state);
70
- }
71
- this.handleTargetStateChange(origin);
72
- if (state === this.state.currentState) {
73
- this.setCurrentState(state, origin);
74
- return { success: true };
75
- }
76
- const armSeconds = delay > 0 ? delay : 0;
77
- if (armSeconds === 0) {
78
- this.setCurrentState(state, origin);
79
- return { success: true };
80
- }
81
- this.state.isArming = true;
82
- this.handleArmingState();
83
- this.log.info(`Arm delay (${armSeconds}s)`);
84
- this.timers.setArmTimer(armSeconds * 1000, () => {
85
- this.state.isArming = false;
86
- this.setCurrentState(state, origin);
87
- });
88
- return { success: true };
89
- }
90
- getArmingSeconds(targetState) {
91
- return getArmingSeconds(this.state, this.options, targetState);
92
- }
93
- resetTimers() {
94
- this.timers.clearAll();
95
- }
96
- /** Returns true while the trigger delay is counting down (trip switch is active). */
97
- isTripping() {
98
- return this.state.isTripping;
99
- }
100
- /** Checks whether arming is currently blocked by an arming-lock switch. */
101
- isArmingLocked(targetState) {
102
- if (this.services.armingLockSwitchService.getCharacteristic(this.Characteristic.On).value) {
103
- return true;
104
- }
105
- const modeMap = {
106
- [SecurityState.HOME]: 'armingLockHomeSwitchService',
107
- [SecurityState.AWAY]: 'armingLockAwaySwitchService',
108
- [SecurityState.NIGHT]: 'armingLockNightSwitchService',
109
- };
110
- const svcKey = modeMap[targetState];
111
- return svcKey
112
- ? Boolean(this.services[svcKey].getCharacteristic(this.Characteristic.On).value)
113
- : false;
114
- }
115
- getAvailableTargetStates() {
116
- const all = [SecurityState.HOME, SecurityState.AWAY, SecurityState.NIGHT, SecurityState.OFF];
117
- const disabled = this.options.disabledModes.map(m => modeToState(m.toLowerCase()));
118
- return all.filter(s => !disabled.includes(s));
119
- }
120
- logMode(type, state) {
121
- const mode = capitalise(stateToMode(state));
122
- this.log.info(`${type} mode (${mode})`);
123
- }
124
- // ── Private helpers ────────────────────────────────────────────────────────
125
- /**
126
- * Returns a human-readable reason string if `state` is an invalid target,
127
- * or `null` if the transition is permitted.
128
- */
129
- getBadTargetStateReason(state) {
130
- const isTriggered = this.state.currentState === SecurityState.TRIGGERED;
131
- const alreadySet = this.state.targetState === state;
132
- if (alreadySet && !isTriggered) {
133
- this.log.warn('Target mode (Already set)');
134
- return 'target mode is already set';
135
- }
136
- if (!this.state.availableTargetStates.includes(state)) {
137
- this.log.warn('Target mode (Disabled)');
138
- return 'target mode is disabled';
139
- }
140
- const hasLock = this.options.armingLockSwitch || this.options.armingLockSwitches;
141
- if (state !== SecurityState.OFF && hasLock && this.isArmingLocked(state)) {
142
- this.log.warn('Arming lock (Not allowed)');
143
- return 'arming is blocked by an arming lock switch';
144
- }
145
- return null;
146
- }
147
- handleTargetStateChange(origin) {
148
- this.resetTimers();
149
- // Notify handlers to reset their displayed state (bus is synchronous).
150
- this.bus.emit(EventType.RESET_TRIP_SWITCHES, {});
151
- this.sensorHandler.resetTrippedMotionSensor();
152
- this.sensorHandler.resetTriggeredMotionSensor();
153
- this.bus.emit(EventType.RESET_MODE_SWITCHES, {});
154
- this.bus.emit(EventType.UPDATE_MODE_SWITCHES, {});
155
- this.bus.emit(EventType.TARGET_CHANGED, { state: this.state.targetState, origin });
156
- if (this.state.currentState === SecurityState.TRIGGERED) {
157
- this.sensorHandler.pulseResetMotionSensor();
158
- }
159
- this.state.isTripping = false;
160
- this.state.isKnocked = false;
161
- }
162
- handleCurrentStateChange(origin) {
163
- if (this.state.currentState === SecurityState.TRIGGERED) {
164
- this.handleTriggeredState();
165
- if (this.options.testMode) {
166
- return;
167
- }
168
- }
169
- else {
170
- // Notify TripHandler to reset trip switches on any non-triggered state change.
171
- // (Do not reset when entering TRIGGERED — the trip switch should remain ON
172
- // to reflect the active sensor / cause of the alarm.)
173
- this.bus.emit(EventType.RESET_TRIP_SWITCHES, {});
174
- }
175
- this.bus.emit(EventType.CURRENT_CHANGED, { state: this.state.currentState, origin });
176
- }
177
- handleTriggeredState() {
178
- this.timers.clearTrippedInterval();
179
- this.sensorHandler.resetTrippedMotionSensor();
180
- this.startTriggeredMotionSensor();
181
- this.timers.setResetTimer(this.options.resetMinutes * 60 * 1000, () => {
182
- this.log.info('Reset (Finished)');
183
- this.sensorHandler.pulseResetMotionSensor();
184
- if (this.options.resetOffFlow) {
185
- this.resetViaOffMode();
186
- }
187
- else {
188
- this.setCurrentState(this.state.targetState, OriginType.EXTERNAL);
189
- }
190
- });
191
- }
192
- startTriggeredMotionSensor() {
193
- const seconds = this.options.triggeredMotionSensorSeconds;
194
- if (seconds === 0) {
195
- this.sensorHandler.setTriggeredMotionSensor(true);
196
- }
197
- else {
198
- this.timers.setTriggeredInterval(seconds * 1000, () => this.sensorHandler.pulseTriggeredMotionSensor());
199
- }
200
- }
201
- handleArmingState() {
202
- this.sensorHandler.updateArmingMotionSensor(true);
203
- this.bus.emit(EventType.ARMING, { state: this.state.targetState });
204
- }
205
- resetViaOffMode() {
206
- const original = this.state.targetState;
207
- this.updateTargetState(SecurityState.OFF, OriginType.INTERNAL, 0);
208
- setTimeout(() => {
209
- this.updateTargetState(original, OriginType.INTERNAL, this.getArmingSeconds(original));
210
- }, 100);
211
- }
212
- }
213
- //# sourceMappingURL=state-handler.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"state-handler.js","sourceRoot":"","sources":["../../src/handlers/state-handler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAKrD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAKnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAG3D;;;;GAIG;AACH,MAAM,OAAO,YAAY;IAEJ,QAAQ;IACR,KAAK;IACL,OAAO;IACP,cAAc;IACd,GAAG;IACH,GAAG;IACH,cAAc;IACd,KAAK;IACL,MAAM;IACN,aAAa;IAVhC,YACmB,QAAyB,EACzB,KAAkB,EAClB,OAA8B,EAC9B,cAAyC,EACzC,GAAY,EACZ,GAAoB,EACpB,cAA8B,EAC9B,KAAmB,EACnB,MAAoB,EACpB,aAA4B;wBAT5B,QAAQ;qBACR,KAAK;uBACL,OAAO;8BACP,cAAc;mBACd,GAAG;mBACH,GAAG;8BACH,cAAc;qBACd,KAAK;sBACL,MAAM;6BACN,aAAa;IAC7B,CAAC;IAEJ,8EAA8E;IAE9E,eAAe,CAAC,KAAoB,EAAE,MAAkB;QACtD,IAAI,CAAC,aAAa,CAAC,uBAAuB,EAAE,CAAC;QAC7C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAElC,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,KAAK,KAAK,EAAE,CAAC;YACtC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;YAC5C,OAAO;QACT,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC;QAChC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,iBAAiB,CACzC,IAAI,CAAC,cAAc,CAAC,0BAA0B,EAC9C,KAAK,CACN,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAE/B,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACvC,CAAC;IAED,iBAAiB,CAAC,KAAoB,EAAE,MAAkB,EAAE,KAAa;QACvE,oEAAoE;QACpE,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,KAAK,aAAa,CAAC,SAAS,EAAE,CAAC;YAC5F,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;gBACtC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YAC3B,CAAC;YAED,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACxB,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;gBAC5B,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC;YAC9B,CAAC;YAED,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,uBAAuB,CAAC,KAAK,CAAC,CAAC;QACnD,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QACpC,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC;QAC/B,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAE9B,IAAI,MAAM,KAAK,UAAU,CAAC,QAAQ,IAAI,MAAM,KAAK,UAAU,CAAC,QAAQ,EAAE,CAAC;YACrE,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,oBAAoB,CAC5C,IAAI,CAAC,cAAc,CAAC,yBAAyB,EAC7C,KAAK,CACN,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;QAErC,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;YACtC,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QAED,MAAM,UAAU,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAEzC,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;YACrB,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,UAAU,IAAI,CAAC,CAAC;QAE5C,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,GAAG,IAAI,EAAE,GAAG,EAAE;YAC9C,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC;YAC5B,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED,gBAAgB,CAAC,WAA0B;QACzC,OAAO,gBAAgB,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IACjE,CAAC;IAED,WAAW;QACT,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IAED,qFAAqF;IACrF,UAAU;QACR,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;IAC/B,CAAC;IAED,2EAA2E;IAC3E,cAAc,CAAC,WAA0B;QACvC,IAAI,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CAAC,iBAAiB,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;YAC1F,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,OAAO,GAAqD;YAChE,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,6BAA6B;YACnD,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,6BAA6B;YACnD,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,8BAA8B;SACtD,CAAC;QAEF,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;QACpC,OAAO,MAAM;YACX,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC;YAChF,CAAC,CAAC,KAAK,CAAC;IACZ,CAAC;IAED,wBAAwB;QACtB,MAAM,GAAG,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,KAAK,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;QAC7F,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QACnF,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,OAAO,CAAC,IAAY,EAAE,KAA6B;QACjD,MAAM,IAAI,GAAG,UAAU,CAAC,WAAW,CAAC,KAAsB,CAAC,CAAC,CAAC;QAC7D,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,UAAU,IAAI,GAAG,CAAC,CAAC;IAC1C,CAAC;IAED,8EAA8E;IAE9E;;;OAGG;IACK,uBAAuB,CAAC,KAAoB;QAClD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,KAAK,aAAa,CAAC,SAAS,CAAC;QACxE,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,KAAK,KAAK,CAAC;QAEpD,IAAI,UAAU,IAAI,CAAC,WAAW,EAAE,CAAC;YAC/B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;YAC3C,OAAO,4BAA4B,CAAC;QACtC,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACtD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;YACxC,OAAO,yBAAyB,CAAC;QACnC,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC;QACjF,IAAI,KAAK,KAAK,aAAa,CAAC,GAAG,IAAI,OAAO,IAAI,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YACzE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;YAC3C,OAAO,4CAA4C,CAAC;QACtD,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,uBAAuB,CAAC,MAAkB;QAChD,IAAI,CAAC,WAAW,EAAE,CAAC;QAEnB,uEAAuE;QACvE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;QACjD,IAAI,CAAC,aAAa,CAAC,wBAAwB,EAAE,CAAC;QAC9C,IAAI,CAAC,aAAa,CAAC,0BAA0B,EAAE,CAAC;QAChD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;QACjD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;QAElD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;QAEnF,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,KAAK,aAAa,CAAC,SAAS,EAAE,CAAC;YACxD,IAAI,CAAC,aAAa,CAAC,sBAAsB,EAAE,CAAC;QAC9C,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC;QAC9B,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC;IAC/B,CAAC;IAEO,wBAAwB,CAAC,MAAkB;QACjD,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,KAAK,aAAa,CAAC,SAAS,EAAE,CAAC;YACxD,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAE5B,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;gBAC1B,OAAO;YACT,CAAC;QACH,CAAC;aAAM,CAAC;YACN,+EAA+E;YAC/E,2EAA2E;YAC3E,sDAAsD;YACtD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;QACnD,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC;IACvF,CAAC;IAEO,oBAAoB;QAC1B,IAAI,CAAC,MAAM,CAAC,oBAAoB,EAAE,CAAC;QACnC,IAAI,CAAC,aAAa,CAAC,wBAAwB,EAAE,CAAC;QAC9C,IAAI,CAAC,0BAA0B,EAAE,CAAC;QAElC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE;YACpE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YAClC,IAAI,CAAC,aAAa,CAAC,sBAAsB,EAAE,CAAC;YAE5C,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;gBAC9B,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;YACpE,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,0BAA0B;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,4BAA4B,CAAC;QAC1D,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;YAClB,IAAI,CAAC,aAAa,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC;QACpD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAC9B,OAAO,GAAG,IAAI,EACd,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,0BAA0B,EAAE,CACtD,CAAC;QACJ,CAAC;IACH,CAAC;IAEO,iBAAiB;QACvB,IAAI,CAAC,aAAa,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IACrE,CAAC;IAEO,eAAe;QACrB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;QACxC,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,GAAG,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QAElE,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC;QACzF,CAAC,EAAE,GAAG,CAAC,CAAC;IACV,CAAC;CACF"}
@@ -1,35 +0,0 @@
1
- import type { Logging } from 'homebridge';
2
- import type { CharacteristicConstructor } from '../interfaces/hap-types-interface.js';
3
- import { SecurityState } from '../types/security-state-type.js';
4
- import type { ServiceRegistry } from '../interfaces/service-registry-interface.js';
5
- import type { SystemState } from '../interfaces/system-state-interface.js';
6
- import type { SecuritySystemOptions } from '../interfaces/options-interface.js';
7
- import type { StateHandler } from './state-handler.js';
8
- import type { TimerManager } from '../timers/timer-manager.js';
9
- import type { EventBusService } from '../services/event-bus-service.js';
10
- import type { ServiceResult } from '../types/service-result-type.js';
11
- /**
12
- * Handles all mode switches and the pause/extended switches.
13
- * Calls StateHandler directly (one-way dependency — no cycle).
14
- * Subscribes to bus events emitted by StateHandler to reset its own display state.
15
- */
16
- export declare class SwitchHandler {
17
- private readonly services;
18
- private readonly state;
19
- private readonly options;
20
- private readonly Characteristic;
21
- private readonly log;
22
- private readonly timers;
23
- private readonly stateHandler;
24
- constructor(services: ServiceRegistry, state: SystemState, options: SecuritySystemOptions, Characteristic: CharacteristicConstructor, log: Logging, timers: TimerManager, stateHandler: StateHandler);
25
- /** Register bus listeners so StateHandler can signal display resets without importing this class. */
26
- subscribeToStateEvents(bus: EventBusService): void;
27
- setModeSwitch(mode: SecurityState, value: boolean): number | null;
28
- setModeOffSwitch(value: boolean): number | null;
29
- setModeAwayExtendedSwitch(value: boolean): number | null;
30
- setModePauseSwitch(value: boolean): number | null;
31
- updateArmingLock(mode: string, value: boolean): ServiceResult;
32
- resetModeSwitches(): void;
33
- updateModeSwitches(): void;
34
- private logArmingLock;
35
- }
@@ -1,134 +0,0 @@
1
- import { SecurityState } from '../types/security-state-type.js';
2
- import { HK_NOT_ALLOWED_IN_CURRENT_STATE } from '../constants/homekit-constant.js';
3
- import { OriginType } from '../types/origin-type.js';
4
- import { capitalise } from '../utils/state-util.js';
5
- import { EventType } from '../types/event-type.js';
6
- /**
7
- * Handles all mode switches and the pause/extended switches.
8
- * Calls StateHandler directly (one-way dependency — no cycle).
9
- * Subscribes to bus events emitted by StateHandler to reset its own display state.
10
- */
11
- export class SwitchHandler {
12
- services;
13
- state;
14
- options;
15
- Characteristic;
16
- log;
17
- timers;
18
- stateHandler;
19
- constructor(services, state, options, Characteristic, log, timers, stateHandler) {
20
- this.services = services;
21
- this.state = state;
22
- this.options = options;
23
- this.Characteristic = Characteristic;
24
- this.log = log;
25
- this.timers = timers;
26
- this.stateHandler = stateHandler;
27
- }
28
- /** Register bus listeners so StateHandler can signal display resets without importing this class. */
29
- subscribeToStateEvents(bus) {
30
- bus.on(EventType.RESET_MODE_SWITCHES, () => this.resetModeSwitches());
31
- bus.on(EventType.UPDATE_MODE_SWITCHES, () => this.updateModeSwitches());
32
- }
33
- // ── Mode switches ──────────────────────────────────────────────────────────
34
- setModeSwitch(mode, value) {
35
- if (!value) {
36
- return HK_NOT_ALLOWED_IN_CURRENT_STATE;
37
- }
38
- const delay = this.stateHandler.getArmingSeconds(mode);
39
- this.stateHandler.updateTargetState(mode, OriginType.INTERNAL, delay);
40
- return null;
41
- }
42
- setModeOffSwitch(value) {
43
- if (!value) {
44
- return HK_NOT_ALLOWED_IN_CURRENT_STATE;
45
- }
46
- this.stateHandler.updateTargetState(SecurityState.OFF, OriginType.INTERNAL, 0);
47
- return null;
48
- }
49
- setModeAwayExtendedSwitch(value) {
50
- if (!value) {
51
- return HK_NOT_ALLOWED_IN_CURRENT_STATE;
52
- }
53
- const delay = this.stateHandler.getArmingSeconds(SecurityState.AWAY);
54
- this.stateHandler.updateTargetState(SecurityState.AWAY, OriginType.INTERNAL, delay);
55
- return null;
56
- }
57
- setModePauseSwitch(value) {
58
- if (this.state.currentState === SecurityState.TRIGGERED) {
59
- this.log.warn('Mode pause (Alarm is triggered)');
60
- return HK_NOT_ALLOWED_IN_CURRENT_STATE;
61
- }
62
- if (value) {
63
- if (this.state.currentState === SecurityState.OFF) {
64
- this.log.warn('Mode pause (Not armed)');
65
- return HK_NOT_ALLOWED_IN_CURRENT_STATE;
66
- }
67
- this.log.info('Mode pause (Started)');
68
- this.state.pausedCurrentState = this.state.currentState;
69
- this.stateHandler.updateTargetState(SecurityState.OFF, OriginType.INTERNAL, 0);
70
- if (this.options.pauseMinutes !== 0) {
71
- this.timers.setPauseTimer(this.options.pauseMinutes * 60 * 1000, () => {
72
- this.log.info('Mode pause (Finished)');
73
- const prev = this.state.pausedCurrentState ?? this.state.defaultState;
74
- this.stateHandler.updateTargetState(prev, OriginType.INTERNAL, this.stateHandler.getArmingSeconds(prev));
75
- });
76
- }
77
- }
78
- else {
79
- this.log.info('Mode pause (Cancelled)');
80
- this.timers.clearPauseTimer();
81
- const prev = this.state.pausedCurrentState ?? this.state.defaultState;
82
- this.stateHandler.updateTargetState(prev, OriginType.INTERNAL, this.stateHandler.getArmingSeconds(prev));
83
- }
84
- return null;
85
- }
86
- // ── Arming lock switches ───────────────────────────────────────────────────
87
- updateArmingLock(mode, value) {
88
- this.logArmingLock(mode, value);
89
- const map = {
90
- global: 'armingLockSwitchService',
91
- home: 'armingLockHomeSwitchService',
92
- away: 'armingLockAwaySwitchService',
93
- night: 'armingLockNightSwitchService',
94
- };
95
- const key = map[mode];
96
- if (!key) {
97
- this.log.debug(`Unknown arming lock mode (${mode})`);
98
- return { success: false, reason: `unknown arming lock mode: ${mode}` };
99
- }
100
- this.services[key].getCharacteristic(this.Characteristic.On).updateValue(value);
101
- return { success: true };
102
- }
103
- // ── Mode switch display ────────────────────────────────────────────────────
104
- resetModeSwitches() {
105
- const switches = [
106
- 'modeHomeSwitchService', 'modeAwaySwitchService', 'modeNightSwitchService',
107
- 'modeOffSwitchService', 'modeAwayExtendedSwitchService', 'modePauseSwitchService',
108
- ];
109
- for (const key of switches) {
110
- const char = this.services[key].getCharacteristic(this.Characteristic.On);
111
- if (char.value) {
112
- char.updateValue(false);
113
- this.log.debug(`${key} (Off)`);
114
- }
115
- }
116
- }
117
- updateModeSwitches() {
118
- const modeMap = {
119
- [SecurityState.HOME]: 'modeHomeSwitchService',
120
- [SecurityState.AWAY]: 'modeAwaySwitchService',
121
- [SecurityState.NIGHT]: 'modeNightSwitchService',
122
- [SecurityState.OFF]: 'modeOffSwitchService',
123
- };
124
- const key = modeMap[this.state.targetState];
125
- if (key) {
126
- this.services[key].updateCharacteristic(this.Characteristic.On, true);
127
- this.log.debug(`${key} (On)`);
128
- }
129
- }
130
- logArmingLock(mode, value) {
131
- this.log.info(`Arming lock [${capitalise(mode)}] (${value ? 'On' : 'Off'})`);
132
- }
133
- }
134
- //# sourceMappingURL=switch-handler.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"switch-handler.js","sourceRoot":"","sources":["../../src/handlers/switch-handler.ts"],"names":[],"mappings":"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"}
@@ -1,51 +0,0 @@
1
- import type { Logging } from 'homebridge';
2
- import type { CharacteristicConstructor } from '../interfaces/hap-types-interface.js';
3
- import { SecurityState } from '../types/security-state-type.js';
4
- import { OriginType } from '../types/origin-type.js';
5
- import type { ServiceRegistry } from '../interfaces/service-registry-interface.js';
6
- import type { SystemState } from '../interfaces/system-state-interface.js';
7
- import type { SecuritySystemOptions } from '../interfaces/options-interface.js';
8
- import type { EventBusService } from '../services/event-bus-service.js';
9
- import type { AudioService } from '../services/audio-service.js';
10
- import type { SensorHandler } from './sensor-handler.js';
11
- import type { TimerManager } from '../timers/timer-manager.js';
12
- import type { ServiceResult } from '../types/service-result-type.js';
13
- /**
14
- * Handles the trip switch and trigger-delay logic, including all blocking conditions.
15
- * Communicates state transitions back to the state machine via the event bus so that
16
- * no circular import is needed with StateHandler.
17
- */
18
- export declare class TripHandler {
19
- private readonly services;
20
- private readonly state;
21
- private readonly options;
22
- private readonly Characteristic;
23
- private readonly log;
24
- private readonly bus;
25
- private readonly audio;
26
- private readonly sensorHandler;
27
- private readonly timers;
28
- private readonly conditions;
29
- constructor(services: ServiceRegistry, state: SystemState, options: SecuritySystemOptions, Characteristic: CharacteristicConstructor, log: Logging, bus: EventBusService, audio: AudioService, sensorHandler: SensorHandler, timers: TimerManager);
30
- /**
31
- * Evaluates all blocking conditions for a trip action without side effects.
32
- * Returns a failed result with the condition's reason if any condition blocks the action.
33
- */
34
- checkTripConditions(value: boolean, origin: OriginType): ServiceResult;
35
- /**
36
- * Core trip-switch logic shared by all trip/trigger paths.
37
- * Returns a result object indicating success or the reason for failure.
38
- */
39
- updateTripSwitch(value: boolean, origin: OriginType, stateChanged: boolean): ServiceResult;
40
- /**
41
- * Trip a mode-specific switch. Only triggers if the system is currently in
42
- * the required mode (or the alarm is triggered and target matches).
43
- */
44
- triggerIfModeSet(requiredState: SecurityState, value: boolean): ServiceResult;
45
- resetTripSwitches(): void;
46
- private makeContext;
47
- private activateTrip;
48
- private startTrippedMotionSensor;
49
- private cancelTrip;
50
- private resolveTriggerSeconds;
51
- }
@@ -1,198 +0,0 @@
1
- import { SecurityState } from '../types/security-state-type.js';
2
- import { OriginType } from '../types/origin-type.js';
3
- import { EventType } from '../types/event-type.js';
4
- import { NotArmedCondition } from '../conditions/not-armed-condition.js';
5
- import { ArmingInProgressCondition } from '../conditions/arming-in-progress-condition.js';
6
- import { AlreadyTriggeredCondition } from '../conditions/already-triggered-condition.js';
7
- import { DoubleKnockCondition } from '../conditions/double-knock-condition.js';
8
- import { TriggerAlreadyRunningCondition } from '../conditions/trigger-already-running-condition.js';
9
- /**
10
- * Handles the trip switch and trigger-delay logic, including all blocking conditions.
11
- * Communicates state transitions back to the state machine via the event bus so that
12
- * no circular import is needed with StateHandler.
13
- */
14
- export class TripHandler {
15
- services;
16
- state;
17
- options;
18
- Characteristic;
19
- log;
20
- bus;
21
- audio;
22
- sensorHandler;
23
- timers;
24
- conditions;
25
- constructor(services, state, options, Characteristic, log, bus, audio, sensorHandler, timers) {
26
- this.services = services;
27
- this.state = state;
28
- this.options = options;
29
- this.Characteristic = Characteristic;
30
- this.log = log;
31
- this.bus = bus;
32
- this.audio = audio;
33
- this.sensorHandler = sensorHandler;
34
- this.timers = timers;
35
- const doubleKnock = new DoubleKnockCondition((seconds, onExpire) => {
36
- this.timers.setDoubleKnockTimer(seconds * 1000, onExpire);
37
- }, () => {
38
- this.timers.clearDoubleKnockTimer();
39
- });
40
- this.conditions = [
41
- new NotArmedCondition(),
42
- new ArmingInProgressCondition(),
43
- doubleKnock,
44
- new AlreadyTriggeredCondition(),
45
- new TriggerAlreadyRunningCondition(),
46
- ];
47
- }
48
- /**
49
- * Evaluates all blocking conditions for a trip action without side effects.
50
- * Returns a failed result with the condition's reason if any condition blocks the action.
51
- */
52
- checkTripConditions(value, origin) {
53
- if (!value) {
54
- return { success: true };
55
- }
56
- const ctx = this.makeContext(value, origin);
57
- for (const condition of this.conditions) {
58
- if (condition.evaluate(ctx)) {
59
- return { success: false, reason: condition.failureReason };
60
- }
61
- }
62
- return { success: true };
63
- }
64
- /**
65
- * Core trip-switch logic shared by all trip/trigger paths.
66
- * Returns a result object indicating success or the reason for failure.
67
- */
68
- updateTripSwitch(value, origin, stateChanged) {
69
- if (value) {
70
- const conditionResult = this.checkTripConditions(value, origin);
71
- if (!conditionResult.success) {
72
- return conditionResult;
73
- }
74
- this.activateTrip(origin);
75
- }
76
- else {
77
- this.cancelTrip(origin, stateChanged);
78
- }
79
- // Sync trip switch characteristic when origin is not a direct switch press.
80
- if (origin === OriginType.INTERNAL || origin === OriginType.EXTERNAL) {
81
- this.services.tripSwitchService.updateCharacteristic(this.Characteristic.On, value);
82
- }
83
- return { success: true };
84
- }
85
- /**
86
- * Trip a mode-specific switch. Only triggers if the system is currently in
87
- * the required mode (or the alarm is triggered and target matches).
88
- */
89
- triggerIfModeSet(requiredState, value) {
90
- const isTriggered = this.state.currentState === SecurityState.TRIGGERED;
91
- if (value) {
92
- const modeMatches = this.state.currentState === requiredState
93
- || (isTriggered && this.state.targetState === requiredState);
94
- if (!modeMatches) {
95
- this.log.debug('Security System (Trip mode not set)');
96
- return { success: false, reason: 'mode not set' };
97
- }
98
- }
99
- return this.updateTripSwitch(value, OriginType.REGULAR_SWITCH, false);
100
- }
101
- resetTripSwitches() {
102
- const switches = [
103
- ['tripSwitchService', 'Trip'],
104
- ['tripHomeSwitchService', 'Trip Home'],
105
- ['tripAwaySwitchService', 'Trip Away'],
106
- ['tripNightSwitchService', 'Trip Night'],
107
- ['tripOverrideSwitchService', 'Trip Override'],
108
- ];
109
- for (const [key, label] of switches) {
110
- const char = this.services[key].getCharacteristic(this.Characteristic.On);
111
- if (char.value) {
112
- char.updateValue(false);
113
- this.log.debug(`${label} Switch (Off)`);
114
- }
115
- }
116
- const customGroups = [
117
- this.services.customTripHomeSwitchServices,
118
- this.services.customTripAwaySwitchServices,
119
- this.services.customTripNightSwitchServices,
120
- ];
121
- for (const group of customGroups) {
122
- for (const svc of group) {
123
- const char = svc.getCharacteristic(this.Characteristic.On);
124
- if (char.value) {
125
- char.updateValue(false);
126
- }
127
- }
128
- }
129
- }
130
- makeContext(value, origin) {
131
- return {
132
- state: this.state,
133
- services: this.services,
134
- options: this.options,
135
- value,
136
- origin,
137
- log: this.log,
138
- };
139
- }
140
- activateTrip(origin) {
141
- this.log.info('Security System (Tripped)');
142
- if (this.options.trippedMotionSensor) {
143
- this.startTrippedMotionSensor();
144
- }
145
- const triggerSeconds = this.resolveTriggerSeconds();
146
- this.log.debug(`Trigger delay (${triggerSeconds}s)`);
147
- this.state.isTripping = true;
148
- this.timers.setTriggerTimer(triggerSeconds * 1000, () => {
149
- this.state.isTripping = false;
150
- this.bus.emit(EventType.TRIGGER_FIRED, { origin });
151
- });
152
- if (triggerSeconds > 0) {
153
- this.bus.emit(EventType.WARNING, { origin, triggerSeconds });
154
- }
155
- }
156
- startTrippedMotionSensor() {
157
- const seconds = this.options.trippedMotionSensorSeconds;
158
- if (seconds === 0) {
159
- this.sensorHandler.setTrippedMotionSensor(true);
160
- }
161
- else {
162
- this.sensorHandler.pulseTrippedMotionSensor();
163
- this.timers.setTrippedInterval(seconds * 1000, () => this.sensorHandler.pulseTrippedMotionSensor());
164
- }
165
- }
166
- cancelTrip(origin, stateChanged) {
167
- this.log.info('Security System (Cancelled)');
168
- this.state.isTripping = false;
169
- this.audio.stop();
170
- this.bus.emit(EventType.TRIP_CANCELLED, { origin, stateChanged });
171
- if (this.options.trippedMotionSensor) {
172
- this.sensorHandler.resetTrippedMotionSensor();
173
- }
174
- this.state.isKnocked = false;
175
- }
176
- resolveTriggerSeconds() {
177
- const seconds = this.options.triggerSeconds;
178
- const cur = this.state.currentState;
179
- if (cur === SecurityState.HOME && this.options.homeTriggerSeconds !== null) {
180
- return this.options.homeTriggerSeconds;
181
- }
182
- if (cur === SecurityState.AWAY) {
183
- const extChar = this.services.modeAwayExtendedSwitchService
184
- .getCharacteristic(this.Characteristic.On);
185
- if (this.options.modeAwayExtendedSwitchTriggerSeconds !== null && extChar.value) {
186
- return this.options.modeAwayExtendedSwitchTriggerSeconds;
187
- }
188
- if (this.options.awayTriggerSeconds !== null) {
189
- return this.options.awayTriggerSeconds;
190
- }
191
- }
192
- if (cur === SecurityState.NIGHT && this.options.nightTriggerSeconds !== null) {
193
- return this.options.nightTriggerSeconds;
194
- }
195
- return seconds;
196
- }
197
- }
198
- //# sourceMappingURL=trip-handler.js.map