node-red-contrib-knx-ultimate 4.0.24 → 4.0.26

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 (264) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/nodes/knxUltimate.html +211 -43
  3. package/nodes/knxUltimateWatchDog.html +106 -8
  4. package/package.json +2 -2
  5. package/resources/KNXSendSnippets.js +76 -2
  6. package/tutorial/HUEApiV2/developers.meethue.com/Getting started - Philips Hue Developer Program.webarchive +0 -0
  7. package/tutorial/HUEApiV2/developers.meethue.com/css/bootstrap.min.css +0 -6
  8. package/tutorial/HUEApiV2/developers.meethue.com/css/default.min.css +0 -1
  9. package/tutorial/HUEApiV2/developers.meethue.com/develop/hue-api-v2/api-reference/index.html +0 -47360
  10. package/tutorial/HUEApiV2/developers.meethue.com/develop/hue-api-v2/core-concepts/index.html +0 -845
  11. package/tutorial/HUEApiV2/developers.meethue.com/develop/hue-api-v2/getting-started/index.html +0 -780
  12. package/tutorial/HUEApiV2/developers.meethue.com/develop/hue-api-v2/index.html +0 -637
  13. package/tutorial/HUEApiV2/developers.meethue.com/develop/hue-entertainment/index.html +0 -643
  14. package/tutorial/HUEApiV2/developers.meethue.com/js/bootstrap.min.js +0 -6
  15. package/tutorial/HUEApiV2/developers.meethue.com/js/highlight.min.js +0 -1296
  16. package/tutorial/HUEApiV2/developers.meethue.com/js/jquery-3.5.1.min.js +0 -2
  17. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/caldera-forms/assets/css/caldera-forms-front.css +0 -62
  18. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/caldera-forms/assets/css/fonts/cf-raty/357/271/22640481674.eot +0 -0
  19. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/caldera-forms/assets/css/fonts/cf-raty/357/271/22640481674.svg +0 -23
  20. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/caldera-forms/assets/css/fonts/cf-raty/357/271/22640481674.ttf +0 -0
  21. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/caldera-forms/assets/css/fonts/cf-raty/357/271/22640481674.woff +0 -0
  22. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/caldera-forms/assets/css/minicolor-colors.png +0 -0
  23. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/caldera-forms/assets/images/credit-card.svg +0 -6
  24. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/caldera-forms/assets/images/loading.gif +0 -0
  25. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/caldera-forms/assets/js/ajax-core.js +0 -324
  26. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/caldera-forms/assets/js/field-config.js +0 -777
  27. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/caldera-forms/assets/js/fields.js +0 -2721
  28. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/caldera-forms/assets/js/frontend-script-init.js +0 -674
  29. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/caldera-forms/assets/js/jquery-baldrick.js +0 -586
  30. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/caldera-forms/assets/js/parsley-aria.js +0 -22
  31. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/caldera-forms/assets/js/parsley.js +0 -2494
  32. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/caldera-forms/assets/js/state/events.js +0 -102
  33. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/caldera-forms/assets/js/state/state.js +0 -472
  34. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/caldera-forms/clients/render/build/index.min.js +0 -1
  35. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/caldera-forms/clients/render/build/style.min.css +0 -1
  36. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/caldera-forms/fields/phone_better/assets/css/intlTelInput.css +0 -1
  37. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/caldera-forms/fields/phone_better/assets/img/flags.png +0 -0
  38. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/caldera-forms/fields/phone_better/assets/img/flags@2x.png +0 -0
  39. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/caldera-forms/fields/phone_better/assets/js/intlTelInput.min.js +0 -6
  40. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/enlighter/cache/enlighterjs.min.css +0 -19
  41. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/enlighter/cache/enlighterjs.min.js +0 -4
  42. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/newsletter/main.js +0 -27
  43. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/newsletter/style.css +0 -350
  44. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/tabulate/assets/jquery-ui/themes/base/images/ui-icons_444444_256x240.png +0 -0
  45. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/tabulate/assets/jquery-ui/themes/base/images/ui-icons_555555_256x240.png +0 -0
  46. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/tabulate/assets/jquery-ui/themes/base/images/ui-icons_777620_256x240.png +0 -0
  47. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/tabulate/assets/jquery-ui/themes/base/images/ui-icons_777777_256x240.png +0 -0
  48. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/tabulate/assets/jquery-ui/themes/base/images/ui-icons_cc0000_256x240.png +0 -0
  49. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/tabulate/assets/jquery-ui/themes/base/images/ui-icons_ffffff_256x240.png +0 -0
  50. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/tabulate/assets/jquery-ui/themes/base/jquery-ui.min.css +0 -7
  51. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/tabulate/assets/jquery-ui-timepicker-addon.css +0 -27
  52. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/tabulate/assets/leaflet/css/leaflet.css +0 -624
  53. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/tabulate/assets/leaflet/images/layers-2x.png +0 -0
  54. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/tabulate/assets/leaflet/images/layers.png +0 -0
  55. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/tabulate/assets/leaflet/images/marker-icon.png +0 -0
  56. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/tabulate/assets/style.css +0 -76
  57. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/css/pickadate/default.css +0 -171
  58. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/css/pickadate/default.date.css +0 -302
  59. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/css/pickadate/default.time.css +0 -113
  60. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/css/select2/select2.min.css +0 -1
  61. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/css/simplebar.css +0 -190
  62. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/css/um-account.css +0 -247
  63. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/css/um-crop.css +0 -271
  64. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/css/um-fileupload.css +0 -201
  65. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/css/um-fonticons-fa.css +0 -1582
  66. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/css/um-fonticons-ii.css +0 -1492
  67. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/css/um-misc.css +0 -118
  68. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/css/um-modal.css +0 -204
  69. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/css/um-old-default.css +0 -271
  70. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/css/um-profile.css +0 -576
  71. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/css/um-raty.css +0 -41
  72. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/css/um-responsive.css +0 -656
  73. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/css/um-styles.css +0 -1064
  74. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/css/um-tipsy.css +0 -31
  75. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/font/fontawesome-webfont/357/271/226v=4.2.0.eot +0 -0
  76. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/font/fontawesome-webfont/357/271/226v=4.2.0.svg +0 -2671
  77. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/font/fontawesome-webfont/357/271/226v=4.2.0.ttf +0 -0
  78. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/font/fontawesome-webfont/357/271/226v=4.2.0.woff +0 -0
  79. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/font/ionicons/357/271/226v=2.0.0.eot +0 -0
  80. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/font/ionicons/357/271/226v=2.0.0.svg +0 -2232
  81. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/font/ionicons/357/271/226v=2.0.0.ttf +0 -0
  82. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/font/ionicons/357/271/226v=2.0.0.woff +0 -0
  83. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/font/raty.eot +0 -0
  84. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/font/raty.svg +0 -15
  85. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/font/raty.ttf +0 -0
  86. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/font/raty.woff +0 -0
  87. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/font/raty/357/271/226.eot +0 -0
  88. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/img/default_avatar.jpg +0 -0
  89. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/img/loading-dots.gif +0 -0
  90. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/img/loading.gif +0 -0
  91. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/js/pickadate/picker.date.js +0 -1357
  92. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/js/pickadate/picker.js +0 -1206
  93. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/js/pickadate/picker.time.js +0 -1016
  94. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/js/select2/select2.full.min.js +0 -2
  95. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/js/simplebar.min.js +0 -1
  96. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/js/um-account.min.js +0 -1
  97. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/js/um-conditional.min.js +0 -1
  98. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/js/um-crop.min.js +0 -1
  99. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/js/um-fileupload.js +0 -8
  100. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/js/um-functions.min.js +0 -1
  101. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/js/um-gdpr.min.js +0 -1
  102. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/js/um-jquery-form.min.js +0 -1
  103. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/js/um-modal.min.js +0 -1
  104. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/js/um-profile.min.js +0 -1
  105. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/js/um-raty.min.js +0 -1
  106. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/js/um-responsive.min.js +0 -1
  107. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/js/um-scripts.min.js +0 -1
  108. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/ultimate-member/assets/js/um-tipsy.min.js +0 -1
  109. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/wp-simple-firewall/assets/dist/shield-notbot.bundle/357/271/226mtime=1755510308.js +0 -2
  110. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/plugins/wp-simple-firewall/assets/dist/shield-userprofile.bundle/357/271/226mtime=1755510308.css +0 -1
  111. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/blockimg/develop_block.png +0 -0
  112. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/blockimg/explore_block.png +0 -0
  113. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/blockimg/support_block.png +0 -0
  114. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/fonts/CentraleSans-Bold.otf +0 -0
  115. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/fonts/CentraleSans-Book.otf +0 -0
  116. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/fonts/CentraleSans-Light.otf +0 -0
  117. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/fonts/CentraleSans-XBold.otf +0 -0
  118. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/fonts/CentraleSans-XBoldIt.otf +0 -0
  119. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/img/0.png +0 -0
  120. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/img/1.png +0 -0
  121. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/img/2.png +0 -0
  122. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/img/account_bg.jpg +0 -0
  123. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/img/bigbg.jpg +0 -0
  124. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/img/check_box.png +0 -0
  125. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/img/checkbox_checked.png +0 -0
  126. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/img/develop_bg.jpg +0 -0
  127. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/img/develop_block.png +0 -0
  128. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/img/develop_ico.png +0 -0
  129. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/img/explore_bg.jpg +0 -0
  130. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/img/explore_ico.png +0 -0
  131. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/img/faq_bg.jpg +0 -0
  132. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/img/jobs_bg.jpg +0 -0
  133. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/img/moblogo.png +0 -0
  134. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/img/more_ico.png +0 -0
  135. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/img/serach big.png +0 -0
  136. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/img/site_logo.png.jpeg +0 -0
  137. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/img/support_ico.png +0 -0
  138. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/js/my-scripts.js +0 -29
  139. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/js/navigation.js +0 -106
  140. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/js/skip-link-focus-fix.js +0 -31
  141. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/mob/bg.jpg +0 -0
  142. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/mob/bg_1.png +0 -0
  143. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/mob/bg_2.png +0 -0
  144. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/mob/bg_3.png +0 -0
  145. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/mob/bg_4.png +0 -0
  146. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/themes/hue_developer_theme/style.css +0 -3198
  147. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2018/02/app_ico.png +0 -0
  148. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2018/02/bridge_ico.png +0 -0
  149. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2018/02/color.png +0 -0
  150. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2018/02/info_ico.png +0 -0
  151. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2018/02/lights_ico.png +0 -0
  152. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2018/02/portal_ico.png +0 -0
  153. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2018/11/cropped-PhilipsHueFREESTANDING-180x180.jpg +0 -0
  154. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2018/11/cropped-PhilipsHueFREESTANDING-192x192.jpg +0 -0
  155. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2018/11/cropped-PhilipsHueFREESTANDING-32x32.jpg +0 -0
  156. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2020/10/265b174e66fd5b50645b1f1c3ea2553a_w80.jpg +0 -0
  157. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2021/10/1-certificate-verification-300x91.png +0 -0
  158. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2021/10/1-certificate-verification-768x233.png +0 -0
  159. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2021/10/1-certificate-verification.png +0 -0
  160. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2021/10/2-403-forbidden-300x78.png +0 -0
  161. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2021/10/2-403-forbidden-768x200.png +0 -0
  162. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2021/10/2-403-forbidden.png +0 -0
  163. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2021/10/3-link-button-300x203.png +0 -0
  164. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2021/10/3-link-button.png +0 -0
  165. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2021/10/4-username-300x194.png +0 -0
  166. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2021/10/4-username.png +0 -0
  167. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2021/10/5-devices-300x279.png +0 -0
  168. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2021/10/5-devices-768x715.png +0 -0
  169. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2021/10/5-devices.png +0 -0
  170. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2021/10/6-light-300x195.png +0 -0
  171. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2021/10/6-light-768x499.png +0 -0
  172. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2021/10/6-light.png +0 -0
  173. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2021/10/7-on-300x115.png +0 -0
  174. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2021/10/7-on-768x293.png +0 -0
  175. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2021/10/7-on.png +0 -0
  176. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2021/10/8-brightness-color-1-300x158.png +0 -0
  177. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2021/10/8-brightness-color-1-768x404.png +0 -0
  178. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2021/10/8-brightness-color-1.png +0 -0
  179. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2024/08/Screenshot-2024-08-06-at-13.01.35-1024x488.png +0 -0
  180. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2024/08/Screenshot-2024-08-06-at-13.01.35-1536x732.png +0 -0
  181. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2024/08/Screenshot-2024-08-06-at-13.01.35-2048x976.png +0 -0
  182. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2024/08/Screenshot-2024-08-06-at-13.01.35-300x143.png +0 -0
  183. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2024/08/Screenshot-2024-08-06-at-13.01.35-768x366.png +0 -0
  184. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2024/08/Screenshot-2024-08-06-at-13.01.35.png +0 -0
  185. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2024/08/Screenshot-2024-08-06-at-13.01.41-1024x294.png +0 -0
  186. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2024/08/Screenshot-2024-08-06-at-13.01.41-1536x440.png +0 -0
  187. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2024/08/Screenshot-2024-08-06-at-13.01.41-2048x587.png +0 -0
  188. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2024/08/Screenshot-2024-08-06-at-13.01.41-300x86.png +0 -0
  189. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2024/08/Screenshot-2024-08-06-at-13.01.41-768x220.png +0 -0
  190. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2024/08/Screenshot-2024-08-06-at-13.01.41.png +0 -0
  191. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2025/09/cropped-hue_site_icon-180x180.png +0 -0
  192. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2025/09/cropped-hue_site_icon-192x192.png +0 -0
  193. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/2025/09/cropped-hue_site_icon-32x32.png +0 -0
  194. package/tutorial/HUEApiV2/developers.meethue.com/wp-content/uploads/ultimatemember/um_old_settings.css +0 -422
  195. package/tutorial/HUEApiV2/developers.meethue.com/wp-includes/css/dist/block-library/style.min.css +0 -11
  196. package/tutorial/HUEApiV2/developers.meethue.com/wp-includes/js/dist/dom-ready.min.js +0 -2
  197. package/tutorial/HUEApiV2/developers.meethue.com/wp-includes/js/dist/hooks.min.js +0 -2
  198. package/tutorial/HUEApiV2/developers.meethue.com/wp-includes/js/dist/i18n.min.js +0 -2
  199. package/tutorial/HUEApiV2/developers.meethue.com/wp-includes/js/dist/vendor/react-dom.min.js +0 -10
  200. package/tutorial/HUEApiV2/developers.meethue.com/wp-includes/js/dist/vendor/react.min.js +0 -10
  201. package/tutorial/HUEApiV2/developers.meethue.com/wp-includes/js/dist/vendor/regenerator-runtime.min.js +0 -1
  202. package/tutorial/HUEApiV2/developers.meethue.com/wp-includes/js/dist/vendor/wp-polyfill-inert.min.js +0 -1
  203. package/tutorial/HUEApiV2/developers.meethue.com/wp-includes/js/dist/vendor/wp-polyfill.min.js +0 -1
  204. package/tutorial/HUEApiV2/developers.meethue.com/wp-includes/js/imagesloaded.min.js +0 -13
  205. package/tutorial/HUEApiV2/developers.meethue.com/wp-includes/js/jquery/jquery.masonry.min.js +0 -11
  206. package/tutorial/HUEApiV2/developers.meethue.com/wp-includes/js/masonry.min.js +0 -10
  207. package/tutorial/HUEApiV2/developers.meethue.com/wp-includes/js/underscore.min.js +0 -2
  208. package/tutorial/HUEApiV2/developers.meethue.com/wp-includes/js/wp-util.min.js +0 -2
  209. package/tutorial/hue-config-teleprompter.txt +0 -43
  210. package/tutorial/hue-config.md +0 -45
  211. package/tutorial/knxUltimate-AllNodes-Presentazione.md +0 -185
  212. package/tutorial/knxUltimate-config-teleprompter.txt +0 -87
  213. package/tutorial/knxUltimate-config.md +0 -65
  214. package/tutorial/knxUltimate-teleprompter.txt +0 -60
  215. package/tutorial/knxUltimate.md +0 -59
  216. package/tutorial/knxUltimateAlerter-teleprompter.txt +0 -48
  217. package/tutorial/knxUltimateAlerter.md +0 -49
  218. package/tutorial/knxUltimateAutoResponder-teleprompter.txt +0 -43
  219. package/tutorial/knxUltimateAutoResponder.md +0 -46
  220. package/tutorial/knxUltimateFutureNodes.md +0 -11
  221. package/tutorial/knxUltimateGlobalContext-teleprompter.txt +0 -44
  222. package/tutorial/knxUltimateGlobalContext.md +0 -44
  223. package/tutorial/knxUltimateHATranslator-teleprompter.txt +0 -45
  224. package/tutorial/knxUltimateHATranslator.md +0 -43
  225. package/tutorial/knxUltimateHueBattery-teleprompter.txt +0 -42
  226. package/tutorial/knxUltimateHueBattery.md +0 -43
  227. package/tutorial/knxUltimateHueButton-teleprompter.txt +0 -45
  228. package/tutorial/knxUltimateHueButton.md +0 -54
  229. package/tutorial/knxUltimateHueCameraMotion-teleprompter.txt +0 -44
  230. package/tutorial/knxUltimateHueCameraMotion.md +0 -45
  231. package/tutorial/knxUltimateHueContactSensor-teleprompter.txt +0 -35
  232. package/tutorial/knxUltimateHueContactSensor.md +0 -45
  233. package/tutorial/knxUltimateHueHumiditySensor-teleprompter.txt +0 -43
  234. package/tutorial/knxUltimateHueHumiditySensor.md +0 -45
  235. package/tutorial/knxUltimateHueLight-teleprompter.txt +0 -50
  236. package/tutorial/knxUltimateHueLight.md +0 -66
  237. package/tutorial/knxUltimateHueLightSensor-teleprompter.txt +0 -46
  238. package/tutorial/knxUltimateHueLightSensor.md +0 -44
  239. package/tutorial/knxUltimateHueMotion-teleprompter.txt +0 -43
  240. package/tutorial/knxUltimateHueMotion.md +0 -44
  241. package/tutorial/knxUltimateHuePlug-teleprompter.txt +0 -48
  242. package/tutorial/knxUltimateHuePlug.md +0 -49
  243. package/tutorial/knxUltimateHueScene-teleprompter.txt +0 -49
  244. package/tutorial/knxUltimateHueScene.md +0 -52
  245. package/tutorial/knxUltimateHueTapDial-teleprompter.txt +0 -44
  246. package/tutorial/knxUltimateHueTapDial.md +0 -44
  247. package/tutorial/knxUltimateHueTemperatureSensor-teleprompter.txt +0 -46
  248. package/tutorial/knxUltimateHueTemperatureSensor.md +0 -44
  249. package/tutorial/knxUltimateHueZigbeeConnectivity-teleprompter.txt +0 -45
  250. package/tutorial/knxUltimateHueZigbeeConnectivity.md +0 -44
  251. package/tutorial/knxUltimateHuedevice_software_update-teleprompter.txt +0 -46
  252. package/tutorial/knxUltimateHuedevice_software_update.md +0 -44
  253. package/tutorial/knxUltimateLoadControl-teleprompter.txt +0 -40
  254. package/tutorial/knxUltimateLoadControl.md +0 -52
  255. package/tutorial/knxUltimateLogger-teleprompter.txt +0 -39
  256. package/tutorial/knxUltimateLogger.md +0 -42
  257. package/tutorial/knxUltimateSceneController-teleprompter.txt +0 -38
  258. package/tutorial/knxUltimateSceneController.md +0 -48
  259. package/tutorial/knxUltimateViewer-teleprompter.txt +0 -37
  260. package/tutorial/knxUltimateViewer.md +0 -41
  261. package/tutorial/knxUltimateWatchDog-teleprompter.txt +0 -39
  262. package/tutorial/knxUltimateWatchDog.md +0 -42
  263. package/tutorial/teleprompter-en.txt +0 -151
  264. package/tutorial/teleprompter-it.txt +0 -151
package/CHANGELOG.md CHANGED
@@ -6,6 +6,14 @@
6
6
 
7
7
  # CHANGELOG
8
8
 
9
+ **Version 4.0.26** - December 2025<br/>
10
+ - Watchdog node editor: added the same GA autocomplete list used in the other KNX nodes, restricted to boolean DPT 1.x addresses and with secure-address highlighting to keep configuration consistent.<br/>
11
+ <br/>
12
+
13
+ **Version 4.0.25** - November 2025<br/>
14
+ - KNX Device node editor: repositioned the "Show manual command button in editor" option directly under the input passthrough setting so related controls stay together.<br/>
15
+ - KNX Function helper: refreshed the send-side snippet library with ready-to-use home-automation templates (motion-triggered lighting, HVAC standby on window-open, night door alerts, bedtime all-off) and cleaned up placeholders for easier copy/paste.<br/>
16
+
9
17
  **Version 4.0.24** - October 2025<br/>
10
18
  - Hue config node: pairing now polls the bridge automatically and closes the dialog as soon as the link button is pressed, with a cancellable wait message and improved error feedback.<br/>
11
19
  - Hue config node: added "I ALREADY HAVE THE CREDENTIALS" button and restored bridge discovery so manual credentials can be entered immediately without running the registration flow.<br/>
@@ -185,6 +185,38 @@
185
185
  $("#tabs").tabs();
186
186
 
187
187
  // 15/09/2020 Supergiovane, set the help sample based on Datapoint
188
+ const knxFunctionHelperItems = [
189
+ {
190
+ id: 'getGAValue',
191
+ label: 'getGAValue(address, dpt?)',
192
+ aceValue: "getGAValue('1/1/1', '1.001')",
193
+ snippet: "getGAValue('${1:1/1/1}', '${2:1.001}')",
194
+ doc: 'Read the cached value of another group address. Provide the datapoint if the ETS import is not available.'
195
+ },
196
+ {
197
+ id: 'setGAValue',
198
+ label: 'setGAValue(address, value, dpt?)',
199
+ aceValue: "setGAValue('1/1/1', true)",
200
+ snippet: "setGAValue('${1:1/1/1}', ${2:true}, '${3:1.001}')",
201
+ doc: 'Send a value to any KNX group address. The datapoint is optional when the ETS file is imported.'
202
+ },
203
+ {
204
+ id: 'self',
205
+ label: 'self(value)',
206
+ aceValue: 'self(false)',
207
+ snippet: 'self(${1:false})',
208
+ doc: 'Set this node value and forward it to the KNX bus.'
209
+ },
210
+ {
211
+ id: 'toggle',
212
+ label: 'toggle()',
213
+ aceValue: 'toggle()',
214
+ snippet: 'toggle()',
215
+ doc: 'Invert this node value and write it to the KNX bus.'
216
+ }
217
+ ];
218
+ const globalScope = typeof window !== 'undefined' ? window : (typeof globalThis !== 'undefined' ? globalThis : {});
219
+
188
220
  function knxUltimateDptsGetHelp(_dpt, _forceClose) {
189
221
  const detailsContainer = $("#dptDetailsContainer")
190
222
  if (_forceClose === true) {
@@ -257,6 +289,56 @@
257
289
  editor.renderer.setShowGutter(false);
258
290
  }
259
291
  if (typeof editor.setShowPrintMargin === 'function') editor.setShowPrintMargin(false);
292
+ if (typeof ace !== 'undefined' && ace.require) {
293
+ try { ace.require('ace/ext/language_tools'); } catch (error) { }
294
+ }
295
+ if (typeof editor.setOptions === 'function') {
296
+ editor.setOptions({
297
+ enableBasicAutocompletion: true,
298
+ enableLiveAutocompletion: true
299
+ });
300
+ }
301
+ if (typeof editor.completers === 'undefined') {
302
+ editor.completers = [];
303
+ }
304
+ if (Array.isArray(editor.completers) && !editor._knxHelperCompleter) {
305
+ const aceCompletions = knxFunctionHelperItems.map(item => ({
306
+ caption: item.label,
307
+ value: item.aceValue,
308
+ snippet: item.snippet,
309
+ meta: 'KNX helper',
310
+ doc: item.doc
311
+ }));
312
+ const helperCompleter = {
313
+ getCompletions: function (_editor, _session, _pos, prefix, callback) {
314
+ const search = (prefix || '').toLowerCase();
315
+ const filtered = search
316
+ ? aceCompletions.filter(entry => entry.caption.toLowerCase().startsWith(search) || entry.value.toLowerCase().startsWith(search))
317
+ : aceCompletions;
318
+ callback(null, filtered.length ? filtered : aceCompletions);
319
+ },
320
+ getDocTooltip: function (item) {
321
+ if (!item || item.docHTML || !item.doc) return;
322
+ item.docHTML = '<b>' + item.caption + '</b><hr />' + item.doc;
323
+ }
324
+ };
325
+ editor.completers.push(helperCompleter);
326
+ editor._knxHelperCompleter = helperCompleter;
327
+ }
328
+ if (typeof monaco !== 'undefined' && !globalScope.knxFunctionMonacoCompletionProvider) {
329
+ try {
330
+ const suggestions = knxFunctionHelperItems.map(item => ({
331
+ label: item.label,
332
+ kind: monaco.languages.CompletionItemKind.Function,
333
+ insertText: item.snippet,
334
+ insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
335
+ documentation: item.doc
336
+ }));
337
+ globalScope.knxFunctionMonacoCompletionProvider = monaco.languages.registerCompletionItemProvider('javascript', {
338
+ provideCompletionItems: () => ({ suggestions })
339
+ });
340
+ } catch (error) { }
341
+ }
260
342
  } catch (error) { }
261
343
  };
262
344
 
@@ -293,20 +375,104 @@
293
375
  } catch (error) { }
294
376
  };
295
377
 
378
+ const sanitizeAutocompleteValue = (raw) => {
379
+ if (typeof raw !== 'string') return '';
380
+ return raw.replace(/['"]/g, '').trim();
381
+ };
382
+ const replaceLiteralAroundCursorAce = (editor, text) => {
383
+ try {
384
+ const AceRange = (typeof ace !== 'undefined' && ace.require) ? ace.require('ace/range').Range : null;
385
+ if (!AceRange) return false;
386
+ const pos = editor.getCursorPosition();
387
+ const line = editor.session.getLine(pos.row) || '';
388
+ let left = pos.column - 1;
389
+ while (left >= 0 && line[left] !== "'") left--;
390
+ if (left < 0) return false;
391
+ let right = pos.column;
392
+ while (right < line.length && line[right] !== "'") right++;
393
+ if (right >= line.length) return false;
394
+ const newLiteral = "'" + text + "'";
395
+ const range = new AceRange(pos.row, left, pos.row, right + 1);
396
+ editor.session.replace(range, newLiteral);
397
+ editor.moveCursorTo(pos.row, left + newLiteral.length);
398
+ return true;
399
+ } catch (error) { }
400
+ return false;
401
+ };
402
+ const replaceLiteralAroundCursorMonaco = (editor, text) => {
403
+ try {
404
+ const position = editor.getPosition();
405
+ if (!position) return false;
406
+ const model = typeof editor.getModel === 'function' ? editor.getModel() : null;
407
+ if (!model) return false;
408
+ const lineContent = model.getLineContent(position.lineNumber) || '';
409
+ let leftIdx = position.column - 2;
410
+ if (leftIdx >= lineContent.length) leftIdx = lineContent.length - 1;
411
+ while (leftIdx >= 0 && lineContent[leftIdx] !== "'") leftIdx--;
412
+ if (leftIdx < 0) return false;
413
+ let rightIdx = position.column - 1;
414
+ if (rightIdx < leftIdx) rightIdx = leftIdx + 1;
415
+ while (rightIdx < lineContent.length && lineContent[rightIdx] !== "'") rightIdx++;
416
+ if (rightIdx >= lineContent.length) return false;
417
+ const newLiteral = "'" + text + "'";
418
+ const range = new monaco.Range(
419
+ position.lineNumber,
420
+ leftIdx + 1,
421
+ position.lineNumber,
422
+ rightIdx + 2
423
+ );
424
+ editor.executeEdits('knxInsertGA', [{ range, text: newLiteral, forceMoveMarkers: true }]);
425
+ editor.setPosition({ lineNumber: position.lineNumber, column: leftIdx + 1 + newLiteral.length });
426
+ return true;
427
+ } catch (error) { }
428
+ return false;
429
+ };
430
+
296
431
  const insertTextIntoEditor = (editor, text) => {
297
432
  if (!editor || !text) return;
298
433
  try {
299
434
  if (editor.session && typeof editor.session.insert === 'function') {
300
435
  editor.focus();
301
- editor.session.insert(editor.getCursorPosition(), text);
436
+ const selectionRange = editor.getSelection && typeof editor.getSelectionRange === 'function'
437
+ ? editor.getSelectionRange()
438
+ : null;
439
+ if (selectionRange && !selectionRange.isEmpty()) {
440
+ editor.session.replace(selectionRange, text);
441
+ return;
442
+ }
443
+ const replaced = replaceLiteralAroundCursorAce(editor, text);
444
+ if (!replaced) {
445
+ const pos = editor.getCursorPosition();
446
+ editor.session.insert(pos, text);
447
+ }
302
448
  return;
303
449
  }
304
450
  if (typeof editor.executeEdits === 'function' && typeof editor.getPosition === 'function' && typeof monaco !== 'undefined') {
451
+ const selection = typeof editor.getSelection === 'function' ? editor.getSelection() : null;
452
+ const hasSelection = selection && (selection.startLineNumber !== selection.endLineNumber || selection.startColumn !== selection.endColumn);
453
+ if (selection && hasSelection) {
454
+ const selectionRange = new monaco.Range(
455
+ selection.startLineNumber,
456
+ selection.startColumn,
457
+ selection.endLineNumber,
458
+ selection.endColumn
459
+ );
460
+ editor.executeEdits('knxInsertGA', [{ range: selectionRange, text, forceMoveMarkers: true }]);
461
+ const targetLine = selectionRange.startLineNumber;
462
+ const targetColumn = selectionRange.startColumn + text.length;
463
+ editor.setPosition({ lineNumber: targetLine, column: targetColumn });
464
+ editor.focus();
465
+ return;
466
+ }
305
467
  const position = editor.getPosition();
306
468
  if (!position) return;
307
- const range = new monaco.Range(position.lineNumber, position.column, position.lineNumber, position.column);
308
- editor.executeEdits('knxInsertGA', [{ range, text, forceMoveMarkers: true }]);
309
- editor.setPosition({ lineNumber: position.lineNumber, column: position.column + text.length });
469
+ let replaced = replaceLiteralAroundCursorMonaco(editor, text);
470
+ if (!replaced) {
471
+ const range = new monaco.Range(position.lineNumber, position.column, position.lineNumber, position.column);
472
+ const newColumn = position.column + text.length;
473
+ editor.executeEdits('knxInsertGA', [{ range, text, forceMoveMarkers: true }]);
474
+ editor.setPosition({ lineNumber: position.lineNumber, column: newColumn });
475
+ }
310
476
  editor.focus();
311
477
  }
312
478
  } catch (error) { }
@@ -329,14 +495,16 @@
329
495
  attachFocusHandlers(node.receiveMsgFromKNXCodeEditor);
330
496
 
331
497
  $("#btn-insert-knxFunctionGA").off('click').on('click', function () {
332
- const value = $("#node-input-knxFunctionHelperGAList").val();
333
- if (!value || value.trim() === '') {
498
+ const rawValue = $("#node-input-knxFunctionHelperGAList").val();
499
+ if (!rawValue || rawValue.trim() === '') {
334
500
  $("#node-input-knxFunctionHelperGAList").focus();
335
501
  return;
336
502
  }
503
+ const sanitizedValue = sanitizeAutocompleteValue(rawValue);
337
504
  const editor = node.activeCodeEditor || node.sendMsgToKNXCodeEditor || node.receiveMsgFromKNXCodeEditor;
338
505
  if (!editor) return;
339
- insertTextIntoEditor(editor, value);
506
+ if (!sanitizedValue) return;
507
+ insertTextIntoEditor(editor, sanitizedValue);
340
508
  });
341
509
 
342
510
  const configureSnippetPicker = (snippets, inputSelector, datalistSelector, applySnippet) => {
@@ -908,6 +1076,42 @@
908
1076
  <option value="yesownprop" data-i18n="knxUltimate.selectlists.passthrough_OwnProp"></option>
909
1077
  </select>
910
1078
  </div>
1079
+ <div class="form-row">
1080
+ <input type="checkbox" id="node-input-buttonEnabled"
1081
+ style="display:inline-block; width:auto; vertical-align:top;" />
1082
+ <label style="width:85%" for="node-input-buttonEnabled">
1083
+ <i class="fa fa-mouse-pointer"></i> <span
1084
+ data-i18n="knxUltimate.button.enable"></span>
1085
+ </label>
1086
+ </div>
1087
+ <div id="knx-button-options" style="display:none">
1088
+ <div class="form-row">
1089
+ <label style="width:180px" for="node-input-buttonMode">
1090
+ <i class="fa fa-bolt"></i> <span data-i18n="knxUltimate.button.mode"></span>
1091
+ </label>
1092
+ <select id="node-input-buttonMode" style="width:220px;">
1093
+ <option value="read" data-i18n="knxUltimate.button.mode_read"></option>
1094
+ <option value="toggle" data-i18n="knxUltimate.button.mode_toggle"></option>
1095
+ <option value="value" data-i18n="knxUltimate.button.mode_value"></option>
1096
+ </select>
1097
+ </div>
1098
+ <div class="form-row knx-button-toggle-row">
1099
+ <label style="width:180px" for="node-input-buttonToggleInitial">
1100
+ <i class="fa fa-refresh"></i> <span data-i18n="knxUltimate.button.toggleInitial"></span>
1101
+ </label>
1102
+ <select id="node-input-buttonToggleInitial" style="width:220px;">
1103
+ <option value="true" data-i18n="knxUltimate.button.toggleInitial_true"></option>
1104
+ <option value="false" data-i18n="knxUltimate.button.toggleInitial_false"></option>
1105
+ </select>
1106
+ </div>
1107
+ <div class="form-row knx-button-value-row">
1108
+ <label style="width:180px" for="node-input-buttonStaticValue">
1109
+ <i class="fa fa-pencil"></i> <span data-i18n="knxUltimate.button.value"></span>
1110
+ </label>
1111
+ <input type="text" id="node-input-buttonStaticValue" style="width:220px;"
1112
+ placeholder="42, true, {\"red\":255}" />
1113
+ </div>
1114
+ </div>
911
1115
  <hr>
912
1116
  <div class="form-row">
913
1117
  <dt>
@@ -988,42 +1192,6 @@
988
1192
  data-i18n="knxUltimate.properties.node-input-notifyreadrequest"></span>
989
1193
  </label>
990
1194
  </div>
991
- <div class="form-row">
992
- <input type="checkbox" id="node-input-buttonEnabled"
993
- style="display:inline-block; width:auto; vertical-align:top;" />
994
- <label style="width:85%" for="node-input-buttonEnabled">
995
- <i class="fa fa-mouse-pointer"></i> <span
996
- data-i18n="knxUltimate.button.enable"></span>
997
- </label>
998
- </div>
999
- <div id="knx-button-options" style="display:none">
1000
- <div class="form-row">
1001
- <label style="width:180px" for="node-input-buttonMode">
1002
- <i class="fa fa-bolt"></i> <span data-i18n="knxUltimate.button.mode"></span>
1003
- </label>
1004
- <select id="node-input-buttonMode" style="width:220px;">
1005
- <option value="read" data-i18n="knxUltimate.button.mode_read"></option>
1006
- <option value="toggle" data-i18n="knxUltimate.button.mode_toggle"></option>
1007
- <option value="value" data-i18n="knxUltimate.button.mode_value"></option>
1008
- </select>
1009
- </div>
1010
- <div class="form-row knx-button-toggle-row">
1011
- <label style="width:180px" for="node-input-buttonToggleInitial">
1012
- <i class="fa fa-refresh"></i> <span data-i18n="knxUltimate.button.toggleInitial"></span>
1013
- </label>
1014
- <select id="node-input-buttonToggleInitial" style="width:220px;">
1015
- <option value="true" data-i18n="knxUltimate.button.toggleInitial_true"></option>
1016
- <option value="false" data-i18n="knxUltimate.button.toggleInitial_false"></option>
1017
- </select>
1018
- </div>
1019
- <div class="form-row knx-button-value-row">
1020
- <label style="width:180px" for="node-input-buttonStaticValue">
1021
- <i class="fa fa-pencil"></i> <span data-i18n="knxUltimate.button.value"></span>
1022
- </label>
1023
- <input type="text" id="node-input-buttonStaticValue" style="width:220px;"
1024
- placeholder="42, true, {\"red\":255}" />
1025
- </div>
1026
- </div>
1027
1195
  <div id="divnotifyreadrequestautoreact">
1028
1196
  <dd>
1029
1197
  <div class="form-row">
@@ -22,6 +22,11 @@
22
22
  },
23
23
  paletteLabel: "KNX WatchDog",
24
24
  oneditprepare: function () {
25
+ const node = this;
26
+ const $knxServerInput = $("#node-input-server");
27
+ const $gaInput = $("#node-input-topic");
28
+ const KNX_EMPTY_VALUES = new Set(['', '_ADD_', '__NONE__', 'none']);
29
+
25
30
  // Go to the help panel
26
31
  try {
27
32
  RED.sidebar.show("help");
@@ -34,19 +39,112 @@
34
39
  active: false
35
40
  });
36
41
 
37
- $("#node-input-checkLevel").on('change', function () {
38
- if ($("#node-input-checkLevel").val() == "Ethernet") {
42
+ const KNX_GA_CACHE = node._knxGaCache || (node._knxGaCache = new Map());
43
+
44
+ const resolveKnxServerValue = () => {
45
+ const domValue = $knxServerInput.val();
46
+ if (domValue !== undefined && domValue !== null && !KNX_EMPTY_VALUES.has(String(domValue))) {
47
+ return domValue;
48
+ }
49
+ if (node.server !== undefined && node.server !== null && !KNX_EMPTY_VALUES.has(String(node.server))) {
50
+ return node.server;
51
+ }
52
+ return '';
53
+ };
54
+
55
+ const fetchGroupAddresses = (serverId) => {
56
+ if (!serverId) return Promise.resolve([]);
57
+ if (KNX_GA_CACHE.has(serverId)) return Promise.resolve(KNX_GA_CACHE.get(serverId));
58
+ return new Promise((resolve) => {
59
+ $.getJSON(`knxUltimatecsv?nodeID=${serverId}&_=${Date.now()}`, (data) => {
60
+ const list = Array.isArray(data) ? data : [];
61
+ KNX_GA_CACHE.set(serverId, list);
62
+ resolve(list);
63
+ }).fail(() => resolve([]));
64
+ });
65
+ };
66
+
67
+ const ensureGaAutocomplete = () => {
68
+ const serverId = resolveKnxServerValue();
69
+ if (!serverId) {
70
+ if ($gaInput.data('ui-autocomplete')) {
71
+ $gaInput.autocomplete('disable');
72
+ }
73
+ return;
74
+ }
75
+
76
+ const sourceFn = (request, response) => {
77
+ fetchGroupAddresses(serverId).then((data) => {
78
+ const items = [];
79
+ (data || []).forEach((entry) => {
80
+ const dpt = typeof entry.dpt === 'string' ? entry.dpt : '';
81
+ if (!dpt.startsWith('1.')) return; // Watchdog only accepts boolean GAs
82
+ const devName = entry.devicename || '';
83
+ const searchStr = `${entry.ga} (${devName}) DPT${dpt}`;
84
+ if (!htmlUtilsfullCSVSearch(searchStr, request.term || '')) return;
85
+ items.push({
86
+ label: `${entry.ga} # ${devName} # ${dpt}`,
87
+ value: entry.ga
88
+ });
89
+ });
90
+ response(items);
91
+ });
92
+ };
93
+
94
+ if ($gaInput.data('knx-watchdog-ga')) {
95
+ $gaInput.autocomplete('option', 'source', sourceFn);
96
+ $gaInput.autocomplete('enable');
97
+ } else {
98
+ $gaInput.autocomplete({
99
+ minLength: 0,
100
+ source: sourceFn,
101
+ select: function (event, ui) {
102
+ event.preventDefault();
103
+ $(this).val(ui.item.value);
104
+ const parts = ui.item.label.split('#');
105
+ let deviceName = (parts[1] || '').trim().replace(/^\)/, '').trim();
106
+ if (deviceName.indexOf('/') > -1) {
107
+ deviceName = deviceName.split('/').pop().trim();
108
+ }
109
+ const $nameInput = $('#node-input-name');
110
+ if (deviceName && $nameInput.length) {
111
+ $nameInput.val(deviceName);
112
+ }
113
+ }
114
+ }).on('focus.knxUltimateWatchDog click.knxUltimateWatchDog', function () {
115
+ const currentValue = $(this).val() || '';
116
+ try {
117
+ $(this).autocomplete('search', currentValue ? `${currentValue} exactmatch` : '');
118
+ } catch (error) { }
119
+ });
120
+ $gaInput.data('knx-watchdog-ga', true);
121
+ }
122
+
123
+ try {
124
+ const srv = RED.nodes.node(serverId);
125
+ if (srv && srv.id) KNX_enableSecureFormatting($gaInput, srv.id);
126
+ } catch (error) { }
127
+ };
128
+
129
+ $knxServerInput.on('change.knxUltimateWatchDog', () => {
130
+ KNX_GA_CACHE.clear();
131
+ ensureGaAutocomplete();
132
+ });
133
+ ensureGaAutocomplete();
134
+
135
+ const syncDivHost = () => {
136
+ const level = $("#node-input-checkLevel").val() || node.checkLevel || "Ethernet";
137
+ if (level === "Ethernet") {
39
138
  $("#divHost").hide();
40
139
  } else {
41
140
  $("#divHost").show();
42
141
  }
43
- })
142
+ };
44
143
 
45
- if (checkLevel !== "Ethernet") {
46
- $("#divHost").hide();
47
- } else {
48
- $("#divHost").show();
49
- }
144
+ $("#node-input-checkLevel").on('change', function () {
145
+ syncDivHost();
146
+ });
147
+ syncDivHost();
50
148
  },
51
149
  oneditsave: function () {
52
150
  // Return to the info tab
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "engines": {
4
4
  "node": ">=20.18.1"
5
5
  },
6
- "version": "4.0.24",
6
+ "version": "4.0.26",
7
7
  "description": "Control your KNX and KNX Secure intallation via Node-Red! A bunch of KNX nodes, with integrated Philips HUE control and ETS group address importer. Easy to use and highly configurable.",
8
8
  "dependencies": {
9
9
  "binary-parser": "2.2.1",
@@ -88,4 +88,4 @@
88
88
  "chai": "^4.3.10",
89
89
  "mocha": "^10.4.0"
90
90
  }
91
- }
91
+ }
@@ -4,8 +4,8 @@
4
4
  id: 'status-ga-check',
5
5
  title: 'Status GA check',
6
6
  code: `// @ts-nocheck
7
- // Replace 'x/x/x' with the real status group address.
8
- const statusGA = getGAValue('x/x/x','1.001');
7
+ // Replace '' with the real status group address.
8
+ const statusGA = getGAValue('','1.001');
9
9
  if (msg.payload !== statusGA){ // " !==" means " not equal"
10
10
  return msg;
11
11
  }else{
@@ -42,6 +42,80 @@ return msg;`
42
42
  if (msg.payload === true){
43
43
  setGAValue('1/0/1',20,'5.001')
44
44
  }
45
+ return msg;`
46
+ },
47
+ {
48
+ id: 'motion-activated-light',
49
+ title: 'Turn on light on motion, auto off',
50
+ code: `// @ts-nocheck
51
+ // This snippet expects a motion sensor boolean on msg.payload.
52
+ // When motion is detected turn the light on, otherwise schedule an auto-off.
53
+ if (msg.payload === true) {
54
+ // Turn on the light immediately.
55
+ setGAValue('', true, '1.001'); // Replace '' with your light GA.
56
+ // Cancel pending auto-off timers if any.
57
+ context.set('autoOffTimer', null);
58
+ } else {
59
+ // Schedule auto-off after 90 seconds of no motion.
60
+ const timer = setTimeout(() => {
61
+ setGAValue('', false, '1.001'); // Replace '' with your light GA.
62
+ }, 90000);
63
+ context.set('autoOffTimer', timer);
64
+ }
65
+ return;`
66
+ },
67
+ {
68
+ id: 'window-hvac-standby',
69
+ title: 'HVAC standby when window open',
70
+ code: `// @ts-nocheck
71
+ // msg.payload should contain the window contact state (true = open).
72
+ // If the window is open, set the HVAC to standby, otherwise restore comfort.
73
+ const hvacGa = ''; // Replace with your HVAC GA.
74
+ const standbyValue = 'standby';
75
+ const comfortValue = 'comfort';
76
+
77
+ if (msg.payload === true) {
78
+ setGAValue(hvacGa, standbyValue, '20.102'); // HVAC mode DPT.
79
+ node.status({fill: 'yellow', shape: 'dot', text: 'HVAC standby'});
80
+ } else {
81
+ setGAValue(hvacGa, comfortValue, '20.102');
82
+ node.status({fill: 'green', shape: 'dot', text: 'HVAC comfort'});
83
+ }
84
+ return;`
85
+ },
86
+ {
87
+ id: 'night-door-alert',
88
+ title: 'Night door alert',
89
+ code: `// @ts-nocheck
90
+ // Send a KNX notification GA if a door opens between 22:00 and 06:00.
91
+ const now = new Date();
92
+ const hour = now.getHours();
93
+
94
+ if (msg.payload === true && (hour >= 22 || hour < 6)) {
95
+ setGAValue('', true, '1.001'); // Replace '' with your alert GA.
96
+ node.status({fill: 'red', shape: 'ring', text: 'Door alert sent'});
97
+ }
98
+ return;`
99
+ },
100
+ {
101
+ id: 'bedtime-all-off',
102
+ title: 'Bedtime all off',
103
+ code: `// @ts-nocheck
104
+ // Turn off a list of lights when a bedtime command is received.
105
+ const lights = [
106
+ '', // Replace with GA of the first light
107
+ '' // Replace with GA of the second light
108
+ ];
109
+
110
+ if (msg.payload === 'bedtime') {
111
+ lights.forEach(ga => {
112
+ if (ga) {
113
+ setGAValue(ga, false, '1.001');
114
+ }
115
+ });
116
+ node.status({fill: 'blue', shape: 'dot', text: 'All lights off'});
117
+ return;
118
+ }
45
119
  return msg;`
46
120
  }
47
121
  ]