iobroker.iot 3.6.0 → 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. package/README.md +8 -4
  2. package/admin/assets/index-5zouxn2w.js +680 -0
  3. package/admin/index_m.html +1 -1
  4. package/admin/rules/assets/{index-BRdNnGcA.js → index-DwYdaT5M.js} +80 -81
  5. package/admin/rules/customRuleBlocks.js +2 -2
  6. package/{lib → build-backend/lib}/AlexaSmartHomeV3/Alexa/AlexaResponse.js +101 -95
  7. package/build-backend/lib/AlexaSmartHomeV3/Alexa/AlexaResponse.js.map +1 -0
  8. package/{lib → build-backend/lib}/AlexaSmartHomeV3/Alexa/Capabilities/Base.js +22 -36
  9. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/Base.js.map +1 -0
  10. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/BrightnessController.js +19 -0
  11. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/BrightnessController.js.map +1 -0
  12. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/ColorController.js +14 -0
  13. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/ColorController.js.map +1 -0
  14. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/ColorTemperatureController.js +19 -0
  15. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/ColorTemperatureController.js.map +1 -0
  16. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/ContactSensor.js +16 -0
  17. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/ContactSensor.js.map +1 -0
  18. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/LockController.js +14 -0
  19. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/LockController.js.map +1 -0
  20. package/{lib → build-backend/lib}/AlexaSmartHomeV3/Alexa/Capabilities/ModeController.js +27 -28
  21. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/ModeController.js.map +1 -0
  22. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/MotionSensor.js +14 -0
  23. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/MotionSensor.js.map +1 -0
  24. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/PercentageController.js +14 -0
  25. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/PercentageController.js.map +1 -0
  26. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/PowerController.js +19 -0
  27. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/PowerController.js.map +1 -0
  28. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/Speaker.js +25 -0
  29. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/Speaker.js.map +1 -0
  30. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/TemperatureSensor.js +14 -0
  31. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/TemperatureSensor.js.map +1 -0
  32. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/ThermostatController.js +37 -0
  33. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/ThermostatController.js.map +1 -0
  34. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/index.js +32 -0
  35. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Capabilities/index.js.map +1 -0
  36. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Directives/Base.js +29 -0
  37. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Directives/Base.js.map +1 -0
  38. package/{lib → build-backend/lib}/AlexaSmartHomeV3/Alexa/Directives/ChangeReport.js +34 -27
  39. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Directives/ChangeReport.js.map +1 -0
  40. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Directives/Discovery.js +39 -0
  41. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Directives/Discovery.js.map +1 -0
  42. package/{lib → build-backend/lib}/AlexaSmartHomeV3/Alexa/Directives/ReportState.js +19 -22
  43. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Directives/ReportState.js.map +1 -0
  44. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Directives/index.js +14 -0
  45. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Directives/index.js.map +1 -0
  46. package/build-backend/lib/AlexaSmartHomeV3/Alexa/ModeValues/Base.js +36 -0
  47. package/build-backend/lib/AlexaSmartHomeV3/Alexa/ModeValues/Base.js.map +1 -0
  48. package/build-backend/lib/AlexaSmartHomeV3/Alexa/ModeValues/Closed.js +57 -0
  49. package/build-backend/lib/AlexaSmartHomeV3/Alexa/ModeValues/Closed.js.map +1 -0
  50. package/build-backend/lib/AlexaSmartHomeV3/Alexa/ModeValues/Open.js +57 -0
  51. package/build-backend/lib/AlexaSmartHomeV3/Alexa/ModeValues/Open.js.map +1 -0
  52. package/build-backend/lib/AlexaSmartHomeV3/Alexa/ModeValues/index.js +12 -0
  53. package/build-backend/lib/AlexaSmartHomeV3/Alexa/ModeValues/index.js.map +1 -0
  54. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/AdjustableProperty.js +16 -0
  55. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/AdjustableProperty.js.map +1 -0
  56. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/Base.js +127 -0
  57. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/Base.js.map +1 -0
  58. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/Brightness.js +18 -0
  59. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/Brightness.js.map +1 -0
  60. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/Color.js +38 -0
  61. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/Color.js.map +1 -0
  62. package/{lib → build-backend/lib}/AlexaSmartHomeV3/Alexa/Properties/ColorTemperatureInKelvin.js +20 -29
  63. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/ColorTemperatureInKelvin.js.map +1 -0
  64. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/DetectionState.js +23 -0
  65. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/DetectionState.js.map +1 -0
  66. package/{lib → build-backend/lib}/AlexaSmartHomeV3/Alexa/Properties/LockState.js +9 -12
  67. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/LockState.js.map +1 -0
  68. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/Mode.js +34 -0
  69. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/Mode.js.map +1 -0
  70. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/Muted.js +19 -0
  71. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/Muted.js.map +1 -0
  72. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/Percentage.js +18 -0
  73. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/Percentage.js.map +1 -0
  74. package/{lib → build-backend/lib}/AlexaSmartHomeV3/Alexa/Properties/PowerState.js +9 -9
  75. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/PowerState.js.map +1 -0
  76. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/TargetSetpoint.js +31 -0
  77. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/TargetSetpoint.js.map +1 -0
  78. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/Temperature.js +22 -0
  79. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/Temperature.js.map +1 -0
  80. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/ThermostatMode.js +49 -0
  81. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/ThermostatMode.js.map +1 -0
  82. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/Volume.js +21 -0
  83. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/Volume.js.map +1 -0
  84. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/index.js +38 -0
  85. package/build-backend/lib/AlexaSmartHomeV3/Alexa/Properties/index.js.map +1 -0
  86. package/build-backend/lib/AlexaSmartHomeV3/Controls/AdjustableControl.js +20 -0
  87. package/build-backend/lib/AlexaSmartHomeV3/Controls/AdjustableControl.js.map +1 -0
  88. package/build-backend/lib/AlexaSmartHomeV3/Controls/AdjustablePercentageControl.js +26 -0
  89. package/build-backend/lib/AlexaSmartHomeV3/Controls/AdjustablePercentageControl.js.map +1 -0
  90. package/build-backend/lib/AlexaSmartHomeV3/Controls/AirCondition.js +148 -0
  91. package/build-backend/lib/AlexaSmartHomeV3/Controls/AirCondition.js.map +1 -0
  92. package/build-backend/lib/AlexaSmartHomeV3/Controls/Blind.js +13 -0
  93. package/build-backend/lib/AlexaSmartHomeV3/Controls/Blind.js.map +1 -0
  94. package/build-backend/lib/AlexaSmartHomeV3/Controls/ContactSensor.js +17 -0
  95. package/build-backend/lib/AlexaSmartHomeV3/Controls/ContactSensor.js.map +1 -0
  96. package/{lib → build-backend/lib}/AlexaSmartHomeV3/Controls/Control.js +73 -104
  97. package/build-backend/lib/AlexaSmartHomeV3/Controls/Control.js.map +1 -0
  98. package/build-backend/lib/AlexaSmartHomeV3/Controls/Ct.js +182 -0
  99. package/build-backend/lib/AlexaSmartHomeV3/Controls/Ct.js.map +1 -0
  100. package/build-backend/lib/AlexaSmartHomeV3/Controls/Dimmer.js +127 -0
  101. package/build-backend/lib/AlexaSmartHomeV3/Controls/Dimmer.js.map +1 -0
  102. package/build-backend/lib/AlexaSmartHomeV3/Controls/Door.js +10 -0
  103. package/build-backend/lib/AlexaSmartHomeV3/Controls/Door.js.map +1 -0
  104. package/build-backend/lib/AlexaSmartHomeV3/Controls/Gate.js +38 -0
  105. package/build-backend/lib/AlexaSmartHomeV3/Controls/Gate.js.map +1 -0
  106. package/build-backend/lib/AlexaSmartHomeV3/Controls/Hue.js +208 -0
  107. package/build-backend/lib/AlexaSmartHomeV3/Controls/Hue.js.map +1 -0
  108. package/{lib → build-backend/lib}/AlexaSmartHomeV3/Controls/Light.js +15 -22
  109. package/build-backend/lib/AlexaSmartHomeV3/Controls/Light.js.map +1 -0
  110. package/build-backend/lib/AlexaSmartHomeV3/Controls/Lock.js +35 -0
  111. package/build-backend/lib/AlexaSmartHomeV3/Controls/Lock.js.map +1 -0
  112. package/build-backend/lib/AlexaSmartHomeV3/Controls/Motion.js +17 -0
  113. package/build-backend/lib/AlexaSmartHomeV3/Controls/Motion.js.map +1 -0
  114. package/build-backend/lib/AlexaSmartHomeV3/Controls/ReadOnlyDetector.js +26 -0
  115. package/build-backend/lib/AlexaSmartHomeV3/Controls/ReadOnlyDetector.js.map +1 -0
  116. package/build-backend/lib/AlexaSmartHomeV3/Controls/Slider.js +10 -0
  117. package/build-backend/lib/AlexaSmartHomeV3/Controls/Slider.js.map +1 -0
  118. package/build-backend/lib/AlexaSmartHomeV3/Controls/Socket.js +21 -0
  119. package/build-backend/lib/AlexaSmartHomeV3/Controls/Socket.js.map +1 -0
  120. package/build-backend/lib/AlexaSmartHomeV3/Controls/Temperature.js +21 -0
  121. package/build-backend/lib/AlexaSmartHomeV3/Controls/Temperature.js.map +1 -0
  122. package/build-backend/lib/AlexaSmartHomeV3/Controls/Thermostat.js +85 -0
  123. package/build-backend/lib/AlexaSmartHomeV3/Controls/Thermostat.js.map +1 -0
  124. package/build-backend/lib/AlexaSmartHomeV3/Controls/VacuumCleaner.js +27 -0
  125. package/build-backend/lib/AlexaSmartHomeV3/Controls/VacuumCleaner.js.map +1 -0
  126. package/build-backend/lib/AlexaSmartHomeV3/Controls/Volume.js +116 -0
  127. package/build-backend/lib/AlexaSmartHomeV3/Controls/Volume.js.map +1 -0
  128. package/build-backend/lib/AlexaSmartHomeV3/Controls/VolumeGroup.js +10 -0
  129. package/build-backend/lib/AlexaSmartHomeV3/Controls/VolumeGroup.js.map +1 -0
  130. package/build-backend/lib/AlexaSmartHomeV3/Controls/Window.js +10 -0
  131. package/build-backend/lib/AlexaSmartHomeV3/Controls/Window.js.map +1 -0
  132. package/build-backend/lib/AlexaSmartHomeV3/Controls/index.js +121 -0
  133. package/build-backend/lib/AlexaSmartHomeV3/Controls/index.js.map +1 -0
  134. package/{lib → build-backend/lib}/AlexaSmartHomeV3/Device.js +29 -30
  135. package/build-backend/lib/AlexaSmartHomeV3/Device.js.map +1 -0
  136. package/build-backend/lib/AlexaSmartHomeV3/DeviceManager.js +392 -0
  137. package/build-backend/lib/AlexaSmartHomeV3/DeviceManager.js.map +1 -0
  138. package/build-backend/lib/AlexaSmartHomeV3/Exceptions/AlexaV3Exception.js +10 -0
  139. package/build-backend/lib/AlexaSmartHomeV3/Exceptions/AlexaV3Exception.js.map +1 -0
  140. package/build-backend/lib/AlexaSmartHomeV3/Exceptions/HourlyDeviceRateLimitExceeded.js +10 -0
  141. package/build-backend/lib/AlexaSmartHomeV3/Exceptions/HourlyDeviceRateLimitExceeded.js.map +1 -0
  142. package/build-backend/lib/AlexaSmartHomeV3/Exceptions/OverallDailyRateLimitExceeded.js +10 -0
  143. package/build-backend/lib/AlexaSmartHomeV3/Exceptions/OverallDailyRateLimitExceeded.js.map +1 -0
  144. package/{lib → build-backend/lib}/AlexaSmartHomeV3/Helpers/AdapterProvider.js +12 -21
  145. package/build-backend/lib/AlexaSmartHomeV3/Helpers/AdapterProvider.js.map +1 -0
  146. package/build-backend/lib/AlexaSmartHomeV3/Helpers/FileHelper.js +53 -0
  147. package/build-backend/lib/AlexaSmartHomeV3/Helpers/FileHelper.js.map +1 -0
  148. package/{lib → build-backend/lib}/AlexaSmartHomeV3/Helpers/IotProxy.js +9 -26
  149. package/build-backend/lib/AlexaSmartHomeV3/Helpers/IotProxy.js.map +1 -0
  150. package/build-backend/lib/AlexaSmartHomeV3/Helpers/Logger.js +93 -0
  151. package/build-backend/lib/AlexaSmartHomeV3/Helpers/Logger.js.map +1 -0
  152. package/build-backend/lib/AlexaSmartHomeV3/Helpers/RateLimiter.js +112 -0
  153. package/build-backend/lib/AlexaSmartHomeV3/Helpers/RateLimiter.js.map +1 -0
  154. package/build-backend/lib/AlexaSmartHomeV3/Helpers/Utils.js +625 -0
  155. package/build-backend/lib/AlexaSmartHomeV3/Helpers/Utils.js.map +1 -0
  156. package/build-backend/lib/Utils.js +96 -0
  157. package/build-backend/lib/Utils.js.map +1 -0
  158. package/build-backend/lib/adminCommonSocket.js +715 -0
  159. package/build-backend/lib/adminCommonSocket.js.map +1 -0
  160. package/build-backend/lib/alexaCustom.js +542 -0
  161. package/build-backend/lib/alexaCustom.js.map +1 -0
  162. package/{lib → build-backend/lib}/alexaSmartHomeV2.js +4 -8
  163. package/{lib → build-backend/lib}/alexaSmartHomeV3.js +25 -45
  164. package/build-backend/lib/alexaSmartHomeV3.js.map +1 -0
  165. package/{lib → build-backend/lib}/alisa.js +41 -44
  166. package/{lib → build-backend/lib}/devices.js +11 -8
  167. package/build-backend/lib/devices.js.map +1 -0
  168. package/{lib → build-backend/lib}/functions.js +11 -8
  169. package/build-backend/lib/functions.js.map +1 -0
  170. package/{lib → build-backend/lib}/googleHome.js +25 -26
  171. package/{lib → build-backend/lib}/notifications.js +15 -22
  172. package/build-backend/lib/notifications.js.map +1 -0
  173. package/{lib → build-backend/lib}/remote.js +615 -636
  174. package/build-backend/lib/remote.js.map +1 -0
  175. package/{lib → build-backend/lib}/rooms.js +11 -8
  176. package/build-backend/lib/rooms.js.map +1 -0
  177. package/{lib → build-backend/lib}/texts.js +6 -4
  178. package/build-backend/lib/texts.js.map +1 -0
  179. package/build-backend/lib/translate.js +21 -0
  180. package/build-backend/lib/translate.js.map +1 -0
  181. package/{lib → build-backend/lib}/visuApp.js +45 -65
  182. package/build-backend/lib/visuApp.js.map +1 -0
  183. package/build-backend/main.js +1361 -0
  184. package/build-backend/main.js.map +1 -0
  185. package/io-package.json +14 -14
  186. package/package.json +18 -15
  187. package/admin/assets/index-DCbOB3g_.js +0 -681
  188. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/BrightnessController.js +0 -15
  189. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/ColorController.js +0 -10
  190. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/ColorTemperatureController.js +0 -15
  191. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/ContactSensor.js +0 -10
  192. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/LockController.js +0 -10
  193. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/MotionSensor.js +0 -10
  194. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/PercentageController.js +0 -10
  195. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/PowerController.js +0 -15
  196. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/Speaker.js +0 -20
  197. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/TemperatureSensor.js +0 -10
  198. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/ThermostatController.js +0 -34
  199. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/index.js +0 -14
  200. package/lib/AlexaSmartHomeV3/Alexa/Directives/Base.js +0 -27
  201. package/lib/AlexaSmartHomeV3/Alexa/Directives/Discovery.js +0 -39
  202. package/lib/AlexaSmartHomeV3/Alexa/Directives/index.js +0 -13
  203. package/lib/AlexaSmartHomeV3/Alexa/ModeValues/Base.js +0 -38
  204. package/lib/AlexaSmartHomeV3/Alexa/ModeValues/Closed.js +0 -55
  205. package/lib/AlexaSmartHomeV3/Alexa/ModeValues/Open.js +0 -56
  206. package/lib/AlexaSmartHomeV3/Alexa/ModeValues/index.js +0 -14
  207. package/lib/AlexaSmartHomeV3/Alexa/Properties/AdjustableProperty.js +0 -11
  208. package/lib/AlexaSmartHomeV3/Alexa/Properties/Base.js +0 -108
  209. package/lib/AlexaSmartHomeV3/Alexa/Properties/Brightness.js +0 -14
  210. package/lib/AlexaSmartHomeV3/Alexa/Properties/Color.js +0 -40
  211. package/lib/AlexaSmartHomeV3/Alexa/Properties/DetectionState.js +0 -22
  212. package/lib/AlexaSmartHomeV3/Alexa/Properties/Mode.js +0 -32
  213. package/lib/AlexaSmartHomeV3/Alexa/Properties/Muted.js +0 -17
  214. package/lib/AlexaSmartHomeV3/Alexa/Properties/Percentage.js +0 -14
  215. package/lib/AlexaSmartHomeV3/Alexa/Properties/TargetSetpoint.js +0 -28
  216. package/lib/AlexaSmartHomeV3/Alexa/Properties/Temperature.js +0 -20
  217. package/lib/AlexaSmartHomeV3/Alexa/Properties/ThermostatMode.js +0 -52
  218. package/lib/AlexaSmartHomeV3/Alexa/Properties/Volume.js +0 -19
  219. package/lib/AlexaSmartHomeV3/Alexa/Properties/index.js +0 -14
  220. package/lib/AlexaSmartHomeV3/Controls/AdjustableControl.js +0 -22
  221. package/lib/AlexaSmartHomeV3/Controls/AdjustablePercentageControl.js +0 -28
  222. package/lib/AlexaSmartHomeV3/Controls/AirCondition.js +0 -144
  223. package/lib/AlexaSmartHomeV3/Controls/Blind.js +0 -12
  224. package/lib/AlexaSmartHomeV3/Controls/ContactSensor.js +0 -17
  225. package/lib/AlexaSmartHomeV3/Controls/Ct.js +0 -172
  226. package/lib/AlexaSmartHomeV3/Controls/Dimmer.js +0 -124
  227. package/lib/AlexaSmartHomeV3/Controls/Door.js +0 -9
  228. package/lib/AlexaSmartHomeV3/Controls/Gate.js +0 -42
  229. package/lib/AlexaSmartHomeV3/Controls/Hue.js +0 -207
  230. package/lib/AlexaSmartHomeV3/Controls/Lock.js +0 -36
  231. package/lib/AlexaSmartHomeV3/Controls/Motion.js +0 -17
  232. package/lib/AlexaSmartHomeV3/Controls/ReadOnlyDetector.js +0 -25
  233. package/lib/AlexaSmartHomeV3/Controls/Slider.js +0 -10
  234. package/lib/AlexaSmartHomeV3/Controls/Socket.js +0 -21
  235. package/lib/AlexaSmartHomeV3/Controls/Temperature.js +0 -22
  236. package/lib/AlexaSmartHomeV3/Controls/Thermostat.js +0 -86
  237. package/lib/AlexaSmartHomeV3/Controls/VacuumCleaner.js +0 -28
  238. package/lib/AlexaSmartHomeV3/Controls/Volume.js +0 -109
  239. package/lib/AlexaSmartHomeV3/Controls/VolumeGroup.js +0 -9
  240. package/lib/AlexaSmartHomeV3/Controls/Window.js +0 -9
  241. package/lib/AlexaSmartHomeV3/Controls/index.js +0 -14
  242. package/lib/AlexaSmartHomeV3/DeviceManager.js +0 -415
  243. package/lib/AlexaSmartHomeV3/Exceptions/AlexaV3Exception.js +0 -8
  244. package/lib/AlexaSmartHomeV3/Exceptions/HourlyDeviceRateLimitExceeded.js +0 -5
  245. package/lib/AlexaSmartHomeV3/Exceptions/OverallDailyRateLimitExceeded.js +0 -5
  246. package/lib/AlexaSmartHomeV3/Helpers/FileHelper.js +0 -70
  247. package/lib/AlexaSmartHomeV3/Helpers/Logger.js +0 -95
  248. package/lib/AlexaSmartHomeV3/Helpers/RateLimiter.js +0 -82
  249. package/lib/AlexaSmartHomeV3/Helpers/Utils.js +0 -583
  250. package/lib/Utils.js +0 -608
  251. package/lib/adminCommonSocket.js +0 -781
  252. package/lib/alexaCustom.js +0 -622
  253. package/lib/translate.js +0 -19
  254. package/main.js +0 -1454
@@ -1,7 +1,11 @@
1
- const { v4: uuidv4 } = require('uuid');
2
- const Utils = require('./Helpers/Utils');
3
- const Logger = require('./Helpers/Logger');
4
-
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const uuid_1 = require("uuid");
7
+ const Utils_1 = require("./Helpers/Utils");
8
+ const Logger_1 = __importDefault(require("./Helpers/Logger"));
5
9
  /**
6
10
  * This class hides the different iobroker controls representing physical devices from Alexa
7
11
  * and makes them appear as a single endpoint.
@@ -10,63 +14,58 @@ const Logger = require('./Helpers/Logger');
10
14
  * to be the same endpoint from Alexa's perspective.
11
15
  * This leads to a situation where while Alexa believes controlling a single endpoint by sending a directive
12
16
  * to change the endpoint's state, in reality, the states of multiple controls, i.e. physical devices, are changed.
13
- *
14
- * @class
15
17
  */
16
18
  class Device {
19
+ log;
20
+ id;
21
+ friendlyName;
22
+ controls;
23
+ autoDetected;
24
+ roomName;
25
+ funcName;
26
+ toggle;
27
+ description;
28
+ lastReportedState;
17
29
  constructor(opts) {
18
- this.id = Utils.defaultIfNullOrEmpty(Utils.endpointId(opts.id), uuidv4());
19
- this.friendlyName = Utils.defaultIfNullOrEmpty(opts.friendlyName, uuidv4());
20
- this.controls = Utils.defaultIfNullOrEmpty(opts.controls, []);
21
- this.log = new Logger(this);
22
- this.autoDetected = opts.autoDetected;
30
+ this.log = new Logger_1.default(this);
31
+ this.id = (0, Utils_1.defaultIfNullOrEmpty)((0, Utils_1.endpointId)(opts.id), (0, uuid_1.v4)());
32
+ this.friendlyName = (0, Utils_1.defaultIfNullOrEmpty)(opts.friendlyName, (0, uuid_1.v4)());
33
+ this.controls = (0, Utils_1.defaultIfNullOrEmpty)(opts.controls, []);
34
+ this.autoDetected = !!opts.autoDetected;
23
35
  this.roomName = opts.roomName;
24
36
  this.funcName = opts.funcName;
25
37
  this.toggle = opts.toggle;
26
38
  }
27
-
28
39
  supports(event) {
29
40
  return this.controls.find(c => c.supports(event)) !== undefined;
30
41
  }
31
-
32
42
  async handle(event) {
33
43
  this.log.debug(`handling alexa event`);
34
44
  this.log.silly(`${JSON.stringify(event)}`);
35
-
36
45
  const promises = [];
37
46
  if (this.toggle) {
38
47
  // get current state
39
48
  event.currentState = await this.reportState();
40
49
  }
41
-
42
50
  this.controls.forEach(control => promises.push(control.handle(event)));
43
51
  const results = await Promise.allSettled(promises);
44
-
45
52
  const fulfilled = results.find(item => item.status === 'fulfilled');
46
- // @ts-ignore
47
53
  return fulfilled !== undefined ? fulfilled.value : results[0].reason;
48
54
  }
49
-
50
55
  async reportState() {
51
56
  const promises = [];
52
57
  this.controls.forEach(control => promises.push(control.reportState()));
53
58
  const results = await Promise.allSettled(promises);
54
-
55
- // @ts-ignore
56
59
  const properties = results.filter(item => item.status === 'fulfilled').flatMap(item => item.value);
57
-
58
- return Utils.distinctByPropertyName(properties, 'name', true);
60
+ return (0, Utils_1.distinctByPropertyName)(properties, 'name', true);
59
61
  }
60
-
61
62
  get capabilities() {
62
63
  const allCapabilities = this.controls.flatMap(item => item.supported);
63
- return Utils.distinctByPropertyName(allCapabilities, 'namespace');
64
+ return (0, Utils_1.distinctByPropertyName)(allCapabilities, 'namespace');
64
65
  }
65
-
66
66
  get displayCategories() {
67
67
  return Array.from(new Set(this.controls.flatMap(item => item.categories)));
68
68
  }
69
-
70
69
  toString() {
71
70
  const controls = this.controls;
72
71
  const controlsAsString = function () {
@@ -74,11 +73,11 @@ class Device {
74
73
  for (const ctrl of controls) {
75
74
  repr += `${ctrl.toString()}, `;
76
75
  }
77
- repr = repr.slice(0, -2) + ')';
76
+ repr = `${repr.slice(0, -2)})`;
78
77
  return repr;
79
78
  };
80
- return `${this.friendlyName}` + controlsAsString();
79
+ return `${this.friendlyName}${controlsAsString()}`;
81
80
  }
82
81
  }
83
-
84
- module.exports = Device;
82
+ exports.default = Device;
83
+ //# sourceMappingURL=Device.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Device.js","sourceRoot":"","sources":["../../../src/lib/AlexaSmartHomeV3/Device.ts"],"names":[],"mappings":"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","sourcesContent":["import { v4 as uuidv4 } from 'uuid';\nimport { endpointId, defaultIfNullOrEmpty, distinctByPropertyName } from './Helpers/Utils';\nimport Logger from './Helpers/Logger';\nimport type { AlexaV3Category, AlexaV3Namespace, AlexaV3ReportedState, AlexaV3Request } from './types';\nimport type Control from './Controls/Control';\nimport type { Base as CapabilitiesBase } from './Alexa/Capabilities/Base';\nimport type AlexaResponse from './Alexa/AlexaResponse';\n\n/**\n * This class hides the different iobroker controls representing physical devices from Alexa\n * and makes them appear as a single endpoint.\n * Due to differences in Alexa's and iobroker's endpoint/devices concepts, we have to merge some of the\n * by the type-detector detected controls to a single device, so that multiple controls are considered\n * to be the same endpoint from Alexa's perspective.\n * This leads to a situation where while Alexa believes controlling a single endpoint by sending a directive\n * to change the endpoint's state, in reality, the states of multiple controls, i.e. physical devices, are changed.\n */\nexport default class Device {\n public log: Logger;\n public id: string;\n public friendlyName: string;\n public controls: Control[];\n public autoDetected: boolean;\n public roomName?: string;\n public funcName?: string;\n public toggle?: boolean;\n public description?: string;\n public lastReportedState?: any;\n\n constructor(opts: {\n id: string;\n friendlyName: string;\n controls: Control[];\n autoDetected?: boolean;\n roomName?: string;\n funcName?: string;\n toggle?: boolean;\n }) {\n this.log = new Logger(this);\n this.id = defaultIfNullOrEmpty<string>(endpointId(opts.id), uuidv4());\n this.friendlyName = defaultIfNullOrEmpty<string>(opts.friendlyName, uuidv4());\n this.controls = defaultIfNullOrEmpty<Control[]>(opts.controls, []);\n this.autoDetected = !!opts.autoDetected;\n this.roomName = opts.roomName;\n this.funcName = opts.funcName;\n this.toggle = opts.toggle;\n }\n\n supports(event: AlexaV3Request): boolean {\n return this.controls.find(c => c.supports(event)) !== undefined;\n }\n\n async handle(event: AlexaV3Request): Promise<AlexaResponse> {\n this.log.debug(`handling alexa event`);\n this.log.silly(`${JSON.stringify(event)}`);\n\n const promises: Promise<AlexaResponse>[] = [];\n if (this.toggle) {\n // get current state\n event.currentState = await this.reportState();\n }\n\n this.controls.forEach(control => promises.push(control.handle(event)));\n const results = await Promise.allSettled(promises);\n\n const fulfilled = results.find(item => item.status === 'fulfilled');\n\n return fulfilled !== undefined ? fulfilled.value : (results[0] as any).reason;\n }\n\n async reportState(): Promise<AlexaV3ReportedState[]> {\n const promises: Promise<AlexaV3ReportedState[]>[] = [];\n this.controls.forEach(control => promises.push(control.reportState()));\n const results = await Promise.allSettled(promises);\n\n const properties: {\n namespace: AlexaV3Namespace;\n instance?: string;\n name: string;\n value: any;\n }[] = results.filter(item => item.status === 'fulfilled').flatMap(item => item.value);\n\n return distinctByPropertyName<{\n namespace: AlexaV3Namespace;\n instance?: string;\n name: string;\n value: any;\n }>(properties, 'name', true);\n }\n\n get capabilities(): CapabilitiesBase[] {\n const allCapabilities = this.controls.flatMap(item => item.supported);\n return distinctByPropertyName(allCapabilities, 'namespace');\n }\n\n get displayCategories(): AlexaV3Category[] {\n return Array.from(new Set(this.controls.flatMap(item => item.categories)));\n }\n\n toString(): string {\n const controls = this.controls;\n const controlsAsString = function (): string {\n let repr = ' (Controls: ';\n for (const ctrl of controls) {\n repr += `${ctrl.toString()}, `;\n }\n repr = `${repr.slice(0, -2)})`;\n return repr;\n };\n return `${this.friendlyName}${controlsAsString()}`;\n }\n}\n"]}
@@ -0,0 +1,392 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const Device_1 = __importDefault(require("./Device"));
40
+ const Utils = __importStar(require("./Helpers/Utils"));
41
+ const Directives_1 = __importDefault(require("./Alexa/Directives"));
42
+ const Controls_1 = __importDefault(require("./Controls"));
43
+ const Logger_1 = __importDefault(require("./Helpers/Logger"));
44
+ const AdapterProvider_1 = __importDefault(require("./Helpers/AdapterProvider"));
45
+ const AlexaResponse_1 = __importDefault(require("./Alexa/AlexaResponse"));
46
+ const IotProxy_1 = __importDefault(require("./Helpers/IotProxy"));
47
+ const RateLimiter_1 = __importDefault(require("./Helpers/RateLimiter"));
48
+ const OverallDailyRateLimitExceeded_1 = __importDefault(require("./Exceptions/OverallDailyRateLimitExceeded"));
49
+ const HourlyDeviceRateLimitExceeded_1 = __importDefault(require("./Exceptions/HourlyDeviceRateLimitExceeded"));
50
+ const ChangeReport_1 = __importDefault(require("./Alexa/Directives/ChangeReport"));
51
+ const Discovery_1 = __importDefault(require("./Alexa/Directives/Discovery"));
52
+ const ReportState_1 = __importDefault(require("./Alexa/Directives/ReportState"));
53
+ const node_crypto_1 = require("node:crypto");
54
+ class DeviceManager {
55
+ lang = 'en';
56
+ devices = [];
57
+ subscribed = [];
58
+ log;
59
+ eventsPausedTill = 0; // timestamp
60
+ collecting = false;
61
+ recollect = false;
62
+ /** Creates a Device Manager */
63
+ constructor() {
64
+ this.log = new Logger_1.default(this);
65
+ }
66
+ informAboutStatesChange() {
67
+ void AdapterProvider_1.default.get().setState('smart.updates3', true, true);
68
+ }
69
+ get language() {
70
+ return this.lang;
71
+ }
72
+ set language(value) {
73
+ this.lang = value;
74
+ }
75
+ matchDirective(event) {
76
+ if (ChangeReport_1.default.matches(event)) {
77
+ return new ChangeReport_1.default();
78
+ }
79
+ if (Discovery_1.default.matches(event)) {
80
+ return new Discovery_1.default();
81
+ }
82
+ if (ReportState_1.default.matches(event)) {
83
+ return new ReportState_1.default();
84
+ }
85
+ return null;
86
+ }
87
+ get endpoints() {
88
+ return this.devices;
89
+ }
90
+ endpointById(id) {
91
+ return this.devices.find(device => device.id === id);
92
+ }
93
+ addDevice(device) {
94
+ this.devices.push(device);
95
+ }
96
+ toDevice(detectedControls, friendlyName, autoDetected, roomName, funcName, toggle) {
97
+ const controls = [];
98
+ this.log.debug(`merging controls to a device with name ${friendlyName}`);
99
+ detectedControls.forEach(item => {
100
+ this.log.silly(`processing control: ${JSON.stringify(item)}`);
101
+ const control = Controls_1.default.factory(item);
102
+ if (control) {
103
+ this.log.debug(`${item.type} added to ${friendlyName}`);
104
+ controls.push(control);
105
+ }
106
+ else {
107
+ this.log.debug(`control of type ${item.type} not supported yet. Skipped.`);
108
+ }
109
+ });
110
+ if (controls.length === 0) {
111
+ // the controls are not supported yet...
112
+ return;
113
+ }
114
+ // create and add a new device to the collected devices
115
+ this.addDevice(new Device_1.default({
116
+ id: friendlyName,
117
+ friendlyName,
118
+ controls,
119
+ autoDetected,
120
+ roomName,
121
+ funcName,
122
+ toggle,
123
+ }));
124
+ }
125
+ getName(name) {
126
+ if (!name) {
127
+ return '';
128
+ }
129
+ if (typeof name === 'object') {
130
+ return name[this.lang] || name.en || '';
131
+ }
132
+ return name;
133
+ }
134
+ async collectEndpoints() {
135
+ if (this.collecting) {
136
+ this.log.debug(`collecting devices already in progress. Skipping...`);
137
+ this.recollect = true;
138
+ return;
139
+ }
140
+ this.collecting = true;
141
+ this.log.debug(`(re)collecting devices...`);
142
+ try {
143
+ // const discoveryNeeded = this.devices.length > 0;
144
+ this.devices = [];
145
+ const defaultToggle = AdapterProvider_1.default.get().config.defaultToggle || false;
146
+ // collect all iobroker controls in terms of iobroker type detector (https://github.com/ioBroker/ioBroker.type-detector)
147
+ let detectedControls = await Utils.controls(AdapterProvider_1.default.get(), this.lang);
148
+ this.log.debug(`type detector found ${detectedControls.length} controls`);
149
+ // Normally, every control is a smart device. But due to the iobroker concept of 'rooms and functions'
150
+ // multiple controls might be merged to a single device.
151
+ // as long as not all controls mapped to a device...
152
+ // detectedControls = detectedControls.filter(c => ['light', 'dimmer'].includes(c.type));
153
+ const createdGroups = [];
154
+ while (detectedControls.length) {
155
+ // take the next control
156
+ const control = detectedControls[0];
157
+ let processedControls = [];
158
+ if (control.room?.common?.name) {
159
+ if (control.functionality?.common?.name) {
160
+ // controls in the same room with the same functionality
161
+ processedControls = detectedControls.filter(item => control.room &&
162
+ item.room?.id === control.room.id &&
163
+ control.functionality &&
164
+ item.functionality?.id === control.functionality.id);
165
+ this.toDevice(processedControls, Utils.friendlyNameByRoomAndFunctionName(control, this.lang), true, this.getName(control.room?.common?.name), this.getName(control.functionality?.common?.name), processedControls[0].object?.toggle ?? defaultToggle);
166
+ }
167
+ else {
168
+ this.log.debug(`Control of type [${control.type}] assigned to room [${this.getName(control.room.common.name)}] has no function. Skipped.`);
169
+ }
170
+ }
171
+ else if (control.groupNames) {
172
+ // no room, but smart name (not only one)
173
+ control.groupNames.forEach(groupName => {
174
+ if (!createdGroups.includes(groupName)) {
175
+ createdGroups.push(groupName);
176
+ processedControls = detectedControls.filter(item => item.groupNames?.includes(groupName));
177
+ this.toDevice(processedControls, this.getName(groupName), false, undefined, undefined, processedControls[0].object?.toggle ?? defaultToggle);
178
+ }
179
+ });
180
+ }
181
+ else {
182
+ // neither room nor smart name
183
+ this.log.debug(`Control of type [${control.type}] has neither room no smart name. Skipped.`);
184
+ }
185
+ if (processedControls.length === 0) {
186
+ processedControls = [control];
187
+ }
188
+ // remove processed controls
189
+ const objectIds = processedControls.map(item => item.object?.id);
190
+ detectedControls = detectedControls.filter(item => item.object && !objectIds.includes(item.object.id));
191
+ }
192
+ // done
193
+ this.log.debug(`finished collecting devices. there is/are ${this.devices.length} device(s) in total`);
194
+ for (const device of this.devices) {
195
+ this.log.debug(`${device.toString()}`);
196
+ }
197
+ // a new discovery process is needed in case we had already devices and device collection was
198
+ // triggered again by, e.g., a change in room/function enums
199
+ // if (discoveryNeeded) {
200
+ // this.log.info(`Please delete all managed by ioBroker devices in your Alexa app and then start discovery`);
201
+ // }
202
+ // collect all relevant states to subscribe to updates
203
+ const stateIds = new Set(this.devices
204
+ .flatMap(d => d.controls)
205
+ .flatMap(item => item.supported)
206
+ .flatMap(item => item.properties)
207
+ .map(item => item.getId)
208
+ .filter(id => id));
209
+ this.log.debug(`registering for updates of total ${stateIds.size} states`);
210
+ const promises = [];
211
+ const newSubscribed = Array.from(stateIds);
212
+ // subscribe to updates
213
+ for (const id of newSubscribed) {
214
+ this.log.silly(`subscribing to updates of ${id}`);
215
+ if (!this.subscribed.includes(id)) {
216
+ this.subscribed.push(id);
217
+ promises.push(AdapterProvider_1.default.subscribe(id));
218
+ }
219
+ }
220
+ this.subscribed.sort();
221
+ // wait till all promises are settled
222
+ const results = await Promise.allSettled(promises);
223
+ // unsubscribe from unused states
224
+ for (let i = this.subscribed.length - 1; i >= 0; i--) {
225
+ const id = this.subscribed[i];
226
+ if (!newSubscribed.includes(id)) {
227
+ this.log.silly(`unsubscribing from updates of ${id}`);
228
+ this.subscribed.splice(i, 1);
229
+ await AdapterProvider_1.default.unsubscribe(id);
230
+ }
231
+ }
232
+ const failedReasons = results.filter(item => item.status !== 'fulfilled').flatMap(item => item.reason);
233
+ if (failedReasons.length) {
234
+ this.log.debug(`failed to subscribe for updates of ${failedReasons.length} states`);
235
+ try {
236
+ for (const reason of failedReasons) {
237
+ this.log.silly(`failed subscribing: ${typeof reason === 'string' ? reason : JSON.stringify(reason)}`);
238
+ }
239
+ }
240
+ catch {
241
+ // nop
242
+ }
243
+ }
244
+ }
245
+ catch (e) {
246
+ this.log.error(`failed to collect devices: ${e}`);
247
+ }
248
+ this.collecting = false;
249
+ // if during the collection a new collection was triggered, start collecting again
250
+ if (this.recollect) {
251
+ this.recollect = false;
252
+ setTimeout(() => this.collectEndpoints(), 1000);
253
+ }
254
+ }
255
+ async destroy() {
256
+ const promises = [];
257
+ for (const id of this.subscribed) {
258
+ this.log.silly(`unsubscribing from updates of ${id}`);
259
+ promises.push(AdapterProvider_1.default.subscribe(id));
260
+ }
261
+ await Promise.allSettled(promises);
262
+ this.subscribed = [];
263
+ }
264
+ publishStateChange(stateChange) {
265
+ if (this.eventsPausedTill < Date.now()) {
266
+ this.log.silly(`publishing ${JSON.stringify(stateChange)}`);
267
+ IotProxy_1.default.publishStateChange(stateChange);
268
+ }
269
+ }
270
+ pauseEvents() {
271
+ this.eventsPausedTill = Date.now() + 30 * 60 * 1000; // 30 minutes
272
+ }
273
+ async executeWithinRateLimits(endpointId, awaitable, errorResponse) {
274
+ try {
275
+ await RateLimiter_1.default.incrementAndGet(endpointId);
276
+ return await awaitable();
277
+ }
278
+ catch (error) {
279
+ if (error instanceof OverallDailyRateLimitExceeded_1.default || error instanceof HourlyDeviceRateLimitExceeded_1.default) {
280
+ this.log.warn(error.message);
281
+ }
282
+ else {
283
+ this.log.error(error.message);
284
+ }
285
+ return errorResponse;
286
+ }
287
+ }
288
+ async handleAlexaEvent(event) {
289
+ this.log.debug(`incoming Alexa event`);
290
+ this.log.silly(`${JSON.stringify(event)}`);
291
+ if (!event?.directive?.header) {
292
+ throw new Error('Alexa event header is missing');
293
+ }
294
+ let response;
295
+ const directive = this.matchDirective(event);
296
+ if (directive) {
297
+ response = await directive.handle(event, this);
298
+ }
299
+ else {
300
+ const endpointId = event?.directive?.endpoint?.endpointId;
301
+ const device = endpointId ? this.endpointById(endpointId) : undefined;
302
+ if (device) {
303
+ if (device.supports(event)) {
304
+ response = await this.executeWithinRateLimits(endpointId, async () => {
305
+ response = await device.handle(event);
306
+ if (!AlexaResponse_1.default.isErrorResponse(response)) {
307
+ // report state change via voice interaction
308
+ const propertyName = response.context?.properties[0].name;
309
+ const responseEvent = ChangeReport_1.default.get(device.id, propertyName || '', false, event.directive.header.messageId);
310
+ const directive = this.matchDirective(responseEvent);
311
+ if (directive) {
312
+ // BF[2024.02.04]: temporarily disabled as produced a huge number of events
313
+ // const stateChange = await directive.handle(responseEvent, this);
314
+ // get device state (not just one control)
315
+ const deviceState = await device.reportState();
316
+ if (JSON.stringify(device.lastReportedState) !== JSON.stringify(deviceState)) {
317
+ device.lastReportedState = deviceState;
318
+ // fire state change report to Alexa
319
+ // BF[2024.02.04]: temporarily disabled as produced a huge number of events
320
+ // this.publishStateChange(stateChange);
321
+ this.informAboutStatesChange();
322
+ }
323
+ else {
324
+ this.log.debug(`ignoring state change event for ${endpointId} due to the same_ value [${JSON.stringify(deviceState)}]`);
325
+ }
326
+ }
327
+ }
328
+ return response;
329
+ }, AlexaResponse_1.default.endpointUnreachable(event.directive.header.messageId).get());
330
+ }
331
+ else {
332
+ response = AlexaResponse_1.default.directiveNotSupportedByDevice(device.friendlyName, event.directive.header.namespace, event.directive.header.messageId, event.directive.header.payloadVersion).get();
333
+ }
334
+ }
335
+ else {
336
+ response = AlexaResponse_1.default.endpointUnreachable(event.directive.header.messageId).get();
337
+ }
338
+ }
339
+ this.log.silly(`response: ${JSON.stringify(response)}`);
340
+ return response;
341
+ }
342
+ async handleStateUpdate(id, state) {
343
+ // ignore updates not confirmed by a corresponding device
344
+ if (!state?.ack) {
345
+ this.log.silly(`ignoring state change event for ${id} due to state.ack == ${state?.ack}`);
346
+ return;
347
+ }
348
+ let notFound = true;
349
+ for (const device of this.devices) {
350
+ const property = device.controls
351
+ .flatMap(item => item.supported)
352
+ .flatMap(item => item.properties)
353
+ .find(item => item.getId === id);
354
+ if (property) {
355
+ notFound = false;
356
+ if (property.currentValue === state.val) {
357
+ this.log.debug(`ignoring state change event for ${id} due to the same value [${state.val}]`);
358
+ }
359
+ else {
360
+ property.currentValue = state.val;
361
+ const responseEvent = Directives_1.default.ChangeReport.get(device.id, property.propertyName, true, (0, node_crypto_1.randomUUID)());
362
+ const directive = this.matchDirective(responseEvent);
363
+ if (directive) {
364
+ // BF[2024.02.04]: temporarily disabled as produced a huge number of events
365
+ // const stateChange = await directive.handle(event, this);
366
+ // get device state (not just one control)
367
+ const deviceState = await device.reportState();
368
+ if (JSON.stringify(device.lastReportedState) !== JSON.stringify(deviceState)) {
369
+ device.lastReportedState = deviceState;
370
+ this.informAboutStatesChange();
371
+ // fire state change report to Alexa
372
+ // BF[2024.02.04]: temporarily disabled as produced a huge number of events
373
+ // await this.executeWithinRateLimits(device.id, async () =>
374
+ // this.publishStateChange(stateChange), undefined);
375
+ }
376
+ else {
377
+ this.log.debug(`ignoring state change event for ${id} due to the same_ value [${JSON.stringify(deviceState)}]`);
378
+ }
379
+ }
380
+ }
381
+ // should be the only device having the id => stop processing here
382
+ break;
383
+ }
384
+ }
385
+ // this should never happen
386
+ if (notFound) {
387
+ this.log.debug(`state id ${id} doesn't belong to any device`);
388
+ }
389
+ }
390
+ }
391
+ exports.default = DeviceManager;
392
+ //# sourceMappingURL=DeviceManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeviceManager.js","sourceRoot":"","sources":["../../../src/lib/AlexaSmartHomeV3/DeviceManager.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,sDAA8B;AAC9B,uDAAyC;AACzC,oEAA4C;AAC5C,0DAAkC;AAElC,8DAAsC;AACtC,gFAAwD;AACxD,0EAAkD;AAClD,kEAA0C;AAC1C,wEAAgD;AAChD,+GAAuF;AACvF,+GAAuF;AAEvF,mFAA2D;AAC3D,6EAAqD;AACrD,iFAAyD;AACzD,6CAAyC;AAEzC,MAAqB,aAAa;IACtB,IAAI,GAAuB,IAAI,CAAC;IAChC,OAAO,GAAa,EAAE,CAAC;IACvB,UAAU,GAAa,EAAE,CAAC;IAC1B,GAAG,CAAS;IACZ,gBAAgB,GAAG,CAAC,CAAC,CAAC,YAAY;IAElC,UAAU,GAAG,KAAK,CAAC;IACnB,SAAS,GAAG,KAAK,CAAC;IAE1B,+BAA+B;IAC/B;QACI,IAAI,CAAC,GAAG,GAAG,IAAI,gBAAM,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAED,uBAAuB;QACnB,KAAK,yBAAe,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,gBAAgB,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACtE,CAAC;IAED,IAAI,QAAQ;QACR,OAAO,IAAI,CAAC,IAAI,CAAC;IACrB,CAAC;IAED,IAAI,QAAQ,CAAC,KAAyB;QAClC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;IACtB,CAAC;IAED,cAAc,CAAC,KAAqB;QAChC,IAAI,sBAAY,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO,IAAI,sBAAY,EAAE,CAAC;QAC9B,CAAC;QACD,IAAI,mBAAS,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,IAAI,mBAAS,EAAE,CAAC;QAC3B,CAAC;QACD,IAAI,qBAAW,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO,IAAI,qBAAW,EAAE,CAAC;QAC7B,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,IAAI,SAAS;QACT,OAAO,IAAI,CAAC,OAAO,CAAC;IACxB,CAAC;IAED,YAAY,CAAC,EAAqB;QAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,SAAS,CAAC,MAAc;QACpB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;IAED,QAAQ,CACJ,gBAA6C,EAC7C,YAAoB,EACpB,YAAqB,EACrB,QAA4B,EAC5B,QAA4B,EAC5B,MAAgB;QAEhB,MAAM,QAAQ,GAAc,EAAE,CAAC;QAE/B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,0CAA0C,YAAY,EAAE,CAAC,CAAC;QAEzE,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YAC5B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,uBAAuB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC9D,MAAM,OAAO,GAAG,kBAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACvC,IAAI,OAAO,EAAE,CAAC;gBACV,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,aAAa,YAAY,EAAE,CAAC,CAAC;gBACxD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC3B,CAAC;iBAAM,CAAC;gBACJ,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,mBAAmB,IAAI,CAAC,IAAI,8BAA8B,CAAC,CAAC;YAC/E,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,wCAAwC;YACxC,OAAO;QACX,CAAC;QAED,uDAAuD;QACvD,IAAI,CAAC,SAAS,CACV,IAAI,gBAAM,CAAC;YACP,EAAE,EAAE,YAAY;YAChB,YAAY;YACZ,QAAQ;YACR,YAAY;YACZ,QAAQ;YACR,QAAQ;YACR,MAAM;SACT,CAAC,CACL,CAAC;IACN,CAAC;IAED,OAAO,CAAC,IAA6C;QACjD,IAAI,CAAC,IAAI,EAAE,CAAC;YACR,OAAO,EAAE,CAAC;QACd,CAAC;QACD,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC;QAC5C,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,gBAAgB;QAClB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAClB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;YACtE,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YACtB,OAAO;QACX,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC5C,IAAI,CAAC;YACD,mDAAmD;YAEnD,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;YAClB,MAAM,aAAa,GAAG,yBAAe,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,aAAa,IAAI,KAAK,CAAC;YAE1E,wHAAwH;YACxH,IAAI,gBAAgB,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,yBAAe,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAE9E,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,uBAAuB,gBAAgB,CAAC,MAAM,WAAW,CAAC,CAAC;YAE1E,sGAAsG;YACtG,wDAAwD;YAExD,oDAAoD;YAEpD,yFAAyF;YACzF,MAAM,aAAa,GAAa,EAAE,CAAC;YAEnC,OAAO,gBAAgB,CAAC,MAAM,EAAE,CAAC;gBAC7B,wBAAwB;gBACxB,MAAM,OAAO,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;gBACpC,IAAI,iBAAiB,GAAgC,EAAE,CAAC;gBAExD,IAAI,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;oBAC7B,IAAI,OAAO,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;wBACtC,wDAAwD;wBACxD,iBAAiB,GAAG,gBAAgB,CAAC,MAAM,CACvC,IAAI,CAAC,EAAE,CACH,OAAO,CAAC,IAAI;4BACZ,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE;4BACjC,OAAO,CAAC,aAAa;4BACrB,IAAI,CAAC,aAAa,EAAE,EAAE,KAAK,OAAO,CAAC,aAAa,CAAC,EAAE,CAC1D,CAAC;wBACF,IAAI,CAAC,QAAQ,CACT,iBAAiB,EACjB,KAAK,CAAC,iCAAiC,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,EAC3D,IAAI,EACJ,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EACxC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,CAAC,EACjD,iBAAiB,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,IAAI,aAAa,CACvD,CAAC;oBACN,CAAC;yBAAM,CAAC;wBACJ,IAAI,CAAC,GAAG,CAAC,KAAK,CACV,oBAAoB,OAAO,CAAC,IAAI,uBAAuB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAC7H,CAAC;oBACN,CAAC;gBACL,CAAC;qBAAM,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;oBAC5B,yCAAyC;oBACzC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;wBACnC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;4BACrC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;4BAC9B,iBAAiB,GAAG,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;4BAC1F,IAAI,CAAC,QAAQ,CACT,iBAAiB,EACjB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EACvB,KAAK,EACL,SAAS,EACT,SAAS,EACT,iBAAiB,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,IAAI,aAAa,CACvD,CAAC;wBACN,CAAC;oBACL,CAAC,CAAC,CAAC;gBACP,CAAC;qBAAM,CAAC;oBACJ,8BAA8B;oBAC9B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,oBAAoB,OAAO,CAAC,IAAI,4CAA4C,CAAC,CAAC;gBACjG,CAAC;gBAED,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACjC,iBAAiB,GAAG,CAAC,OAAO,CAAC,CAAC;gBAClC,CAAC;gBAED,4BAA4B;gBAC5B,MAAM,SAAS,GAAG,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBACjE,gBAAgB,GAAG,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;YAC3G,CAAC;YAED,OAAO;YACP,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,6CAA6C,IAAI,CAAC,OAAO,CAAC,MAAM,qBAAqB,CAAC,CAAC;YACtG,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBAChC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAC3C,CAAC;YAED,6FAA6F;YAC7F,4DAA4D;YAC5D,yBAAyB;YACzB,iHAAiH;YACjH,IAAI;YAEJ,sDAAsD;YACtD,MAAM,QAAQ,GAAG,IAAI,GAAG,CACpB,IAAI,CAAC,OAAO;iBACP,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;iBACxB,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC;iBAC/B,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC;iBAChC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;iBACvB,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CACxB,CAAC;YACF,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,oCAAoC,QAAQ,CAAC,IAAI,SAAS,CAAC,CAAC;YAC3E,MAAM,QAAQ,GAAG,EAAE,CAAC;YACpB,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC3C,uBAAuB;YACvB,KAAK,MAAM,EAAE,IAAI,aAAa,EAAE,CAAC;gBAC7B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,6BAA6B,EAAE,EAAE,CAAC,CAAC;gBAClD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;oBAChC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBACzB,QAAQ,CAAC,IAAI,CAAC,yBAAe,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;gBACjD,CAAC;YACL,CAAC;YAED,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;YAEvB,qCAAqC;YACrC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YAEnD,iCAAiC;YACjC,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBACnD,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBAC9B,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;oBAC9B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,iCAAiC,EAAE,EAAE,CAAC,CAAC;oBACtD,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBAC7B,MAAM,yBAAe,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;gBAC1C,CAAC;YACL,CAAC;YAED,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACvG,IAAI,aAAa,CAAC,MAAM,EAAE,CAAC;gBACvB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,sCAAsC,aAAa,CAAC,MAAM,SAAS,CAAC,CAAC;gBACpF,IAAI,CAAC;oBACD,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;wBACjC,IAAI,CAAC,GAAG,CAAC,KAAK,CACV,uBAAuB,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CACxF,CAAC;oBACN,CAAC;gBACL,CAAC;gBAAC,MAAM,CAAC;oBACL,MAAM;gBACV,CAAC;YACL,CAAC;QACL,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,8BAA8B,CAAC,EAAE,CAAC,CAAC;QACtD,CAAC;QAED,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QAExB,kFAAkF;QAClF,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,IAAI,CAAC,CAAC;QACpD,CAAC;IACL,CAAC;IAED,KAAK,CAAC,OAAO;QACT,MAAM,QAAQ,GAAG,EAAE,CAAC;QACpB,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAC/B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,iCAAiC,EAAE,EAAE,CAAC,CAAC;YACtD,QAAQ,CAAC,IAAI,CAAC,yBAAe,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;QACjD,CAAC;QACD,MAAM,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAEnC,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;IACzB,CAAC;IAED,kBAAkB,CAAC,WAA0B;QACzC,IAAI,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YACrC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;YAC5D,kBAAQ,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;QAC7C,CAAC;IACL,CAAC;IAED,WAAW;QACP,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;IACtE,CAAC;IAED,KAAK,CAAC,uBAAuB,CACzB,UAA6B,EAC7B,SAAuC,EACvC,aAA4B;QAE5B,IAAI,CAAC;YACD,MAAM,qBAAW,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;YAC9C,OAAO,MAAM,SAAS,EAAE,CAAC;QAC7B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,KAAK,YAAY,uCAA6B,IAAI,KAAK,YAAY,uCAA6B,EAAE,CAAC;gBACnG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACjC,CAAC;iBAAM,CAAC;gBACJ,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAClC,CAAC;YAED,OAAO,aAAa,CAAC;QACzB,CAAC;IACL,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,KAAqB;QACxC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QACvC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC3C,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACrD,CAAC;QAED,IAAI,QAAuB,CAAC;QAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,SAAS,EAAE,CAAC;YACZ,QAAQ,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACnD,CAAC;aAAM,CAAC;YACJ,MAAM,UAAU,GAAG,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,CAAC;YAC1D,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAEtE,IAAI,MAAM,EAAE,CAAC;gBACT,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;oBACzB,QAAQ,GAAG,MAAM,IAAI,CAAC,uBAAuB,CACzC,UAAW,EACX,KAAK,IAAI,EAAE;wBACP,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;wBACtC,IAAI,CAAC,uBAAa,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC;4BAC3C,4CAA4C;4BAC5C,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;4BAC1D,MAAM,aAAa,GAAG,sBAAY,CAAC,GAAG,CAClC,MAAM,CAAC,EAAE,EACT,YAAY,IAAI,EAAE,EAClB,KAAK,EACL,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CACnC,CAAC;4BACF,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;4BACrD,IAAI,SAAS,EAAE,CAAC;gCACZ,2EAA2E;gCAC3E,mEAAmE;gCACnE,0CAA0C;gCAC1C,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;gCAC/C,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC;oCAC3E,MAAM,CAAC,iBAAiB,GAAG,WAAW,CAAC;oCACvC,oCAAoC;oCACpC,2EAA2E;oCAC3E,wCAAwC;oCACxC,IAAI,CAAC,uBAAuB,EAAE,CAAC;gCACnC,CAAC;qCAAM,CAAC;oCACJ,IAAI,CAAC,GAAG,CAAC,KAAK,CACV,mCAAmC,UAAU,4BAA4B,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,CAC1G,CAAC;gCACN,CAAC;4BACL,CAAC;wBACL,CAAC;wBACD,OAAO,QAAQ,CAAC;oBACpB,CAAC,EACD,uBAAa,CAAC,mBAAmB,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,CAC5E,CAAC;gBACN,CAAC;qBAAM,CAAC;oBACJ,QAAQ,GAAG,uBAAa,CAAC,6BAA6B,CAClD,MAAM,CAAC,YAAY,EACnB,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,EAChC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,EAChC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,cAAc,CACxC,CAAC,GAAG,EAAE,CAAC;gBACZ,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,QAAQ,GAAG,uBAAa,CAAC,mBAAmB,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC;YACzF,CAAC;QACL,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACxD,OAAO,QAAQ,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,EAAU,EAAE,KAAwC;QACxE,yDAAyD;QACzD,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC;YACd,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,mCAAmC,EAAE,wBAAwB,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;YAC1F,OAAO;QACX,CAAC;QAED,IAAI,QAAQ,GAAG,IAAI,CAAC;QAEpB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAChC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ;iBAC3B,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC;iBAC/B,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC;iBAChC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;YAErC,IAAI,QAAQ,EAAE,CAAC;gBACX,QAAQ,GAAG,KAAK,CAAC;gBACjB,IAAI,QAAQ,CAAC,YAAY,KAAK,KAAK,CAAC,GAAG,EAAE,CAAC;oBACtC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,mCAAmC,EAAE,2BAA2B,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC;gBACjG,CAAC;qBAAM,CAAC;oBACJ,QAAQ,CAAC,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC;oBAElC,MAAM,aAAa,GAAG,oBAAU,CAAC,YAAY,CAAC,GAAG,CAC7C,MAAM,CAAC,EAAE,EACT,QAAQ,CAAC,YAAY,EACrB,IAAI,EACJ,IAAA,wBAAU,GAAE,CACf,CAAC;oBACF,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;oBACrD,IAAI,SAAS,EAAE,CAAC;wBACZ,2EAA2E;wBAC3E,2DAA2D;wBAE3D,0CAA0C;wBAC1C,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;wBAE/C,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC;4BAC3E,MAAM,CAAC,iBAAiB,GAAG,WAAW,CAAC;4BACvC,IAAI,CAAC,uBAAuB,EAAE,CAAC;4BAC/B,oCAAoC;4BAEpC,2EAA2E;4BAC3E,4DAA4D;4BAC5D,wDAAwD;wBAC5D,CAAC;6BAAM,CAAC;4BACJ,IAAI,CAAC,GAAG,CAAC,KAAK,CACV,mCAAmC,EAAE,4BAA4B,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,CAClG,CAAC;wBACN,CAAC;oBACL,CAAC;gBACL,CAAC;gBAED,kEAAkE;gBAClE,MAAM;YACV,CAAC;QACL,CAAC;QAED,2BAA2B;QAC3B,IAAI,QAAQ,EAAE,CAAC;YACX,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,EAAE,+BAA+B,CAAC,CAAC;QAClE,CAAC;IACL,CAAC;CACJ;AArbD,gCAqbC","sourcesContent":["import Device from './Device';\nimport * as Utils from './Helpers/Utils';\nimport Directives from './Alexa/Directives';\nimport Controls from './Controls';\nimport type Control from './Controls/Control';\nimport Logger from './Helpers/Logger';\nimport AdapterProvider from './Helpers/AdapterProvider';\nimport AlexaResponse from './Alexa/AlexaResponse';\nimport IotProxy from './Helpers/IotProxy';\nimport RateLimiter from './Helpers/RateLimiter';\nimport OverallDailyRateLimitExceeded from './Exceptions/OverallDailyRateLimitExceeded';\nimport HourlyDeviceRateLimitExceeded from './Exceptions/HourlyDeviceRateLimitExceeded';\nimport type { AlexaV3EndpointID, AlexaV3Request, IotExternalPatternControl } from './types';\nimport ChangeReport from './Alexa/Directives/ChangeReport';\nimport Discovery from './Alexa/Directives/Discovery';\nimport ReportState from './Alexa/Directives/ReportState';\nimport { randomUUID } from 'node:crypto';\n\nexport default class DeviceManager {\n private lang: ioBroker.Languages = 'en';\n private devices: Device[] = [];\n private subscribed: string[] = [];\n private log: Logger;\n private eventsPausedTill = 0; // timestamp\n\n private collecting = false;\n private recollect = false;\n\n /** Creates a Device Manager */\n constructor() {\n this.log = new Logger(this);\n }\n\n informAboutStatesChange(): void {\n void AdapterProvider.get().setState('smart.updates3', true, true);\n }\n\n get language(): ioBroker.Languages {\n return this.lang;\n }\n\n set language(value: ioBroker.Languages) {\n this.lang = value;\n }\n\n matchDirective(event: AlexaV3Request): ChangeReport | Discovery | ReportState | null {\n if (ChangeReport.matches(event)) {\n return new ChangeReport();\n }\n if (Discovery.matches(event)) {\n return new Discovery();\n }\n if (ReportState.matches(event)) {\n return new ReportState();\n }\n\n return null;\n }\n\n get endpoints(): Device[] {\n return this.devices;\n }\n\n endpointById(id: AlexaV3EndpointID): Device | undefined {\n return this.devices.find(device => device.id === id);\n }\n\n addDevice(device: Device): void {\n this.devices.push(device);\n }\n\n toDevice(\n detectedControls: IotExternalPatternControl[],\n friendlyName: string,\n autoDetected: boolean,\n roomName: string | undefined,\n funcName: string | undefined,\n toggle?: boolean,\n ): Device | undefined {\n const controls: Control[] = [];\n\n this.log.debug(`merging controls to a device with name ${friendlyName}`);\n\n detectedControls.forEach(item => {\n this.log.silly(`processing control: ${JSON.stringify(item)}`);\n const control = Controls.factory(item);\n if (control) {\n this.log.debug(`${item.type} added to ${friendlyName}`);\n controls.push(control);\n } else {\n this.log.debug(`control of type ${item.type} not supported yet. Skipped.`);\n }\n });\n\n if (controls.length === 0) {\n // the controls are not supported yet...\n return;\n }\n\n // create and add a new device to the collected devices\n this.addDevice(\n new Device({\n id: friendlyName,\n friendlyName,\n controls,\n autoDetected,\n roomName,\n funcName,\n toggle,\n }),\n );\n }\n\n getName(name: ioBroker.StringOrTranslated | undefined): string {\n if (!name) {\n return '';\n }\n if (typeof name === 'object') {\n return name[this.lang] || name.en || '';\n }\n return name;\n }\n\n async collectEndpoints(): Promise<void> {\n if (this.collecting) {\n this.log.debug(`collecting devices already in progress. Skipping...`);\n this.recollect = true;\n return;\n }\n this.collecting = true;\n this.log.debug(`(re)collecting devices...`);\n try {\n // const discoveryNeeded = this.devices.length > 0;\n\n this.devices = [];\n const defaultToggle = AdapterProvider.get().config.defaultToggle || false;\n\n // collect all iobroker controls in terms of iobroker type detector (https://github.com/ioBroker/ioBroker.type-detector)\n let detectedControls = await Utils.controls(AdapterProvider.get(), this.lang);\n\n this.log.debug(`type detector found ${detectedControls.length} controls`);\n\n // Normally, every control is a smart device. But due to the iobroker concept of 'rooms and functions'\n // multiple controls might be merged to a single device.\n\n // as long as not all controls mapped to a device...\n\n // detectedControls = detectedControls.filter(c => ['light', 'dimmer'].includes(c.type));\n const createdGroups: string[] = [];\n\n while (detectedControls.length) {\n // take the next control\n const control = detectedControls[0];\n let processedControls: IotExternalPatternControl[] = [];\n\n if (control.room?.common?.name) {\n if (control.functionality?.common?.name) {\n // controls in the same room with the same functionality\n processedControls = detectedControls.filter(\n item =>\n control.room &&\n item.room?.id === control.room.id &&\n control.functionality &&\n item.functionality?.id === control.functionality.id,\n );\n this.toDevice(\n processedControls,\n Utils.friendlyNameByRoomAndFunctionName(control, this.lang),\n true,\n this.getName(control.room?.common?.name),\n this.getName(control.functionality?.common?.name),\n processedControls[0].object?.toggle ?? defaultToggle,\n );\n } else {\n this.log.debug(\n `Control of type [${control.type}] assigned to room [${this.getName(control.room.common.name)}] has no function. Skipped.`,\n );\n }\n } else if (control.groupNames) {\n // no room, but smart name (not only one)\n control.groupNames.forEach(groupName => {\n if (!createdGroups.includes(groupName)) {\n createdGroups.push(groupName);\n processedControls = detectedControls.filter(item => item.groupNames?.includes(groupName));\n this.toDevice(\n processedControls,\n this.getName(groupName),\n false,\n undefined,\n undefined,\n processedControls[0].object?.toggle ?? defaultToggle,\n );\n }\n });\n } else {\n // neither room nor smart name\n this.log.debug(`Control of type [${control.type}] has neither room no smart name. Skipped.`);\n }\n\n if (processedControls.length === 0) {\n processedControls = [control];\n }\n\n // remove processed controls\n const objectIds = processedControls.map(item => item.object?.id);\n detectedControls = detectedControls.filter(item => item.object && !objectIds.includes(item.object.id));\n }\n\n // done\n this.log.debug(`finished collecting devices. there is/are ${this.devices.length} device(s) in total`);\n for (const device of this.devices) {\n this.log.debug(`${device.toString()}`);\n }\n\n // a new discovery process is needed in case we had already devices and device collection was\n // triggered again by, e.g., a change in room/function enums\n // if (discoveryNeeded) {\n // this.log.info(`Please delete all managed by ioBroker devices in your Alexa app and then start discovery`);\n // }\n\n // collect all relevant states to subscribe to updates\n const stateIds = new Set(\n this.devices\n .flatMap(d => d.controls)\n .flatMap(item => item.supported)\n .flatMap(item => item.properties)\n .map(item => item.getId)\n .filter(id => id),\n );\n this.log.debug(`registering for updates of total ${stateIds.size} states`);\n const promises = [];\n const newSubscribed = Array.from(stateIds);\n // subscribe to updates\n for (const id of newSubscribed) {\n this.log.silly(`subscribing to updates of ${id}`);\n if (!this.subscribed.includes(id)) {\n this.subscribed.push(id);\n promises.push(AdapterProvider.subscribe(id));\n }\n }\n\n this.subscribed.sort();\n\n // wait till all promises are settled\n const results = await Promise.allSettled(promises);\n\n // unsubscribe from unused states\n for (let i = this.subscribed.length - 1; i >= 0; i--) {\n const id = this.subscribed[i];\n if (!newSubscribed.includes(id)) {\n this.log.silly(`unsubscribing from updates of ${id}`);\n this.subscribed.splice(i, 1);\n await AdapterProvider.unsubscribe(id);\n }\n }\n\n const failedReasons = results.filter(item => item.status !== 'fulfilled').flatMap(item => item.reason);\n if (failedReasons.length) {\n this.log.debug(`failed to subscribe for updates of ${failedReasons.length} states`);\n try {\n for (const reason of failedReasons) {\n this.log.silly(\n `failed subscribing: ${typeof reason === 'string' ? reason : JSON.stringify(reason)}`,\n );\n }\n } catch {\n // nop\n }\n }\n } catch (e) {\n this.log.error(`failed to collect devices: ${e}`);\n }\n\n this.collecting = false;\n\n // if during the collection a new collection was triggered, start collecting again\n if (this.recollect) {\n this.recollect = false;\n setTimeout(() => this.collectEndpoints(), 1000);\n }\n }\n\n async destroy(): Promise<void> {\n const promises = [];\n for (const id of this.subscribed) {\n this.log.silly(`unsubscribing from updates of ${id}`);\n promises.push(AdapterProvider.subscribe(id));\n }\n await Promise.allSettled(promises);\n\n this.subscribed = [];\n }\n\n publishStateChange(stateChange: AlexaResponse): void {\n if (this.eventsPausedTill < Date.now()) {\n this.log.silly(`publishing ${JSON.stringify(stateChange)}`);\n IotProxy.publishStateChange(stateChange);\n }\n }\n\n pauseEvents(): void {\n this.eventsPausedTill = Date.now() + 30 * 60 * 1000; // 30 minutes\n }\n\n async executeWithinRateLimits(\n endpointId: AlexaV3EndpointID,\n awaitable: () => Promise<AlexaResponse>,\n errorResponse: AlexaResponse,\n ): Promise<AlexaResponse> {\n try {\n await RateLimiter.incrementAndGet(endpointId);\n return await awaitable();\n } catch (error) {\n if (error instanceof OverallDailyRateLimitExceeded || error instanceof HourlyDeviceRateLimitExceeded) {\n this.log.warn(error.message);\n } else {\n this.log.error(error.message);\n }\n\n return errorResponse;\n }\n }\n\n async handleAlexaEvent(event: AlexaV3Request): Promise<AlexaResponse> {\n this.log.debug(`incoming Alexa event`);\n this.log.silly(`${JSON.stringify(event)}`);\n if (!event?.directive?.header) {\n throw new Error('Alexa event header is missing');\n }\n\n let response: AlexaResponse;\n const directive = this.matchDirective(event);\n if (directive) {\n response = await directive.handle(event, this);\n } else {\n const endpointId = event?.directive?.endpoint?.endpointId;\n const device = endpointId ? this.endpointById(endpointId) : undefined;\n\n if (device) {\n if (device.supports(event)) {\n response = await this.executeWithinRateLimits(\n endpointId!,\n async () => {\n response = await device.handle(event);\n if (!AlexaResponse.isErrorResponse(response)) {\n // report state change via voice interaction\n const propertyName = response.context?.properties[0].name;\n const responseEvent = ChangeReport.get(\n device.id,\n propertyName || '',\n false,\n event.directive.header.messageId,\n );\n const directive = this.matchDirective(responseEvent);\n if (directive) {\n // BF[2024.02.04]: temporarily disabled as produced a huge number of events\n // const stateChange = await directive.handle(responseEvent, this);\n // get device state (not just one control)\n const deviceState = await device.reportState();\n if (JSON.stringify(device.lastReportedState) !== JSON.stringify(deviceState)) {\n device.lastReportedState = deviceState;\n // fire state change report to Alexa\n // BF[2024.02.04]: temporarily disabled as produced a huge number of events\n // this.publishStateChange(stateChange);\n this.informAboutStatesChange();\n } else {\n this.log.debug(\n `ignoring state change event for ${endpointId} due to the same_ value [${JSON.stringify(deviceState)}]`,\n );\n }\n }\n }\n return response;\n },\n AlexaResponse.endpointUnreachable(event.directive.header.messageId).get(),\n );\n } else {\n response = AlexaResponse.directiveNotSupportedByDevice(\n device.friendlyName,\n event.directive.header.namespace,\n event.directive.header.messageId,\n event.directive.header.payloadVersion,\n ).get();\n }\n } else {\n response = AlexaResponse.endpointUnreachable(event.directive.header.messageId).get();\n }\n }\n\n this.log.silly(`response: ${JSON.stringify(response)}`);\n return response;\n }\n\n async handleStateUpdate(id: string, state: ioBroker.State | null | undefined): Promise<void> {\n // ignore updates not confirmed by a corresponding device\n if (!state?.ack) {\n this.log.silly(`ignoring state change event for ${id} due to state.ack == ${state?.ack}`);\n return;\n }\n\n let notFound = true;\n\n for (const device of this.devices) {\n const property = device.controls\n .flatMap(item => item.supported)\n .flatMap(item => item.properties)\n .find(item => item.getId === id);\n\n if (property) {\n notFound = false;\n if (property.currentValue === state.val) {\n this.log.debug(`ignoring state change event for ${id} due to the same value [${state.val}]`);\n } else {\n property.currentValue = state.val;\n\n const responseEvent = Directives.ChangeReport.get(\n device.id,\n property.propertyName,\n true,\n randomUUID(),\n );\n const directive = this.matchDirective(responseEvent);\n if (directive) {\n // BF[2024.02.04]: temporarily disabled as produced a huge number of events\n // const stateChange = await directive.handle(event, this);\n\n // get device state (not just one control)\n const deviceState = await device.reportState();\n\n if (JSON.stringify(device.lastReportedState) !== JSON.stringify(deviceState)) {\n device.lastReportedState = deviceState;\n this.informAboutStatesChange();\n // fire state change report to Alexa\n\n // BF[2024.02.04]: temporarily disabled as produced a huge number of events\n // await this.executeWithinRateLimits(device.id, async () =>\n // this.publishStateChange(stateChange), undefined);\n } else {\n this.log.debug(\n `ignoring state change event for ${id} due to the same_ value [${JSON.stringify(deviceState)}]`,\n );\n }\n }\n }\n\n // should be the only device having the id => stop processing here\n break;\n }\n }\n\n // this should never happen\n if (notFound) {\n this.log.debug(`state id ${id} doesn't belong to any device`);\n }\n }\n}\n"]}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class AlexaV3Exception extends Error {
4
+ constructor(message) {
5
+ super(message);
6
+ this.name = this.constructor.name;
7
+ }
8
+ }
9
+ exports.default = AlexaV3Exception;
10
+ //# sourceMappingURL=AlexaV3Exception.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AlexaV3Exception.js","sourceRoot":"","sources":["../../../../src/lib/AlexaSmartHomeV3/Exceptions/AlexaV3Exception.ts"],"names":[],"mappings":";;AAAA,MAAqB,gBAAiB,SAAQ,KAAK;IAC/C,YAAY,OAAe;QACvB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IACtC,CAAC;CACJ;AALD,mCAKC","sourcesContent":["export default class AlexaV3Exception extends Error {\n constructor(message: string) {\n super(message);\n this.name = this.constructor.name;\n }\n}\n"]}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const AlexaV3Exception_1 = __importDefault(require("./AlexaV3Exception"));
7
+ class HourlyDeviceRateLimitExceeded extends AlexaV3Exception_1.default {
8
+ }
9
+ exports.default = HourlyDeviceRateLimitExceeded;
10
+ //# sourceMappingURL=HourlyDeviceRateLimitExceeded.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HourlyDeviceRateLimitExceeded.js","sourceRoot":"","sources":["../../../../src/lib/AlexaSmartHomeV3/Exceptions/HourlyDeviceRateLimitExceeded.ts"],"names":[],"mappings":";;;;;AAAA,0EAAkD;AAElD,MAAqB,6BAA8B,SAAQ,0BAAgB;CAAG;AAA9E,gDAA8E","sourcesContent":["import AlexaV3Exception from './AlexaV3Exception';\n\nexport default class HourlyDeviceRateLimitExceeded extends AlexaV3Exception {}\n"]}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const AlexaV3Exception_1 = __importDefault(require("./AlexaV3Exception"));
7
+ class OverallDailyRateLimitExceeded extends AlexaV3Exception_1.default {
8
+ }
9
+ exports.default = OverallDailyRateLimitExceeded;
10
+ //# sourceMappingURL=OverallDailyRateLimitExceeded.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OverallDailyRateLimitExceeded.js","sourceRoot":"","sources":["../../../../src/lib/AlexaSmartHomeV3/Exceptions/OverallDailyRateLimitExceeded.ts"],"names":[],"mappings":";;;;;AAAA,0EAAkD;AAElD,MAAqB,6BAA8B,SAAQ,0BAAgB;CAAG;AAA9E,gDAA8E","sourcesContent":["import AlexaV3Exception from './AlexaV3Exception';\n\nexport default class OverallDailyRateLimitExceeded extends AlexaV3Exception {}\n"]}