homebridge-virtual-accessories 3.6.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 (270) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +1091 -0
  3. package/VirtualAccessories.jpg +0 -0
  4. package/VirtualAccessories.png +0 -0
  5. package/assets/changeorder.png +0 -0
  6. package/assets/creative-ideas/HowToAddAFakeThermostat.png +0 -0
  7. package/assets/keepaccessories.png +0 -0
  8. package/assets/mentions/youtube-EdgarsHomeTech.png +0 -0
  9. package/assets/mentions/youtube-MakeSmartMatter.png +0 -0
  10. package/assets/wiki/automation-shortcut-1.png +0 -0
  11. package/assets/wiki/automation-shortcut-2.png +0 -0
  12. package/assets/wiki/cron-schedule-config.png +0 -0
  13. package/assets/wiki/enable-sensor-webhooks.png +0 -0
  14. package/assets/wiki/humidifier-dehumidifier-config.png +0 -0
  15. package/assets/wiki/new-automation.png +0 -0
  16. package/assets/wiki/timer-duration-new.png +0 -0
  17. package/assets/wiki/timer-duration-old.png +0 -0
  18. package/assets/wiki/valve-timer-duration-new.png +0 -0
  19. package/assets/wiki/valve-timer-duration-old.png +0 -0
  20. package/config.schema.json +1570 -0
  21. package/dist/accessories/audioAccessory.d.ts +29 -0
  22. package/dist/accessories/audioAccessory.js +119 -0
  23. package/dist/accessories/audioAccessory.js.map +1 -0
  24. package/dist/accessories/externalAccessory.d.ts +10 -0
  25. package/dist/accessories/externalAccessory.js +13 -0
  26. package/dist/accessories/externalAccessory.js.map +1 -0
  27. package/dist/accessories/openingAccessory.d.ts +35 -0
  28. package/dist/accessories/openingAccessory.js +166 -0
  29. package/dist/accessories/openingAccessory.js.map +1 -0
  30. package/dist/accessories/triggerableEventAccessory.d.ts +7 -0
  31. package/dist/accessories/triggerableEventAccessory.js +2 -0
  32. package/dist/accessories/triggerableEventAccessory.js.map +1 -0
  33. package/dist/accessories/virtualAccessory.d.ts +29 -0
  34. package/dist/accessories/virtualAccessory.js +86 -0
  35. package/dist/accessories/virtualAccessory.js.map +1 -0
  36. package/dist/accessories/virtualAccessoryDoor.d.ts +14 -0
  37. package/dist/accessories/virtualAccessoryDoor.js +20 -0
  38. package/dist/accessories/virtualAccessoryDoor.js.map +1 -0
  39. package/dist/accessories/virtualAccessoryDoorbell.d.ts +29 -0
  40. package/dist/accessories/virtualAccessoryDoorbell.js +111 -0
  41. package/dist/accessories/virtualAccessoryDoorbell.js.map +1 -0
  42. package/dist/accessories/virtualAccessoryFan.d.ts +27 -0
  43. package/dist/accessories/virtualAccessoryFan.js +122 -0
  44. package/dist/accessories/virtualAccessoryFan.js.map +1 -0
  45. package/dist/accessories/virtualAccessoryFilterMaintenance.d.ts +26 -0
  46. package/dist/accessories/virtualAccessoryFilterMaintenance.js +122 -0
  47. package/dist/accessories/virtualAccessoryFilterMaintenance.js.map +1 -0
  48. package/dist/accessories/virtualAccessoryGarageDoor.d.ts +28 -0
  49. package/dist/accessories/virtualAccessoryGarageDoor.js +162 -0
  50. package/dist/accessories/virtualAccessoryGarageDoor.js.map +1 -0
  51. package/dist/accessories/virtualAccessoryHeaterCooler.d.ts +62 -0
  52. package/dist/accessories/virtualAccessoryHeaterCooler.js +441 -0
  53. package/dist/accessories/virtualAccessoryHeaterCooler.js.map +1 -0
  54. package/dist/accessories/virtualAccessoryHumidifierDehumidifier.d.ts +53 -0
  55. package/dist/accessories/virtualAccessoryHumidifierDehumidifier.js +365 -0
  56. package/dist/accessories/virtualAccessoryHumidifierDehumidifier.js.map +1 -0
  57. package/dist/accessories/virtualAccessoryInputSource.d.ts +38 -0
  58. package/dist/accessories/virtualAccessoryInputSource.js +196 -0
  59. package/dist/accessories/virtualAccessoryInputSource.js.map +1 -0
  60. package/dist/accessories/virtualAccessoryLightbulb.d.ts +37 -0
  61. package/dist/accessories/virtualAccessoryLightbulb.js +222 -0
  62. package/dist/accessories/virtualAccessoryLightbulb.js.map +1 -0
  63. package/dist/accessories/virtualAccessoryLock.d.ts +34 -0
  64. package/dist/accessories/virtualAccessoryLock.js +198 -0
  65. package/dist/accessories/virtualAccessoryLock.js.map +1 -0
  66. package/dist/accessories/virtualAccessorySecuritySystem.d.ts +30 -0
  67. package/dist/accessories/virtualAccessorySecuritySystem.js +214 -0
  68. package/dist/accessories/virtualAccessorySecuritySystem.js.map +1 -0
  69. package/dist/accessories/virtualAccessorySpeaker.d.ts +14 -0
  70. package/dist/accessories/virtualAccessorySpeaker.js +20 -0
  71. package/dist/accessories/virtualAccessorySpeaker.js.map +1 -0
  72. package/dist/accessories/virtualAccessorySwitch.d.ts +34 -0
  73. package/dist/accessories/virtualAccessorySwitch.js +191 -0
  74. package/dist/accessories/virtualAccessorySwitch.js.map +1 -0
  75. package/dist/accessories/virtualAccessoryTelevision.d.ts +44 -0
  76. package/dist/accessories/virtualAccessoryTelevision.js +230 -0
  77. package/dist/accessories/virtualAccessoryTelevision.js.map +1 -0
  78. package/dist/accessories/virtualAccessoryValve.d.ts +34 -0
  79. package/dist/accessories/virtualAccessoryValve.js +215 -0
  80. package/dist/accessories/virtualAccessoryValve.js.map +1 -0
  81. package/dist/accessories/virtualAccessoryWindow.d.ts +14 -0
  82. package/dist/accessories/virtualAccessoryWindow.js +20 -0
  83. package/dist/accessories/virtualAccessoryWindow.js.map +1 -0
  84. package/dist/accessories/virtualAccessoryWindowCovering.d.ts +14 -0
  85. package/dist/accessories/virtualAccessoryWindowCovering.js +20 -0
  86. package/dist/accessories/virtualAccessoryWindowCovering.js.map +1 -0
  87. package/dist/accessoryFactory.d.ts +15 -0
  88. package/dist/accessoryFactory.js +147 -0
  89. package/dist/accessoryFactory.js.map +1 -0
  90. package/dist/colors.d.ts +22 -0
  91. package/dist/colors.js +146 -0
  92. package/dist/colors.js.map +1 -0
  93. package/dist/companions/companionLightbulb.d.ts +10 -0
  94. package/dist/companions/companionLightbulb.js +12 -0
  95. package/dist/companions/companionLightbulb.js.map +1 -0
  96. package/dist/companions/companionSensors.d.ts +9 -0
  97. package/dist/companions/companionSensors.js +117 -0
  98. package/dist/companions/companionSensors.js.map +1 -0
  99. package/dist/companions/companionSwitch.d.ts +15 -0
  100. package/dist/companions/companionSwitch.js +46 -0
  101. package/dist/companions/companionSwitch.js.map +1 -0
  102. package/dist/configuration/accessories/configurationDoor.d.ts +9 -0
  103. package/dist/configuration/accessories/configurationDoor.js +31 -0
  104. package/dist/configuration/accessories/configurationDoor.js.map +1 -0
  105. package/dist/configuration/accessories/configurationDoorbell.d.ts +10 -0
  106. package/dist/configuration/accessories/configurationDoorbell.js +23 -0
  107. package/dist/configuration/accessories/configurationDoorbell.js.map +1 -0
  108. package/dist/configuration/accessories/configurationFan.d.ts +12 -0
  109. package/dist/configuration/accessories/configurationFan.js +36 -0
  110. package/dist/configuration/accessories/configurationFan.js.map +1 -0
  111. package/dist/configuration/accessories/configurationFilterMaintenance.d.ts +12 -0
  112. package/dist/configuration/accessories/configurationFilterMaintenance.js +48 -0
  113. package/dist/configuration/accessories/configurationFilterMaintenance.js.map +1 -0
  114. package/dist/configuration/accessories/configurationGarageDoor.d.ts +9 -0
  115. package/dist/configuration/accessories/configurationGarageDoor.js +31 -0
  116. package/dist/configuration/accessories/configurationGarageDoor.js.map +1 -0
  117. package/dist/configuration/accessories/configurationHeaterCooler.d.ts +20 -0
  118. package/dist/configuration/accessories/configurationHeaterCooler.js +116 -0
  119. package/dist/configuration/accessories/configurationHeaterCooler.js.map +1 -0
  120. package/dist/configuration/accessories/configurationHumidifierDehumidifier.d.ts +12 -0
  121. package/dist/configuration/accessories/configurationHumidifierDehumidifier.js +44 -0
  122. package/dist/configuration/accessories/configurationHumidifierDehumidifier.js.map +1 -0
  123. package/dist/configuration/accessories/configurationInputSource.d.ts +12 -0
  124. package/dist/configuration/accessories/configurationInputSource.js +33 -0
  125. package/dist/configuration/accessories/configurationInputSource.js.map +1 -0
  126. package/dist/configuration/accessories/configurationLightbulb.d.ts +14 -0
  127. package/dist/configuration/accessories/configurationLightbulb.js +55 -0
  128. package/dist/configuration/accessories/configurationLightbulb.js.map +1 -0
  129. package/dist/configuration/accessories/configurationLock.d.ts +11 -0
  130. package/dist/configuration/accessories/configurationLock.js +30 -0
  131. package/dist/configuration/accessories/configurationLock.js.map +1 -0
  132. package/dist/configuration/accessories/configurationSecuritySystem.d.ts +18 -0
  133. package/dist/configuration/accessories/configurationSecuritySystem.js +48 -0
  134. package/dist/configuration/accessories/configurationSecuritySystem.js.map +1 -0
  135. package/dist/configuration/accessories/configurationSpeaker.d.ts +9 -0
  136. package/dist/configuration/accessories/configurationSpeaker.js +24 -0
  137. package/dist/configuration/accessories/configurationSpeaker.js.map +1 -0
  138. package/dist/configuration/accessories/configurationSwitch.d.ts +13 -0
  139. package/dist/configuration/accessories/configurationSwitch.js +27 -0
  140. package/dist/configuration/accessories/configurationSwitch.js.map +1 -0
  141. package/dist/configuration/accessories/configurationTelevision.d.ts +12 -0
  142. package/dist/configuration/accessories/configurationTelevision.js +47 -0
  143. package/dist/configuration/accessories/configurationTelevision.js.map +1 -0
  144. package/dist/configuration/accessories/configurationValve.d.ts +25 -0
  145. package/dist/configuration/accessories/configurationValve.js +88 -0
  146. package/dist/configuration/accessories/configurationValve.js.map +1 -0
  147. package/dist/configuration/accessories/configurationWindow.d.ts +9 -0
  148. package/dist/configuration/accessories/configurationWindow.js +31 -0
  149. package/dist/configuration/accessories/configurationWindow.js.map +1 -0
  150. package/dist/configuration/accessories/configurationWindowCovering.d.ts +9 -0
  151. package/dist/configuration/accessories/configurationWindowCovering.js +31 -0
  152. package/dist/configuration/accessories/configurationWindowCovering.js.map +1 -0
  153. package/dist/configuration/configuration.d.ts +13 -0
  154. package/dist/configuration/configuration.js +41 -0
  155. package/dist/configuration/configuration.js.map +1 -0
  156. package/dist/configuration/configurationAccessory.d.ts +6 -0
  157. package/dist/configuration/configurationAccessory.js +6 -0
  158. package/dist/configuration/configurationAccessory.js.map +1 -0
  159. package/dist/configuration/configurationAudioAccessoryConfiguration.d.ts +9 -0
  160. package/dist/configuration/configurationAudioAccessoryConfiguration.js +9 -0
  161. package/dist/configuration/configurationAudioAccessoryConfiguration.js.map +1 -0
  162. package/dist/configuration/configurationCompanionSensor.d.ts +11 -0
  163. package/dist/configuration/configurationCompanionSensor.js +26 -0
  164. package/dist/configuration/configurationCompanionSensor.js.map +1 -0
  165. package/dist/configuration/configurationDuration.d.ts +19 -0
  166. package/dist/configuration/configurationDuration.js +55 -0
  167. package/dist/configuration/configurationDuration.js.map +1 -0
  168. package/dist/configuration/configurationOpenableAccesory.d.ts +9 -0
  169. package/dist/configuration/configurationOpenableAccesory.js +9 -0
  170. package/dist/configuration/configurationOpenableAccesory.js.map +1 -0
  171. package/dist/configuration/configurationPlatform.d.ts +76 -0
  172. package/dist/configuration/configurationPlatform.js +381 -0
  173. package/dist/configuration/configurationPlatform.js.map +1 -0
  174. package/dist/configuration/configurationSchema.d.ts +178 -0
  175. package/dist/configuration/configurationSchema.js +198 -0
  176. package/dist/configuration/configurationSchema.js.map +1 -0
  177. package/dist/configuration/configurationSensor.d.ts +11 -0
  178. package/dist/configuration/configurationSensor.js +30 -0
  179. package/dist/configuration/configurationSensor.js.map +1 -0
  180. package/dist/configuration/configurationSensorServer.d.ts +11 -0
  181. package/dist/configuration/configurationSensorServer.js +26 -0
  182. package/dist/configuration/configurationSensorServer.js.map +1 -0
  183. package/dist/configuration/configurationTimer.d.ts +15 -0
  184. package/dist/configuration/configurationTimer.js +101 -0
  185. package/dist/configuration/configurationTimer.js.map +1 -0
  186. package/dist/configuration/triggers/configurationCronTrigger.d.ts +18 -0
  187. package/dist/configuration/triggers/configurationCronTrigger.js +65 -0
  188. package/dist/configuration/triggers/configurationCronTrigger.js.map +1 -0
  189. package/dist/configuration/triggers/configurationPingTrigger.d.ts +11 -0
  190. package/dist/configuration/triggers/configurationPingTrigger.js +26 -0
  191. package/dist/configuration/triggers/configurationPingTrigger.js.map +1 -0
  192. package/dist/configuration/triggers/configurationSunEventsTrigger.d.ts +18 -0
  193. package/dist/configuration/triggers/configurationSunEventsTrigger.js +52 -0
  194. package/dist/configuration/triggers/configurationSunEventsTrigger.js.map +1 -0
  195. package/dist/configuration/triggers/configurationWebhookTriggerConfiguration.d.ts +9 -0
  196. package/dist/configuration/triggers/configurationWebhookTriggerConfiguration.js +17 -0
  197. package/dist/configuration/triggers/configurationWebhookTriggerConfiguration.js.map +1 -0
  198. package/dist/errors.d.ts +27 -0
  199. package/dist/errors.js +52 -0
  200. package/dist/errors.js.map +1 -0
  201. package/dist/index.d.ts +6 -0
  202. package/dist/index.js +9 -0
  203. package/dist/index.js.map +1 -0
  204. package/dist/platform.d.ts +28 -0
  205. package/dist/platform.js +221 -0
  206. package/dist/platform.js.map +1 -0
  207. package/dist/sensorServer.d.ts +27 -0
  208. package/dist/sensorServer.js +227 -0
  209. package/dist/sensorServer.js.map +1 -0
  210. package/dist/sensors/virtualSensor.d.ts +37 -0
  211. package/dist/sensors/virtualSensor.js +87 -0
  212. package/dist/sensors/virtualSensor.js.map +1 -0
  213. package/dist/sensors/virtualSensorCarbonDioxide.d.ts +20 -0
  214. package/dist/sensors/virtualSensorCarbonDioxide.js +45 -0
  215. package/dist/sensors/virtualSensorCarbonDioxide.js.map +1 -0
  216. package/dist/sensors/virtualSensorCarbonMonoxide.d.ts +20 -0
  217. package/dist/sensors/virtualSensorCarbonMonoxide.js +45 -0
  218. package/dist/sensors/virtualSensorCarbonMonoxide.js.map +1 -0
  219. package/dist/sensors/virtualSensorContact.d.ts +20 -0
  220. package/dist/sensors/virtualSensorContact.js +45 -0
  221. package/dist/sensors/virtualSensorContact.js.map +1 -0
  222. package/dist/sensors/virtualSensorLeak.d.ts +20 -0
  223. package/dist/sensors/virtualSensorLeak.js +45 -0
  224. package/dist/sensors/virtualSensorLeak.js.map +1 -0
  225. package/dist/sensors/virtualSensorMotion.d.ts +20 -0
  226. package/dist/sensors/virtualSensorMotion.js +45 -0
  227. package/dist/sensors/virtualSensorMotion.js.map +1 -0
  228. package/dist/sensors/virtualSensorOccupancy.d.ts +20 -0
  229. package/dist/sensors/virtualSensorOccupancy.js +45 -0
  230. package/dist/sensors/virtualSensorOccupancy.js.map +1 -0
  231. package/dist/sensors/virtualSensorSmoke.d.ts +20 -0
  232. package/dist/sensors/virtualSensorSmoke.js +45 -0
  233. package/dist/sensors/virtualSensorSmoke.js.map +1 -0
  234. package/dist/settings.d.ts +8 -0
  235. package/dist/settings.js +9 -0
  236. package/dist/settings.js.map +1 -0
  237. package/dist/timer.d.ts +58 -0
  238. package/dist/timer.js +110 -0
  239. package/dist/timer.js.map +1 -0
  240. package/dist/triggerableSensor.d.ts +6 -0
  241. package/dist/triggerableSensor.js +2 -0
  242. package/dist/triggerableSensor.js.map +1 -0
  243. package/dist/triggers/trigger.d.ts +13 -0
  244. package/dist/triggers/trigger.js +16 -0
  245. package/dist/triggers/trigger.js.map +1 -0
  246. package/dist/triggers/triggerCron.d.ts +19 -0
  247. package/dist/triggers/triggerCron.js +102 -0
  248. package/dist/triggers/triggerCron.js.map +1 -0
  249. package/dist/triggers/triggerPing.d.ts +19 -0
  250. package/dist/triggers/triggerPing.js +110 -0
  251. package/dist/triggers/triggerPing.js.map +1 -0
  252. package/dist/triggers/triggerSunEvents.d.ts +20 -0
  253. package/dist/triggers/triggerSunEvents.js +200 -0
  254. package/dist/triggers/triggerSunEvents.js.map +1 -0
  255. package/dist/triggers/triggerWebhook.d.ts +10 -0
  256. package/dist/triggers/triggerWebhook.js +26 -0
  257. package/dist/triggers/triggerWebhook.js.map +1 -0
  258. package/dist/updatableObstruction.d.ts +6 -0
  259. package/dist/updatableObstruction.js +2 -0
  260. package/dist/updatableObstruction.js.map +1 -0
  261. package/dist/updatableSensor.d.ts +6 -0
  262. package/dist/updatableSensor.js +2 -0
  263. package/dist/updatableSensor.js.map +1 -0
  264. package/dist/utils.d.ts +28 -0
  265. package/dist/utils.js +120 -0
  266. package/dist/utils.js.map +1 -0
  267. package/dist/virtualLogger.d.ts +15 -0
  268. package/dist/virtualLogger.js +38 -0
  269. package/dist/virtualLogger.js.map +1 -0
  270. package/package.json +120 -0
@@ -0,0 +1,111 @@
1
+ import { Accessory } from './virtualAccessory.js';
2
+ import { AccessoryNotAllowedError } from '../errors.js';
3
+ import { CompanionSwitch } from '../companions/companionSwitch.js';
4
+ import { SwitchConfiguration } from '../configuration/accessories/configurationSwitch.js';
5
+ import { TimerConfiguration } from '../configuration/configurationTimer.js';
6
+ import { DurationConfiguration } from '../configuration/configurationDuration.js';
7
+ /**
8
+ * Doorbell - Accessory implementation
9
+ */
10
+ export class Doorbell extends Accessory {
11
+ static ACCESSORY_TYPE_NAME = 'Doorbell';
12
+ static SINGLE_PRESS = 0; // Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS
13
+ static DOUBLE_PRESS = 1; // Characteristic.ProgrammableSwitchEvent.DOUBLE_PRESS
14
+ static LONG_PRESS = 2; // Characteristic.ProgrammableSwitchEvent.LONG_PRESS;
15
+ static COMPANION_TIMER_RESET = 1;
16
+ companionSensorResetTimerId;
17
+ states = {
18
+ Volume: 100,
19
+ };
20
+ companionSwitch;
21
+ constructor(platform, accessory) {
22
+ super(platform, accessory);
23
+ // First configure the device based on the accessory details
24
+ this.states.Volume = this.accessoryConfiguration.doorbell.volume;
25
+ this.service = this.accessory.getService(this.platform.Service.Doorbell) || this.accessory.addService(this.platform.Service.Doorbell);
26
+ this.service.setCharacteristic(this.platform.Characteristic.Name, this.accessoryConfiguration.accessoryName);
27
+ this.service.getCharacteristic(this.platform.Characteristic.ProgrammableSwitchEvent)
28
+ .onGet(this.getProgrammableSwitchEvent.bind(this));
29
+ // TODO: Figure out how to change the volume
30
+ this.service.getCharacteristic(this.platform.Characteristic.Volume)
31
+ .onSet(this.setVolume.bind(this))
32
+ .onGet(this.getVolume.bind(this));
33
+ // Create switch service
34
+ this.companionSwitch = this.createCompanionSwitch();
35
+ }
36
+ // Handlers
37
+ async getProgrammableSwitchEvent() {
38
+ // implement your own code to check if the device is on
39
+ const pressEvent = Doorbell.SINGLE_PRESS;
40
+ this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Getting Programmable Switch Event: ${Doorbell.getEventName(pressEvent)}`);
41
+ return pressEvent;
42
+ }
43
+ async setVolume(value) {
44
+ this.states.Volume = value;
45
+ this.log.info(`[${this.accessoryConfiguration.accessoryName}] Setting Volume: ${this.states.Volume}`);
46
+ }
47
+ async getVolume() {
48
+ const volume = this.states.Volume;
49
+ this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Getting Volume: ${volume}`);
50
+ return volume;
51
+ }
52
+ /**
53
+ * This method is called by the comoanion switch to ring the doorbell
54
+ */
55
+ async triggerEvent(companionAccessory) {
56
+ if (!(companionAccessory.accessoryConfiguration.accessoryID === this.accessoryConfiguration.accessoryID)) {
57
+ throw new AccessoryNotAllowedError(`Switch ${companionAccessory.accessoryConfiguration.accessoryName} is not allowed to trigger this sensor`);
58
+ }
59
+ this.service.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchEvent, (Doorbell.SINGLE_PRESS));
60
+ this.log.info(`[${this.accessoryConfiguration.accessoryName}] Triggered Doorbell Event: ${Doorbell.getEventName(Doorbell.SINGLE_PRESS)}`);
61
+ }
62
+ getJsonState() {
63
+ return JSON.stringify({});
64
+ }
65
+ getAccessoryTypeName() {
66
+ return Doorbell.ACCESSORY_TYPE_NAME;
67
+ }
68
+ static getEventName(event) {
69
+ let eventName;
70
+ switch (event) {
71
+ case undefined: {
72
+ eventName = 'undefined';
73
+ break;
74
+ }
75
+ case Doorbell.SINGLE_PRESS: {
76
+ eventName = 'SINGLE PRESS';
77
+ break;
78
+ }
79
+ case Doorbell.DOUBLE_PRESS: {
80
+ eventName = 'DOUBLE PRESS';
81
+ break;
82
+ }
83
+ case Doorbell.LONG_PRESS: {
84
+ eventName = 'LONG PRESS';
85
+ break;
86
+ }
87
+ default: {
88
+ eventName = event.toString();
89
+ }
90
+ }
91
+ return eventName;
92
+ }
93
+ createCompanionSwitch() {
94
+ // Enrich configuration with "switch" settings
95
+ this.accessoryConfiguration.switch = new SwitchConfiguration();
96
+ this.accessoryConfiguration.switch.defaultState = 'off';
97
+ this.accessoryConfiguration.switch.hasCompanionSensor = false;
98
+ this.accessoryConfiguration.switch.hasResetTimer = true;
99
+ this.accessoryConfiguration.switch.muteLogging = false;
100
+ // Enrich configuration with "resetTimer" settings
101
+ this.accessoryConfiguration.resetTimer = new TimerConfiguration();
102
+ this.accessoryConfiguration.resetTimer.duration = new DurationConfiguration();
103
+ this.accessoryConfiguration.resetTimer.duration.days = 0;
104
+ this.accessoryConfiguration.resetTimer.duration.hours = 0;
105
+ this.accessoryConfiguration.resetTimer.duration.minutes = 0;
106
+ this.accessoryConfiguration.resetTimer.duration.seconds = Doorbell.COMPANION_TIMER_RESET;
107
+ const companionSwitch = new CompanionSwitch(this.platform, this.accessory, this.accessoryConfiguration.accessoryName + ' Switch', this);
108
+ return companionSwitch;
109
+ }
110
+ }
111
+ //# sourceMappingURL=virtualAccessoryDoorbell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"virtualAccessoryDoorbell.js","sourceRoot":"","sources":["../../src/accessories/virtualAccessoryDoorbell.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { CharacteristicValue, PlatformAccessory } from 'homebridge';
2
+ import { VirtualAccessoriesPlatform } from '../platform.js';
3
+ import { Accessory } from './virtualAccessory.js';
4
+ /**
5
+ * Fan - Accessory implementation
6
+ */
7
+ export declare class Fan extends Accessory {
8
+ static readonly ACCESSORY_TYPE_NAME: string;
9
+ static readonly ON: boolean;
10
+ static readonly OFF: boolean;
11
+ static readonly CLOCKWISE: number;
12
+ static readonly COUNTER_CLOCKWISE: number;
13
+ private readonly stateStorageKey;
14
+ private readonly rotatioDirectionStorageKey;
15
+ private readonly rotatioSpeedStorageKey;
16
+ private states;
17
+ constructor(platform: VirtualAccessoriesPlatform, accessory: PlatformAccessory);
18
+ setOn(value: CharacteristicValue): Promise<void>;
19
+ getOn(): Promise<CharacteristicValue>;
20
+ setRotationDirection(value: CharacteristicValue): Promise<void>;
21
+ getRotationDirection(): Promise<CharacteristicValue>;
22
+ setRotationSpeed(value: CharacteristicValue): Promise<void>;
23
+ getRotationSpeed(): Promise<CharacteristicValue>;
24
+ protected getJsonState(): string;
25
+ protected getAccessoryTypeName(): string;
26
+ static getStateName(state: boolean): string;
27
+ }
@@ -0,0 +1,122 @@
1
+ import { Accessory } from './virtualAccessory.js';
2
+ /**
3
+ * Fan - Accessory implementation
4
+ */
5
+ export class Fan extends Accessory {
6
+ static ACCESSORY_TYPE_NAME = 'Fan';
7
+ static ON = true;
8
+ static OFF = false;
9
+ static CLOCKWISE = 0; // Characteristic.ProgrammableSwitchEvent.RotationDirection.CLOCKWISE;
10
+ static COUNTER_CLOCKWISE = 1; // Characteristic.ProgrammableSwitchEvent.RotationDirection.COUNTER_CLOCKWISE;
11
+ stateStorageKey = 'FanState';
12
+ rotatioDirectionStorageKey = 'FanRotationDirection';
13
+ rotatioSpeedStorageKey = 'FanRotationSpeed';
14
+ states = {
15
+ FanState: Fan.OFF,
16
+ FanRotationDirection: Fan.CLOCKWISE,
17
+ FanRotationSpeed: 100,
18
+ };
19
+ constructor(platform, accessory) {
20
+ super(platform, accessory);
21
+ // First configure the device based on the accessory details
22
+ this.defaultState = this.accessoryConfiguration.fan.defaultState === 'on' ? Fan.ON : Fan.OFF;
23
+ const rotationDirection = this.accessoryConfiguration.fan.rotationDirection === 'clockwise' ? Fan.CLOCKWISE : Fan.COUNTER_CLOCKWISE;
24
+ const rotationSpeed = this.accessoryConfiguration.fan.rotationSpeed;
25
+ this.states.FanState = this.defaultState;
26
+ this.states.FanRotationDirection = rotationDirection;
27
+ this.states.FanRotationSpeed = rotationSpeed;
28
+ // If the accessory is stateful retrieve stored state
29
+ if (this.accessoryConfiguration.accessoryIsStateful) {
30
+ const accessoryState = this.loadAccessoryState(this.storagePath);
31
+ const cachedState = accessoryState[this.stateStorageKey];
32
+ const cachedRotationDirection = accessoryState[this.rotatioDirectionStorageKey];
33
+ const cachedRotationSpeed = accessoryState[this.rotatioSpeedStorageKey];
34
+ if (cachedState !== undefined && cachedRotationDirection !== undefined && cachedRotationSpeed !== undefined) {
35
+ this.states.FanState = cachedState;
36
+ this.states.FanRotationDirection = cachedRotationDirection;
37
+ this.states.FanRotationSpeed = cachedRotationSpeed;
38
+ }
39
+ }
40
+ this.service = this.accessory.getService(this.platform.Service.Fan) || this.accessory.addService(this.platform.Service.Fan);
41
+ this.service.setCharacteristic(this.platform.Characteristic.Name, this.accessoryConfiguration.accessoryName);
42
+ // Update the initial state of the accessory
43
+ this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Setting Fan Current State: ${Fan.getStateName(this.states.FanState)}`);
44
+ this.service.updateCharacteristic(this.platform.Characteristic.On, (this.states.FanState));
45
+ this.service.updateCharacteristic(this.platform.Characteristic.RotationDirection, (this.states.FanRotationDirection));
46
+ this.service.updateCharacteristic(this.platform.Characteristic.RotationSpeed, (this.states.FanRotationSpeed));
47
+ // register handlers
48
+ this.service.getCharacteristic(this.platform.Characteristic.On)
49
+ .onSet(this.setOn.bind(this))
50
+ .onGet(this.getOn.bind(this));
51
+ this.service.getCharacteristic(this.platform.Characteristic.RotationDirection)
52
+ .onSet(this.setRotationDirection.bind(this))
53
+ .onGet(this.getRotationDirection.bind(this));
54
+ this.service.getCharacteristic(this.platform.Characteristic.RotationSpeed)
55
+ .onSet(this.setRotationSpeed.bind(this))
56
+ .onGet(this.getRotationSpeed.bind(this));
57
+ }
58
+ // Handlers
59
+ async setOn(value) {
60
+ this.states.FanState = value;
61
+ this.storeState();
62
+ this.log.info(`[${this.accessoryConfiguration.accessoryName}] Setting State: ${Fan.getStateName(this.states.FanState)}`);
63
+ }
64
+ async getOn() {
65
+ const fanState = this.states.FanState;
66
+ this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Getting State: ${Fan.getStateName(fanState)}`);
67
+ return fanState;
68
+ }
69
+ async setRotationDirection(value) {
70
+ this.states.FanRotationDirection = value;
71
+ this.storeState();
72
+ this.log.info(`[${this.accessoryConfiguration.accessoryName}] Setting Rotation Direction: ${this.states.FanRotationDirection}`);
73
+ }
74
+ async getRotationDirection() {
75
+ const fanRotationDirection = this.states.FanRotationDirection;
76
+ this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Getting Rotation Direction: ${fanRotationDirection}`);
77
+ return fanRotationDirection;
78
+ }
79
+ async setRotationSpeed(value) {
80
+ this.states.FanRotationSpeed = value;
81
+ this.storeState();
82
+ this.log.info(`[${this.accessoryConfiguration.accessoryName}] Setting Rotation Speed: ${this.states.FanRotationSpeed}%`);
83
+ }
84
+ async getRotationSpeed() {
85
+ const fanRotationSpeed = this.states.FanRotationSpeed;
86
+ this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Getting Rotation Speed: ${fanRotationSpeed}%`);
87
+ return fanRotationSpeed;
88
+ }
89
+ getJsonState() {
90
+ const json = JSON.stringify({
91
+ [this.stateStorageKey]: this.states.FanState,
92
+ [this.rotatioDirectionStorageKey]: this.states.FanRotationDirection,
93
+ [this.rotatioSpeedStorageKey]: this.states.FanRotationSpeed,
94
+ });
95
+ return json;
96
+ }
97
+ getAccessoryTypeName() {
98
+ return Fan.ACCESSORY_TYPE_NAME;
99
+ }
100
+ static getStateName(state) {
101
+ let stateName;
102
+ switch (state) {
103
+ case undefined: {
104
+ stateName = 'undefined';
105
+ break;
106
+ }
107
+ case Fan.ON: {
108
+ stateName = 'ON';
109
+ break;
110
+ }
111
+ case Fan.OFF: {
112
+ stateName = 'OFF';
113
+ break;
114
+ }
115
+ default: {
116
+ stateName = state.toString();
117
+ }
118
+ }
119
+ return stateName;
120
+ }
121
+ }
122
+ //# sourceMappingURL=virtualAccessoryFan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"virtualAccessoryFan.js","sourceRoot":"","sources":["../../src/accessories/virtualAccessoryFan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { CharacteristicValue, PlatformAccessory } from 'homebridge';
2
+ import { VirtualAccessoriesPlatform } from '../platform.js';
3
+ import { Accessory } from './virtualAccessory.js';
4
+ /**
5
+ * FilterMaintenance - Accessory implementation
6
+ */
7
+ export declare class FilterMaintenance extends Accessory {
8
+ static readonly ACCESSORY_TYPE_NAME: string;
9
+ static readonly FILTER_OK: number;
10
+ static readonly CHANGE_FILTER: number;
11
+ private readonly timerStartTimeStorageKey;
12
+ private readonly timerDurationStorageKey;
13
+ private readonly timerIsRunningStorageKey;
14
+ private lifespan;
15
+ private lifespanTimer;
16
+ private filterChangeIndicator;
17
+ private states;
18
+ constructor(platform: VirtualAccessoriesPlatform, accessory: PlatformAccessory);
19
+ getFilterChangeIndication(): Promise<CharacteristicValue>;
20
+ getFilterLifeLevel(): Promise<CharacteristicValue>;
21
+ setResetFilterIndication(value: CharacteristicValue): Promise<void>;
22
+ protected getJsonState(): string;
23
+ protected getAccessoryTypeName(): string;
24
+ static getStateName(event: number): string;
25
+ private onTimerExpired;
26
+ }
@@ -0,0 +1,122 @@
1
+ /* eslint-disable brace-style */
2
+ import { Accessory } from './virtualAccessory.js';
3
+ import { Timer } from '../timer.js';
4
+ import { Utils } from '../utils.js';
5
+ /**
6
+ * FilterMaintenance - Accessory implementation
7
+ */
8
+ export class FilterMaintenance extends Accessory {
9
+ static ACCESSORY_TYPE_NAME = 'Filter';
10
+ static FILTER_OK = 0; // Characteristic.FilterChangeIndication.FILTER_OK
11
+ static CHANGE_FILTER = 1; // Characteristic.FilterChangeIndication.CHANGE_FILTER
12
+ timerStartTimeStorageKey = 'TimerStartTime';
13
+ timerDurationStorageKey = 'TimerDuration';
14
+ timerIsRunningStorageKey = 'TimerIsRunning';
15
+ lifespan;
16
+ lifespanTimer;
17
+ filterChangeIndicator;
18
+ states = {};
19
+ constructor(platform, accessory) {
20
+ super(platform, accessory);
21
+ // First configure the device based on the accessory details
22
+ this.lifespan = Utils.daysHoursMinutesSecondsToSeconds(this.accessoryConfiguration.filterMaintenance.lifespan.days, this.accessoryConfiguration.filterMaintenance.lifespan.hours, this.accessoryConfiguration.filterMaintenance.lifespan.minutes, this.accessoryConfiguration.filterMaintenance.lifespan.seconds);
23
+ const timerIsResettable = true;
24
+ this.lifespanTimer = new Timer(this.accessoryConfiguration.accessoryName, this.log, timerIsResettable, this.lifespan);
25
+ const accessoryState = this.loadAccessoryState(this.storagePath);
26
+ if (this.isEmptyAccessoryState(accessoryState)) {
27
+ // No stored state -> First run
28
+ this.lifespanTimer.start(this.onTimerExpired);
29
+ this.storeState();
30
+ }
31
+ else {
32
+ const cachedTimerStartTime = accessoryState[this.timerStartTimeStorageKey];
33
+ const cachedTimerDuration = accessoryState[this.timerDurationStorageKey];
34
+ const cachedTimerIsRunning = accessoryState[this.timerIsRunningStorageKey];
35
+ this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Cached Timer Start Time: ${cachedTimerStartTime}`);
36
+ this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Cached Timer Duration: ${cachedTimerDuration}`);
37
+ this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Cached Timer Is Running: ${cachedTimerIsRunning}`);
38
+ // If the timer was running, calculate elapsed time and set timer for remaining duration
39
+ if (cachedTimerIsRunning) {
40
+ Utils.restoreRunningTimer(this.lifespanTimer, cachedTimerStartTime, cachedTimerDuration, this.onTimerExpired, this.accessoryConfiguration.accessoryName, this.log);
41
+ // Do not store state if the timer was restored!
42
+ // Store state only when the timer started or reset
43
+ }
44
+ }
45
+ this.filterChangeIndicator = this.lifespanTimer?.isTimerRunning() ? FilterMaintenance.FILTER_OK : FilterMaintenance.CHANGE_FILTER;
46
+ this.service = this.accessory.getService(this.platform.Service.FilterMaintenance) || this.accessory.addService(this.platform.Service.FilterMaintenance);
47
+ this.service.setCharacteristic(this.platform.Characteristic.Name, this.accessoryConfiguration.accessoryName);
48
+ this.service.getCharacteristic(this.platform.Characteristic.FilterChangeIndication)
49
+ .onGet(this.getFilterChangeIndication.bind(this));
50
+ this.service.getCharacteristic(this.platform.Characteristic.FilterLifeLevel)
51
+ .onGet(this.getFilterLifeLevel.bind(this));
52
+ this.service.getCharacteristic(this.platform.Characteristic.ResetFilterIndication)
53
+ .onSet(this.setResetFilterIndication.bind(this));
54
+ }
55
+ // Handlers
56
+ async getFilterChangeIndication() {
57
+ const filterChangeIndicator = this.filterChangeIndicator;
58
+ this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Getting Filter Change Indication: ${FilterMaintenance.getStateName(filterChangeIndicator)}`);
59
+ return filterChangeIndicator;
60
+ }
61
+ async getFilterLifeLevel() {
62
+ const lifeLevel = (this.lifespanTimer.getRuntime() === 0) ?
63
+ 0 :
64
+ this.lifespanTimer.getRemainingDuration() / this.lifespanTimer.getRuntime() * 100;
65
+ this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Getting Filter Life Level: ${lifeLevel.toFixed(2)}`);
66
+ return lifeLevel;
67
+ }
68
+ async setResetFilterIndication(value) {
69
+ const reset = value;
70
+ if (reset === 1) {
71
+ this.lifespanTimer.stop();
72
+ this.lifespanTimer.start(this.onTimerExpired);
73
+ this.filterChangeIndicator = FilterMaintenance.FILTER_OK;
74
+ this.storeState();
75
+ this.log.info(`[${this.accessoryConfiguration.accessoryName}] Reset Filter Indication`);
76
+ }
77
+ else {
78
+ this.log.error(`[${this.accessoryConfiguration.accessoryName}] Reset Filter Indication called with invalid value ${reset}`);
79
+ }
80
+ }
81
+ getJsonState() {
82
+ const timerStartTime = this.lifespanTimer.getStartTime().toString();
83
+ const timerDuration = (this.lifespanTimer.getRuntime() > 0) ? this.lifespanTimer.getRuntime() : this.lifespanTimer.getDefaultDuration();
84
+ const timerIsRunning = this.lifespanTimer.isTimerRunning();
85
+ const jsonState = {
86
+ [this.timerStartTimeStorageKey]: timerStartTime,
87
+ [this.timerDurationStorageKey]: timerDuration,
88
+ [this.timerIsRunningStorageKey]: timerIsRunning,
89
+ };
90
+ const json = JSON.stringify(jsonState);
91
+ return json;
92
+ }
93
+ getAccessoryTypeName() {
94
+ return FilterMaintenance.ACCESSORY_TYPE_NAME;
95
+ }
96
+ static getStateName(event) {
97
+ let stateName;
98
+ switch (event) {
99
+ case undefined: {
100
+ stateName = 'undefined';
101
+ break;
102
+ }
103
+ case FilterMaintenance.FILTER_OK: {
104
+ stateName = 'FILTER OK';
105
+ break;
106
+ }
107
+ case FilterMaintenance.CHANGE_FILTER: {
108
+ stateName = 'CHANGE FILTER';
109
+ break;
110
+ }
111
+ default: {
112
+ stateName = event.toString();
113
+ }
114
+ }
115
+ return stateName;
116
+ }
117
+ onTimerExpired() {
118
+ this.filterChangeIndicator = FilterMaintenance.CHANGE_FILTER;
119
+ this.storeState();
120
+ }
121
+ }
122
+ //# sourceMappingURL=virtualAccessoryFilterMaintenance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"virtualAccessoryFilterMaintenance.js","sourceRoot":"","sources":["../../src/accessories/virtualAccessoryFilterMaintenance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { CharacteristicValue, PlatformAccessory } from 'homebridge';
2
+ import { VirtualAccessoriesPlatform } from '../platform.js';
3
+ import { Accessory } from './virtualAccessory.js';
4
+ import { UpdatableObstruction } from '../updatableObstruction.js';
5
+ /**
6
+ * GarageDoor - Accessory implementation
7
+ */
8
+ export declare class GarageDoor extends Accessory implements UpdatableObstruction {
9
+ static readonly ACCESSORY_TYPE_NAME: string;
10
+ static readonly OPEN: number;
11
+ static readonly CLOSED: number;
12
+ static readonly OPENING: number;
13
+ static readonly CLOSING: number;
14
+ static readonly STOPPED: number;
15
+ private static readonly DEFAULT_TIMEOUT_SECS;
16
+ private readonly stateStorageKey;
17
+ private transitionTimerId;
18
+ private states;
19
+ constructor(platform: VirtualAccessoriesPlatform, accessory: PlatformAccessory);
20
+ getCurrentDoorState(): Promise<CharacteristicValue>;
21
+ setTargetDoorState(value: CharacteristicValue): Promise<void>;
22
+ getTargetDoorState(): Promise<CharacteristicValue>;
23
+ getObstructionDetected(): Promise<CharacteristicValue>;
24
+ protected getJsonState(): string;
25
+ protected getAccessoryTypeName(): string;
26
+ static getStateName(state: number): string;
27
+ updateObstruction(value: boolean, accessoryId: string): void;
28
+ }
@@ -0,0 +1,162 @@
1
+ /* eslint-disable brace-style */
2
+ /* eslint-disable max-len */
3
+ import { Accessory } from './virtualAccessory.js';
4
+ import { InvalidObstructionValueType, ObstructionValueUpdateNotAllowed } from '../errors.js';
5
+ /**
6
+ * GarageDoor - Accessory implementation
7
+ */
8
+ export class GarageDoor extends Accessory {
9
+ static ACCESSORY_TYPE_NAME = 'GarageDoor';
10
+ static OPEN = 0; // Characteristic.CurrentDoorState.OPEN - Characteristic.TargetDoorState.OPEN
11
+ static CLOSED = 1; // Characteristic.CurrentDoorState.CLOSED - Characteristic.TargetDoorState.CLOSED
12
+ static OPENING = 2; // Characteristic.CurrentDoorState.OPENING;
13
+ static CLOSING = 3; // Characteristic.CurrentDoorState.CLOSING;
14
+ static STOPPED = 4; // Characteristic.CurrentDoorState.STOPPED;
15
+ static DEFAULT_TIMEOUT_SECS = 3;
16
+ stateStorageKey = 'GarageDoorState';
17
+ transitionTimerId;
18
+ states = {
19
+ GarageDoorCurrentState: GarageDoor.CLOSED,
20
+ GarageDoorTargetState: GarageDoor.CLOSED,
21
+ ObstructionDetected: false,
22
+ };
23
+ constructor(platform, accessory) {
24
+ super(platform, accessory);
25
+ // First configure the device based on the accessory details
26
+ this.defaultState = this.accessoryConfiguration.garageDoor.defaultState === 'open' ? GarageDoor.OPEN : GarageDoor.CLOSED;
27
+ this.states.GarageDoorCurrentState = this.defaultState;
28
+ // If the accessory is stateful retrieve stored state
29
+ if (this.accessoryConfiguration.accessoryIsStateful) {
30
+ const accessoryState = this.loadAccessoryState(this.storagePath);
31
+ const cachedState = accessoryState[this.stateStorageKey];
32
+ if (cachedState !== undefined) {
33
+ this.states.GarageDoorCurrentState = cachedState;
34
+ }
35
+ }
36
+ this.states.GarageDoorTargetState = this.states.GarageDoorCurrentState;
37
+ this.service = this.accessory.getService(this.platform.Service.GarageDoorOpener) || this.accessory.addService(this.platform.Service.GarageDoorOpener);
38
+ this.service.setCharacteristic(this.platform.Characteristic.Name, this.accessoryConfiguration.accessoryName);
39
+ // Update the initial state of the accessory
40
+ this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Setting Garage Door Current State: ${GarageDoor.getStateName(this.states.GarageDoorCurrentState)}`);
41
+ this.service.updateCharacteristic(this.platform.Characteristic.CurrentDoorState, (this.states.GarageDoorCurrentState));
42
+ this.service.updateCharacteristic(this.platform.Characteristic.TargetDoorState, (this.states.GarageDoorTargetState));
43
+ // register handlers
44
+ this.service.getCharacteristic(this.platform.Characteristic.CurrentDoorState)
45
+ .onGet(this.getCurrentDoorState.bind(this));
46
+ this.service.getCharacteristic(this.platform.Characteristic.TargetDoorState)
47
+ .onSet(this.setTargetDoorState.bind(this))
48
+ .onGet(this.getTargetDoorState.bind(this));
49
+ this.service.getCharacteristic(this.platform.Characteristic.ObstructionDetected)
50
+ .onGet(this.getObstructionDetected.bind(this));
51
+ }
52
+ // Handlers
53
+ async getCurrentDoorState() {
54
+ const garageDoorCurrentState = this.states.GarageDoorCurrentState;
55
+ this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Getting Current Door State: ${GarageDoor.getStateName(garageDoorCurrentState)}`);
56
+ return garageDoorCurrentState;
57
+ }
58
+ async setTargetDoorState(value) {
59
+ this.states.GarageDoorTargetState = value;
60
+ this.log.info(`[${this.accessoryConfiguration.accessoryName}] Setting Target Door State: ${GarageDoor.getStateName(this.states.GarageDoorTargetState)}`);
61
+ // Clear the obstruction flag
62
+ this.states.ObstructionDetected = false;
63
+ this.service.setCharacteristic(this.platform.Characteristic.ObstructionDetected, (this.states.ObstructionDetected));
64
+ this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Setting Obstruction Detected: ${this.states.ObstructionDetected}`);
65
+ // CurrentDoorState CLOSING/OPENING
66
+ this.states.GarageDoorCurrentState = (this.states.GarageDoorTargetState === GarageDoor.OPEN) ? GarageDoor.OPENING : GarageDoor.CLOSING;
67
+ this.service.setCharacteristic(this.platform.Characteristic.CurrentDoorState, (this.states.GarageDoorCurrentState));
68
+ this.log.info(`[${this.accessoryConfiguration.accessoryName}] Setting Current Door State: ${GarageDoor.getStateName(this.states.GarageDoorCurrentState)}`);
69
+ // CurrentDoorState CLOSED/OPEN with 3 second delay
70
+ const transitionDuration = this.accessoryConfiguration.garageDoor.transitionDuration;
71
+ const transitionDelayMillis = (transitionDuration ? transitionDuration : GarageDoor.DEFAULT_TIMEOUT_SECS) * 1000;
72
+ // Reset timer, if running
73
+ clearTimeout(this.transitionTimerId);
74
+ this.transitionTimerId = setTimeout(() => {
75
+ this.states.GarageDoorCurrentState = this.states.GarageDoorTargetState;
76
+ this.service.setCharacteristic(this.platform.Characteristic.CurrentDoorState, (this.states.GarageDoorCurrentState));
77
+ this.storeState();
78
+ this.log.info(`[${this.accessoryConfiguration.accessoryName}] Setting Current Door State: ${GarageDoor.getStateName(this.states.GarageDoorCurrentState)}`);
79
+ }, transitionDelayMillis);
80
+ }
81
+ async getTargetDoorState() {
82
+ const garageDoorTargetState = this.states.GarageDoorTargetState;
83
+ this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Getting Target Door State: ${GarageDoor.getStateName(garageDoorTargetState)}`);
84
+ return garageDoorTargetState;
85
+ }
86
+ async getObstructionDetected() {
87
+ const obstructionDetected = this.states.ObstructionDetected;
88
+ this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Getting Obstruction Detected: ${obstructionDetected}`);
89
+ return obstructionDetected;
90
+ }
91
+ getJsonState() {
92
+ const json = JSON.stringify({
93
+ [this.stateStorageKey]: this.states.GarageDoorCurrentState,
94
+ });
95
+ return json;
96
+ }
97
+ getAccessoryTypeName() {
98
+ return GarageDoor.ACCESSORY_TYPE_NAME;
99
+ }
100
+ static getStateName(state) {
101
+ let stateName;
102
+ switch (state) {
103
+ case undefined: {
104
+ stateName = 'undefined';
105
+ break;
106
+ }
107
+ case GarageDoor.OPEN: {
108
+ stateName = 'OPEN';
109
+ break;
110
+ }
111
+ case GarageDoor.CLOSED: {
112
+ stateName = 'CLOSED';
113
+ break;
114
+ }
115
+ case GarageDoor.OPENING: {
116
+ stateName = 'OPENING';
117
+ break;
118
+ }
119
+ case GarageDoor.CLOSING: {
120
+ stateName = 'CLOSING';
121
+ break;
122
+ }
123
+ case GarageDoor.STOPPED: {
124
+ stateName = 'STOPPED';
125
+ break;
126
+ }
127
+ default: {
128
+ stateName = state.toString();
129
+ }
130
+ }
131
+ return stateName;
132
+ }
133
+ // Updatable Obstruction interface
134
+ updateObstruction(value, accessoryId) {
135
+ this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Request update obstruction detected to ${value}`);
136
+ if (accessoryId !== this.accessoryConfiguration.accessoryID) {
137
+ this.log.error(`[${this.accessoryConfiguration.accessoryName}] Accessory Id ${accessoryId} is not valid for this accessory`);
138
+ throw new ObstructionValueUpdateNotAllowed(`Invalid accessory id: ${accessoryId}`);
139
+ }
140
+ else if (typeof value !== 'boolean') {
141
+ this.log.error(`[${this.accessoryConfiguration.accessoryName}] Value ${value} is not valid for a Garage Door obstruction detected`);
142
+ throw new InvalidObstructionValueType(`Invalid sensor value: ${value}`);
143
+ }
144
+ else if (this.states.GarageDoorCurrentState === GarageDoor.OPENING || this.states.GarageDoorCurrentState === GarageDoor.CLOSING) {
145
+ this.states.ObstructionDetected = value;
146
+ this.service.setCharacteristic(this.platform.Characteristic.ObstructionDetected, (this.states.ObstructionDetected));
147
+ // Only log to 'info' if setting ObstructionDetected to true
148
+ this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Updating obstruction detected to ${value}`);
149
+ if (value === true) {
150
+ // Reset timer, if running
151
+ clearTimeout(this.transitionTimerId);
152
+ this.states.GarageDoorCurrentState = GarageDoor.STOPPED;
153
+ this.service.setCharacteristic(this.platform.Characteristic.CurrentDoorState, (this.states.GarageDoorCurrentState));
154
+ this.log.info(`[${this.accessoryConfiguration.accessoryName}] Setting Current Door State: ${GarageDoor.getStateName(this.states.GarageDoorCurrentState)}`);
155
+ }
156
+ }
157
+ else {
158
+ this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Ignoring. Garage Door is ${GarageDoor.getStateName(this.states.GarageDoorCurrentState)}`);
159
+ }
160
+ }
161
+ }
162
+ //# sourceMappingURL=virtualAccessoryGarageDoor.js.map