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
package/main.js DELETED
@@ -1,1454 +0,0 @@
1
- const DeviceModule = require('aws-iot-device-sdk').device;
2
- const { Adapter } = require('@iobroker/adapter-core'); // Get common adapter utils
3
- const { readFileSync } = require('node:fs');
4
- const axios = require('axios');
5
- const { deflateSync } = require('node:zlib');
6
-
7
- const AlexaSH2 = require('./lib/alexaSmartHomeV2');
8
- const AlexaSH3 = require('./lib/alexaSmartHomeV3');
9
- const AlexaCustom = require('./lib/alexaCustom');
10
- const GoogleHome = require('./lib/googleHome');
11
- const YandexAlisa = require('./lib/alisa');
12
- const Remote = require('./lib/remote');
13
- const { handleGeofenceData, handleDevicesData, handleSendToAdapter, handleGetInstances } = require('./lib/visuApp.js');
14
- const { buildMessageFromNotification } = require('./lib/notifications');
15
-
16
- const packageJSON = JSON.parse(readFileSync(`${__dirname}/package.json`, 'utf8'));
17
-
18
- const version = packageJSON.version;
19
- const adapterName = packageJSON.name.split('.').pop();
20
-
21
- let recalcTimeout = null;
22
- let lang = 'de';
23
- let translate = false;
24
- let alexaSH2 = null;
25
- let alexaSH3 = null;
26
- let googleHome = null;
27
- let alexaCustom = null;
28
- let yandexAlisa = null;
29
- let remote = null;
30
- let device = null;
31
- let urlKey = '';
32
-
33
- let connected = false;
34
- let secret;
35
- let adapter;
36
- let connectStarted;
37
-
38
- const NONE = '___none___';
39
- const MAX_IOT_MESSAGE_LENGTH = 127 * 1024;
40
- const SPECIAL_ADAPTERS = ['netatmo'];
41
- const ALLOWED_SERVICES = SPECIAL_ADAPTERS.concat(['text2command']);
42
-
43
- function startAdapter(options) {
44
- options = options || {};
45
-
46
- Object.assign(options, {
47
- name: adapterName,
48
- objectChange: (id, obj) => {
49
- if (id === 'system.config' && obj && !translate) {
50
- lang = obj.common.language;
51
-
52
- if (lang !== 'en' && lang !== 'de' && lang !== 'ru') {
53
- lang = 'en';
54
- }
55
- defaultHistory = obj.common.defaultHistory;
56
-
57
- alexaSH2 && alexaSH2.setLanguage(lang);
58
- alexaSH3 && alexaSH3.setLanguage(lang);
59
- yandexAlisa && yandexAlisa.setLanguage(lang);
60
- alexaCustom && alexaCustom.setLanguage(lang);
61
- googleHome && googleHome.setLanguage(lang);
62
- remote && remote.setLanguage(lang);
63
- }
64
- // if it is an instance
65
- if (id.startsWith('system.adapter.')) {
66
- // try to find it in special adapters
67
- const adpr = SPECIAL_ADAPTERS.find(a => id.startsWith(`system.adapter.${a}.`));
68
- // if found and it is really instance
69
- if (adpr && id.match(/\.\d+$/)) {
70
- // update state
71
- setTimeout(async () => await createStateForAdapter(adpr), 1000);
72
- }
73
-
74
- return;
75
- }
76
- alexaSH3 && alexaSH3.handleObjectChange(id, obj);
77
-
78
- id && remote && remote.updateObject(id, obj);
79
- },
80
- stateChange: async (id, state) => {
81
- if (id === `${adapter.namespace}.app.message` && state && !state.ack) {
82
- try {
83
- await sendMessageToApp(state.val);
84
- } catch (e) {
85
- adapter.log.error(`Cannot send message to app: ${e}`);
86
- }
87
- }
88
-
89
- state && adapter.config.googleHome && googleHome && googleHome.updateState(id, state);
90
- state && adapter.config.amazonAlexa && alexaSH3 && alexaSH3.handleStateUpdate(id, state);
91
- state &&
92
- adapter.config.yandexAlisa &&
93
- yandexAlisa &&
94
- yandexAlisa.updateState &&
95
- yandexAlisa.updateState(id, state);
96
- id && remote && remote.updateState(id, state);
97
-
98
- if (id === `${adapter.namespace}.smart.lastResponse` && state && !state.ack) {
99
- alexaCustom && alexaCustom.setResponse(state.val);
100
- }
101
- },
102
- unload: async callback => {
103
- try {
104
- if (device) {
105
- device.end();
106
- device = null;
107
- }
108
- if (remote) {
109
- remote.destroy();
110
- remote = null;
111
- }
112
-
113
- alexaSH3 && (await alexaSH3.destroy());
114
- } catch (e) {
115
- // ignore
116
- }
117
- callback();
118
- },
119
- message: async obj => {
120
- if (obj) {
121
- switch (obj.command) {
122
- case 'update':
123
- recalcTimeout && clearTimeout(recalcTimeout);
124
-
125
- recalcTimeout = setTimeout(async () => {
126
- recalcTimeout = null;
127
- alexaSH2 &&
128
- alexaSH2.updateDevices(obj.message, async analyseAddedId => {
129
- await adapter.setStateAsync('smart.updatesResult', analyseAddedId || '', true);
130
- adapter.log.debug('Devices updated!');
131
- await adapter.setStateAsync('smart.updates', true, true);
132
- });
133
-
134
- // alexaSH3 && alexaSH3.updateDevices(obj.message, async analyseAddedId => {
135
- // await adapter.setStateAsync('smart.updatesResult', analyseAddedId || '', true);
136
- // await adapter.setStateAsync('smart.updates3', true, true);
137
- // });
138
- if (alexaSH3) {
139
- await alexaSH3.updateDevices();
140
- await adapter.setStateAsync('smart.updates3', true, true);
141
- }
142
-
143
- googleHome &&
144
- googleHome.updateDevices(async analyseAddedId => {
145
- await adapter.setStateAsync('smart.updatesResult', analyseAddedId || '', true);
146
- adapter.log.debug('GH Devices updated!');
147
- await adapter.setStateAsync('smart.updatesGH', true, true);
148
- });
149
- }, 1000);
150
- break;
151
-
152
- case 'browse':
153
- if (obj.callback) {
154
- adapter.log.info('Request devices');
155
- if (alexaSH2) {
156
- alexaSH2.updateDevices(() => {
157
- adapter.sendTo(obj.from, obj.command, alexaSH2.getDevices(), obj.callback);
158
- adapter.setState('smart.updates', false, true);
159
- });
160
- } else {
161
- adapter.sendTo(obj.from, obj.command, { error: 'not activated' }, obj.callback);
162
- }
163
- }
164
- break;
165
-
166
- case 'browse3':
167
- if (obj.callback) {
168
- adapter.log.info('Request V3 devices');
169
- if (alexaSH3) {
170
- const devices = await alexaSH3.getDevices();
171
- adapter.sendTo(obj.from, obj.command, devices, obj.callback);
172
- await adapter.setStateAsync('smart.updates3', false, true);
173
- } else {
174
- adapter.sendTo(obj.from, obj.command, { error: 'not activated' }, obj.callback);
175
- }
176
- }
177
- break;
178
-
179
- case 'browseGH':
180
- if (obj.callback) {
181
- adapter.log.info('Request google home devices');
182
- if (googleHome) {
183
- googleHome.updateDevices(() => {
184
- adapter.sendTo(obj.from, obj.command, googleHome.getDevices(), obj.callback);
185
- adapter.setState('smart.updatesGH', false, true);
186
- });
187
- } else {
188
- adapter.sendTo(obj.from, obj.command, { error: 'not activated' }, obj.callback);
189
- }
190
- }
191
- break;
192
-
193
- case 'browseAlisa':
194
- if (obj.callback) {
195
- adapter.log.info('Request Yandex Alice devices');
196
- if (yandexAlisa) {
197
- yandexAlisa.updateDevices(() => {
198
- adapter.sendTo(obj.from, obj.command, yandexAlisa.getDevices(), obj.callback);
199
- adapter.setState('smart.updatesYA', false, true);
200
- });
201
- } else {
202
- adapter.sendTo(obj.from, obj.command, { error: 'not activated' }, obj.callback);
203
- }
204
- }
205
- break;
206
-
207
- case 'alexaCustomKnownDevices':
208
- // Admin UI can request the known/discoveredAlexa devices used via Custom skill
209
- // Allow setting the rooms of the devices and store in adapter config
210
- // Restart adapter after change - or we also add a set message to the config
211
- if (obj.callback) {
212
- adapter.log.info('Request Alexa Custom known devices');
213
- if (alexaCustom) {
214
- const devices = alexaCustom.getKnownDevices();
215
- adapter.sendTo(obj.from, obj.command, devices, obj.callback);
216
- } else {
217
- adapter.sendTo(obj.from, obj.command, { error: 'not activated' }, obj.callback);
218
- }
219
- }
220
- break;
221
-
222
- case 'alexaCustomKnownUsers':
223
- // Admin UI can request the known/discoveredAlexa users used via Custom skill
224
- // Allow setting the names of the users and store in adapter config
225
- // Restart adapter after change - or we also add a set message to the config
226
- if (obj.callback) {
227
- adapter.log.info('Request Alexa Custom known users');
228
- if (alexaCustom) {
229
- const users = alexaCustom.getKnownUsers();
230
- adapter.sendTo(obj.from, obj.command, users, obj.callback);
231
- } else {
232
- adapter.sendTo(obj.from, obj.command, { error: 'not activated' }, obj.callback);
233
- }
234
- }
235
- break;
236
-
237
- case 'private':
238
- if (typeof obj.message !== 'object') {
239
- try {
240
- obj.message = JSON.parse(obj.message);
241
- } catch (e) {
242
- adapter.log.error(`Cannot parse object: ${e}`);
243
- obj.callback &&
244
- adapter.sendTo(
245
- obj.from,
246
- obj.command,
247
- { error: 'Invalid message format: cannot parse object' },
248
- obj.callback,
249
- );
250
- return;
251
- }
252
- }
253
- const response = await processMessage(obj.message.type, obj.message.request);
254
- obj.callback && adapter.sendTo(obj.from, obj.command, response, obj.callback);
255
-
256
- break;
257
-
258
- case 'ifttt':
259
- sendDataToIFTTT(obj.message);
260
- break;
261
-
262
- case 'alexaCustomResponse':
263
- alexaCustom && alexaCustom.setResponse(obj.message);
264
- break;
265
-
266
- case 'debug':
267
- alexaSH2.getDebug(data => adapter.sendTo(obj.from, obj.command, data, obj.callback));
268
- break;
269
-
270
- case 'getServiceEndpoint':
271
- if (obj.callback) {
272
- if (!urlKey) {
273
- try {
274
- urlKey = await readUrlKey();
275
- } catch (error) {
276
- try {
277
- urlKey = await createUrlKey(adapter.config.login, adapter.config.pass);
278
- } catch (err) {
279
- return (
280
- obj.callback &&
281
- adapter.sendTo(
282
- obj.from,
283
- obj.command,
284
- { error: `Cannot get urlKey: ${err.toString()}` },
285
- obj.callback,
286
- )
287
- );
288
- }
289
- }
290
- }
291
-
292
- const result = {
293
- url: `https://service.iobroker.in/v1/iotService?key=${urlKey.key}&user=${encodeURIComponent(adapter.config.login)}`,
294
- };
295
- let serviceName =
296
- typeof obj.message === 'string' ? obj.message : obj.message && obj.message.serviceName;
297
- if (serviceName) {
298
- result.url += `&service=${encodeURIComponent(serviceName)}`;
299
- result.stateID = `${adapter.namespace}.services.${serviceName}`;
300
- }
301
- if (obj.message && obj.message.data) {
302
- result.data += `&data=${typeof obj.message.data === 'object' ? JSON.stringify(obj.message.data) : obj.message.data}`;
303
- }
304
- // check if the service name is in the white list
305
- if (
306
- serviceName &&
307
- adapter.config.allowedServices[0] !== '*' &&
308
- !adapter.config.allowedServices.includes(serviceName.replace(/^custom_/, '')) &&
309
- !ALLOWED_SERVICES.includes(serviceName)
310
- ) {
311
- result.warning = 'Service name is not in white list';
312
- adapter.log.warn(`Service "${serviceName}" is not in allowed services list`);
313
- }
314
-
315
- obj.callback && adapter.sendTo(obj.from, obj.command, result, obj.callback);
316
- }
317
- break;
318
- case 'sendNotification':
319
- try {
320
- const { message, title } = buildMessageFromNotification(obj.message);
321
- await sendMessageToApp(JSON.stringify({ message, title }));
322
- if (obj.callback) {
323
- adapter.sendTo(obj.from, 'sendNotification', { sent: true }, obj.callback);
324
- }
325
- } catch {
326
- if (obj.callback) {
327
- adapter.sendTo(obj.from, 'sendNotification', { sent: false }, obj.callback);
328
- }
329
- }
330
- break;
331
- default:
332
- adapter.log.warn(`Unknown command: ${obj.command}`);
333
- break;
334
- }
335
- }
336
- },
337
- ready: () =>
338
- main()
339
- .then(() => {})
340
- .catch(error => {
341
- adapter.log.error(`Error in main: ${error.toString()}`);
342
- }),
343
- });
344
-
345
- adapter = new Adapter(options);
346
-
347
- // warning: `adapter.log = obj => console.log(obj)` does not implemented. Only adapter.on('log', obj => console.log(obj))
348
- adapter.on('log', obj => remote.onLog(obj));
349
-
350
- return adapter;
351
- }
352
-
353
- function sendDataToIFTTT(obj) {
354
- if (!obj) {
355
- return adapter.log.warn('No data to send to IFTTT');
356
- } else if (!adapter.config.iftttKey && (typeof obj !== 'object' || !obj.key)) {
357
- return adapter.log.warn('No IFTTT key is defined');
358
- }
359
-
360
- let url;
361
- let data;
362
- if (typeof obj !== 'object') {
363
- url = `https://maker.ifttt.com/trigger/state/with/key/${adapter.config.iftttKey}`;
364
- data = {
365
- value1: `${adapter.namespace}.services.ifttt`,
366
- value2: obj,
367
- };
368
- } else if (obj.event) {
369
- const event = obj.event;
370
- const key = obj.key;
371
- delete obj.event;
372
- delete obj.key;
373
- url = `https://maker.ifttt.com/trigger/${event}/with/key/${key || adapter.config.iftttKey}`;
374
- data = obj;
375
- } else if (obj.val === undefined) {
376
- return adapter.log.warn('No value is defined');
377
- } else {
378
- obj.id = obj.id || `${adapter.namespace}.services.ifttt`;
379
- url = `https://maker.ifttt.com/trigger/state/with/key/${adapter.config.iftttKey}`;
380
- data = {
381
- value1: obj.id,
382
- value2: obj.val,
383
- value3: obj.ack,
384
- };
385
- }
386
-
387
- if (url) {
388
- axios
389
- .post(url, data, {
390
- timeout: 15000,
391
- validateStatus: status => status < 400,
392
- })
393
- .then(response => adapter.log.debug(`Response from IFTTT: ${JSON.stringify(response.data)}`))
394
- .catch(error => {
395
- if (error.response) {
396
- adapter.log.warn(
397
- `Response from IFTTT: ${error.response.data ? JSON.stringify(error.response.data) : error.response.status}`,
398
- );
399
- } else {
400
- adapter.log.warn(`Response from IFTTT: ${error.code}`);
401
- }
402
- });
403
- } else {
404
- adapter.log.warn(`Invalid request to IFTTT: ${JSON.stringify(obj)}`);
405
- }
406
- }
407
-
408
- /**
409
- * Send a message to the ioBroker Visu App by using the app-message endpoint (which then forwards it to the app via FCM)
410
- *
411
- * @param message either a json string or the message itself, if the message itself the other props will be taken from the adapter states
412
- * @returns {Promise<void>}
413
- */
414
- async function sendMessageToApp(message) {
415
- if (!message) {
416
- throw new Error('Empty message');
417
- }
418
- let json = message.toString().trim();
419
- if (json.startsWith('{') && json.endsWith('}')) {
420
- try {
421
- json = JSON.parse(json);
422
- } catch {
423
- adapter.log.warn(`Cannot parse message: ${json}`);
424
- json = null;
425
- }
426
- } else {
427
- json = null;
428
- }
429
-
430
- if (!json) {
431
- // take expires
432
- const ttlSecondsState = await adapter.getStateAsync(`${adapter.namespace}.app.expire`);
433
- const priorityState = await adapter.getStateAsync(`${adapter.namespace}.app.priority`);
434
- const titleState = await adapter.getStateAsync(`${adapter.namespace}.app.title`);
435
- let priority = priorityState?.val;
436
- if (priority === '1' || priority === 'high' || priority === true) {
437
- priority = 'high';
438
- } else {
439
- priority = undefined;
440
- }
441
- json = {
442
- message: message.toString(),
443
- priority,
444
- ttlSeconds: parseInt(ttlSecondsState?.val, 0) || undefined,
445
- title: titleState?.title || 'ioBroker',
446
- };
447
- } else {
448
- if (json.expire) {
449
- json.ttlSeconds = json.expire;
450
- delete json.expire;
451
- }
452
- }
453
-
454
- json.ttlSeconds = parseInt(json.ttlSeconds, 0) || undefined;
455
-
456
- if (json.ttlSeconds && json.ttlSeconds > 3_600 * 48) {
457
- json.ttlSeconds = 3_600 * 48;
458
- }
459
-
460
- if (!json.message) {
461
- throw new Error('Empty message');
462
- }
463
-
464
- const response = await axios.post('https://app-message.iobroker.in/', json, {
465
- headers: {
466
- 'Content-Type': 'application/json',
467
- Authorization: `Bearer ${Buffer.from(`${adapter.config.login}:${adapter.config.pass}`).toString('base64')}`,
468
- },
469
- timeout: 5_000,
470
- validateStatus: status => status < 400,
471
- });
472
- await adapter.setState('app.message', message, true);
473
- adapter.log.debug(`Message sent: ${JSON.stringify(response.data)}`);
474
- }
475
-
476
- async function controlState(id, data) {
477
- id = id || 'services.ifttt';
478
-
479
- if (typeof data === 'object') {
480
- if (data.id) {
481
- if (data.id === `${adapter.namespace}.services.ifttt`) {
482
- data.ack = true;
483
- }
484
- if (data.val === undefined) {
485
- throw new Error('No value set');
486
- }
487
- const obj = await adapter.getForeignObjectAsync(data.id);
488
- if (!obj || !obj.common) {
489
- throw new Error(`Unknown ID: ${data.id}`);
490
- } else {
491
- if (typeof data.val === 'string') {
492
- data.val = data.val.replace(/^@ifttt\s?/, '');
493
- }
494
- if (obj.common.type === 'boolean') {
495
- data.val =
496
- data.val === true ||
497
- data.val === 'true' ||
498
- data.val === 'on' ||
499
- data.val === 'ON' ||
500
- data.val === 1 ||
501
- data.val === '1';
502
- } else if (obj.common.type === 'number') {
503
- data.val = parseFloat(data.val);
504
- }
505
-
506
- await adapter.setForeignStateAsync(data.id, data.val, data.ack);
507
- }
508
- } else if (data.val !== undefined) {
509
- if (typeof data.val === 'string') {
510
- data.val = data.val.replace(/^@ifttt\s?/, '');
511
- }
512
- await adapter.setStateAsync(id, data.val, data.ack !== undefined ? data.ack : true);
513
- } else {
514
- if (typeof data === 'string') {
515
- data = data.replace(/^@ifttt\s?/, '');
516
- }
517
- await adapter.setStateAsync(id, JSON.stringify(data), true);
518
- }
519
- } else {
520
- if (typeof data === 'string') {
521
- data = data.replace(/^@ifttt\s?/, '');
522
- }
523
- await adapter.setStateAsync(id, data, true);
524
- }
525
- }
526
-
527
- async function processIfttt(data) {
528
- adapter.log.debug(`Received IFTTT object: ${data}`);
529
- let id;
530
- if (typeof data === 'object' && data.id && data.data !== undefined) {
531
- id = data.id;
532
- if (typeof data.data === 'string' && data.data[0] === '{') {
533
- try {
534
- data = JSON.parse(data.data);
535
- } catch (e) {
536
- adapter.log.debug(`Cannot parse: ${data.data}`);
537
- }
538
- } else {
539
- data = data.data;
540
- }
541
- } else {
542
- if (typeof data === 'string' && data[0] === '{') {
543
- try {
544
- data = JSON.parse(data);
545
-
546
- if (typeof data.id === 'string') {
547
- id = data.id;
548
- if (data.data) {
549
- data = data.data;
550
- }
551
- }
552
- } catch (e) {
553
- adapter.log.debug(`Cannot parse: ${data}`);
554
- }
555
- }
556
- }
557
-
558
- if (id) {
559
- let obj = await adapter.getForeignObjectAsync(id);
560
- if (!obj) {
561
- const newId = `${adapter.namespace}.services.${id}`;
562
- obj = await adapter.getForeignObjectAsync(newId);
563
- if (!obj) {
564
- // create state
565
- await adapter.setObjectNotExistsAsync(`services.${id}`, {
566
- type: 'state',
567
- common: {
568
- name: 'IFTTT value',
569
- write: false,
570
- role: 'state',
571
- read: true,
572
- type: 'mixed',
573
- desc: 'Custom state',
574
- },
575
- native: {},
576
- });
577
- id = newId;
578
- }
579
- }
580
- }
581
-
582
- return controlState(id || null, data);
583
- }
584
-
585
- function onDisconnect(event) {
586
- const now = Date.now();
587
- if (now - connectStarted < 500) {
588
- adapter.log.warn(
589
- 'Looks like your connection certificates are invalid. Please renew them via configuration dialog.',
590
- );
591
- }
592
-
593
- if (typeof event === 'string') {
594
- if (event.toLowerCase().includes('duplicate')) {
595
- // disable adapter
596
- adapter.log.error(
597
- `Two devices are trying to connect with the same iot account. This is not allowed. Stopping`,
598
- );
599
- adapter.getForeignObjectAsync(`system.adapter.${adapter.namespace}`).then(obj => {
600
- obj.common.enabled = false;
601
- return adapter.setForeignObjectAsync(obj._id, obj);
602
- });
603
- }
604
- adapter.log.info(`Connection changed: ${event}`);
605
- } else {
606
- adapter.log.info('Connection changed: disconnect');
607
- }
608
-
609
- if (connected) {
610
- adapter.log.info('Connection lost');
611
- connected = false;
612
- adapter.setState('info.connection', false, true);
613
- }
614
-
615
- remote && remote.onCloudDisconnect(event);
616
- }
617
-
618
- function onConnect(clientId) {
619
- if (!connected) {
620
- adapter.log.info(`Connection changed: connect "${clientId}"`);
621
- connected = true;
622
- adapter.setState('info.connection', connected, true);
623
- // setTimeout(() => {
624
- // device.publish(`response/${clientId}/stateChange`, JSON.stringify({alive: true}), {qos: 0}, (error, result) => {
625
- // console.log(`Published alive: ${result}, ${error}`);
626
- // });
627
- // }, 2000);
628
- } else {
629
- adapter.log.info('Connection not changed: was connected');
630
- }
631
- }
632
-
633
- function encrypt(key, value) {
634
- let result = '';
635
- for (let i = 0; i < value.length; i++) {
636
- result += String.fromCharCode(key[i % key.length].charCodeAt(0) ^ value.charCodeAt(i));
637
- }
638
- return `base64:${Buffer.from(result).toString('base64')}`;
639
- }
640
-
641
- function decrypt(key, value) {
642
- if (value.startsWith('base64:')) {
643
- try {
644
- value = Buffer.from(value.substring(7), 'base64').toString('ascii');
645
- } catch (e) {
646
- adapter.log.error(`Cannot decrypt key: ${e}`);
647
- }
648
- }
649
-
650
- let result = '';
651
- for (let i = 0; i < value.length; i++) {
652
- result += String.fromCharCode(key[i % key.length].charCodeAt(0) ^ value.charCodeAt(i));
653
- }
654
- return result;
655
- }
656
-
657
- async function readUrlKey() {
658
- const key = await adapter.getStateAsync('certs.urlKey');
659
-
660
- if (!key || !key.val) {
661
- throw new Error('Not exists');
662
- } else {
663
- return { key: key.val };
664
- }
665
- }
666
-
667
- async function createUrlKey(login, pass) {
668
- adapter.log.debug('Fetching URL key...');
669
-
670
- let response;
671
- try {
672
- response = await axios.get(
673
- `https://generate-key.iobroker.in/v1/generateUrlKey?user=${encodeURIComponent(login)}&pass=${encodeURIComponent(pass)}&version=${version}`,
674
- {
675
- timeout: 15000,
676
- validateStatus: status => status < 400,
677
- },
678
- );
679
- } catch (error) {
680
- if (error.response) {
681
- if (error.response.status === 401) {
682
- adapter.log.error(`Cannot create URL key because of invalid user or password`);
683
- }
684
-
685
- throw new Error(error.response.data);
686
- } else {
687
- throw error;
688
- }
689
- }
690
-
691
- if (response.data && response.data.error) {
692
- adapter.log.error(`Cannot fetch URL key: ${JSON.stringify(response.data.error)}`);
693
- throw new Error(response.data);
694
- } else if (response.data && response.data.key) {
695
- await adapter.setStateAsync('certs.urlKey', response.data.key, true);
696
- return { key: response.data.key };
697
- } else {
698
- adapter.log.error(`Cannot fetch URL key: ${JSON.stringify(response.data)}`);
699
- throw new Error(response.data);
700
- }
701
- }
702
-
703
- async function readCertificates() {
704
- let privateKey;
705
- let certificate;
706
-
707
- try {
708
- privateKey = await adapter.getStateAsync('certs.private');
709
- certificate = await adapter.getStateAsync('certs.certificate');
710
- } catch (error) {
711
- throw new Error('Not exists');
712
- }
713
-
714
- if (!certificate?.val || !privateKey?.val) {
715
- throw new Error('Not exists');
716
- } else {
717
- return {
718
- private: decrypt(secret, privateKey.val),
719
- certificate: decrypt(secret, certificate.val),
720
- };
721
- }
722
- }
723
-
724
- async function writeKeys(data) {
725
- await adapter.setStateAsync('certs.private', encrypt(secret, data.keyPair.PrivateKey), true);
726
- await adapter.setStateAsync('certs.public', encrypt(secret, data.keyPair.PublicKey), true);
727
- await adapter.setStateAsync('certs.certificate', encrypt(secret, data.certificatePem), true);
728
- await adapter.setStateAsync('certs.id', data.certificateId, true);
729
- }
730
-
731
- async function fetchCertificates(login, pass, _forceUserCreation) {
732
- let state;
733
-
734
- state = await adapter.getStateAsync('certs.forceUserCreate');
735
- let forceUserCreation = state && state.val;
736
-
737
- if (forceUserCreation) {
738
- await adapter.setStateAsync('certs.forceUserCreate', false, true);
739
- }
740
-
741
- adapter.log.debug('Fetching certificates...');
742
- let response;
743
- try {
744
- response = await axios.get(
745
- `https://create-user.iobroker.in/v1/createUser?user=${encodeURIComponent(login)}&pass=${encodeURIComponent(pass)}&forceRecreate=${forceUserCreation}&version=${version}`,
746
- {
747
- timeout: 15000,
748
- validateStatus: status => status < 400,
749
- },
750
- );
751
- } catch (error) {
752
- if (error.response) {
753
- if (error.response.status === 401) {
754
- adapter.log.error(`Cannot fetch connection certificates because of invalid user or password`);
755
- } else {
756
- adapter.log.error(`Cannot fetch connection certificates: ${JSON.stringify(error.response.data)}`);
757
- }
758
- throw new Error(error.response.data);
759
- } else {
760
- adapter.log.error(`Cannot fetch connection certificates: ${JSON.stringify(error.code)}`);
761
- throw error;
762
- }
763
- }
764
-
765
- if (response && response.data && response.data.certificates) {
766
- await writeKeys(response.data.certificates);
767
-
768
- return {
769
- private: response.data.certificates.keyPair.PrivateKey,
770
- certificate: response.data.certificates.certificatePem,
771
- };
772
- }
773
- adapter.log.error(`Cannot fetch connection certificates: ${JSON.stringify(response.data)}`);
774
- throw new Error(response.data);
775
- }
776
-
777
- function sendToAsync(instance, command, request) {
778
- return new Promise(resolve =>
779
- adapter.sendTo(instance, command, request, response => {
780
- adapter.log.debug(`Response from ${instance}: ${JSON.stringify(response)}`);
781
- // try to parse JSON
782
- if (typeof response === 'string' && (response[0] === '{' || response[0] === '[')) {
783
- try {
784
- response = JSON.parse(response);
785
- } catch (e) {}
786
- }
787
- resolve(response);
788
- }),
789
- );
790
- }
791
-
792
- async function processMessage(type, request) {
793
- if (request instanceof Buffer) {
794
- request = request.toString();
795
- }
796
-
797
- adapter.log.debug(`Data: ${JSON.stringify(request)}`);
798
-
799
- if (!request || !type) {
800
- return { error: 'invalid request' };
801
- }
802
-
803
- if (type.startsWith('remote')) {
804
- const start = Date.now();
805
- if (remote) {
806
- return remote
807
- .process(request, type)
808
- .then(response => {
809
- if (response !== NONE) {
810
- adapter.log.debug(
811
- `[REMOTE] Response in: ${Date.now() - start}ms (Length: ${Array.isArray(response) ? `A ${response.length}` : JSON.stringify(response).length}) for ${request}`,
812
- );
813
- }
814
- return response;
815
- })
816
- .catch(err => adapter.log.error(`Error in processing of remote request: ${err.toString()}`));
817
- }
818
- adapter.log.error(`Received command, but remote already closed.`);
819
- } else if (type.startsWith('nightscout')) {
820
- if (adapter.config.nightscout) {
821
- let state = await adapter.getForeignStateAsync(
822
- `system.adapter.nightscout.${adapter.config.nightscout}.alive`,
823
- );
824
- if (state && state.val) {
825
- return sendToAsync(`nightscout.${adapter.config.nightscout}`, 'send', request);
826
- }
827
- return { error: `nightscout.${adapter.config.nightscout} is offline` };
828
- }
829
- return { error: 'Service is disabled' };
830
- } else if (type.startsWith('alexa')) {
831
- if (typeof request === 'string') {
832
- try {
833
- request = JSON.parse(request);
834
- } catch (e) {
835
- adapter.log.error(`Cannot parse request: ${request}`);
836
- return { error: 'Cannot parse request' };
837
- }
838
- }
839
-
840
- adapter.log.debug(`${Date.now()} ALEXA: ${JSON.stringify(request)}`);
841
-
842
- if (request && request.directive) {
843
- if (alexaSH3) {
844
- return await alexaSH3.process(request);
845
- }
846
- return { error: 'Service is disabled' };
847
- } else if (request && request.error) {
848
- // answer from alexa3 events cloud actually just show it in log
849
- if (request.error.includes('You have no iobroker.iot license')) {
850
- // pause for 30 minutes send of the events
851
- alexaSH3 && alexaSH3.pauseEvents();
852
- }
853
- adapter.log.error(`Error from Alexa events cloud: ${request.error}`);
854
- } else if (request && !request.header) {
855
- if (alexaCustom) {
856
- return alexaCustom.process(request, adapter.config.amazonAlexa);
857
- }
858
- return { error: 'Service is disabled' };
859
- } else {
860
- if (alexaSH2) {
861
- return alexaSH2.process(request, adapter.config.amazonAlexa);
862
- }
863
- return { error: 'Service is disabled' };
864
- }
865
- } else if (type.startsWith('ifttt')) {
866
- try {
867
- if (typeof request === 'object') {
868
- request = JSON.stringify(request);
869
- } else {
870
- request = request.toString();
871
- }
872
- } catch (e) {
873
- adapter.log.error(`Cannot parse request: ${request}`);
874
- return { error: 'Cannot parse request' };
875
- }
876
-
877
- return processIfttt(request);
878
- } else if (type.startsWith('ghome')) {
879
- if (typeof request === 'string') {
880
- try {
881
- request = JSON.parse(request);
882
- } catch (e) {
883
- adapter.log.error(`Cannot parse request: ${request}`);
884
- return { error: 'Cannot parse request' };
885
- }
886
- }
887
-
888
- if (googleHome) {
889
- return googleHome.process(request, adapter.config.googleHome);
890
- }
891
- return { error: 'Service is disabled' };
892
- } else if (type.startsWith('alisa')) {
893
- if (typeof request === 'string') {
894
- try {
895
- request = JSON.parse(request);
896
- } catch (e) {
897
- adapter.log.error(`Cannot parse request: ${request}`);
898
- return { error: 'Cannot parse request' };
899
- }
900
- }
901
-
902
- adapter.log.debug(`${Date.now()} ALISA: ${JSON.stringify(request)}`);
903
- if (yandexAlisa) {
904
- return yandexAlisa.process(request, adapter.config.yandexAlisa);
905
- }
906
- return { error: 'Service is disabled' };
907
- } else {
908
- let isCustom = false;
909
- let _type = type;
910
- if (_type.match(/^custom_/)) {
911
- _type = _type.substring(7);
912
- isCustom = true;
913
- }
914
- if (_type === 'visu') {
915
- adapter.log.debug(`Received visu command: ${JSON.stringify(request)}`);
916
- if (typeof request === 'object') {
917
- request = JSON.stringify(request);
918
- } else {
919
- request = request.toString();
920
- }
921
-
922
- try {
923
- const visuData = JSON.parse(request);
924
-
925
- if (visuData.presence) {
926
- await handleGeofenceData(visuData, adapter);
927
- }
928
-
929
- if (visuData.devices) {
930
- await handleDevicesData(visuData, adapter);
931
- }
932
-
933
- if (visuData.command === 'getInstances') {
934
- const res = await handleGetInstances(visuData, adapter);
935
- return { result: 'Ok', ...res };
936
- }
937
-
938
- if (visuData.command === 'sendToAdapter') {
939
- return await handleSendToAdapter(visuData, adapter);
940
- }
941
- } catch (e) {
942
- adapter.log.error(`Could not handle data "${request}" by Visu App: ${e.message}`);
943
- return { error: e.message };
944
- }
945
-
946
- return { result: 'Ok' };
947
- } else if (
948
- adapter.config.allowedServices[0] === '*' ||
949
- adapter.config.allowedServices.includes(_type) ||
950
- ALLOWED_SERVICES.includes(_type)
951
- ) {
952
- if (typeof request === 'object') {
953
- request = JSON.stringify(request);
954
- } else {
955
- request = request.toString();
956
- }
957
-
958
- if (SPECIAL_ADAPTERS.includes(_type)) {
959
- try {
960
- await adapter.setStateAsync(`services.${_type}`, request, true);
961
- } catch (err) {
962
- return { result: err };
963
- }
964
-
965
- return { result: 'Ok' };
966
- } else if (type.startsWith('text2command')) {
967
- if (adapter.config.text2command !== undefined && adapter.config.text2command !== '') {
968
- try {
969
- await adapter.setForeignStateAsync(`text2command.${adapter.config.text2command}.text`, request);
970
- } catch (err) {
971
- return { result: err };
972
- }
973
- return { result: 'Ok' };
974
- }
975
- adapter.log.warn('Received service text2command, but instance is not defined');
976
- return { result: 'but instance is not defined' };
977
- } else if (type.startsWith('simpleApi')) {
978
- return { result: 'not implemented' };
979
- } else if (isCustom) {
980
- let obj;
981
- try {
982
- obj = await adapter.getObjectAsync(`services.custom_${_type}`);
983
- } catch (e) {
984
- adapter.log.error(`Cannot get object services.custom_${_type}: ${e}`);
985
- }
986
-
987
- if (!obj) {
988
- try {
989
- await adapter.setObjectNotExistsAsync(`services.custom_${_type}`, {
990
- _id: `${adapter.namespace}.services.custom_${_type}`,
991
- type: 'state',
992
- common: {
993
- name: `Service for ${_type}`,
994
- write: false,
995
- read: true,
996
- type: 'mixed',
997
- role: 'value',
998
- },
999
- native: {},
1000
- });
1001
- await adapter.setStateAsync(`services.custom_${_type}`, request, true);
1002
- } catch (err) {
1003
- adapter.log.error(`Cannot control .services.custom_${_type}: ${JSON.stringify(err)}`);
1004
- return { error: err };
1005
- }
1006
- } else {
1007
- await adapter.setStateAsync(`services.custom_${_type}`, request, true);
1008
- return { result: 'Ok' };
1009
- }
1010
- } else {
1011
- adapter.log.warn(`Received service "${type}", but it is not allowed`);
1012
- return { error: 'not allowed' };
1013
- }
1014
- } else {
1015
- adapter.log.warn(`Received service "${type}", but it is not found in whitelist`);
1016
- return { error: 'Unknown service' };
1017
- }
1018
- }
1019
- }
1020
-
1021
- function closeDevice() {
1022
- return new Promise(resolve => {
1023
- if (device) {
1024
- try {
1025
- device.end(true, () => {
1026
- device = null;
1027
- resolve();
1028
- });
1029
- } catch (e) {
1030
- device = null;
1031
- resolve();
1032
- }
1033
- } else {
1034
- resolve();
1035
- }
1036
- });
1037
- }
1038
-
1039
- async function startDevice(clientId, login, password, retry) {
1040
- retry = retry || 0;
1041
- let certs;
1042
-
1043
- try {
1044
- certs = await readCertificates();
1045
- } catch (error) {
1046
- if (error.message === 'Not exists') {
1047
- try {
1048
- certs = await fetchCertificates(login, password);
1049
- } catch (error) {}
1050
- } else {
1051
- throw error;
1052
- }
1053
- }
1054
-
1055
- // destroy the old device
1056
- await closeDevice();
1057
-
1058
- if (!certs) {
1059
- return adapter.log.error(`Cannot read connection certificates`);
1060
- }
1061
-
1062
- try {
1063
- connectStarted = Date.now();
1064
- device = new DeviceModule({
1065
- privateKey: Buffer.from(certs.private),
1066
- clientCert: Buffer.from(certs.certificate),
1067
- caCert: readFileSync(`${__dirname}/keys/root-CA.crt`),
1068
- clientId,
1069
- username: 'ioBroker',
1070
- host: adapter.config.cloudUrl,
1071
- debug: !!adapter.config.debug,
1072
- baseReconnectTimeMs: 5000,
1073
- keepalive: 60,
1074
- });
1075
- remote.registerDevice(device);
1076
-
1077
- device.subscribe(`command/${clientId}/#`);
1078
- device.on('connect', () => onConnect(clientId));
1079
- device.on('close', onDisconnect);
1080
- device.on('reconnect', () => adapter.log.debug('reconnect'));
1081
- device.on('offline', () => adapter.log.debug('offline'));
1082
- device.on('error', error => {
1083
- const errorTxt = (error && error.message && JSON.stringify(error.message)) || JSON.stringify(error);
1084
- adapter.log.error(`Error by device connection: ${errorTxt}`);
1085
-
1086
- // restart the iot device if DNS cannot be resolved
1087
- if (errorTxt.includes('EAI_AGAIN')) {
1088
- adapter.log.error(
1089
- `DNS name of ${adapter.config.cloudUrl} cannot be resolved: connection will be retried in 10 seconds.`,
1090
- );
1091
- setTimeout(() => startDevice(clientId, login, password), 10000);
1092
- }
1093
- });
1094
-
1095
- device.on('message', async (topic, request) => {
1096
- adapter.log.debug(`Request ${topic}`);
1097
- if (topic.startsWith(`command/${clientId}/`)) {
1098
- let type = topic.substring(clientId.length + 9);
1099
-
1100
- try {
1101
- const response = await processMessage(type, request);
1102
-
1103
- if (adapter.common.loglevel === 'debug' && !type.startsWith('remote')) {
1104
- adapter.log.debug(`Response: ${JSON.stringify(response)}`);
1105
- }
1106
-
1107
- if (device && response !== NONE) {
1108
- if (Array.isArray(response)) {
1109
- try {
1110
- for (let m = 0; m < response.length; m++) {
1111
- const trunk = response[m];
1112
- await new Promise((resolve, reject) =>
1113
- device.publish(
1114
- `response/${clientId}/${type}`,
1115
- typeof trunk !== 'string' ? JSON.stringify(trunk) : trunk,
1116
- { qos: 1 },
1117
- error => {
1118
- if (error) {
1119
- reject(error);
1120
- } else {
1121
- resolve();
1122
- }
1123
- },
1124
- ),
1125
- );
1126
- }
1127
- } catch (err) {
1128
- adapter.log.error(`[REMOTE] Cannot send packet: ${err}`);
1129
- }
1130
- } else {
1131
- adapter.log.debug(
1132
- `[REMOTE] Send response to 'response/${clientId}/${type}: ${JSON.stringify(response)}`,
1133
- );
1134
-
1135
- const msg = JSON.stringify(response);
1136
- if (msg && msg.length > MAX_IOT_MESSAGE_LENGTH) {
1137
- let packed = deflateSync(msg).toString('base64');
1138
- adapter.log.debug(
1139
- `[REMOTE] Content was packed from ${msg.length} bytes to ${packed.length} bytes`,
1140
- );
1141
- if (packed.length > MAX_IOT_MESSAGE_LENGTH) {
1142
- adapter.log.warn(
1143
- `[REMOTE] Content was packed to ${packed.length} bytes which is still near/over the message limit!`,
1144
- );
1145
- }
1146
- device.publish(`response/${clientId}/${type}`, packed);
1147
- } else {
1148
- // console.log(`Publish to "response/${clientId}/${type}": ${msg}`);
1149
- device.publish(`response/${clientId}/${type}`, msg);
1150
- }
1151
- }
1152
- }
1153
- } catch (error) {
1154
- adapter.log.debug(`Error processing request ${topic}`);
1155
- adapter.log.debug(`${error}`);
1156
- }
1157
- }
1158
- });
1159
- } catch (error) {
1160
- if (error && typeof error === 'object' && error.message) {
1161
- adapter.log.error(`Cannot read connection certificates: ${error.message}`);
1162
- } else {
1163
- adapter.log.error(
1164
- `Cannot read connection certificates: ${JSON.stringify(error)} / ${error && error.toString()}`,
1165
- );
1166
- }
1167
-
1168
- if ((error === 'timeout' || (error.message && error.message.includes('timeout'))) && retry < 10) {
1169
- setTimeout(() => startDevice(clientId, login, password, retry + 1), 10000);
1170
- }
1171
- }
1172
- }
1173
-
1174
- async function updateNightscoutSecret() {
1175
- if (!adapter.config.nightscout) {
1176
- return;
1177
- }
1178
-
1179
- const email = adapter.config.login.replace(/[^\w\d-_]/g, '_');
1180
- const secret = adapter.config.nightscoutPass;
1181
- const apiSecret = email + (secret ? `-${secret}` : '');
1182
- const URL = `https://generate-key.iobroker.in/v1/generateUrlKey?user=${encodeURIComponent(adapter.config.login)}&pass=${encodeURIComponent(adapter.config.pass)}&apisecret=${encodeURIComponent(apiSecret)}`;
1183
- let response;
1184
-
1185
- try {
1186
- response = await axios.get(URL, {
1187
- timeout: 15000,
1188
- validateStatus: status => status < 400,
1189
- });
1190
- if (response.data.error) {
1191
- adapter.log.error(`Api-Secret cannot be updated: ${response.data.error}`);
1192
- } else {
1193
- adapter.log.debug(`Api-Secret updated: ${JSON.stringify(response.data)}`);
1194
- }
1195
- } catch (error) {
1196
- if (error.response) {
1197
- adapter.log.warn(
1198
- `Cannot update api-secret: ${error.response.data ? JSON.stringify(error.response.data) : error.response.status}`,
1199
- );
1200
- } else {
1201
- adapter.log.warn(`Cannot update api-secret: ${error.code}`);
1202
- }
1203
- }
1204
- }
1205
-
1206
- async function createStateForAdapter(adapterName) {
1207
- // find any instance of this adapter
1208
- const instances = await adapter.getObjectViewAsync('system', 'instance', {
1209
- startkey: `system.adapter.${adapterName}.`,
1210
- endkey: `system.adapter.${adapterName}.\u9999`,
1211
- });
1212
- if (instances && instances.rows && instances.rows.length) {
1213
- let obj;
1214
- try {
1215
- obj = await adapter.getObjectAsync(`service.${adapterName}`);
1216
- } catch (e) {
1217
- // ignore
1218
- }
1219
- if (!obj) {
1220
- try {
1221
- await adapter.setForeignObjectAsync(`${adapter.namespace}.services.${adapterName}`, {
1222
- type: 'state',
1223
- common: {
1224
- name: `Service for ${adapterName}`,
1225
- write: false,
1226
- read: true,
1227
- type: 'mixed',
1228
- role: 'value',
1229
- },
1230
- native: {},
1231
- });
1232
- } catch (e) {
1233
- // ignore
1234
- }
1235
- }
1236
- } else {
1237
- try {
1238
- // delete if object exists
1239
- const obj = await adapter.getObjectAsync(`service.${adapterName}`);
1240
- if (obj) {
1241
- await adapter.delObjectAsync(`service.${adapterName}`);
1242
- }
1243
- } catch (e) {
1244
- // ignore
1245
- }
1246
- }
1247
- }
1248
-
1249
- async function main() {
1250
- if (adapter.config.googleHome === undefined) {
1251
- adapter.config.googleHome = false;
1252
- }
1253
-
1254
- if (adapter.config.amazonAlexa === undefined) {
1255
- adapter.config.amazonAlexa = true;
1256
- }
1257
-
1258
- if (adapter.config.yandexAlisa === undefined) {
1259
- adapter.config.yandexAlisa = false;
1260
- }
1261
-
1262
- adapter.config.pingTimeout = parseInt(adapter.config.pingTimeout, 10) || 5000;
1263
-
1264
- if (adapter.config.pingTimeout < 3000) {
1265
- adapter.config.pingTimeout = 3000;
1266
- }
1267
-
1268
- if (adapter.config.deviceOffLevel === undefined) {
1269
- adapter.config.deviceOffLevel = 30;
1270
- }
1271
-
1272
- if (adapter.config.login !== (adapter.config.login || '').trim().toLowerCase()) {
1273
- adapter.log.error('Please write your login only in lowercase!');
1274
- }
1275
- if (!adapter.config.login || !adapter.config.pass) {
1276
- return adapter.log.error('No cloud credentials found. Please get one on https://iobroker.pro');
1277
- }
1278
-
1279
- let systemConfig = await adapter.getForeignObjectAsync('system.config');
1280
- if (!systemConfig) {
1281
- adapter.log.warn('Object system.config not found. Please check your installation!');
1282
- systemConfig = { common: {} };
1283
- }
1284
-
1285
- // create service state for netatmo if any instance exists
1286
- for (let a = 0; a < SPECIAL_ADAPTERS.length; a++) {
1287
- await createStateForAdapter(SPECIAL_ADAPTERS[a]);
1288
- }
1289
-
1290
- const oUuid = await adapter.getForeignObjectAsync('system.meta.uuid');
1291
-
1292
- secret = (systemConfig && systemConfig.native && systemConfig.native.secret) || 'Zgfr56gFe87jJOM';
1293
-
1294
- adapter.config.pass = decrypt(secret, adapter.config.pass);
1295
- adapter.config.deviceOffLevel = parseFloat(adapter.config.deviceOffLevel) || 0;
1296
- adapter.config.concatWord = (adapter.config.concatWord || '').toString().trim();
1297
- adapter.config.apikey = (adapter.config.apikey || '').trim();
1298
- adapter.config.replaces = adapter.config.replaces ? adapter.config.replaces.split(',') : null;
1299
- adapter.config.cloudUrl = (adapter.config.cloudUrl || '').toString();
1300
- adapter.config.nightscout = adapter.config.nightscout || '';
1301
-
1302
- if (adapter.config.replaces) {
1303
- let text = [];
1304
- for (let r = 0; r < adapter.config.replaces.length; r++) {
1305
- text.push(`"${adapter.config.replaces}"`);
1306
- }
1307
- adapter.log.debug(`Following strings will be replaced in names: ${text.join(', ')}`);
1308
- }
1309
- if (adapter.config.amazonAlexa) {
1310
- alexaSH2 = new AlexaSH2(adapter);
1311
- alexaCustom = new AlexaCustom(adapter);
1312
- }
1313
- if (adapter.config.yandexAlisa) {
1314
- yandexAlisa = new YandexAlisa(adapter);
1315
- }
1316
-
1317
- remote = new Remote(adapter, adapter.config.login.replace(/[^-_:a-zA-Z1-9]/g, '_'));
1318
-
1319
- adapter.config.allowedServices = (adapter.config.allowedServices || '')
1320
- .split(/[,\s]+/)
1321
- .map(s => s.trim())
1322
- .filter(s => s);
1323
-
1324
- adapter.setState('info.connection', false, true);
1325
- adapter.config.cloudUrl = adapter.config.cloudUrl || 'a18wym7vjdl22g.iot.eu-west-1.amazonaws.com';
1326
-
1327
- if (!adapter.config.login || !adapter.config.pass) {
1328
- return adapter.log.error('No cloud credentials found. Please get one on https://iobroker.pro');
1329
- }
1330
-
1331
- if (adapter.config.iftttKey) {
1332
- await adapter.subscribeStatesAsync('services.ifttt');
1333
- // create ifttt object
1334
- const iftttObj = await adapter.getObjectAsync('.services.ifttt');
1335
- if (!iftttObj) {
1336
- await adapter.setObjectNotExistsAsync('services.ifttt', {
1337
- _id: `${adapter.namespace}.services.ifttt`,
1338
- type: 'state',
1339
- common: {
1340
- name: 'IFTTT value',
1341
- write: true,
1342
- role: 'state',
1343
- read: true,
1344
- type: 'mixed',
1345
- desc: 'All written data will be sent to IFTTT. If no state specified all requests from IFTTT will be saved here',
1346
- },
1347
- native: {},
1348
- });
1349
- }
1350
- }
1351
-
1352
- // detect netatmo creation
1353
- await adapter.subscribeForeignObjectsAsync('system.adapter.*');
1354
-
1355
- await adapter.subscribeStatesAsync('smart.*');
1356
-
1357
- adapter.log.info(`Connecting with ${adapter.config.cloudUrl}`);
1358
-
1359
- if (adapter.config.language) {
1360
- translate = true;
1361
- lang = adapter.config.language;
1362
- } else {
1363
- lang = systemConfig.common.language;
1364
- }
1365
-
1366
- if (lang !== 'en' && lang !== 'de' && lang !== 'ru') {
1367
- lang = 'en';
1368
- }
1369
-
1370
- defaultHistory = systemConfig.common.defaultHistory;
1371
-
1372
- if (adapter.config.amazonAlexa && alexaSH2) {
1373
- alexaSH2.setLanguage(lang, translate);
1374
- alexaSH2.updateDevices();
1375
- }
1376
-
1377
- alexaCustom?.setLanguage(lang, translate);
1378
-
1379
- remote?.setLanguage(lang);
1380
- // check password
1381
- if (
1382
- adapter.config.pass.length < 8 ||
1383
- !adapter.config.pass.match(/[a-z]/) ||
1384
- !adapter.config.pass.match(/[A-Z]/) ||
1385
- !adapter.config.pass.match(/\d/)
1386
- ) {
1387
- return adapter.log.error(
1388
- 'The password must be at least 8 characters long and have numbers, upper and lower case letters. Please change the password in the profile https://iobroker.pro/accountProfile.',
1389
- );
1390
- }
1391
-
1392
- if (oUuid?.native) {
1393
- uuid = oUuid.native.uuid;
1394
- }
1395
-
1396
- await updateNightscoutSecret();
1397
-
1398
- const iotClientId = adapter.config.login.replace(/[^-_:a-zA-Z1-9]/g, '_');
1399
- // user will be created here
1400
- await startDevice(iotClientId, adapter.config.login, adapter.config.pass);
1401
-
1402
- // after the user created, we can try to generate URL key
1403
- // read URL keys from server
1404
- try {
1405
- urlKey = await readUrlKey();
1406
- } catch (error) {
1407
- if (
1408
- adapter.config.googleHome ||
1409
- adapter.config.yandexAlisa ||
1410
- adapter.config.allowedServices.length ||
1411
- adapter.config.iftttKey
1412
- ) {
1413
- try {
1414
- urlKey = await createUrlKey(adapter.config.login, adapter.config.pass);
1415
- } catch (err) {
1416
- return adapter.log.error(`Cannot read URL key: ${typeof err === 'object' ? JSON.stringify(err) : err}`);
1417
- }
1418
- }
1419
- }
1420
-
1421
- if (adapter.config.amazonAlexaV3) {
1422
- alexaSH3 = new AlexaSH3({
1423
- adapter,
1424
- iotClientId,
1425
- iotDevice: device,
1426
- });
1427
- alexaSH3.setLanguage(lang);
1428
- await alexaSH3.updateDevices();
1429
- }
1430
-
1431
- if (adapter.config.googleHome) {
1432
- googleHome = new GoogleHome(adapter, urlKey);
1433
- } // no else
1434
- if (adapter.config.yandexAlisa) {
1435
- yandexAlisa = new YandexAlisa(adapter, urlKey);
1436
- }
1437
-
1438
- googleHome?.setLanguage(lang, translate);
1439
- googleHome?.updateDevices();
1440
-
1441
- yandexAlisa?.setLanguage(lang, translate);
1442
- yandexAlisa?.updateDevices();
1443
-
1444
- await adapter.subscribeStatesAsync('app.message');
1445
- }
1446
-
1447
- // If started as allInOne mode => return function to create instance
1448
- // @ts-ignore
1449
- if (module.parent) {
1450
- module.exports = startAdapter;
1451
- } else {
1452
- // or start the instance directly
1453
- startAdapter();
1454
- }