@evilbunny/node-red-contrib-zigbee2mqtt 0.0.0 → 3.2.8

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 (68) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +62 -43
  3. package/api.html +22 -0
  4. package/api.js +176 -0
  5. package/examples/Basic usage.json +316 -0
  6. package/icons/homekit-logo.png +0 -0
  7. package/icons/icon-color.png +0 -0
  8. package/icons/icon.png +0 -0
  9. package/icons/icon.pxd/QuickLook/Icon.tiff +0 -0
  10. package/icons/icon.pxd/QuickLook/Thumbnail.tiff +0 -0
  11. package/icons/icon.pxd/data/15644CBE-CB2C-4054-AAB1-064FBC3F72DB +0 -0
  12. package/icons/icon.pxd/data/2D35D9CD-316A-4D5B-A1D9-1C09DB37FAC9 +0 -0
  13. package/icons/icon.pxd/data/BF7855C2-D304-4F39-84A3-141656F5E18C +0 -0
  14. package/icons/icon.pxd/data/selection/meta +33 -0
  15. package/icons/icon.pxd/data/selection/shapeSelection/meta +12 -0
  16. package/icons/icon.pxd/data/selection/shapeSelection/path +0 -0
  17. package/icons/icon.pxd/data/selectionForContentTransform/meta +33 -0
  18. package/icons/icon.pxd/data/selectionForContentTransform/shapeSelection/meta +12 -0
  19. package/icons/icon.pxd/data/selectionForContentTransform/shapeSelection/path +0 -0
  20. package/icons/icon.pxd/metadata.info +0 -0
  21. package/nodes/bridge.html +523 -0
  22. package/nodes/bridge.js +124 -0
  23. package/nodes/get.html +106 -0
  24. package/nodes/get.js +47 -0
  25. package/nodes/in.html +125 -0
  26. package/nodes/in.js +123 -0
  27. package/nodes/locales/en-US/bridge.html +23 -0
  28. package/nodes/locales/en-US/bridge.json +84 -0
  29. package/nodes/locales/en-US/get.html +19 -0
  30. package/nodes/locales/en-US/get.json +23 -0
  31. package/nodes/locales/en-US/in.html +24 -0
  32. package/nodes/locales/en-US/in.json +43 -0
  33. package/nodes/locales/en-US/out.html +24 -0
  34. package/nodes/locales/en-US/out.json +31 -0
  35. package/nodes/locales/en-US/server.html +12 -0
  36. package/nodes/locales/en-US/server.json +36 -0
  37. package/nodes/locales/sk-SK/bridge.html +23 -0
  38. package/nodes/locales/sk-SK/bridge.json +84 -0
  39. package/nodes/locales/sk-SK/get.html +18 -0
  40. package/nodes/locales/sk-SK/get.json +21 -0
  41. package/nodes/locales/sk-SK/in.html +23 -0
  42. package/nodes/locales/sk-SK/in.json +43 -0
  43. package/nodes/locales/sk-SK/out.html +23 -0
  44. package/nodes/locales/sk-SK/out.json +21 -0
  45. package/nodes/locales/sk-SK/server.html +12 -0
  46. package/nodes/locales/sk-SK/server.json +36 -0
  47. package/nodes/out.html +300 -0
  48. package/nodes/out.js +361 -0
  49. package/nodes/server.html +96 -0
  50. package/nodes/server.js +854 -0
  51. package/package.json +42 -6
  52. package/readme/1.png +0 -0
  53. package/readme/2.png +0 -0
  54. package/readme/3.png +0 -0
  55. package/readme/4.png +0 -0
  56. package/readme/5.png +0 -0
  57. package/readme/options.gif +0 -0
  58. package/resources/Zigbee2mqttHelper.js +470 -0
  59. package/resources/css/common.css +56 -0
  60. package/resources/css/multiple-select.css +183 -0
  61. package/resources/js/multiple-select.js +10 -0
  62. package/resources/js/multiple-select.min.js +10 -0
  63. package/resources/js/node-red-contrib-zigbee2mqtt-helpers.js +416 -0
  64. package/resources/js/zigbee2mqtt-helpers.js +416 -0
  65. package/resources/tokeninput/jquery.tokeninput.js +861 -0
  66. package/resources/tokeninput/token-input-facebook.css +134 -0
  67. package/resources/tokeninput/token-input-mac.css +204 -0
  68. package/resources/tokeninput/token-input.css +113 -0
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>backingScale</key>
6
+ <real>1</real>
7
+ <key>pathFilename</key>
8
+ <string>path</string>
9
+ <key>version</key>
10
+ <integer>1</integer>
11
+ </dict>
12
+ </plist>
@@ -0,0 +1,33 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>backingScale</key>
6
+ <real>1</real>
7
+ <key>mode</key>
8
+ <integer>0</integer>
9
+ <key>shapeSelectionFilename</key>
10
+ <string>shapeSelection</string>
11
+ <key>size</key>
12
+ <data>
13
+ NC10UHpTVFAQAAAAQGbAAAAAAABAZ2AAAAAAAA==
14
+ </data>
15
+ <key>softness</key>
16
+ <real>0.0</real>
17
+ <key>timestamp</key>
18
+ <real>606977182.81130302</real>
19
+ <key>transform</key>
20
+ <array>
21
+ <real>1</real>
22
+ <real>0.0</real>
23
+ <real>0.0</real>
24
+ <real>1</real>
25
+ <real>0.0</real>
26
+ <real>0.0</real>
27
+ <real>0.0</real>
28
+ <real>0.0</real>
29
+ </array>
30
+ <key>version</key>
31
+ <integer>2</integer>
32
+ </dict>
33
+ </plist>
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>backingScale</key>
6
+ <real>1</real>
7
+ <key>pathFilename</key>
8
+ <string>path</string>
9
+ <key>version</key>
10
+ <integer>1</integer>
11
+ </dict>
12
+ </plist>
Binary file
@@ -0,0 +1,523 @@
1
+ <style>
2
+ .node-input-devices-friendly_name, .node-input-groups-friendly_name {
3
+ width:100% !important;
4
+ min-width: 200px !important;
5
+ }
6
+ table.z2m_table {
7
+ border-spacing: 5px;
8
+ border-collapse: separate;
9
+ }
10
+ table.z2m_table th {
11
+ text-align: left;
12
+ }
13
+ table.z2m_table td {
14
+ vertical-align: top;
15
+ }
16
+ </style>
17
+ <script type='text/javascript'>
18
+ $.getScript('resources/@evilbunny/node-red-contrib-zigbee2mqtt/tokeninput/jquery.tokeninput.js');
19
+ </script>
20
+
21
+
22
+
23
+ <script type="text/x-red" data-template-name="zigbee2mqtt-eb-bridge">
24
+ <link rel="stylesheet" href="resources/@evilbunny/node-red-contrib-zigbee2mqtt/css/multiple-select.css" type="text/css" />
25
+ <link rel="stylesheet" href="resources/@evilbunny/node-red-contrib-zigbee2mqtt/css/common.css" type="text/css" />
26
+ <link rel="stylesheet" href="resources/@evilbunny/node-red-contrib-zigbee2mqtt/tokeninput/token-input-facebook.css" type="text/css" />
27
+
28
+ <div class="form-row">
29
+ <label for="node-input-name" class="l-width"><i class="fa fa-bookmark"></i> <span data-i18n="label.name"></span></label>
30
+ <input type="text" id="node-input-name" data-i18n="[placeholder]placeholder.name">
31
+ </div>
32
+ <div class="form-row">
33
+ <label for="node-input-server" class="l-width"><i class="fa fa-globe"></i> <span data-i18n="label.server"></span></label>
34
+ <input type="text" id="node-input-server">
35
+ </div>
36
+ <div class="form-row">
37
+ <label for="refreshBtn" class="l-width"><i class="fa fa-refresh"></i> <span data-i18n="label.refresh"></span></label>
38
+ <a class="red-ui-button s-width" id="refreshBtn"><span data-i18n="label.refresh_all"></span></a>
39
+ </div>
40
+
41
+ <div id="config_wr" style="display:none;">
42
+ <div class="form-row">
43
+ <!-- Tabsheets -->
44
+ <ul style="background: #fff; min-width: 600px; margin-bottom: 20px;" id="node-z2m-tabs"></ul>
45
+ </div>
46
+ <div id="node-z2m-tabs-content" style="min-height: 150px">
47
+ <!-- Content of all tabsheets -->
48
+ <div id="node-z2m-tab-bridge" class="node-z2m-tab-bridge" style="position: relative; margin-top: 30px;">
49
+ <div class="form-row">
50
+ <label for="permit_join_btn" class="l-width"><i class="fa fa-share-alt"></i> <span data-i18n="label.permit_join"></span></label>
51
+ <button style="width: 70%" class="red-ui-button permit_join_btn" id="permit_join_btn"><span data-i18n="label.permit_join_help"></span></button>
52
+ <button style="width: 70%" class="red-ui-button permit_join_btn" style="display:none;" id="permit_join_cancel_btn"><span data-i18n="label.permit_join_cancel_help"></span></button>
53
+ </div>
54
+ <div class="form-row">
55
+ <label for="log_level_info_btn" class="l-width"><i class="fa fa-commenting-o"></i> <span data-i18n="label.log_level"></span></label>
56
+ <button style="width: 17%" class="red-ui-button log_level_btn" data-level="info" id="log_level_info_btn"><span data-i18n="label.log_level_info"></span></button>
57
+ <button style="width: 17%" class="red-ui-button log_level_btn" data-level="debug" id="log_level_debug_btn"><span data-i18n="label.log_level_debug"></span></button>
58
+ <button style="width: 17%" class="red-ui-button log_level_btn" data-level="warning" id="log_level_warning_btn"><span data-i18n="label.log_level_warning"></span></button>
59
+ <button style="width: 17%" class="red-ui-button log_level_btn" data-level="error" id="log_level_error_btn"><span data-i18n="label.log_level_error"></span></button>
60
+ </div>
61
+ <div class="form-row">
62
+ <label for="config_version" class="l-width"><span data-i18n="label.version"></span></label>
63
+ <span id="config_version" style="font-weight:bold"> - </span>
64
+ </div>
65
+ <div class="form-row">
66
+ <label for="config_coordinator" class="l-width"><span data-i18n="label.coordinator"></span></label>
67
+ <span id="config_coordinator" style="font-weight:bold"> - </span>
68
+ </div>
69
+ <div class="form-row">
70
+ <label for="config_advanced_output" class="l-width"><span data-i18n="label.advanced_output"></span></label>
71
+ <span id="config_advanced_output"> - </span>
72
+ </div>
73
+ <div class="form-row">
74
+ <label for="config_legacy_api" class="l-width"><span data-i18n="label.no_legacy_api"></span></label>
75
+ <span id="config_legacy_api"> - </span>
76
+ </div>
77
+ <!-- <div class="form-row">-->
78
+ <!-- <label for="config_last_seen" class="l-width"><span data-i18n="label.last_seen"></span></label>-->
79
+ <!-- <span id="config_last_seen"> - </span>-->
80
+ <!-- </div>-->
81
+ <div class="form-row">
82
+ <label for="config_mqtt_disable_retain" class="l-width"><span data-i18n="label.mqtt_disable_retain"></span></label>
83
+ <span id="config_mqtt_disable_retain"> - </span>
84
+ </div>
85
+ <div class="form-row">
86
+ <label for="config_availability" class="l-width"><span data-i18n="label.availability"></span></label>
87
+ <span id="config_availability"> - </span>
88
+ </div>
89
+ <div class="form-row">
90
+ <label for="config_restart_required" class="l-width"><span data-i18n="label.restart_required"></span></label>
91
+ <span id="config_restart_required"> - </span>
92
+ </div>
93
+ <div class="form-row">
94
+ <label for="restart_btn" class="l-width"><i class="fa fa-power-off"></i> <span data-i18n="label.restart"></span></label>
95
+ <button style="width: 70%" class="red-ui-button" id="restart_btn"><span data-i18n="label.restart_zigbee2mqtt"></span></button>
96
+ </div>
97
+ </div>
98
+
99
+ <div id="node-z2m-tab-devices" class="node-z2m-tab-devices" style="position: relative; margin-top: 30px;">
100
+ <table class="z2m_table" id="node-z2m-devices_table">
101
+ <thead>
102
+ <th style="width:150px"><span data-i18n="devices.friendly_name"></span></th>
103
+ <th style="width:95%;"><span data-i18n="devices.device"></span></th>
104
+ <th style="width:50px;"></th>
105
+ <th style="width:50px;"></th>
106
+ </thead>
107
+ <tbody>
108
+ </tbody>
109
+ </table>
110
+ <div class="form-row form-row-auto-height">
111
+ <ol id="node-input-devices-container"></ol>
112
+ </div>
113
+ </div>
114
+
115
+ <div id="node-z2m-tab-groups" class="node-z2m-tab-groups" style="position: relative; margin-top: 30px;">
116
+ <a href="#" class="red-ui-item-add red-ui-button"><i class="fa fa-plus"></i>&nbsp;<span data-i18n="groups.add"></span></a>
117
+ <table class="z2m_table" id="node-z2m-groups_table">
118
+ <thead>
119
+ <th style="width:95%;"><span data-i18n="groups.friendly_name"></span></th>
120
+ <th style="width:50px;"></th>
121
+ <th style="width:50px;"></th>
122
+ </thead>
123
+ <tbody>
124
+ </tbody>
125
+ </table>
126
+ <div class="form-row form-row-auto-height">
127
+ <ol id="node-input-groups-container"></ol>
128
+ </div>
129
+ </div>
130
+
131
+
132
+ <div id="node-z2m-tab-map" class="node-z2m-tab-map" style="position: relative; margin-top: 30px;">
133
+
134
+
135
+ <select id="node-input-engine" style="width:100px;display:none;">
136
+ <option value="circo" selected>circo</option>
137
+ <option value="dot">dot</option>
138
+ <option value="fdp">fdp</option>
139
+ <option value="neato">neato</option>
140
+ <option value="osage">osage</option>
141
+ <option value="twopi">twopi</option>
142
+ </select>
143
+
144
+ <a href="#" id="z2m_map_refresh_btn" class="red-ui-item-add red-ui-button"><i class="fa fa-refresh"></i>&nbsp;<span data-i18n="map.refresh"></span></a>
145
+ <a href="#" id="z2m_map_fullscreen_btn" style="display:none;" class="red-ui-item-add red-ui-button"><i class="fa fa-external-link"></i>&nbsp;<span data-i18n="map.fullscreen"></span></a>
146
+ <div id="z2m_map_img"></div>
147
+ </div>
148
+ </div>
149
+ </div>
150
+ </script>
151
+
152
+ <script type='text/javascript'>
153
+ RED.nodes.registerType('zigbee2mqtt-eb-bridge', {
154
+ category: 'ZigBee2MQTT',
155
+ color: '#FDBF48',
156
+ defaults: {
157
+ name: {
158
+ value: ""
159
+ },
160
+ server: {
161
+ type: "zigbee2mqtt-eb-server",
162
+ required: true
163
+ },
164
+ topic: {
165
+ value: null,
166
+ required: false
167
+ }
168
+ },
169
+ inputs: 1,
170
+ outputs: 1,
171
+ outputLabels: ["value"],
172
+ paletteLabel: 'bridge',
173
+ icon: "icon.png",
174
+ label: function () {
175
+ var label = 'ZigBee2MQTT Bridge';
176
+ if (this.name) {
177
+ label = this.name;
178
+ }
179
+ return label;
180
+ },
181
+ oneditprepare: function () {
182
+ var node = this;
183
+
184
+ node.tabs = RED.tabs.create({
185
+ id: "node-z2m-tabs",
186
+ onchange: function (tab) {
187
+ $("#node-z2m-tabs-content").children().hide();
188
+ $("#" + tab.id).show();
189
+ }
190
+ });
191
+ node.tabs.addTab({
192
+ id: "node-z2m-tab-bridge",
193
+ label: RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:tabs.bridge")
194
+ });
195
+ node.tabs.addTab({
196
+ id: "node-z2m-tab-devices",
197
+ label: RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:tabs.devices")
198
+ });
199
+ node.tabs.addTab({
200
+ id: "node-z2m-tab-groups",
201
+ label: RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:tabs.groups")
202
+ });
203
+ node.tabs.addTab({
204
+ id: "node-z2m-tab-map",
205
+ label: RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:tabs.map")
206
+ });
207
+
208
+ $('#refreshBtn').on("click", function(){
209
+ init();
210
+ });
211
+
212
+ init();
213
+
214
+
215
+
216
+ function init () {
217
+ var $permitJoinBtn = $('#permit_join_btn');
218
+
219
+ //get config
220
+ $.getJSON('/zigbee2mqtt-eb/getConfig', {
221
+ controllerID: node.server,
222
+ permit_join: true
223
+ }).done(function (data, textStatus, jqXHR) {
224
+ if (data) {
225
+ $('#config_wr').show();
226
+ $('#config_version').text(data.version);
227
+ $('#config_coordinator')
228
+ .text(data.coordinator.type + ' (' + data.coordinator.meta.revision + ')');
229
+ $('#config_legacy_api')
230
+ .html(data.config.advanced.legacy_api
231
+ ? '<b style="color:#c10000;">' +
232
+ RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:label.turn_off_legacy_api") + '</b>'
233
+ : '<b style="color:green;">' + RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:label.ok") +
234
+ '</b>');
235
+ $('#config_advanced_output')
236
+ .html(data.config.advanced.output !== 'json'
237
+ ? '<b style="color:#c10000;">' +
238
+ RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:label.should_be_json") + '</b>'
239
+ : '<b style="color:green;">' + RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:label.ok") +
240
+ '</b>');
241
+ // $('#config_last_seen').html(data.config.advanced.last_seen!=='disabled'?'<b style="color:green;">'+RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:label.ok")+'</b> ' + data.config.advanced.last_seen:'<b>'+RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:label.disabled")+'</b>');
242
+ $('#config_availability')
243
+ .html(data.availability !== false ? '<b style="color:green;">' +
244
+ RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:label.ok") + '</b>' : '<b>' +
245
+ RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:label.disabled") + '</b>');
246
+ $('#config_restart_required')
247
+ .html(data.restart_required
248
+ ? '<b style="color:#c10000;">' +
249
+ RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:label.restart_needed") + '</b>'
250
+ : '<b style="color:green;">' + RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:label.ok") +
251
+ '</b>');
252
+ $('#config_mqtt_disable_retain')
253
+ .html(data.config.mqtt.force_disable_retain
254
+ ? '<b style="color:#c10000;">' +
255
+ RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:label.retain_disabled_error") + '</b>'
256
+ : '<b style="color:green;">' + RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:label.ok") +
257
+ '</b>');
258
+
259
+ $('.log_level_btn').each(function() {
260
+ $(this).removeClass('active');
261
+ });
262
+ $('.log_level_btn#log_level_' + data.log_level + '_btn').addClass('active');
263
+
264
+ $('.permit_join_btn').each(function() {
265
+ $(this).hide();
266
+ });
267
+
268
+ if (data.permit_join) {
269
+ $('#permit_join_cancel_btn').show()
270
+ } else {
271
+ $permitJoinBtn.show();
272
+ }
273
+ $('.log_level_btn#log_level_' + data.log_level + '_btn').addClass('active');
274
+ }
275
+ });
276
+
277
+ //restart
278
+ $('#restart_btn').off('click').on('click', function () {
279
+ if (confirm(RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:label.sure_restart"))) {
280
+ $.getJSON('/zigbee2mqtt-eb/restart', {
281
+ controllerID: node.server
282
+ });
283
+ }
284
+ });
285
+
286
+ //log level
287
+ $('.log_level_btn').off('click').on('click', function () {
288
+ $('.log_level_btn').each(function () {
289
+ $(this).removeClass('active');
290
+ });
291
+ $(this).addClass('active');
292
+
293
+ $.getJSON('/zigbee2mqtt-eb/setLogLevel', {
294
+ controllerID: node.server,
295
+ log_level: $(this).data('level')
296
+ }).done(function (data, textStatus, jqXHR) {
297
+ });
298
+ });
299
+
300
+ var timeout = null;
301
+ //permit join
302
+ $('#permit_join_cancel_btn').off('click').on('click', function () {
303
+ $permitJoinBtn.show();
304
+ $('#permit_join_cancel_btn').hide();
305
+ $.getJSON('/zigbee2mqtt-eb/setPermitJoin', {
306
+ controllerID: node.server,
307
+ permit_join: false
308
+ });
309
+ });
310
+
311
+ $permitJoinBtn.off('click').on('click', function () {
312
+ clearTimeout(timeout);
313
+ $permitJoinBtn.hide();
314
+ $('#permit_join_cancel_btn').show();
315
+ $.getJSON('/zigbee2mqtt-eb/setPermitJoin', {
316
+ controllerID: node.server,
317
+ permit_join: true
318
+ }).done(function (data, textStatus, jqXHR) {
319
+ timeout = setTimeout(function () {
320
+ $permitJoinBtn.show();
321
+ $('#permit_join_cancel_btn').hide();
322
+ $.getJSON('/zigbee2mqtt-eb/setPermitJoin', {
323
+ controllerID: node.server,
324
+ permit_join: false
325
+ });
326
+ }, 60000 * 3);
327
+ });
328
+ });
329
+
330
+ $('#z2m_map_refresh_btn').off('click').on('click', function () {
331
+ var $btn = $(this);
332
+ $('#z2m_map_img').html('');
333
+ $btn.find('.fa-refresh').addClass('fa-spin');
334
+ $btn.find('span').text(RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:map.loading"));
335
+ $('#z2m_map_fullscreen_btn').hide();
336
+ $.getJSON('/zigbee2mqtt-eb/refreshMap', {
337
+ controllerID: node.server,
338
+ engine: $('#node-input-engine').val()
339
+ }).done(function (data, textStatus, jqXHR) {
340
+ $btn.find('.fa-refresh').removeClass('fa-spin');
341
+ $btn.find('span').text(RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:map.refresh"));
342
+ $('#z2m_map_fullscreen_btn').show();
343
+ $('#z2m_map_img').html(data.svg).find('svg').attr('width','100%').attr('height','100%');
344
+ });
345
+ });
346
+ $('#z2m_map_fullscreen_btn').off('click').on('click', function () {
347
+ var url = '/zigbee2mqtt-eb/showMap?controllerID='+node.server;
348
+
349
+ var win = window.open(url, '_blank');
350
+ if (win) {
351
+ //Browser has allowed it to be opened
352
+ win.focus();
353
+ } else {
354
+ //Browser has blocked it
355
+ alert('Please allow popups for this website');
356
+ }
357
+ });
358
+
359
+ $.getJSON('/zigbee2mqtt-eb/getDevices', {
360
+ controllerID: node.server
361
+ }).done(function (data, textStatus, jqXHR) {
362
+
363
+ var tokeninputArr = [];
364
+ var tokeninputArrPrePopulate = [];
365
+ var devices = data[0]; //devices
366
+ var devicesById = {}; //devices
367
+ if (devices) {
368
+ $('#node-z2m-devices_table tbody tr').remove();
369
+ devices.forEach(function (device, index) {
370
+ if ("Coordinator" === device.type) return;
371
+
372
+ devicesById[device.ieee_address+''] = device;
373
+
374
+ tokeninputArr.push({'id':device.ieee_address, 'name':device.friendly_name, 'model': device.definition.model});
375
+ var input = '<input class="node-input-devices-friendly_name" type="text" value="' + device.friendly_name + '">';
376
+ var info = '<div class="device_wr"><span><b>' + device.ieee_address + '</b>: ' + device.definition.model + '</span></div>';
377
+ var removeBtn = '<a href="#" class="red-ui-item-remove red-ui-button" data-id="' + device.ieee_address + '"><i class="fa fa-remove"></i></a>'
378
+ var saveBtn = '<a href="#" class="red-ui-item-save red-ui-button" data-ieee_address="' + device.ieee_address + '"><i class="fa fa-check"></i>&nbsp;' + RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:devices.set") + '</a>'
379
+
380
+ $('#node-z2m-devices_table tbody').append('<tr><td>' + input + '</td><td>' + info + '</td><td>' + saveBtn + '</td><td>' + removeBtn + '</td><</tr>');
381
+ });
382
+
383
+ $('#node-z2m-devices_table .red-ui-item-save').on('click', function () {
384
+ var ieee_address = $(this).attr('data-ieee_address');
385
+ var newName = $(this).closest('tr').find('.node-input-devices-friendly_name').val();
386
+
387
+ $.getJSON('/zigbee2mqtt-eb/renameDevice', {
388
+ controllerID: node.server,
389
+ ieee_address: ieee_address,
390
+ newName: newName
391
+ }).done(function (data, textStatus, jqXHR) {
392
+ if ("error" in data) alert(data.description);
393
+ });
394
+ });
395
+ $('#node-z2m-devices_table .red-ui-item-remove').on('click', function () {
396
+ if (confirm(RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:devices.sure_remove"))) {
397
+ var id = $(this).attr('data-id');
398
+ $(this).closest('tr').remove();
399
+
400
+ $.getJSON('/zigbee2mqtt-eb/removeDevice', {
401
+ controllerID: node.server,
402
+ id: id
403
+ }).done(function (data, textStatus, jqXHR) {
404
+ if ("error" in data) alert(data.description);
405
+ });
406
+ }
407
+ });
408
+ }
409
+
410
+ var groups = data[1]; //groups
411
+ if (groups) {
412
+ $('#node-z2m-groups_table tbody tr').remove();
413
+ groups.forEach(function (group, index) {
414
+ var input = '<input class="node-input-groups-friendly_name" type="text" value="' + group.friendly_name + '">';
415
+
416
+ // var info = '<div class="device_wr"><span><b>'+device.ieee_address+'</b>: '+device.modelID+'</span><div class="help-tips">'+device.description+'</div></div>';
417
+ var removeBtn = '<a href="#" class="red-ui-item-remove red-ui-button" data-id="' + group.id + '"><i class="fa fa-remove"></i></a>'
418
+ var saveBtn = '<a href="#" class="red-ui-item-save red-ui-button" data-id="' + group.id + '"><i class="fa fa-check"></i>&nbsp;' + RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:groups.set") + '</a>'
419
+
420
+ $('#node-z2m-groups_table tbody').append('<tr class="group_row_' + group.id + '"><td>' + input + '</td><td>' + saveBtn + '</td><td>' + removeBtn + '</td></tr><tr class="group_row_' + group.id + '"><td colspan="4" style="padding-bottom:25px;"><input type="hidden" data-group_id="' + group.id + '" id="tokeninput_'+group.id+'" class="tokeninput"/></td></tr>');
421
+
422
+ tokeninputArrPrePopulate = [];
423
+
424
+ group.members.forEach(function (value) {
425
+ if (value) {
426
+ tokeninputArrPrePopulate.push({
427
+ "id": value.ieee_address,
428
+ "name": devicesById[value.ieee_address + '']['friendly_name'],
429
+ "model": devicesById[value.ieee_address + '']['definition']['model']
430
+ });
431
+ }
432
+ });
433
+ $("#tokeninput_"+group.id).tokenInput(tokeninputArr, {
434
+ theme:'facebook',
435
+ prePopulate:tokeninputArrPrePopulate,
436
+ processPrePopulate:true,
437
+ hintText:RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:tokeninput.type_to_search"),
438
+ noResultsText:RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:tokeninput.no_results"),
439
+ searchingText:RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:tokeninput.searching"),
440
+ deleteText:'&times;',
441
+ animateDropdown:true,
442
+ resultsFormatter:function (item) {
443
+ return '<li>' + item.name + ' : '+item.model+'</li>'
444
+ },
445
+ onAdd:function (item) {
446
+ var groupId = this.attr('data-group_id');
447
+ var deviceId = item.id;
448
+
449
+ $.getJSON('/zigbee2mqtt-eb/addDeviceToGroup', {
450
+ controllerID: node.server,
451
+ groupId: groupId,
452
+ deviceId: deviceId,
453
+ }).done(function (data, textStatus, jqXHR) {
454
+ if ("error" in data) alert(data.description);
455
+ });
456
+ },
457
+ onDelete:function (item) {
458
+ var groupId = this.attr('data-group_id');
459
+ var deviceId = item.id;
460
+
461
+ $.getJSON('/zigbee2mqtt-eb/removeDeviceFromGroup', {
462
+ controllerID: node.server,
463
+ groupId: groupId,
464
+ deviceId: deviceId,
465
+ }).done(function (data, textStatus, jqXHR) {
466
+ if ("error" in data) alert(data.description);
467
+ });
468
+ },
469
+ });
470
+ });
471
+
472
+
473
+ $('#node-z2m-groups_table .red-ui-item-save').on('click', function () {
474
+ var id = $(this).attr('data-id');
475
+ var newName = $(this).closest('tr').find('.node-input-groups-friendly_name').val();
476
+
477
+ $.getJSON('/zigbee2mqtt-eb/renameGroup', {
478
+ controllerID: node.server,
479
+ id: id,
480
+ newName: newName
481
+ }).done(function (data, textStatus, jqXHR) {
482
+ if ("error" in data) alert(data.description);
483
+ });
484
+ });
485
+ $('#node-z2m-groups_table .red-ui-item-remove').on('click', function () {
486
+ if (confirm(RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:groups.sure_remove"))) {
487
+ var id = $(this).attr('data-id');
488
+ $('.group_row_' + id).remove();
489
+
490
+ $.getJSON('/zigbee2mqtt-eb/removeGroup', {
491
+ controllerID: node.server,
492
+ id: id
493
+ }).done(function (data, textStatus, jqXHR) {
494
+ if ("error" in data) alert(data.description);
495
+ });
496
+ }
497
+ });
498
+ $('#node-z2m-tab-groups .red-ui-item-add').on('click', function () {
499
+ var name = prompt(RED._("@evilbunny/node-red-contrib-zigbee2mqtt/bridge:groups.enter_group_name"), "");
500
+ if (name) {
501
+ $.getJSON('/zigbee2mqtt-eb/addGroup', {
502
+ controllerID: node.server,
503
+ name: name
504
+ }).done(function (data, textStatus, jqXHR) {
505
+ if ("error" in data) alert(data.description);
506
+ setTimeout(function(){
507
+ init();
508
+ }, 1000);
509
+ });
510
+ }
511
+ });
512
+ }
513
+
514
+ });
515
+ }
516
+
517
+ },
518
+ oneditsave: function () {
519
+
520
+ }
521
+ });
522
+ </script>
523
+