node-red-contrib-huemagic 2.8.2 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/CHANGELOG.md +229 -0
  2. package/README.md +806 -729
  3. package/examples/Hue Bridge.json +189 -35
  4. package/examples/Hue Brightness.json +124 -14
  5. package/examples/Hue Buttons.json +88 -0
  6. package/examples/Hue Group.json +575 -63
  7. package/examples/Hue Light.json +805 -58
  8. package/examples/Hue Magic.json +69 -24
  9. package/examples/Hue Motion.json +110 -42
  10. package/examples/Hue Rules.json +105 -37
  11. package/examples/Hue Scene.json +145 -28
  12. package/examples/Hue Temperature.json +124 -14
  13. package/huemagic/animations/001-sunny.json +22 -22
  14. package/huemagic/animations/002-cloudy.json +46 -46
  15. package/huemagic/animations/003-nightsky.json +20 -20
  16. package/huemagic/animations/004-sunrise.json +54 -54
  17. package/huemagic/animations/005-sunset.json +46 -46
  18. package/huemagic/animations/006-fireplace.json +74 -74
  19. package/huemagic/animations/007-spring.json +31 -31
  20. package/huemagic/animations/008-autmn.json +23 -23
  21. package/huemagic/animations/009-winter.json +23 -23
  22. package/huemagic/animations/010-dirtyfog.json +23 -23
  23. package/huemagic/animations/011-lgbt.json +49 -50
  24. package/huemagic/animations/012-rasta.json +28 -29
  25. package/huemagic/animations/013-strobo.json +30 -31
  26. package/huemagic/animations/014-randomrainbow.json +30 -31
  27. package/huemagic/animations/015-sos.json +158 -159
  28. package/huemagic/animations/016-milkyway.json +83 -0
  29. package/huemagic/animations/017-beach.json +40 -0
  30. package/huemagic/animations/018-forest.json +43 -0
  31. package/huemagic/animations/019-christmas.json +30 -0
  32. package/huemagic/animations/020-superhero.json +56 -0
  33. package/huemagic/animations/021-neoncity.json +52 -0
  34. package/huemagic/animations/previews/001-sunny.gif +0 -0
  35. package/huemagic/animations/previews/002-cloudy.gif +0 -0
  36. package/huemagic/animations/previews/003-nightsky.gif +0 -0
  37. package/huemagic/animations/previews/004-sunrise.gif +0 -0
  38. package/huemagic/animations/previews/005-sunset.gif +0 -0
  39. package/huemagic/animations/previews/006-fireplace.gif +0 -0
  40. package/huemagic/animations/previews/007-spring.gif +0 -0
  41. package/huemagic/animations/previews/008-autmn.gif +0 -0
  42. package/huemagic/animations/previews/009-winter.gif +0 -0
  43. package/huemagic/animations/previews/010-dirtyfog.gif +0 -0
  44. package/huemagic/animations/previews/011-lgbt.gif +0 -0
  45. package/huemagic/animations/previews/012-rasta.gif +0 -0
  46. package/huemagic/animations/previews/013-strobo.gif +0 -0
  47. package/huemagic/animations/previews/014-randomrainbow.gif +0 -0
  48. package/huemagic/animations/previews/015-sos.gif +0 -0
  49. package/huemagic/animations/previews/016-milkyway.gif +0 -0
  50. package/huemagic/animations/previews/017-beach.gif +0 -0
  51. package/huemagic/animations/previews/018-forest.gif +0 -0
  52. package/huemagic/animations/previews/019-christmas.gif +0 -0
  53. package/huemagic/animations/previews/020-superhero.gif +0 -0
  54. package/huemagic/animations/previews/021-neoncity.gif +0 -0
  55. package/huemagic/hue-bridge-config.html +105 -61
  56. package/huemagic/hue-bridge-config.js +629 -319
  57. package/huemagic/hue-bridge.html +41 -21
  58. package/huemagic/hue-bridge.js +191 -398
  59. package/huemagic/hue-brightness.html +130 -49
  60. package/huemagic/hue-brightness.js +131 -35
  61. package/huemagic/hue-buttons.html +197 -0
  62. package/huemagic/hue-buttons.js +152 -0
  63. package/huemagic/hue-group.html +137 -60
  64. package/huemagic/hue-group.js +394 -367
  65. package/huemagic/hue-light.html +133 -59
  66. package/huemagic/hue-light.js +551 -336
  67. package/huemagic/hue-magic.html +91 -237
  68. package/huemagic/hue-magic.js +57 -27
  69. package/huemagic/hue-motion.html +128 -50
  70. package/huemagic/hue-motion.js +116 -87
  71. package/huemagic/hue-rules.html +121 -50
  72. package/huemagic/hue-rules.js +84 -64
  73. package/huemagic/hue-scene.html +96 -115
  74. package/huemagic/hue-scene.js +65 -96
  75. package/huemagic/hue-temperature.html +130 -49
  76. package/huemagic/hue-temperature.js +136 -32
  77. package/huemagic/icons/hue-bridge.png +0 -0
  78. package/huemagic/icons/hue-bridge.svg +3 -0
  79. package/huemagic/icons/hue-brightness.png +0 -0
  80. package/huemagic/icons/hue-brightness.svg +11 -0
  81. package/huemagic/icons/hue-buttons.png +0 -0
  82. package/huemagic/icons/hue-buttons.svg +4 -0
  83. package/huemagic/icons/hue-group.png +0 -0
  84. package/huemagic/icons/hue-group.svg +12 -0
  85. package/huemagic/icons/hue-light.png +0 -0
  86. package/huemagic/icons/hue-light.svg +3 -0
  87. package/huemagic/icons/hue-magic.png +0 -0
  88. package/huemagic/icons/hue-magic.svg +3 -0
  89. package/huemagic/icons/hue-motion.png +0 -0
  90. package/huemagic/icons/hue-motion.svg +9 -0
  91. package/huemagic/icons/hue-rules.png +0 -0
  92. package/huemagic/icons/hue-rules.svg +4 -0
  93. package/huemagic/icons/hue-scene.png +0 -0
  94. package/huemagic/icons/hue-scene.svg +5 -0
  95. package/huemagic/icons/hue-temperature.png +0 -0
  96. package/huemagic/icons/hue-temperature.svg +7 -0
  97. package/huemagic/locales/de/hue-bridge-config.html +17 -12
  98. package/huemagic/locales/de/hue-bridge-config.json +7 -5
  99. package/huemagic/locales/de/hue-bridge.html +64 -145
  100. package/huemagic/locales/de/hue-bridge.json +6 -17
  101. package/huemagic/locales/de/hue-brightness.html +52 -38
  102. package/huemagic/locales/de/hue-brightness.json +7 -2
  103. package/huemagic/locales/de/hue-buttons.html +58 -0
  104. package/huemagic/locales/de/hue-buttons.json +28 -0
  105. package/huemagic/locales/de/hue-group.html +46 -122
  106. package/huemagic/locales/de/hue-group.json +4 -2
  107. package/huemagic/locales/de/hue-light.html +68 -116
  108. package/huemagic/locales/de/hue-light.json +5 -2
  109. package/huemagic/locales/de/hue-magic.html +65 -57
  110. package/huemagic/locales/de/hue-magic.json +2 -1
  111. package/huemagic/locales/de/hue-motion.html +48 -44
  112. package/huemagic/locales/de/hue-motion.json +6 -3
  113. package/huemagic/locales/de/hue-rules.html +68 -73
  114. package/huemagic/locales/de/hue-rules.json +5 -2
  115. package/huemagic/locales/de/hue-scene.html +23 -32
  116. package/huemagic/locales/de/hue-scene.json +5 -2
  117. package/huemagic/locales/de/hue-temperature.html +53 -36
  118. package/huemagic/locales/de/hue-temperature.json +7 -2
  119. package/huemagic/locales/en-US/hue-bridge-config.html +17 -12
  120. package/huemagic/locales/en-US/hue-bridge-config.json +5 -3
  121. package/huemagic/locales/en-US/hue-bridge.html +64 -145
  122. package/huemagic/locales/en-US/hue-bridge.json +5 -16
  123. package/huemagic/locales/en-US/hue-brightness.html +52 -38
  124. package/huemagic/locales/en-US/hue-brightness.json +10 -3
  125. package/huemagic/locales/en-US/hue-buttons.html +58 -0
  126. package/huemagic/locales/en-US/hue-buttons.json +34 -0
  127. package/huemagic/locales/en-US/hue-group.html +46 -122
  128. package/huemagic/locales/en-US/hue-group.json +7 -3
  129. package/huemagic/locales/en-US/hue-light.html +68 -116
  130. package/huemagic/locales/en-US/hue-light.json +8 -3
  131. package/huemagic/locales/en-US/hue-magic.html +65 -57
  132. package/huemagic/locales/en-US/hue-magic.json +3 -1
  133. package/huemagic/locales/en-US/hue-motion.html +48 -44
  134. package/huemagic/locales/en-US/hue-motion.json +9 -4
  135. package/huemagic/locales/en-US/hue-rules.html +68 -73
  136. package/huemagic/locales/en-US/hue-rules.json +5 -2
  137. package/huemagic/locales/en-US/hue-scene.html +23 -32
  138. package/huemagic/locales/en-US/hue-scene.json +5 -2
  139. package/huemagic/locales/en-US/hue-temperature.html +53 -36
  140. package/huemagic/locales/en-US/hue-temperature.json +10 -3
  141. package/huemagic/utils/api.js +290 -0
  142. package/huemagic/utils/color.js +382 -0
  143. package/{utils → huemagic/utils}/merge.js +9 -6
  144. package/huemagic/utils/messages.js +447 -0
  145. package/package.json +12 -12
  146. package/examples/Hue Switch.json +0 -40
  147. package/examples/Hue Tap.json +0 -40
  148. package/huemagic/assets/anime.js +0 -8
  149. package/huemagic/hue-switch.html +0 -119
  150. package/huemagic/hue-switch.js +0 -113
  151. package/huemagic/hue-tap.html +0 -119
  152. package/huemagic/hue-tap.js +0 -74
  153. package/huemagic/icons/hue-button.png +0 -0
  154. package/huemagic/icons/hue-switch.png +0 -0
  155. package/huemagic/icons/hue-tap.png +0 -0
  156. package/huemagic/locales/de/hue-switch.html +0 -50
  157. package/huemagic/locales/de/hue-switch.json +0 -31
  158. package/huemagic/locales/de/hue-tap.html +0 -41
  159. package/huemagic/locales/de/hue-tap.json +0 -23
  160. package/huemagic/locales/en-US/hue-switch.html +0 -50
  161. package/huemagic/locales/en-US/hue-switch.json +0 -31
  162. package/huemagic/locales/en-US/hue-tap.html +0 -41
  163. package/huemagic/locales/en-US/hue-tap.json +0 -23
  164. package/utils/messages.js +0 -571
  165. package/utils/rgb.js +0 -188
@@ -1,7 +1,7 @@
1
1
  <script type="text/x-red" data-template-name="hue-magic">
2
2
  <div class="form-row">
3
3
  <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="hue-magic.config.name"></span></label>
4
- <input type="text" id="node-input-name" data-i18n="[placeholder]hue-magic.config.input-name">
4
+ <input type="text" id="node-input-name" data-i18n="[placeholder]hue-magic.config.input-name" style="width: calc(100% - 105px)">
5
5
  </div>
6
6
  <div class="form-row">
7
7
  <label for="node-input-endless"><i class="fa fa-refresh"></i> <span data-i18n="hue-magic.config.loop"></span></label>
@@ -13,21 +13,20 @@
13
13
  <input type="checkbox" id="node-input-restore" style="display:inline-block; width:22px; vertical-align:baseline;"><span data-i18n="hue-magic.config.restore-state"></span>
14
14
  </label>
15
15
  </div>
16
- <div class="form-row">
16
+ <div class="form-row" style="margin-top: 30px">
17
17
  <label for="node-input-steps"><i class="fa fa-magic"></i> <span data-i18n="hue-magic.config.animation"></span></label>
18
18
  </div>
19
19
  <div style="display: none;">
20
20
  <div class="form-row">
21
- <input type="text" id="node-input-preset" placeholder="...">
21
+ <input type="text" id="node-input-preset" placeholder="{}">
22
22
  </div>
23
23
  <div class="form-row">
24
- <input type="text" id="node-input-steps" placeholder="...">
24
+ <input type="text" id="node-input-steps" placeholder="{}">
25
25
  </div>
26
26
  </div>
27
27
  <div class="form-row form-animations">
28
28
  <div class="animation template">
29
- <div class="color"></div>
30
- <div class="brightness"></div>
29
+ <img src="#" class="color">
31
30
  <div class="info">
32
31
  <span><name>Name</name> <dur>(dur)</dur></span>
33
32
  </div>
@@ -43,9 +42,10 @@
43
42
  display: grid;
44
43
  -ms-grid-columns: 30% 3.29% 30% 3.29% 30%;
45
44
  grid-template-columns: 30% 30% 30%;
46
- grid-gap: 3.29%;
45
+ grid-gap: 2.29% 3.29%;
47
46
 
48
47
  max-width: 40vw;
48
+ padding-bottom: 85px;
49
49
  }
50
50
 
51
51
  .form-animations .animation
@@ -53,12 +53,15 @@
53
53
  position: relative;
54
54
  cursor: pointer;
55
55
 
56
+ border-radius: 20px;
56
57
  overflow: hidden;
57
- -webkit-border-radius: 5px;
58
- -moz-border-radius: 5px;
59
- border-radius: 5px;
60
58
 
61
- border: 3px solid #fff;
59
+ border: 2px solid #fff;
60
+ -webkit-transition: -webkit-box-shadow 333ms ease-in-out;
61
+ transition: -webkit-box-shadow 333ms ease-in-out;
62
+ -o-transition: box-shadow 333ms ease-in-out;
63
+ transition: box-shadow 333ms ease-in-out;
64
+ transition: box-shadow 333ms ease-in-out, -webkit-box-shadow 333ms ease-in-out;
62
65
  }
63
66
 
64
67
  .form-animations .animation.template
@@ -66,25 +69,17 @@
66
69
  display: none;
67
70
  }
68
71
 
69
- .form-animations .animation.selected
72
+ .form-animations .animation:active
70
73
  {
71
- border: 3px solid #000;
74
+ opacity: 0.7;
72
75
  }
73
76
 
74
- .form-animations .animation .color
77
+ .form-animations .animation.selected
75
78
  {
76
- position: absolute;
77
-
78
- top: 0;
79
- left: 0;
80
-
81
- height: 100%;
82
- width: 100%;
83
-
84
- z-index: 1;
79
+ box-shadow: 0 10px 40px rgba(0,0,0,0.1), 0 6px 13px rgba(0,0,0,0.23);
85
80
  }
86
81
 
87
- .form-animations .animation .brightness
82
+ .form-animations .animation .color
88
83
  {
89
84
  position: absolute;
90
85
 
@@ -94,11 +89,8 @@
94
89
  height: 100%;
95
90
  width: 100%;
96
91
 
97
- z-index: 11;
98
- opacity: 0;
99
-
100
- background: rgb(0,0,0);
101
- background: linear-gradient(0deg, rgba(0,0,0,1) 0%, rgba(77,77,77,1) 100%);
92
+ z-index: 1;
93
+ pointer-events: none;
102
94
  }
103
95
 
104
96
  .form-animations .animation .info
@@ -116,17 +108,13 @@
116
108
 
117
109
  .form-animations .animation .info span
118
110
  {
119
- display: inline-block;
120
- margin: 0 auto;
121
-
111
+ display: block;
112
+ margin: 0 12px;
122
113
  color: #000;
123
114
  background-color: rgba(255,255,255,0.8);
124
115
  font-size: 11px;
125
- padding: 2.5px 5px;
126
-
127
- -webkit-border-radius: 3px;
128
- -moz-border-radius: 3px;
129
- border-radius: 3px;
116
+ padding: 2.5px 0;
117
+ border-radius: 8px;
130
118
  }
131
119
 
132
120
  .form-animations .animation .info span name
@@ -157,228 +145,77 @@
157
145
  category: 'HueMagic',
158
146
  color: '#ff4242',
159
147
  defaults: {
160
- name: {value:""},
161
- endless: {value: true},
162
- restore: {value: false},
163
- preset: {value: null},
164
- steps: {value: null}
148
+ name: { value:"" },
149
+ endless: { value: true },
150
+ restore: { value: false },
151
+ preset: { value: null },
152
+ steps: { value: null }
165
153
  },
154
+ align: 'left',
155
+ icon: "hue-magic.png",
166
156
  inputs: 1,
167
157
  outputs: 1,
158
+ label: function() {
159
+ return this.name || this._("hue-magic.node.title");
160
+ },
161
+ paletteLabel: function() {
162
+ return this._("hue-magic.node.title");
163
+ },
168
164
  inputLabels: function() {
169
165
  return this._("hue-magic.node.input");
170
166
  },
171
167
  outputLabels: function() {
172
168
  return this._("hue-magic.node.output");
173
169
  },
174
- align: 'right',
175
- icon: "hue-magic.png",
176
- paletteLabel: function() {
177
- return this._("hue-magic.node.title");
178
- },
179
- label: function() {
180
- return this.name || this._("hue-magic.node.title");
181
- },
182
170
  oneditprepare: function()
183
171
  {
184
- var scope = this;
172
+ const scope = this;
185
173
  this.animations = [];
186
174
 
187
175
  var preset = $('#node-input-preset').val();
188
- $.getScript("hue/assets/anime.js", function( data, textStatus, jqxhr )
176
+
177
+ // LOAD ANIMATIONS
178
+ $.get('hue/animations?nc=' + Math.random())
179
+ .done( function(data)
189
180
  {
190
- // LOAD ANIMATIONS
191
- $.get('hue/animations?nc=' + Math.random())
192
- .done( function(data)
181
+ scope.animations = JSON.parse(data);
182
+ $.each(scope.animations, function(i, animation)
193
183
  {
194
- // HELPER
195
- function rgbToHex(r, g, b)
184
+ var animationTemplate = $(".animation.template").clone();
185
+ animationTemplate.removeClass("template");
186
+
187
+ // APPLY INFORMATION
188
+ animationTemplate.attr("data-id", animation.info.id);
189
+ animationTemplate.attr("data-name", animation.info.name);
190
+ animationTemplate.attr("data-steps", JSON.stringify(animation.steps));
191
+ animationTemplate.find("name").html(animation.info.name);
192
+ animationTemplate.find(".color").attr("src", "hue/animations/" + animation.info.id + ".gif");
193
+
194
+ // IS SELECTED?
195
+ if(preset == animation.info.id)
196
196
  {
197
- return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
197
+ animationTemplate.addClass("selected");
198
198
  }
199
199
 
200
- function adjustBrightness(hex, lum)
201
- {
202
- hex = String(hex).replace(/[^0-9a-f]/gi, '');
203
- if (hex.length < 6)
204
- {
205
- hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];
206
- }
207
- lum = lum || 0;
208
-
209
- var rgb = "#", c, i;
210
- for (i = 0; i < 3; i++)
211
- {
212
- c = parseInt(hex.substr(i*2,2), 16);
213
- c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16);
214
- rgb += ("00"+c).substr(c.length);
215
- }
216
-
217
- return rgb;
218
- }
219
-
220
-
221
- // FRAMES
222
- function addPreviewFrame(step)
223
- {
224
- // TRANSITION?
225
- var stepTransition = 300;
226
- if(typeof step.animation.transitionTime != 'undefined')
227
- {
228
- stepTransition = parseFloat(step.animation.transitionTime)*1000;
229
- }
230
-
231
- // DEFINE COLOR
232
- var color = "#fff";
233
- if(typeof step.animation.rgb != 'undefined')
234
- {
235
- color = rgbToHex(step.animation.rgb[0], step.animation.rgb[1], step.animation.rgb[2]);
236
- }
237
- else if(typeof step.animation.hex != 'undefined')
238
- {
239
- color = step.animation.hex;
240
- }
241
- else if(typeof step.animation.color != 'undefined')
242
- {
243
- if(step.animation.color == "random"||step.animation.color == "any")
244
- {
245
- color = '#'+(Math.random()*0xFFFFFF<<0).toString(16);
246
- }
247
- else
248
- {
249
- color = step.animation.color;
250
- }
251
- }
252
-
253
- // ADJUST COLOR BRIGHTNESS
254
- if(typeof step.animation.brightness != 'undefined')
255
- {
256
- var lum = (step.animation.brightness/100)-1;
257
- color = adjustBrightness(color, (lum < -0.5) ? -0.5 : lum);
258
- }
259
-
260
- return { background: color, delay: step.delay, duration: stepTransition };
261
- }
262
-
263
- function addPreviewFrameBrightness(step)
264
- {
265
- // TRANSITION?
266
- var stepTransition = 300;
267
- if(typeof step.animation.transitionTime != 'undefined')
268
- {
269
- stepTransition = parseFloat(step.animation.transitionTime)*1000;
270
- }
200
+ // CALC DURATION IN SECONDS AND ANIMATION
201
+ var duration = 0;
202
+ $.each(animation.steps, function(z, oneStep) { duration += oneStep.delay; });
271
203
 
272
- // ADJUST COLOR BRIGHTNESS
273
- var opacity = 0;
274
- if(typeof step.animation.brightness != 'undefined')
275
- {
276
- opacity = 1-(step.animation.brightness/100);
277
- opacity = (opacity > 0.5) ? 0.5 : opacity;
278
- }
279
-
280
- return { opacity: opacity, delay: step.delay, duration: stepTransition };
281
- }
204
+ // NORMALIZE DUR IN SECONDS
205
+ duration = duration/1000;
282
206
 
283
- // LOGIC
284
- scope.animations = JSON.parse(data);
285
- $.each(scope.animations, function(i, animation)
286
- {
287
- var animationTemplate = $(".animation.template").clone();
288
- animationTemplate.removeClass("template");
289
-
290
- // APPLY INFORMATION
291
- animationTemplate.attr("data-id", animation.info.id);
292
- animationTemplate.attr("data-name", animation.info.name);
293
- animationTemplate.attr("data-steps", JSON.stringify(animation.steps));
294
- animationTemplate.find("name").html(animation.info.name);
295
-
296
- // SPECIAL CONFIGS?
297
- var randomOrder = false;
298
- if(typeof animation.specials != 'undefined')
299
- {
300
- // APPLY RANDOM ORDER CONFIG
301
- if(typeof animation.specials.randomOrder != 'undefined')
302
- {
303
- randomOrder = animation.specials.randomOrder;
304
- }
305
- }
306
-
307
- // IS SELECTED?
308
- if(preset == animation.info.id)
309
- {
310
- animationTemplate.addClass("selected");
311
- }
312
-
313
- // CALC DURATION IN SECONDS AND ANIMATION
314
- var duration = 0;
315
- var isFirst = true;
316
- var keyframes = [];
317
- // var keyframesBrightness = [];
318
- $.each(animation.steps, function(z, oneStep)
319
- {
320
- duration += oneStep.delay;
321
-
322
- // TRANSITION?
323
- if(typeof oneStep.animation.transitionTime != 'undefined')
324
- {
325
- duration += parseFloat(oneStep.animation.transitionTime)*1000;
326
- }
327
-
328
- if(isFirst == true)
329
- {
330
- oneStep.animation.transitionTime = 0;
331
- isFirst = false;
332
- }
333
-
334
- // SET CURRENT STEP COLOR
335
- keyframes.push(addPreviewFrame(oneStep));
336
- // keyframesBrightness.push(addPreviewFrameBrightness(oneStep));
337
- });
338
-
339
- // REPEAT KEYFRAMES FOR SMOOTH TRANSITIONS
340
- var r = 0;
341
- while (r < 10)
342
- {
343
- keyframes = keyframes.concat(keyframes);
344
- // keyframesBrightness = keyframesBrightness.concat(keyframesBrightness);
345
- r++;
346
- }
207
+ // HUMAN READABLE DURATION
208
+ var suffix = (duration <= 60) ? scope._("hue-magic.config.seconds") : scope._("hue-magic.config.minutes");
209
+ duration = (duration <= 60) ? (Math.round(duration * 10) / 10) : (Math.round( (duration/60) * 10 ) / 10);
210
+ animationTemplate.find("dur").html("("+duration + " " + suffix + ")");
347
211
 
348
- // INITIALIZE COLOR ANIMATION
349
- var animationColorPreview = anime({
350
- targets: animationTemplate.find("div.color")[0],
351
- loop: true,
352
- autoplay: true,
353
- easing: 'linear',
354
- keyframes: keyframes
355
- });
356
-
357
- // INITIALIZE BRIGHTNESS ANIMATION
358
- // var animationBrightness = anime({
359
- // targets: animationTemplate.find("div.brightness")[0],
360
- // loop: true,
361
- // autoplay: true,
362
- // easing: 'linear',
363
- // keyframes: keyframesBrightness
364
- // });
365
-
366
- // NORMALIZE DUR IN SECONDS
367
- duration = duration/1000;
368
-
369
- // HUMAN READABLE DURATION
370
- var suffix = (duration <= 60) ? scope._("hue-magic.config.seconds") : scope._("hue-magic.config.minutes");
371
- duration = (duration <= 60) ? (Math.round(duration * 10) / 10) : (Math.round( (duration/60) * 10 ) / 10);
372
- animationTemplate.find("dur").html("("+duration + " " + suffix + ")");
373
-
374
- // PUSH TO FRONTEND
375
- animationTemplate.appendTo(".form-animations");
376
- });
377
- })
378
- .fail(function()
379
- {
380
- RED.notify(scope._("hue-magic.config.unknown-error"), "error");
212
+ // PUSH TO FRONTEND
213
+ animationTemplate.appendTo(".form-animations");
381
214
  });
215
+ })
216
+ .fail(function()
217
+ {
218
+ RED.notify(scope._("hue-magic.config.unknown-error"), "error");
382
219
  });
383
220
 
384
221
  // SELECT ANIMATION
@@ -400,9 +237,26 @@
400
237
  // SET STEPS
401
238
  var index = selectedAnimation.attr("data-id");
402
239
  var steps = JSON.stringify(JSON.parse(selectedAnimation.attr("data-steps")));
403
-
404
240
  $('#node-input-steps').val(steps);
405
241
  });
242
+ },
243
+ button: {
244
+ onclick: function()
245
+ {
246
+ const node = this;
247
+ if(node.steps)
248
+ {
249
+ $.ajax({
250
+ url: "inject/" + node.id,
251
+ type: "POST",
252
+ data: JSON.stringify({ __user_inject_props__: "play"}),
253
+ contentType: "application/json; charset=utf-8",
254
+ success: function (resp) {
255
+ RED.notify(node.name + ": " + node._("hue-magic.node.playmsg"), { type: "success", id: "status", timeout: 2000 });
256
+ }
257
+ });
258
+ }
259
+ }
406
260
  }
407
261
  });
408
262
  </script>
@@ -6,10 +6,10 @@ module.exports = function(RED)
6
6
  {
7
7
  RED.nodes.createNode(this, config);
8
8
 
9
- var scope = this;
10
- let async = require('async');
11
- var isEndless = config.endless;
12
- var restoreState = config.restore;
9
+ const scope = this;
10
+ const async = require('async');
11
+ const isEndless = config.endless;
12
+ const restoreState = config.restore;
13
13
 
14
14
  // STEPS INITIALIZATION
15
15
  this.steps = config.steps;
@@ -182,16 +182,25 @@ module.exports = function(RED)
182
182
  }
183
183
 
184
184
  //
185
- // ENABLE HUE MAGIC ANIMATION
185
+ // START THE HUEMAGIC ANIMATION
186
186
  this.on('input', function(msg, send, done)
187
187
  {
188
- // Node-RED < 1.0
188
+ // REDEFINE SEND AND DONE IF NOT AVAILABLE
189
189
  send = send || function() { scope.send.apply(scope,arguments); }
190
+ done = done || function() { scope.done.apply(scope,arguments); }
191
+
192
+ if(typeof msg.payload != 'undefined' && typeof msg.payload.steps != 'undefined')
193
+ {
194
+ scope.steps = msg.payload.steps;
195
+ msg.payload.animate = true;
196
+ }
197
+
198
+ const playFromButton = (typeof msg.__user_inject_props__ != 'undefined' && msg.__user_inject_props__ == "play");
190
199
 
191
- if(scope.steps != null||typeof msg.payload.steps != 'undefined')
200
+ if(scope.steps != null)
192
201
  {
193
202
  // SPECIALS CONFIG
194
- if(typeof msg.payload.specials != 'undefined')
203
+ if(typeof msg.payload != 'undefined' && typeof msg.payload.specials != 'undefined')
195
204
  {
196
205
  // APPLY RANDOM ORDER CONFIG
197
206
  if(typeof msg.payload.specials.randomOrder != 'undefined')
@@ -201,11 +210,11 @@ module.exports = function(RED)
201
210
  }
202
211
 
203
212
  // TURN ON ANIMATION
204
- if(typeof msg.payload.animate == 'undefined'||msg.payload.animate == true||msg.payload === true)
213
+ if(typeof msg.payload != 'undefined' && msg.payload.animate == true||msg.payload === true||playFromButton === true)
205
214
  {
215
+ var animationSteps = typeof scope.steps === 'string' ? JSON.parse(scope.steps) : scope.steps;
206
216
  if(scope.isAnimating == false)
207
217
  {
208
- var animationSteps = (typeof msg.payload.steps != 'undefined') ? msg.payload.steps : JSON.parse(scope.steps);
209
218
  scope.status({fill: "green", shape: "dot", text: "hue-magic.node.animating"});
210
219
 
211
220
  scope.isAnimating = true;
@@ -214,7 +223,7 @@ module.exports = function(RED)
214
223
  }
215
224
 
216
225
  // TURN OFF ANIMATION
217
- if((typeof msg.payload.animate != 'undefined' && msg.payload.animate == false)||msg.payload === false)
226
+ if((typeof msg.payload != 'undefined' && typeof msg.payload.animate != 'undefined' && msg.payload.animate == false)||msg.payload === false)
218
227
  {
219
228
  scope.animationStopped(done);
220
229
  scope.isAnimating = false;
@@ -244,36 +253,57 @@ module.exports = function(RED)
244
253
  // GET ANIMATIONS
245
254
  RED.httpAdmin.get('/hue/animations', function(req, res, next)
246
255
  {
247
- let fs = require("fs");
248
- let path = require("path");
256
+ const fs = require("fs");
257
+ const path = require("path");
258
+ const dir = path.resolve(__dirname, 'animations');
249
259
 
250
260
  var allAnimations = [];
251
- var dir = path.resolve(__dirname, 'animations');
261
+ fs.readdirSync(dir).forEach(function(filename)
262
+ {
263
+ try
264
+ {
265
+ var filepath = path.resolve(dir, filename);
266
+ var stat = fs.statSync(filepath);
267
+ var isFile = stat.isFile();
268
+ var fileID = path.basename(filepath, '.json');
252
269
 
253
- fs.readdirSync(dir).forEach(filename => {
254
- var filepath = path.resolve(dir, filename);
255
- var stat = fs.statSync(filepath);
256
- var isFile = stat.isFile();
257
- var fileID = path.basename(filepath, '.json');
270
+ if(isFile)
271
+ {
272
+ var animation = JSON.parse(fs.readFileSync(filepath, "utf8"));
273
+ animation.info.id = fileID;
258
274
 
259
- if(isFile)
275
+ allAnimations.push(animation);
276
+ };
277
+ }
278
+ catch(e)
260
279
  {
261
- var animation = JSON.parse(fs.readFileSync(filepath, "utf8"));
262
- animation.info.id = fileID;
263
-
264
- allAnimations.push(animation);
265
- };
280
+ console.log(fileID, e);
281
+ }
266
282
  });
267
283
 
268
284
  // SEND ALL ANIMATIONS
269
285
  res.end(JSON.stringify(allAnimations));
270
286
  });
271
287
 
288
+ //
289
+ // GET ANIMATION PREVIEWS
290
+ RED.httpAdmin.get('/hue/animations/:file', function(req, res, next)
291
+ {
292
+ let path = require("path");
293
+ res.sendFile(req.params.file, {
294
+ root: path.resolve(__dirname, 'animations', 'previews'),
295
+ dotfiles: 'deny'
296
+ });
297
+ });
298
+
272
299
  //
273
300
  // GET ASSETS
274
301
  RED.httpAdmin.get('/hue/assets/:file', function(req, res, next)
275
302
  {
276
303
  let path = require("path");
277
- res.sendFile(path.resolve(__dirname, 'assets', req.params.file));
304
+ res.sendFile(req.params.file, {
305
+ root: path.resolve(__dirname, 'assets'),
306
+ dotfiles: 'deny'
307
+ });
278
308
  });
279
- }
309
+ }