iobroker.zigbee 3.0.0 → 3.0.1
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.
- package/README.md +16 -3
- package/admin/admin.js +140 -14
- package/admin/index_m.html +133 -121
- package/admin/tab_m.html +101 -88
- package/docs/en/readme.md +7 -12
- package/io-package.json +15 -14
- package/lib/commands.js +40 -9
- package/lib/groups.js +1 -1
- package/lib/localConfig.js +31 -8
- package/lib/networkmap.js +2 -1
- package/lib/statescontroller.js +53 -53
- package/lib/zbDeviceConfigure.js +1 -1
- package/lib/zigbeecontroller.js +1 -0
- package/main.js +4 -3
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -68,13 +68,18 @@ At first start, it is vital to set up the adapter settings. These include:
|
|
|
68
68
|
- the network parameters PanID (a number between 0 and 65565), extended PanID (a 16 digit HEX number) and the zigbee Channel **important: Do not run the adapter without changing the values for PanID (6754) and Extended PanID (DDDDDDDDDDDDDDDD) to unique values for your Zigbee Installation.**
|
|
69
69
|
|
|
70
70
|
|
|
71
|
-

|
|
72
|
+
|
|
73
|
+
The *Test Port* and *Star/Stop* buttons are provided to test the settings.
|
|
74
|
+
|
|
75
|
+
**Once the settings are verified the adapter can be prepared for automatic start by setting the CheckBox *start the zigbee network automatically* and saving the parameters.**
|
|
76
|
+
|
|
72
77
|
Please refer to the [in depth documentation](docs/en/readme.md) ([german version](docs/de/readme.md), [russian version](docs/ru/readme.md)) for a detailed explanation on how to configure the adapter.
|
|
73
78
|
|
|
74
79
|
Once the adapter is up and running, the desired devices need to be integrated into the network. This requires for both the adapter and the device to be in pairing mode. Most new devices will be in pairing-mode when they are powered up for the first time, but some will require a special procedure for this. Please refer to the device manual for information on this.
|
|
75
80
|
|
|
76
81
|
The adapter is placed in pairing mode by pressing the pairing button:
|
|
77
|
-

|
|
78
83
|
|
|
79
84
|
A dialog showing a pairing countdown appears. When a new device is discovered, interviewed and paired with the network, messages will be shown in this dialog, and the device will show up in the grid of active devices. Any known device should show up with an image and the correct device name, as well as a number of changable settings. Any unknown device will show up with a device name and a ? as icon, while devices which failed the pairing will show up as 'unknown' with the same ? icon. These should be removed from the network to be paired again. Please refer to the documentation linked above for more details.
|
|
80
85
|
|
|
@@ -152,8 +157,16 @@ You can thank the authors by these links:
|
|
|
152
157
|
|
|
153
158
|
-----------------------------------------------------------------------------------------------------
|
|
154
159
|
## Changelog
|
|
160
|
+
### 3.0.1 (2025-04-25)
|
|
161
|
+
* (AlexHaxe) Fix for Ikea SOMRIG configuration raising 'definition.endpoint is not a function' error.
|
|
162
|
+
* (asgothian) Access to 'zigbee2mqtt options as settings in zigbee adapter (ALPHA Stage !)
|
|
163
|
+
* (asgothian) Fix for 'error: zigbee.0 (1118300) zigbee.0 already running' at adapter start (Alpha Stage)
|
|
164
|
+
* (asgothian) Updated hardware configuration panel - exchanged text buttons for buttons with icons.
|
|
165
|
+
* (asgothian) Limited states on device tiles to states which are read only or which can be modified sensibly via the device tile.
|
|
166
|
+
*
|
|
167
|
+
|
|
155
168
|
### 3.0.0 (2025-04-08)
|
|
156
|
-
* (asgothian) Breaking change: Start of zigbee subsystem requires
|
|
169
|
+
* (asgothian) Breaking change: Start of zigbee subsystem requires checking the 'start the Zigbee network automatically' checkbox. !!!
|
|
157
170
|
* (asgothian) Hardware configuration panel
|
|
158
171
|
* (asgothian) Update for external converter - detect /dist/ subfolder
|
|
159
172
|
* (asgothian) Update device image: use of icons defined in external converter (beta)
|
package/admin/admin.js
CHANGED
|
@@ -429,7 +429,81 @@ function EndPointIDfromEndPoint(ep) {
|
|
|
429
429
|
return 'unidentified';
|
|
430
430
|
}
|
|
431
431
|
|
|
432
|
+
|
|
433
|
+
|
|
432
434
|
function editName(id, name) {
|
|
435
|
+
|
|
436
|
+
const device_options = {};
|
|
437
|
+
const received_options = {};
|
|
438
|
+
|
|
439
|
+
function removeOption(k) {
|
|
440
|
+
if (k && device_options.hasOwnProperty(k)) delete device_options[k];
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
function addOption() {
|
|
444
|
+
let idx=1;
|
|
445
|
+
let key = '';
|
|
446
|
+
do {
|
|
447
|
+
key = `o${idx++}`;
|
|
448
|
+
}
|
|
449
|
+
while (device_options.hasOwnProperty(key));
|
|
450
|
+
device_options[key] = {key:`option_${idx++}`, value:''};
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
function updateOptions() {
|
|
454
|
+
const html_options=[];
|
|
455
|
+
|
|
456
|
+
console.warn(`device_options is ${JSON.stringify(device_options)}`)
|
|
457
|
+
|
|
458
|
+
for (const k in device_options) {
|
|
459
|
+
html_options.push(`<div class="row">`);
|
|
460
|
+
html_options.push(`<div class="input-field suffix col s5 m5 l5"><input id="option_key_${k}" type="text" class="value" /><label for="option_key_${k}">Option</label></div>`)
|
|
461
|
+
html_options.push(`<div class="input-field suffix col s5 m5 l5"><input id="option_value_${k}" type="text" class="value" /><label for="option_value_${k}">Value</label></div>`)
|
|
462
|
+
html_options.push(`<div class="col"><a id="option_rem_${k}" class='btn' ><i class="material-icons">remove_circle</i></a></div>`);
|
|
463
|
+
html_options.push(`</div>`)
|
|
464
|
+
}
|
|
465
|
+
console.warn(`html is ${$('#modaledit').find('.options_grid').html()}`)
|
|
466
|
+
$('#modaledit').find('.options_grid').html(html_options.join(''));
|
|
467
|
+
console.warn(`html is now ${$('#modaledit').find('.options_grid').html()}`)
|
|
468
|
+
if (html_options.length > 0) {
|
|
469
|
+
$('#modaledit').find('.options_available').removeClass('hide');
|
|
470
|
+
for (const k of Object.keys(device_options)) {
|
|
471
|
+
$(`#option_key_${k}`).val(device_options[k].key);
|
|
472
|
+
$(`#option_value_${k}`).val(device_options[k].value);
|
|
473
|
+
$(`#option_rem_${k}`).unbind('click');
|
|
474
|
+
$(`#option_rem_${k}`).click(() => { removeOption(k); updateOptions() });
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
else {
|
|
478
|
+
$('#modaledit').find('.options_available').addClass('hide');
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
function getOptionsFromUI(_do, _so) {
|
|
483
|
+
const _no = {};
|
|
484
|
+
let changed = false;
|
|
485
|
+
for (const k in _do) {
|
|
486
|
+
const key = $(`#option_key_${k}`).val();
|
|
487
|
+
_do[k].key = key;
|
|
488
|
+
const val = $(`#option_value_${k}`).val();
|
|
489
|
+
try {
|
|
490
|
+
_do[k].value = JSON.parse(val);
|
|
491
|
+
}
|
|
492
|
+
catch {
|
|
493
|
+
_do[k].value = val;
|
|
494
|
+
}
|
|
495
|
+
if (device_options[k].key.length > 0) {
|
|
496
|
+
_no[key] = device_options[k].value;
|
|
497
|
+
changed |= _no[key] != _so[key];
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
changed |= (Object.keys(_no).length != Object.keys(_so).length);
|
|
501
|
+
if (changed) return _no;
|
|
502
|
+
return undefined;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
|
|
433
507
|
console.warn('editName called with ' + id + ' and ' + name);
|
|
434
508
|
const dev = devices.find((d) => d._id == id);
|
|
435
509
|
$('#modaledit').find('input[id=\'d_name\']').val(name);
|
|
@@ -442,14 +516,16 @@ function editName(id, name) {
|
|
|
442
516
|
}
|
|
443
517
|
}
|
|
444
518
|
const numEP = groupables.length;
|
|
445
|
-
|
|
446
|
-
$('#modaledit').find('.row.epid1').addClass('hide');
|
|
447
|
-
$('#modaledit').find('.row.epid2').addClass('hide');
|
|
448
|
-
$('#modaledit').find('.row.epid3').addClass('hide');
|
|
449
|
-
$('#modaledit').find('.row.epid4').addClass('hide');
|
|
450
|
-
$('#modaledit').find('.row.epid5').addClass('hide');
|
|
451
|
-
$('#modaledit').find('.row.epid6').addClass('hide');
|
|
519
|
+
|
|
452
520
|
if (numEP > 0) {
|
|
521
|
+
$('#modaledit').find('.groups_available').removeClass('hide');
|
|
522
|
+
$('#modaledit').find('.row.epid0').addClass('hide');
|
|
523
|
+
$('#modaledit').find('.row.epid1').addClass('hide');
|
|
524
|
+
$('#modaledit').find('.row.epid2').addClass('hide');
|
|
525
|
+
$('#modaledit').find('.row.epid3').addClass('hide');
|
|
526
|
+
$('#modaledit').find('.row.epid4').addClass('hide');
|
|
527
|
+
$('#modaledit').find('.row.epid5').addClass('hide');
|
|
528
|
+
$('#modaledit').find('.row.epid6').addClass('hide');
|
|
453
529
|
// go through all the groups. Find the ones to list for each groupable
|
|
454
530
|
if (numEP == 1) {
|
|
455
531
|
$('#modaledit').find('.endpointid').addClass('hide');
|
|
@@ -479,7 +555,37 @@ function editName(id, name) {
|
|
|
479
555
|
list2select('#d_groups_ep' + i, groups, groupables[i].memberOf || []);
|
|
480
556
|
}
|
|
481
557
|
}
|
|
558
|
+
else
|
|
559
|
+
{
|
|
560
|
+
$('#modaledit').find('.groups_available').addClass('hide');
|
|
561
|
+
}
|
|
562
|
+
sendTo(namespace, 'getLocalConfigItems', { target:id, global:false, key:'options' }, function (msg) {
|
|
563
|
+
if (msg) {
|
|
564
|
+
if (msg.error) showMessage(msg.error, '_Error');
|
|
565
|
+
console.warn(`return is ${msg}`)
|
|
566
|
+
Object.keys(device_options).forEach(key => delete device_options[key]);
|
|
567
|
+
Object.keys(received_options).forEach(key => delete received_options[key]);
|
|
568
|
+
if (typeof msg.options === 'object') {
|
|
569
|
+
|
|
570
|
+
let cnt = 1;
|
|
571
|
+
for (const key in msg.options)
|
|
572
|
+
{
|
|
573
|
+
received_options[key]=msg.options[key];
|
|
574
|
+
device_options[`o${cnt}`] = { key:key, value:msg.options[key]}
|
|
575
|
+
cnt++;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
updateOptions();
|
|
579
|
+
|
|
580
|
+
} else showMessage('callback without message');
|
|
581
|
+
});
|
|
482
582
|
$('#modaledit a.btn[name=\'save\']').unbind('click');
|
|
583
|
+
$('#modaledit a.btn[name=\'add_options\']').unbind('click');
|
|
584
|
+
$('#modaledit a.btn[name=\'add_options\']').click(() => {
|
|
585
|
+
getOptionsFromUI(device_options, received_options);
|
|
586
|
+
addOption();
|
|
587
|
+
updateOptions()
|
|
588
|
+
});
|
|
483
589
|
$('#modaledit a.btn[name=\'save\']').click(() => {
|
|
484
590
|
const newName = $('#modaledit').find('input[id=\'d_name\']').val();
|
|
485
591
|
const groupsbyid = {};
|
|
@@ -490,8 +596,21 @@ function editName(id, name) {
|
|
|
490
596
|
groupsbyid[groupables[i].ep.ID] = GenerateGroupChange(groupables[i].memberOf, ng);
|
|
491
597
|
}
|
|
492
598
|
}
|
|
493
|
-
|
|
599
|
+
// read device_options from UI
|
|
600
|
+
const co = getOptionsFromUI(device_options, received_options)
|
|
601
|
+
console.warn(`options have ${co ? 'changed' : 'not changed'} : ${JSON.stringify(co)} vs ${JSON.stringify(received_options)} , saving them`);
|
|
602
|
+
if (co) {
|
|
603
|
+
sendTo(namespace, 'updateLocalConfigItems', {
|
|
604
|
+
target: id,
|
|
605
|
+
global:false,
|
|
606
|
+
data: { options:co }
|
|
607
|
+
},
|
|
608
|
+
function (msg) {
|
|
609
|
+
if (msg && msg.error) showMessage(msg.error, '_Error');
|
|
610
|
+
});
|
|
611
|
+
}
|
|
494
612
|
updateDev(id, newName, groupsbyid);
|
|
613
|
+
|
|
495
614
|
});
|
|
496
615
|
$('#modaledit').modal('open');
|
|
497
616
|
Materialize.updateTextFields();
|
|
@@ -848,8 +967,8 @@ async function toggleDebugDevice(id) {
|
|
|
848
967
|
});
|
|
849
968
|
}
|
|
850
969
|
|
|
851
|
-
function
|
|
852
|
-
sendTo(namespace, '
|
|
970
|
+
function updateLocalConfigItems(device, data, global) {
|
|
971
|
+
sendTo(namespace, 'updateLocalConfigItems', {target: device, data:data, global:global}, function(msg) {
|
|
853
972
|
if (msg && msg.hasOwnProperty.error) {
|
|
854
973
|
showMessage(msg.error, _('Error'));
|
|
855
974
|
}
|
|
@@ -898,7 +1017,7 @@ async function selectImageOverride(id) {
|
|
|
898
1017
|
const data = {};
|
|
899
1018
|
if (image != 'current') data.icon= image;
|
|
900
1019
|
if (name != dev.common.name) data.name = name;
|
|
901
|
-
|
|
1020
|
+
updateLocalConfigItems(id, data, global);
|
|
902
1021
|
});
|
|
903
1022
|
$('#chooseimage').modal('open');
|
|
904
1023
|
Materialize.updateTextFields();
|
|
@@ -1022,6 +1141,7 @@ function displayDebugMessages(msg) {
|
|
|
1022
1141
|
Html.push('</tbody></table></li>')
|
|
1023
1142
|
for (const devID of Object.keys(dbgData)) {
|
|
1024
1143
|
const dev = devices.find((d) => d._id.endsWith(devID.slice(-16)));
|
|
1144
|
+
if (!dev) continue;
|
|
1025
1145
|
const type_url = (dev && dev.common && dev.common.type ? sanitizeModelParameter(dev.common.type) : 'unknown');
|
|
1026
1146
|
const image = `<img src="${dev.common.icon || dev.icon}" width="40px" onerror="this.onerror=null;this.src='img/unavailable.png';">`
|
|
1027
1147
|
const modelUrl = (type_url === 'unknown') ? 'unknown' : `<a href="https://www.zigbee2mqtt.io/devices/${type_url}.html" target="_blank" rel="noopener noreferrer">${image}</a>`;
|
|
@@ -3358,6 +3478,7 @@ function getDashCard(dev, groupImage, groupstatus) {
|
|
|
3358
3478
|
let options;
|
|
3359
3479
|
if (typeof stateDef.states == 'string') {
|
|
3360
3480
|
const sts = stateDef.states.split(';');
|
|
3481
|
+
if (sts.length < 2) return '';
|
|
3361
3482
|
options = sts.map((item) => {
|
|
3362
3483
|
const v = item.split(':');
|
|
3363
3484
|
return `<option value="${v[0]}" ${(val == v[0]) ? 'selected' : ''}>${v[1]}</option>`;
|
|
@@ -3368,9 +3489,14 @@ function getDashCard(dev, groupImage, groupstatus) {
|
|
|
3368
3489
|
options.push(`<option value="${key}" ${(val == key) ? 'selected' : ''}>${key}</option>`);
|
|
3369
3490
|
}
|
|
3370
3491
|
}
|
|
3492
|
+
if (options.length < 2) return '';
|
|
3371
3493
|
val = `<select class="browser-default enum" style="color : white; background-color: grey; height: 16px; padding: 0; width: auto; display: inline-block">${options.join('')}</select>`;
|
|
3372
|
-
} else {
|
|
3373
|
-
|
|
3494
|
+
} else if (stateDef.write) {
|
|
3495
|
+
return;
|
|
3496
|
+
// val = `<span class="input-field dash value"><input class="dash value" id="${stateDef.name}" value="${val}"></input></span>`;
|
|
3497
|
+
}
|
|
3498
|
+
else {
|
|
3499
|
+
val = `<span class="dash value">${val ? val : '(null)'} ${(stateDef.unit) ? stateDef.unit : ''}</span>`;
|
|
3374
3500
|
}
|
|
3375
3501
|
return `<li><span class="label dash truncate">${stateDef.name}</span><span id=${sid} oid=${id} class="state">${val}</span></li>`;
|
|
3376
3502
|
}).join('') : '';
|
|
@@ -3536,7 +3662,7 @@ function validateConfigData(key, val) {
|
|
|
3536
3662
|
}
|
|
3537
3663
|
if (nvRamBackup[key]) {
|
|
3538
3664
|
console.warn(`value of ${key} is ${val} (${nvRamBackup[key]})`);
|
|
3539
|
-
if (val == nvRamBackup[key])
|
|
3665
|
+
if ((typeof val == 'string' && typeof nvRamBackup[key] == 'string' && val.toLowerCase == nvRamBackup[key].toLowerCase) || val == nvRamBackup[key])
|
|
3540
3666
|
{
|
|
3541
3667
|
console.warn(`ok set for ${key} (${val})`)
|
|
3542
3668
|
$(`#${key}_OK`).removeClass('hide')
|
package/admin/index_m.html
CHANGED
|
@@ -480,6 +480,10 @@
|
|
|
480
480
|
.m .navbar-fixed {
|
|
481
481
|
z-index: unset;
|
|
482
482
|
}
|
|
483
|
+
.img-btn {
|
|
484
|
+
padding: 2px;
|
|
485
|
+
height: 100%;
|
|
486
|
+
}
|
|
483
487
|
|
|
484
488
|
@keyframes blinking-icon {
|
|
485
489
|
0% { opacity: 0; }
|
|
@@ -920,7 +924,7 @@
|
|
|
920
924
|
</label>
|
|
921
925
|
</div>
|
|
922
926
|
<div class="input-field col s12 m6 l8">
|
|
923
|
-
<a id="scan" class=
|
|
927
|
+
<a id="scan" class="waves-effect waves-light btn" data-target='channel_a'><img class="img-btn" src="img/channel_scan.png" title="scan zigbee channels" ></a>
|
|
924
928
|
<p class="translate">ChannelChangeText</p>
|
|
925
929
|
</div>
|
|
926
930
|
</div>
|
|
@@ -938,27 +942,21 @@
|
|
|
938
942
|
</div>
|
|
939
943
|
</div>
|
|
940
944
|
<div class="row">
|
|
941
|
-
<h6>Verification</h6>
|
|
945
|
+
<h6>Test and Verification</h6>
|
|
942
946
|
</div>
|
|
943
947
|
<div class="row">
|
|
944
|
-
<div class="
|
|
945
|
-
<a id="test-btn" class="waves-effect waves-light white-text btn-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
<a id="
|
|
949
|
-
|
|
950
|
-
<div class="input-field col s9 m4 l3">
|
|
951
|
-
<a id="readNVRam-btn" class="waves-effect waves-light white-text btn-large translate">Read NVBackup</a>
|
|
952
|
-
</div>
|
|
953
|
-
<div class="input-field col s9 m4 l3">
|
|
954
|
-
<a id="deleteNVRam-btn" class="waves-effect waves-light white-text btn-large translate">remove NVBackup</a>
|
|
955
|
-
</div>
|
|
956
|
-
<div class="input-field col s9 m4 l3">
|
|
957
|
-
<a id="reset-btn" class="waves-effect waves-light white-text btn-large translate">Reset...</a>
|
|
948
|
+
<div class="col">
|
|
949
|
+
<a id="test-btn" class="waves-effect waves-light white-text btn"><img class="img-btn" src="img/test_port.png" title="test port"></a>
|
|
950
|
+
<a id="show_test_run" class="waves-effect waves-light blue btn"><img class="img-btn" src="img/start_stop.png" title="start / stop" ></a>
|
|
951
|
+
<a id="readNVRam-btn" class="waves-effect waves-light btn"><img class="img-btn" src="img/nvram_read.png" title="read nvram backup" ></a>
|
|
952
|
+
<a id="deleteNVRam-btn" class="waves-effect waves-light btn"><img class="img-btn" src="img/nvram_delete.png" title="remove nvram backup" ></a>
|
|
953
|
+
<a id="reset-btn" class="waves-effect waves-light white-text btn translate"><img class="img-btn" src="img/reset.png" title="reset..." ></a>
|
|
958
954
|
</div>
|
|
959
955
|
</div>
|
|
960
956
|
<div class="row textarea">
|
|
961
|
-
<
|
|
957
|
+
<div class="col">
|
|
958
|
+
<textarea class="monospaced" id="stdout_t" disabled="disabled" cols="120" rows="20" style="height: calc(50% - 115px)"></textarea>
|
|
959
|
+
</div>
|
|
962
960
|
</div>
|
|
963
961
|
</div>
|
|
964
962
|
<div id="tab-expos" class="col s12 page">
|
|
@@ -1232,115 +1230,129 @@
|
|
|
1232
1230
|
</div>
|
|
1233
1231
|
</div>
|
|
1234
1232
|
</div>
|
|
1235
|
-
<div class="
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
<p class="translate device_with_endpoint">Main Endpoint</p>
|
|
1239
|
-
</div>
|
|
1240
|
-
</div>
|
|
1241
|
-
<div class="col1">
|
|
1242
|
-
<div class="input-field groups">
|
|
1243
|
-
<select id="d_groups_ep0" class="materialSelect" multiple>
|
|
1244
|
-
<option value="1">select</option>
|
|
1245
|
-
</select>
|
|
1246
|
-
<label for="d_groups_ep0" class="translate">Groups</label>
|
|
1247
|
-
</div>
|
|
1248
|
-
</div>
|
|
1249
|
-
</div>
|
|
1250
|
-
<div class="row epid1">
|
|
1251
|
-
<div class="col epid">
|
|
1252
|
-
<div class=endpointid>
|
|
1253
|
-
<p class="translate device_with_endpoint">Sub Endpoint 1</p>
|
|
1254
|
-
</div>
|
|
1255
|
-
</div>
|
|
1256
|
-
<div class="col">
|
|
1257
|
-
<div class="input-field groups">
|
|
1258
|
-
<select id="d_groups_ep1" class="materialSelect" multiple>
|
|
1259
|
-
<option value="1">select</option>
|
|
1260
|
-
</select>
|
|
1261
|
-
<label for="d_groups_ep1" class="translate">Groups</label>
|
|
1262
|
-
</div>
|
|
1263
|
-
</div>
|
|
1264
|
-
</div>
|
|
1265
|
-
<div class="row epid2">
|
|
1266
|
-
<div class="col epid">
|
|
1267
|
-
<div class=endpointid>
|
|
1268
|
-
<p class="translate device_with_endpoint">Sub Endpoint 2</p>
|
|
1269
|
-
</div>
|
|
1270
|
-
</div>
|
|
1271
|
-
<div class="col">
|
|
1272
|
-
<div class="input-field groups">
|
|
1273
|
-
<select id="d_groups_ep2" class="materialSelect" multiple>
|
|
1274
|
-
<option value="1">select</option>
|
|
1275
|
-
</select>
|
|
1276
|
-
<label for="d_groups_ep2" class="translate">Groups</label>
|
|
1277
|
-
</div>
|
|
1278
|
-
</div>
|
|
1279
|
-
</div>
|
|
1280
|
-
<div class="row epid3">
|
|
1281
|
-
<div class="col epid">
|
|
1282
|
-
<div class=endpointid>
|
|
1283
|
-
<p class="translate device_with_endpoint">Sub Endpoint 3</p>
|
|
1284
|
-
</div>
|
|
1285
|
-
</div>
|
|
1286
|
-
<div class="col">
|
|
1287
|
-
<div class="input-field groups">
|
|
1288
|
-
<select id="d_groups_ep3" class="materialSelect" multiple>
|
|
1289
|
-
<option value="1">select</option>
|
|
1290
|
-
</select>
|
|
1291
|
-
<label for="d_groups_ep3" class="translate">Groups</label>
|
|
1292
|
-
</div>
|
|
1293
|
-
</div>
|
|
1294
|
-
</div>
|
|
1295
|
-
<div class="row epid4">
|
|
1296
|
-
<div class="col epid">
|
|
1297
|
-
<div class=endpointid>
|
|
1298
|
-
<p class="translate device_with_endpoint">Sub Endpoint 4</p>
|
|
1299
|
-
</div>
|
|
1300
|
-
</div>
|
|
1301
|
-
<div class="col">
|
|
1302
|
-
<div class="input-field groups">
|
|
1303
|
-
<select id="d_groups_ep4" class="materialSelect" multiple>
|
|
1304
|
-
<option value="1">select</option>
|
|
1305
|
-
</select>
|
|
1306
|
-
<label for="d_groups_ep4" class="translate">Groups</label>
|
|
1307
|
-
</div>
|
|
1308
|
-
</div>
|
|
1233
|
+
<div class="groups_available">
|
|
1234
|
+
<div class="row">
|
|
1235
|
+
<h6>Groups</h6>
|
|
1309
1236
|
</div>
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1237
|
+
<div class="row epid0">
|
|
1238
|
+
<div class="col">
|
|
1239
|
+
<div class=endpointid>
|
|
1240
|
+
<p class="translate device_with_endpoint">Main Endpoint</p>
|
|
1241
|
+
</div>
|
|
1242
|
+
</div>
|
|
1243
|
+
<div class="col1">
|
|
1244
|
+
<div class="input-field groups">
|
|
1245
|
+
<select id="d_groups_ep0" class="materialSelect" multiple>
|
|
1246
|
+
<option value="1">select</option>
|
|
1247
|
+
</select>
|
|
1248
|
+
<label for="d_groups_ep0" class="translate">Groups</label>
|
|
1249
|
+
</div>
|
|
1250
|
+
</div>
|
|
1251
|
+
</div>
|
|
1252
|
+
<div class="row epid1">
|
|
1253
|
+
<div class="col epid">
|
|
1254
|
+
<div class=endpointid>
|
|
1255
|
+
<p class="translate device_with_endpoint">Sub Endpoint 1</p>
|
|
1256
|
+
</div>
|
|
1257
|
+
</div>
|
|
1258
|
+
<div class="col">
|
|
1259
|
+
<div class="input-field groups">
|
|
1260
|
+
<select id="d_groups_ep1" class="materialSelect" multiple>
|
|
1261
|
+
<option value="1">select</option>
|
|
1262
|
+
</select>
|
|
1263
|
+
<label for="d_groups_ep1" class="translate">Groups</label>
|
|
1264
|
+
</div>
|
|
1265
|
+
</div>
|
|
1266
|
+
</div>
|
|
1267
|
+
<div class="row epid2">
|
|
1268
|
+
<div class="col epid">
|
|
1269
|
+
<div class=endpointid>
|
|
1270
|
+
<p class="translate device_with_endpoint">Sub Endpoint 2</p>
|
|
1271
|
+
</div>
|
|
1272
|
+
</div>
|
|
1273
|
+
<div class="col">
|
|
1274
|
+
<div class="input-field groups">
|
|
1275
|
+
<select id="d_groups_ep2" class="materialSelect" multiple>
|
|
1276
|
+
<option value="1">select</option>
|
|
1277
|
+
</select>
|
|
1278
|
+
<label for="d_groups_ep2" class="translate">Groups</label>
|
|
1279
|
+
</div>
|
|
1280
|
+
</div>
|
|
1281
|
+
</div>
|
|
1282
|
+
<div class="row epid3">
|
|
1283
|
+
<div class="col epid">
|
|
1284
|
+
<div class=endpointid>
|
|
1285
|
+
<p class="translate device_with_endpoint">Sub Endpoint 3</p>
|
|
1286
|
+
</div>
|
|
1287
|
+
</div>
|
|
1288
|
+
<div class="col">
|
|
1289
|
+
<div class="input-field groups">
|
|
1290
|
+
<select id="d_groups_ep3" class="materialSelect" multiple>
|
|
1291
|
+
<option value="1">select</option>
|
|
1292
|
+
</select>
|
|
1293
|
+
<label for="d_groups_ep3" class="translate">Groups</label>
|
|
1294
|
+
</div>
|
|
1295
|
+
</div>
|
|
1296
|
+
</div>
|
|
1297
|
+
<div class="row epid4">
|
|
1298
|
+
<div class="col epid">
|
|
1299
|
+
<div class=endpointid>
|
|
1300
|
+
<p class="translate device_with_endpoint">Sub Endpoint 4</p>
|
|
1301
|
+
</div>
|
|
1302
|
+
</div>
|
|
1303
|
+
<div class="col">
|
|
1304
|
+
<div class="input-field groups">
|
|
1305
|
+
<select id="d_groups_ep4" class="materialSelect" multiple>
|
|
1306
|
+
<option value="1">select</option>
|
|
1307
|
+
</select>
|
|
1308
|
+
<label for="d_groups_ep4" class="translate">Groups</label>
|
|
1309
|
+
</div>
|
|
1310
|
+
</div>
|
|
1311
|
+
</div>
|
|
1312
|
+
<div class="row epid5">
|
|
1313
|
+
<div class="col epid">
|
|
1314
|
+
<div class=endpointid>
|
|
1315
|
+
<p class="translate device_with_endpoint">Sub Endpoint 5</p>
|
|
1316
|
+
</div>
|
|
1317
|
+
</div>
|
|
1318
|
+
<div class="col">
|
|
1319
|
+
<div class="input-field groups">
|
|
1320
|
+
<select id="d_groups_ep5" class="materialSelect" multiple>
|
|
1321
|
+
<option value="1">select</option>
|
|
1322
|
+
</select>
|
|
1323
|
+
<label for="d_groups_ep5" class="translate">Groups</label>
|
|
1324
|
+
</div>
|
|
1325
|
+
</div>
|
|
1326
|
+
</div>
|
|
1327
|
+
<div class="row epid6">
|
|
1328
|
+
<div class="col epid">
|
|
1329
|
+
<div class=endpointid>
|
|
1330
|
+
<p class="translate device_with_endpoint">Sub Endpoint 6</p>
|
|
1331
|
+
</div>
|
|
1332
|
+
</div>
|
|
1333
|
+
<div class="col">
|
|
1334
|
+
<div class="input-field groups">
|
|
1335
|
+
<select id="d_groups_ep6" class="materialSelect" multiple>
|
|
1336
|
+
<option value="1">select</option>
|
|
1337
|
+
</select>
|
|
1338
|
+
<label for="d_groups_ep6" class="translate">Groups</label>
|
|
1339
|
+
</div>
|
|
1340
|
+
</div>
|
|
1341
|
+
</div>
|
|
1324
1342
|
</div>
|
|
1325
|
-
<div class="
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
<div class="input-field groups">
|
|
1333
|
-
<select id="d_groups_ep6" class="materialSelect" multiple>
|
|
1334
|
-
<option value="1">select</option>
|
|
1335
|
-
</select>
|
|
1336
|
-
<label for="d_groups_ep6" class="translate">Groups</label>
|
|
1337
|
-
</div>
|
|
1338
|
-
</div>
|
|
1343
|
+
<div class="options_available">
|
|
1344
|
+
<div class="row">
|
|
1345
|
+
<h6>Options</h6>
|
|
1346
|
+
</div>
|
|
1347
|
+
<div class="row options">
|
|
1348
|
+
|
|
1349
|
+
</div>
|
|
1339
1350
|
</div>
|
|
1340
1351
|
</div>
|
|
1341
1352
|
<div class="modal-footer">
|
|
1342
|
-
<a name="
|
|
1343
|
-
|
|
1353
|
+
<a name="remove_options" class="waves-effect waves-green btn green translate"><i class="material-icons large">remove_circle</i></a>
|
|
1354
|
+
<a name="add_options" class="waves-effect waves-green btn green translate"><i class="material-icons large">add_circle</i></a>
|
|
1355
|
+
<a name="save" href="#!" class="modal-action modal-close waves-effect waves-green btn green translate">Save</a>
|
|
1344
1356
|
<a href="#!" class="modal-action modal-close waves-effect waves-red btn-flat translate">Cancel</a>
|
|
1345
1357
|
</div>
|
|
1346
1358
|
</div>
|