iobroker.zigbee 1.6.8 → 1.6.12

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 CHANGED
@@ -112,10 +112,20 @@ You can thank the authors by these links:
112
112
 
113
113
  ## Changelog
114
114
 
115
+ ### 1.6.12 (2022-01)
116
+ * (asgothian) Groups were newly revised (read here https://github.com/ioBroker/ioBroker.zigbee/pull/1327)
117
+
118
+
119
+ ### 1.6.9 (2021-12)
120
+ * (simatec) fix admin Dark-Mode
121
+ * (asgothian) Expose Access Handling
122
+ * (arteck) translations
123
+ * (asgothian) fix groups
124
+ * (agross) use different normalization rules
125
+
115
126
  ### 1.6.1 (2021-08)
116
127
  * (kirovilya) herdsman compatibility
117
128
 
118
-
119
129
  ### 1.6.0 (2021-08-09)
120
130
  ## Attention! Attention! Attention! Attention! Attention! Attention! Attention!
121
131
 
package/admin/admin.js CHANGED
@@ -146,7 +146,7 @@ function getGroupCard(dev) {
146
146
  info = info.concat(`<li><span class="labelinfo">No devices in group</span></li>`);
147
147
  } else {
148
148
  for (let m=0;m < dev.memberinfo.length; m++) {
149
- info = info.concat(`<li><span class="labelinfo">${dev.memberinfo[m].name}</span><span> ...${dev.memberinfo[m].ieee.slice(-4)}</span></li>`);
149
+ info = info.concat(`<li><span align:"left">${dev.memberinfo[m].device}.${dev.memberinfo[m].epid}</span><span align:"right"> ...${dev.memberinfo[m].ieee.slice(-4)}</span></li>`);
150
150
  }
151
151
  memberCount = (dev.memberinfo.length<8?dev.memberinfo.length:7);
152
152
  };
@@ -258,6 +258,9 @@ function getCard(dev) {
258
258
  <button name="edit" class="right btn-flat btn-small">
259
259
  <i class="material-icons icon-green">edit</i>
260
260
  </button>
261
+ <button name="reconfigure" class="right btn-flat btn-small tooltipped" title="Reconfigure">
262
+ <i class="material-icons icon-red">sync</i>
263
+ </button>
261
264
  ${permitJoinBtn}
262
265
  </div>
263
266
  </div>
@@ -348,25 +351,96 @@ function cleanConfirmation() {
348
351
  Materialize.updateTextFields();
349
352
  }
350
353
 
354
+ function EndPointIDfromEndPoint(ep)
355
+ {
356
+ if (ep && ep.deviceIeeeAddress && ep.ID)
357
+ return `${ep.deviceIeeeAddress}:${ep.ID}`;
358
+ return 'unidentified';
359
+ }
360
+
351
361
  function editName(id, name) {
362
+ console.log('editName called with '+name);
352
363
  const dev = devices.find((d) => d._id == id);
353
364
  $('#modaledit').find("input[id='d_name']").val(name);
354
- if (dev.info && dev.info.device._type == 'Router') {
355
- list2select('#d_groups', groups, devGroups[id] || []);
356
- $('#modaledit').find('.input-field.groups').removeClass('hide');
357
- } else {
358
- $('#modaledit').find('.input-field.groups').addClass('hide');
359
- }
365
+ // if (dev.info && dev.info.device._type == 'Router') {
366
+ const groupables = [];
367
+ if (dev && dev.info && dev.info.endpoints) {
368
+ for (const ep of dev.info.endpoints) {
369
+ if (ep.inputClusters.includes(4)) {
370
+ groupables.push({ epid:EndPointIDfromEndPoint(ep), ep:ep, memberOf:[]});
371
+ }
372
+ }
373
+ }
374
+ const numEP = groupables.length;
375
+ // console.log('groupables: '+JSON.stringify(groupables));
376
+ $('#modaledit').find('.row.epid0').addClass('hide');
377
+ $('#modaledit').find('.row.epid1').addClass('hide');
378
+ $('#modaledit').find('.row.epid2').addClass('hide');
379
+ $('#modaledit').find('.row.epid3').addClass('hide');
380
+ if (numEP > 0) {
381
+ // go through all the groups. Find the ones to list for each groupable
382
+ if (numEP == 1) {
383
+ $('#modaledit').find('.endpointid').addClass('hide');
384
+ }
385
+ else {
386
+ $('#modaledit').find('.endpointid').removeClass('hide');
387
+ }
388
+ for (const d of devices) {
389
+ if (d && d.common && d.common.type == 'group') {
390
+ if (d.hasOwnProperty("memberinfo")) {
391
+ for (const member of d.memberinfo) {
392
+ const epid = EndPointIDfromEndPoint(member.ep)
393
+ for (var i=0;i<groupables.length;i++) {
394
+ if (groupables[i].epid == epid) {
395
+ groupables[i].memberOf.push(d.native.id.replace('group_', ''));
396
+ }
397
+ }
398
+ }
399
+ }
400
+ }
401
+ }
402
+ console.log("groupables: " + JSON.stringify(groupables));
403
+ for (var i = 0;i<groupables.length;i++)
404
+ {
405
+ if (i > 1) {
406
+ $('#modaledit').find("translate.device_with_endpoint").innerHtml = name + ' ' + groupables[i].epid;
407
+ }
408
+ $('#modaledit').find('.row.epid'+i).removeClass('hide');
409
+ list2select('#d_groups_ep'+i, groups, groupables[i].memberOf || []);
410
+ }
411
+ }
412
+ // } else {
413
+ // $('#modaledit').find('.input-field.endpoints').addClass('hide');
414
+ // $('#modaledit').find('.input-field.groups').addClass('hide');
415
+ // }
360
416
  $("#modaledit a.btn[name='save']").unbind('click');
361
417
  $("#modaledit a.btn[name='save']").click(() => {
362
- const newName = $('#modaledit').find("input[id='d_name']").val(),
363
- newGroups = $('#d_groups').val();
364
- updateDev(id, newName, newGroups);
418
+ const newName = $('#modaledit').find("input[id='d_name']").val();
419
+ const groupsbyid = {};
420
+ if (groupables.length > 0) {
421
+ for (var i = 0;i<groupables.length;i++) {
422
+ const ng = $('#d_groups_ep'+i).val();
423
+ if (ng.toString() != groupables[i].memberOf.toString())
424
+ groupsbyid[groupables[i].ep.ID] = GenerateGroupChange(groupables[i].memberOf, ng);
425
+ }
426
+ }
427
+ console.log('grpid ' + JSON.stringify(groupsbyid));
428
+ updateDev(id, newName, groupsbyid);
365
429
  });
366
430
  $('#modaledit').modal('open');
367
431
  Materialize.updateTextFields();
368
432
  }
369
433
 
434
+ function GenerateGroupChange(oldmembers, newmembers)
435
+ {
436
+ let grpchng = [];
437
+ for (const oldg of oldmembers)
438
+ if (!newmembers.includes(oldg)) grpchng.push('-'+oldg);
439
+ for (const newg of newmembers)
440
+ if (!oldmembers.includes(newg)) grpchng.push(newg)
441
+ return grpchng;
442
+ }
443
+
370
444
  function deleteDevice(id, force) {
371
445
  sendTo(namespace, 'deleteDevice', {id: id, force: force}, function (msg) {
372
446
  closeWaitingDialog();
@@ -529,7 +603,7 @@ function showDevices() {
529
603
  const dev_block = $(this).parents('div.device'),
530
604
  id = dev_block.attr('id').replace(namespace+'.group_', ''),
531
605
  name = getDevName(dev_block);
532
- editGroupName(id, name);
606
+ editGroupName(id, name, false);
533
607
  });
534
608
  $("button.btn-floating[name='join']").click(function() {
535
609
  const dev_block = $(this).parents('div.device');
@@ -548,6 +622,10 @@ function showDevices() {
548
622
  $("a.btn-flat[name='close']").click((e) => {
549
623
  closeReval(e);
550
624
  });
625
+ $(".card-reveal-buttons button[name='reconfigure']").click(function() {
626
+ const dev_block = $(this).parents('div.device');
627
+ reconfigureDlg(getDevId(dev_block));
628
+ });
551
629
 
552
630
  showNetworkMap(devices, map);
553
631
  translateAll();
@@ -763,11 +841,11 @@ function load(settings, onChange) {
763
841
 
764
842
  $('#add_group').click(function() {
765
843
  const maxind = parseInt(Object.getOwnPropertyNames(groups).reduce((a,b) => a>b ? a : b, 0));
766
- editGroupName(maxind+1, '');
844
+ editGroupName(maxind+1, 'Group ' + maxind+1, true);
767
845
  });
768
846
  $('#add_grp_btn').click(function() {
769
847
  const maxind = parseInt(Object.getOwnPropertyNames(groups).reduce((a,b) => a>b ? a : b, 0));
770
- editGroupName(maxind+1, '');
848
+ editGroupName(maxind+1, 'Group ' + maxind+1, true);
771
849
  getDevices();
772
850
  });
773
851
 
@@ -1706,7 +1784,7 @@ function showGroups() {
1706
1784
  $("a.btn-floating[name='groupedit']").click(function() {
1707
1785
  const index = $(this).attr('id'),
1708
1786
  name = groups[index];
1709
- editGroupName(index, name);
1787
+ editGroupName(index, name, false);
1710
1788
  });
1711
1789
  $("a.btn-floating[name='groupdelete']").click(function() {
1712
1790
  const index = $(this).attr('id'),
@@ -1715,8 +1793,35 @@ function showGroups() {
1715
1793
  });
1716
1794
  }
1717
1795
 
1718
- function editGroupName(id, name) {
1796
+ function editGroupName(id, name, isnew) {
1797
+ //const dev = devices.find((d) => d._id == id);
1798
+ //console.log('devices: '+ JSON.stringify(devices));
1799
+ const groupables = [];
1800
+ for (const d of devices) {
1801
+ if (d && d.info && d.info.endpoints) {
1802
+ for (const ep of d.info.endpoints) {
1803
+ if (ep.inputClusters.includes(4))
1804
+ {
1805
+ groupables.push(ep);
1806
+ }
1807
+ }
1808
+ }
1809
+ //console.log('device ' + JSON.stringify(d));
1810
+ }
1811
+
1719
1812
  //var text = 'Enter new name for "'+name+'" ('+id+')?';
1813
+ if (isnew) {
1814
+ $('#groupedit').find('.editgroup').addClass('hide');
1815
+ $('#groupedit').find('.addgroup').removeClass('hide');
1816
+ $('#groupedit').find('.input-field.members').addClass('hide');
1817
+ $('#groupedit').find('.input-field.groupid').removeClass('hide');
1818
+ }
1819
+ else {
1820
+ $('#groupedit').find('.editgroup').removeClass('hide');
1821
+ $('#groupedit').find('.addgroup').addClass('hide');
1822
+ $('#groupedit').find('.input-field.members').removeClass('hide');
1823
+ $('#groupedit').find('.input-field.groupid').addClass('hide');
1824
+ }
1720
1825
  $('#groupedit').find("input[id='g_index']").val(id);
1721
1826
  $('#groupedit').find("input[id='g_name']").val(name);
1722
1827
  $("#groupedit a.btn[name='save']").unbind('click');
@@ -1760,6 +1865,21 @@ function updateDev(id, newName, newGroups) {
1760
1865
  if (dev && dev.common.name != newName) {
1761
1866
  renameDevice(id, newName);
1762
1867
  }
1868
+ const keys = Object.keys(newGroups)
1869
+ if (keys && keys.length)
1870
+ {
1871
+ sendTo(namespace, 'updateGroupMembership', { id: id, groups: newGroups }, function (msg) {
1872
+ if (msg && msg.error) {
1873
+ showMessage(msg.error, _('Error'));
1874
+ }
1875
+ else {
1876
+ // save dev-groups on success
1877
+ dev.groups = newGroups;
1878
+ }
1879
+ showDevices();
1880
+ });
1881
+ }
1882
+ /*
1763
1883
  if (dev.info.device._type == 'Router') {
1764
1884
  const oldGroups = devGroups[id] || [];
1765
1885
  if (oldGroups.toString() != newGroups.toString()) {
@@ -1776,6 +1896,7 @@ function updateDev(id, newName, newGroups) {
1776
1896
  });
1777
1897
  }
1778
1898
  }
1899
+ */
1779
1900
  }
1780
1901
 
1781
1902
  function resetConfirmation() {
@@ -2170,7 +2291,7 @@ function genDevInfo(device) {
2170
2291
  const dev = (device && device.info) ? device.info.device : undefined;
2171
2292
  const mapped = (device && device.info) ? device.info.mapped : undefined;
2172
2293
  if (!dev) return `<div class="truncate">No info</div>`;
2173
- const genRow = function(name, value) {
2294
+ const genRow = function(name, value, refresh) {
2174
2295
  if (value === undefined) {
2175
2296
  return '';
2176
2297
  } else {
@@ -2234,7 +2355,7 @@ function genDevInfo(device) {
2234
2355
  ${genRow('date code', dev._dateCode)}
2235
2356
  ${genRow('build', dev._softwareBuildID)}
2236
2357
  ${genRow('interviewed', dev._interviewCompleted)}
2237
- ${genRow('configured', (dev.meta.configured === 1))}
2358
+ ${genRow('configured', (dev.meta.configured === 1), true)}
2238
2359
  </ul>
2239
2360
  </div>
2240
2361
  </div>
@@ -2250,17 +2371,19 @@ function showDevInfo(id){
2250
2371
  $('#modaldevinfo').modal('open');
2251
2372
  }
2252
2373
 
2374
+ let waitingTimeout, waitingInt;
2253
2375
 
2254
2376
  function showWaitingDialog(text, timeout){
2255
2377
  let countDown = timeout;
2256
- const waitingInt = setInterval(function() {
2378
+ waitingInt = setInterval(function() {
2257
2379
  countDown -= 1;
2258
2380
  const percent = 100-100*countDown/timeout;
2259
2381
  $('#waiting_progress_line').css('width', `${percent}%`);
2260
2382
  }, 1000);
2261
- setTimeout(function() {
2383
+ waitingTimeout = setTimeout(function() {
2262
2384
  $('#waiting_progress_line').css('width', `0%`);
2263
2385
  clearTimeout(waitingInt);
2386
+ clearTimeout(waitingTimeout);
2264
2387
  $('#modalWaiting').modal('close');
2265
2388
  }, timeout*1000);
2266
2389
  $('#waiting_message').text(text);
@@ -2268,6 +2391,8 @@ function showWaitingDialog(text, timeout){
2268
2391
  }
2269
2392
 
2270
2393
  function closeWaitingDialog(){
2394
+ if (waitingInt) clearTimeout(waitingInt);
2395
+ if (waitingTimeout) clearTimeout(waitingTimeout);
2271
2396
  $('#modalWaiting').modal('close');
2272
2397
  }
2273
2398
 
@@ -2702,3 +2827,26 @@ function removeDevice(id) {
2702
2827
  }
2703
2828
  }
2704
2829
  }
2830
+
2831
+ function reconfigureDlg(id) {
2832
+ const text = translateWord(`Do you really want to reconfigure device?`);
2833
+ $('#modalreconfigure').find('p').text(text);
2834
+ $("#modalreconfigure a.btn[name='yes']").unbind('click');
2835
+ $("#modalreconfigure a.btn[name='yes']").click(() => {
2836
+ reconfigureDevice(id, force);
2837
+ });
2838
+ $('#modalreconfigure').modal('open');
2839
+ Materialize.updateTextFields();
2840
+ }
2841
+
2842
+ function reconfigureDevice(id) {
2843
+ sendTo(namespace, 'reconfigure', {id: id}, function (msg) {
2844
+ closeWaitingDialog();
2845
+ if (msg) {
2846
+ if (msg.error) {
2847
+ showMessage(msg.error, _('Error'));
2848
+ }
2849
+ }
2850
+ });
2851
+ showWaitingDialog('Device is being reconfigure', 30);
2852
+ }
Binary file
Binary file
Binary file
Binary file
@@ -370,7 +370,7 @@
370
370
  </div>
371
371
  <ul id="nav-mobile" class="right">
372
372
  <li>
373
- <a id="state_cleanup_btn" class="btn-floating waves-effect waves-light blue tooltipped center-align hoverable translateT" title="State Cleanup">
373
+ <a id="state_cleanup_btn" class="btn-floating waves-effect waves-light red tooltipped center-align hoverable translateT" title="State Cleanup">
374
374
  <i class="material-icons large icon-blue">sync</i></a>
375
375
  </li>
376
376
  <li>
@@ -378,7 +378,7 @@
378
378
  <i class="material-icons large icon-blue">system_update</i></a>
379
379
  </li>
380
380
  <li>
381
- <a id="add_grp_btn" class="btn-floating waves-effect waves-light green tooltipped center-align hoverable translateT" title="Add Group">
381
+ <a id="add_grp_btn" class="btn-floating waves-effect waves-light brown tooltipped center-align hoverable translateT" title="Add Group">
382
382
  <i class="material-icons large">group_work</i></a>
383
383
  </li>
384
384
  <li>
@@ -420,7 +420,7 @@
420
420
  <input id="device-search" class="filter-input translateP" placeholder="Искать" autocomplete="new-password" readonly="readonly" onfocus="if (this.hasAttribute('readonly')) {this.removeAttribute('readonly'); this.blur(); this.focus();}" data-lang-placeholder="Filter">
421
421
  <a class="filter-clear btn-floating btn-very-small translateT red lighten-3" title="Очистить" data-lang-title="clear" style="display: none;"><i class="material-icons">clear</i></a>
422
422
  </div>
423
-
423
+
424
424
  </li>
425
425
  <li>
426
426
  <div class="col input-field" style="line-height: 24px;">
@@ -547,6 +547,7 @@
547
547
  <option value="-22">low</option>
548
548
  <option value="0">norm</option>
549
549
  <option value="19">high</option>
550
+ <option value="20">high+</option>
550
551
  </select>
551
552
  <label class="translate" for="transmitPower">transmitPower</label>
552
553
  </div>
@@ -579,7 +580,7 @@
579
580
  </div>
580
581
  <div class="input-field col s12 m12 l12 col-disableLed">
581
582
  <input id="startWithInconsistent" type="checkbox" class="value" />
582
- <label class="translate" for="startWithInconsistent">Force start adapter with inconsistent configuration (not recommended). Please update the adapter to compatible firmware and recreate your network as soon as possible.</label>
583
+ <label class="translate" for="startWithInconsistent">SettingsExclude</label>
583
584
  </div>
584
585
  </div>
585
586
 
@@ -810,17 +811,67 @@
810
811
  <div class="materialize-dialogs m">
811
812
  <div id="modaledit" class="modal">
812
813
  <div class="modal-content">
813
- <!-- <h3 class="translate">Config device</h3> -->
814
- <div class="row">
815
- <div class="input-field">
816
- <input id="d_name" type="text" class="value validate">
817
- <label for="d_name" class="translate">Name</label>
818
- </div>
819
- <div class="input-field groups">
820
- <select id="d_groups" class="materialSelect" multiple><option value="1">Значение</option></select>
821
- <label for="d_groups" class="translate">Groups</label>
822
- </div>
814
+ <h3 class="translate">Config device</h3>
815
+ <div class="row">
816
+ <div class="col">
817
+ <div class="input-field">
818
+ <input id="d_name" type="text" class="value validate">
819
+ <label for="d_name" class="translate">Name</label>
820
+ </div>
821
+ </div>
822
+ </div>
823
+ <div class="row epid0">
824
+ <div class="col">
825
+ <div class=endpointid>
826
+ <p class="translate device_with_endpoint">Main Endpoint</p>
827
+ </div>
828
+ </div>
829
+ <div class="col">
830
+ <div class="input-field groups">
831
+ <select id="d_groups_ep0" class="materialSelect" multiple><option value="1">Значение</option></select>
832
+ <label for="d_groups_ep0" class="translate">Groups</label>
833
+ </div>
834
+ </div>
835
+ </div>
836
+ <div class="row epid1">
837
+ <div class="col epid">
838
+ <div class=endpointid>
839
+ <p class="translate device_with_endpoint">Sub Endpoint 1</p>
840
+ </div>
823
841
  </div>
842
+ <div class="col">
843
+ <div class="input-field groups">
844
+ <select id="d_groups_ep1" class="materialSelect" multiple><option value="1">Значение</option></select>
845
+ <label for="d_groups_ep1" class="translate">Groups</label>
846
+ </div>
847
+ </div>
848
+ </div>
849
+ <div class="row epid2">
850
+ <div class="col epid">
851
+ <div class=endpointid>
852
+ <p class="translate device_with_endpoint">Sub Endpoint 2</p>
853
+ </div>
854
+ </div>
855
+ <div class="col">
856
+ <div class="input-field groups">
857
+ <select id="d_groups_ep2" class="materialSelect" multiple><option value="1">Значение</option></select>
858
+ <label for="d_groups_ep2" class="translate">Groups</label>
859
+ </div>
860
+ </div>
861
+ </div>
862
+ <div class="row epid3">
863
+ <div class="col epid">
864
+ <div class=endpointid>
865
+ <p class="translate device_with_endpoint">Sub Endpoint 3</p>
866
+ </div>
867
+ </div>
868
+ <div class="col">
869
+ <div class="input-field groups">
870
+ <select id="d_groups_ep3" class="materialSelect" multiple><option value="1">Значение</option></select>
871
+ <label for="d_groups_ep3" class="translate">Groups</label>
872
+ </div>
873
+ </div>
874
+ </div>
824
875
  </div>
825
876
  <div class="modal-footer">
826
877
  <a name="save" href="#!" class="modal-action modal-close waves-effect waves-green btn green translate">Save</a>
@@ -830,19 +881,32 @@
830
881
 
831
882
  <div id="groupedit" class="modal">
832
883
  <div class="modal-content">
833
- <h3 class="translate">Add/Edit Group</h3>
884
+ <div class = "addgroup">
885
+ <h3 class="translate">Add Group</h3>
886
+ </div>
887
+ <div class = "editgroup">
888
+ <h3 class="translate">Edit Group</h3>
889
+ </div>
834
890
  <div class="row">
835
- <div class="input-field col s12 m4 l2">
891
+ <div class="col s4 m4 l2">
892
+ <div class="input-field groupid">
836
893
  <input id="g_index" type="number" min="1" class="value validate">
837
894
  <label for="g_index" class="translate">№</label>
895
+ </div>
838
896
  </div>
839
- </div>
840
- <div class="row">
841
- <div class="input-field col s12">
897
+ <div class="input-field col s8 m8 l10">
842
898
  <input id="g_name" type="text" class="value validate">
843
899
  <label for="g_name" class="translate">Name</label>
844
900
  </div>
845
901
  </div>
902
+ <div class="row hide">
903
+ <div class="col s12">
904
+ <div class="input-field members">
905
+ <label for="g_members" class="translate">Members</label>
906
+ <select id="g_members" class="materialSelect" multiple><option value="1">Значение</option></select>
907
+ </div>
908
+ </div>
909
+ </div>
846
910
  </div>
847
911
  <div class="modal-footer">
848
912
  <a name="save" href="#!" class="modal-action modal-close waves-effect waves-green btn green translate">Save</a>
@@ -878,6 +942,16 @@
878
942
  <a href="#!" class="modal-action modal-close waves-effect waves-red btn-flat translate">Cancel</a>
879
943
  </div>
880
944
  </div>
945
+ <div id="modalreconfigure" class="modal">
946
+ <div class="modal-content">
947
+ <h3 class="translate">Reconfigure device</h3>
948
+ <p>A bunch of text</p>
949
+ </div>
950
+ <div class="modal-footer">
951
+ <a name="yes" href="#!" class="modal-action modal-close waves-effect waves-green btn green translate">Yes</a>
952
+ <a href="#!" class="modal-action modal-close waves-effect waves-red btn-flat translate">Cancel</a>
953
+ </div>
954
+ </div>
881
955
 
882
956
  <div id="modalpairing" class="modal modal-fixed-footer">
883
957
  <div class="modal-content">