iobroker.zigbee 2.0.4 → 3.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.
- package/README.md +90 -57
- package/admin/admin.js +497 -120
- package/admin/img/philips_hue_lom001.png +0 -0
- package/admin/index_m.html +168 -124
- package/admin/tab_m.html +20 -11
- package/docs/de/img/Bild30.png +0 -0
- package/docs/de/img/Bild38.png +0 -0
- package/docs/de/img/Info.png +0 -0
- package/docs/de/img/Zigbee_config_de.jpg +0 -0
- package/docs/de/img/battery.png +0 -0
- package/docs/de/img/debug.png +0 -0
- package/docs/de/img/delete.png +0 -0
- package/docs/de/img/disconnected.png +0 -0
- package/docs/de/img/edit_grp.png +0 -0
- package/docs/de/img/edit_image.png +0 -0
- package/docs/de/img/grp_nok.png +0 -0
- package/docs/de/img/grp_ok.png +0 -0
- package/docs/de/img/on_off.png +0 -0
- package/docs/de/img/reconfigure.png +0 -0
- package/docs/de/readme.md +52 -43
- package/docs/en/img/Zigbee_config_en.png +0 -0
- package/docs/en/img/Zigbee_pairing_en.png +0 -0
- package/docs/en/readme.md +71 -66
- package/docs/tutorial/groups-1.png +0 -0
- package/docs/tutorial/groups-2.png +0 -0
- package/docs/tutorial/tab-dev-1.png +0 -0
- package/io-package.json +31 -65
- package/lib/DeviceDebug.js +5 -2
- package/lib/commands.js +182 -31
- package/lib/developer.js +0 -0
- package/lib/devices.js +2 -2
- package/lib/exposes.js +10 -27
- package/lib/groups.js +6 -8
- package/lib/localConfig.js +4 -5
- package/lib/ota.js +6 -6
- package/lib/seriallist.js +9 -2
- package/lib/statescontroller.js +397 -128
- package/lib/utils.js +41 -11
- package/lib/zbDeviceAvailability.js +2 -2
- package/lib/zbDeviceConfigure.js +99 -58
- package/lib/zigbeecontroller.js +152 -128
- package/main.js +251 -264
- package/package.json +10 -10
- package/docs/en/img/Bild23.png +0 -0
- package/docs/en/img/Bild25.png +0 -0
- package/docs/en/img/Bild26.png +0 -0
- package/docs/en/img/Bild4.png +0 -0
- package/docs/en/img/Bild9.png +0 -0
package/admin/admin.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
/*global $, M, _, sendTo, systemLang, translateWord, translateAll, showMessage, socket, document, instance, vis, Option*/
|
|
2
|
-
|
|
3
2
|
/*
|
|
4
3
|
* you must run 'iobroker upload zigbee' if you edited this file to make changes visible
|
|
5
4
|
*/
|
|
@@ -31,7 +30,13 @@ let devices = [],
|
|
|
31
30
|
},
|
|
32
31
|
cidList,
|
|
33
32
|
shuffleInstance,
|
|
34
|
-
errorData = []
|
|
33
|
+
errorData = [],
|
|
34
|
+
debugMessages = {},
|
|
35
|
+
debugInLog = true,
|
|
36
|
+
nvRamBackup = {},
|
|
37
|
+
isHerdsmanRunning = false;
|
|
38
|
+
const dbgMsgfilter = new Set();
|
|
39
|
+
const dbgMsghide = new Set();
|
|
35
40
|
const updateCardInterval = setInterval(updateCardTimer, 6000);
|
|
36
41
|
|
|
37
42
|
const networkOptions = {
|
|
@@ -52,11 +57,12 @@ const networkOptions = {
|
|
|
52
57
|
|
|
53
58
|
const savedSettings = [
|
|
54
59
|
'port', 'panID', 'channel', 'disableLed', 'countDown', 'groups', 'extPanID', 'precfgkey', 'transmitPower',
|
|
55
|
-
'adapterType', 'debugHerdsman', 'disableBackup', 'disablePing', 'external', 'startWithInconsistent',
|
|
60
|
+
'adapterType', 'debugHerdsman', 'disableBackup', 'disablePing', 'external', 'startWithInconsistent',
|
|
61
|
+
'warnOnDeviceAnnouncement', 'baudRate', 'flowCTRL', 'autostart'
|
|
56
62
|
];
|
|
57
63
|
|
|
58
64
|
function getDeviceByID(ID) {
|
|
59
|
-
return devices.find((devInfo) => {
|
|
65
|
+
if (devices) return devices.find((devInfo) => {
|
|
60
66
|
try {
|
|
61
67
|
return devInfo._id == ID;
|
|
62
68
|
} catch (e) {
|
|
@@ -240,7 +246,6 @@ function getCard(dev) {
|
|
|
240
246
|
rooms.push(dev.rooms[r]);
|
|
241
247
|
}
|
|
242
248
|
}
|
|
243
|
-
console.warn('debug for ' + ieee + ' is ' + isDebug);
|
|
244
249
|
const room = rooms.join(',') || ' ';
|
|
245
250
|
const paired = (dev.paired) ? '' : '<i class="material-icons right">leak_remove</i>';
|
|
246
251
|
const rid = id.split('.').join('_');
|
|
@@ -378,6 +383,31 @@ function deleteConfirmation(id, name) {
|
|
|
378
383
|
Materialize.updateTextFields();
|
|
379
384
|
}
|
|
380
385
|
|
|
386
|
+
function deleteNvBackupConfirmation() {
|
|
387
|
+
const text = translateWord('Do you really want to the NV Backup data ?');
|
|
388
|
+
$('#modaldelete').find('p').text(text);
|
|
389
|
+
$('#force').prop('checked', false);
|
|
390
|
+
$('#forcediv').addClass('hide');
|
|
391
|
+
$('#modaldelete a.btn[name=\'yes\']').unbind('click');
|
|
392
|
+
$('#modaldelete a.btn[name=\'yes\']').click(() => {
|
|
393
|
+
//const force = $('#force').prop('checked');
|
|
394
|
+
showWaitingDialog('Attempting to delete nvBackup.json', 60000);
|
|
395
|
+
sendTo(namespace, 'deleteNVBackup', {}, function (msg) {
|
|
396
|
+
closeWaitingDialog();
|
|
397
|
+
if (msg) {
|
|
398
|
+
if (msg.error) {
|
|
399
|
+
showMessage(msg.error, _('Error'));
|
|
400
|
+
} else {
|
|
401
|
+
getDevices();
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
});
|
|
406
|
+
$('#modaldelete').modal('open');
|
|
407
|
+
Materialize.updateTextFields();
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
|
|
381
411
|
function cleanConfirmation() {
|
|
382
412
|
const text = translateWord('Do you really want to remove orphaned states?');
|
|
383
413
|
$('#modalclean').find('p').text(text);
|
|
@@ -400,7 +430,7 @@ function EndPointIDfromEndPoint(ep) {
|
|
|
400
430
|
}
|
|
401
431
|
|
|
402
432
|
function editName(id, name) {
|
|
403
|
-
console.
|
|
433
|
+
console.warn('editName called with ' + id + ' and ' + name);
|
|
404
434
|
const dev = devices.find((d) => d._id == id);
|
|
405
435
|
$('#modaledit').find('input[id=\'d_name\']').val(name);
|
|
406
436
|
const groupables = [];
|
|
@@ -780,18 +810,27 @@ function getCoordinatorInfo() {
|
|
|
780
810
|
sendTo(namespace, 'getCoordinatorInfo', {}, function (msg) {
|
|
781
811
|
if (msg) {
|
|
782
812
|
if (msg.error) {
|
|
783
|
-
|
|
813
|
+
errorData.push(msg.error);
|
|
814
|
+
isHerdsmanRunning = false;
|
|
815
|
+
updateStartButton();
|
|
784
816
|
} else {
|
|
785
817
|
coordinatorinfo = msg;
|
|
818
|
+
isHerdsmanRunning = true;
|
|
819
|
+
updateStartButton()
|
|
786
820
|
}
|
|
787
821
|
}
|
|
788
822
|
});
|
|
789
823
|
}
|
|
824
|
+
|
|
790
825
|
function checkDebugDevice(id) {
|
|
791
|
-
|
|
826
|
+
// returns: -1: debug not set
|
|
827
|
+
// 0: debug set explicitly
|
|
828
|
+
// > 0: debug set by pattern.
|
|
829
|
+
if (!debugDevices) return -1;
|
|
830
|
+
if (debugDevices.indexOf(id) > -1) return 0 // debug set
|
|
792
831
|
for (const addressPart of debugDevices) {
|
|
793
832
|
if (typeof id === 'string' && id.includes(addressPart)) {
|
|
794
|
-
return debugDevices.indexOf(addressPart)+1;
|
|
833
|
+
return debugDevices.indexOf(addressPart)+1; // debug set by pattern (>0)
|
|
795
834
|
}
|
|
796
835
|
}
|
|
797
836
|
return -1;
|
|
@@ -830,7 +869,6 @@ async function selectImageOverride(id) {
|
|
|
830
869
|
sendTo(namespace, 'getLocalImages', {}, function(msg) {
|
|
831
870
|
if (msg && msg.imageData) {
|
|
832
871
|
const imagedata = msg.imageData;
|
|
833
|
-
console.warn(JSON.stringify(dev.common));
|
|
834
872
|
const default_icon = (dev.common.type === 'group' ? dev.common.modelIcon : `img/${dev.common.type.replace(/\//g, '-')}.png`);
|
|
835
873
|
if (dev.legacyIcon) imagedata.unshift( { file:dev.legacyIcon, name:'legacy', data:dev.legacyIcon});
|
|
836
874
|
imagedata.unshift( { file:'none', name:'default', data:default_icon});
|
|
@@ -844,10 +882,10 @@ async function selectImageOverride(id) {
|
|
|
844
882
|
return image.file;
|
|
845
883
|
},
|
|
846
884
|
function (key, image) {
|
|
847
|
-
if (image.
|
|
848
|
-
return `data-icon="${image.data}"`;
|
|
849
|
-
} else {
|
|
885
|
+
if (image.isBase64) {
|
|
850
886
|
return `data-icon="data:image/png; base64, ${image.data}"`;
|
|
887
|
+
} else {
|
|
888
|
+
return `data-icon="${image.data}"`;
|
|
851
889
|
}
|
|
852
890
|
},
|
|
853
891
|
);
|
|
@@ -857,7 +895,6 @@ async function selectImageOverride(id) {
|
|
|
857
895
|
const image = $('#chooseimage').find('#images option:selected').val();
|
|
858
896
|
const global = $('#chooseimage').find('#globaloverride').prop('checked');
|
|
859
897
|
const name = $('#chooseimage').find('input[id=\'d_name\']').val();
|
|
860
|
-
console.warn(`update device image : ${id} : ${image} : ${global} : ${name} : ${dev.common.name}`);
|
|
861
898
|
const data = {};
|
|
862
899
|
if (image != 'current') data.icon= image;
|
|
863
900
|
if (name != dev.common.name) data.name = name;
|
|
@@ -869,10 +906,208 @@ async function selectImageOverride(id) {
|
|
|
869
906
|
});
|
|
870
907
|
}
|
|
871
908
|
|
|
909
|
+
|
|
910
|
+
function safestring(val) {
|
|
911
|
+
const t = typeof val;
|
|
912
|
+
if (t==='object') return JSON.stringify(val).replaceAll(',',', ');
|
|
913
|
+
if (t==='string') return val.replaceAll(',',', ');
|
|
914
|
+
if (t==='function') return 'function';
|
|
915
|
+
return val;
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
function fne(item) {
|
|
919
|
+
const rv = [];
|
|
920
|
+
if (item.flags) {
|
|
921
|
+
if (item.flags.includes('SUCCESS')) rv.push('SUCCESS');
|
|
922
|
+
else rv.push(...item.flags);
|
|
923
|
+
}
|
|
924
|
+
if (item.errors && item.errors.length > 0) {
|
|
925
|
+
if (item.errors.length > 1) rv.push('errors: '+item.errors.join(','));
|
|
926
|
+
else rv.push('error: '+item.errors[0]);
|
|
927
|
+
}
|
|
928
|
+
return rv.join(', ');
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
function HtmlFromInDebugMessages(messages, devID, filter) {
|
|
932
|
+
const Html = [];
|
|
933
|
+
const filterSet = new Set();
|
|
934
|
+
let isodd = true;
|
|
935
|
+
if (dbgMsghide.has('i_'+devID)) {
|
|
936
|
+
console.warn('in all filtered out')
|
|
937
|
+
Html.push(' ')
|
|
938
|
+
} else for (const item of messages) {
|
|
939
|
+
if (item.states.length > 0) {
|
|
940
|
+
const rowspan = item.states.length > 1 ? ` rowspan="${item.states.length}"` : '';
|
|
941
|
+
let idx = item.states.length;
|
|
942
|
+
const IHtml = [];
|
|
943
|
+
let fs = '';
|
|
944
|
+
for (const state of item.states) {
|
|
945
|
+
fs = fs+state.id+'.'+fne(item);
|
|
946
|
+
const redText = (item.errors && item.errors.length > 0 ? ' id="dbgred"' : '');
|
|
947
|
+
idx--;
|
|
948
|
+
const LHtml = [(`<tr id="${isodd ? 'dbgrowodd' : 'dbgroweven'}">`)];
|
|
949
|
+
if (idx==0)
|
|
950
|
+
LHtml.push(`<td${rowspan}>${item.dataID.toString(16).slice(-4)}</td><td${rowspan}>${safestring(item.payload)}</td>`);
|
|
951
|
+
LHtml.push(`<td></td><td${redText}>${safestring(state.payload)}</td><td${redText}>${state.id}</td><td${redText}>${state.value}</td><td${redText}>${fne(item)}</td></tr>`);
|
|
952
|
+
IHtml.unshift(...LHtml)
|
|
953
|
+
}
|
|
954
|
+
if (filter)
|
|
955
|
+
if (filterSet.has(fs)) continue; else filterSet.add(fs);
|
|
956
|
+
Html.unshift(...IHtml);
|
|
957
|
+
isodd=!isodd;
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
const ifbutton = `<a id="i_${devID}" class="btn-floating waves-effect waves-light blue tooltipped center-align hoverable translateT" title="Update debug messages"><i class="material-icons large">${dbgMsgfilter.has('i_'+devID) ? 'filter_list' : 'format_align_justify' }</i></a>`
|
|
961
|
+
const ofbutton = `<a id="hi_${devID}" class="btn-floating waves-effect waves-light blue tooltipped center-align hoverable translateT" title="Update debug messages"><i class="material-icons large">${dbgMsghide.has('i_'+devID) ? 'unfold_more' : 'unfold_less' }</i></a>`
|
|
962
|
+
const dataHide = dbgMsgfilter.has('hi_'+devID) ? 'Data hidden' : ' ';
|
|
963
|
+
return `<thead id="dbgtable"><tr><td> </td><td>Incoming messages</td><td> </td><td> </td><td>${dataHide}</td><td>${ifbutton}</td><td>${ofbutton}</td></tr><tr><td>ID</td><td>Zigbee Payload</td><td> </td><td>State Payload</td><td>ID</td><td>value</td><td>Flags</td></tr></thead><tbody>${Html.join('')}</tbody>`;
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
|
|
967
|
+
function HtmlFromOutDebugMessages(messages, devID, filter) {
|
|
968
|
+
const Html = [];
|
|
969
|
+
const filterSet = new Set();
|
|
970
|
+
let isodd=true;
|
|
971
|
+
if (dbgMsghide.has('o_'+devID)) {
|
|
972
|
+
console.warn('out all filtered out')
|
|
973
|
+
Html.push(' ')
|
|
974
|
+
}
|
|
975
|
+
else for (const item of messages) {
|
|
976
|
+
if (item.states.length > 0) {
|
|
977
|
+
const rowspan = item.states.length > 1 ? ` rowspan="${item.states.length}"` : '';
|
|
978
|
+
let idx = item.states.length;
|
|
979
|
+
let fs = '';
|
|
980
|
+
const IHtml = [];
|
|
981
|
+
for (const state of item.states) {
|
|
982
|
+
fs = fs+state.id+'.'+fne(item);
|
|
983
|
+
const redText = (item.errors && item.errors.length > 0 ? ' id="dbgred"' : '');
|
|
984
|
+
const LHtml = [(`<tr id="${isodd ? 'dbgrowodd' : 'dbgroweven'}">`)];
|
|
985
|
+
idx--;
|
|
986
|
+
if (idx==0)
|
|
987
|
+
LHtml.push(`<td${rowspan}>${item.dataID.toString(16).slice(-4)}</td><td${rowspan}>${safestring(item.payload)}</td>`);
|
|
988
|
+
LHtml.push(`<td${redText}>${state.ep ? state.ep : ''}</td><td${redText}>${state.id}</td><td${redText}>${safestring(state.value)}</td><td${redText}>${safestring(state.payload)}</td><td${redText}>${fne(item)}</td></tr>`);
|
|
989
|
+
IHtml.unshift(...LHtml);
|
|
990
|
+
|
|
991
|
+
}
|
|
992
|
+
if (filter)
|
|
993
|
+
if (filterSet.has(fs)) continue; else filterSet.add(fs);
|
|
994
|
+
Html.unshift(...IHtml);
|
|
995
|
+
isodd=!isodd;
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
const ifbutton = `<a id="o_${devID}" class="btn-floating waves-effect waves-light blue tooltipped center-align hoverable translateT" title="Update debug messages"><i class="material-icons large">${dbgMsgfilter.has('o_'+devID) ? 'filter_list' : 'format_align_justify' }</i></a>`
|
|
999
|
+
const ofbutton = `<a id="ho_${devID}" class="btn-floating waves-effect waves-light blue tooltipped center-align hoverable translateT" title="Update debug messages"><i class="material-icons large">${dbgMsghide.has('o_'+devID) ? 'unfold_more' : 'unfold_less'}</i></a>`
|
|
1000
|
+
const dataHide = dbgMsgfilter.has('ho_'+devID) ? 'Data hidden' : ' ';
|
|
1001
|
+
return `<thead id="dbgtable"><tr><td> </td><td>Outgoing messages</td><td> </td><td> </td><td>${dataHide}</td><td>${ifbutton}</td><td>${ofbutton}</td></tr><tr><td>ID</td><td>Zigbee Payload</td><td>EP</td><td>ID</td><td>value</td><td>State Payload</td><td>Flags</td></tr></thead><tbody>${Html.join('')}</tbody>`;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
|
|
1005
|
+
function displayDebugMessages(msg) {
|
|
1006
|
+
const buttonNames = [];
|
|
1007
|
+
if (msg.byId) {
|
|
1008
|
+
const dbgData = msg.byId;
|
|
1009
|
+
const keys = Object.keys(dbgData);
|
|
1010
|
+
const keylength = keys.length;
|
|
1011
|
+
const Html = [];
|
|
1012
|
+
const button = `<a id="e_all" class="btn-floating waves-effect waves-light green tooltipped center-align hoverable translateT" title="Update debug messages"><i class="material-icons large">sync_problem</i></a>`;
|
|
1013
|
+
const fbutton = `<a id="f_all" class="btn-floating waves-effect waves-light blue tooltipped center-align hoverable translateT" title="Update debug messages"><i class="material-icons large">${dbgMsgfilter.size != 0 ? 'filter_list' : 'format_align_justify' }</i></a>`;
|
|
1014
|
+
const hbutton = `<a id="h_all" class="btn-floating waves-effect waves-light blue tooltipped center-align hoverable translateT" title="Update debug messages"><i class="material-icons large">${dbgMsghide.size != 0 ? 'unfold_more' : 'unfold_less'}</i></a>`;
|
|
1015
|
+
const logbutton = `<a id="l_all" class="btn-floating waves-effect waves-light ${debugInLog ? 'green' : 'red'} tooltipped center-align hoverable translateT" title="Log messages"><i class="material-icons large">${debugInLog ? 'speaker_notes' : 'speaker_notes_off'}</i></a>`;
|
|
1016
|
+
Html.push(`<li><table><thead id="dbgtable"><tr><td>${logbutton}</td><td colspan="3">Debug information by device</td><td>${fbutton}</td><td>${hbutton}</td><td>${button}</td></tr></thead><tbody>`);
|
|
1017
|
+
if (!keylength) {
|
|
1018
|
+
Html.push('<tr><td></td><td>No debug data loaded - press reload to refresh</td><td></td><td> </td><td> </td><td> </td><td> </td><td> </td></tr></tbody></table></li>')
|
|
1019
|
+
$('#dbg_data_list').html(Html.join(''));
|
|
1020
|
+
}
|
|
1021
|
+
else {
|
|
1022
|
+
Html.push('</tbody></table></li>')
|
|
1023
|
+
for (const devID of Object.keys(dbgData)) {
|
|
1024
|
+
const dev = devices.find((d) => d._id.endsWith(devID.slice(-16)));
|
|
1025
|
+
const type_url = (dev && dev.common && dev.common.type ? sanitizeModelParameter(dev.common.type) : 'unknown');
|
|
1026
|
+
const image = `<img src="${dev.common.icon || dev.icon}" width="40px" onerror="this.onerror=null;this.src='img/unavailable.png';">`
|
|
1027
|
+
const modelUrl = (type_url === 'unknown') ? 'unknown' : `<a href="https://www.zigbee2mqtt.io/devices/${type_url}.html" target="_blank" rel="noopener noreferrer">${image}</a>`;
|
|
1028
|
+
const devName = (dev && dev.common && dev.common.name) ? dev.common.name : 'unnamed';
|
|
1029
|
+
const button = `<a id="e_${devID}" class="btn-floating waves-effect waves-light green tooltipped center-align hoverable translateT" title="Update debug messages"><i class="material-icons large">sync_problem</i></a>`
|
|
1030
|
+
buttonNames.push(devID);
|
|
1031
|
+
Html.push(`<li><table><thead id="dbgtable"><tr><td colspan="4">${devName} (ID: ${devID} Model: ${dev && dev.common ? dev.common.name : 'unknown'})</td><td>${modelUrl}</td><td> </td><td>${button}</td></tr></thead><tbody>`);
|
|
1032
|
+
if (dbgData[devID].IN.length > 0) {
|
|
1033
|
+
Html.push(`${HtmlFromInDebugMessages(dbgData[devID].IN, devID, dbgMsgfilter.has('i_'+devID))}`);
|
|
1034
|
+
}
|
|
1035
|
+
if (dbgData[devID].OUT.length > 0) {
|
|
1036
|
+
Html.push(`${HtmlFromOutDebugMessages(dbgData[devID].OUT, devID, dbgMsgfilter.has('o_'+devID))}`);
|
|
1037
|
+
}
|
|
1038
|
+
Html.push('</tbody></table></li>');
|
|
1039
|
+
}
|
|
1040
|
+
$('#dbg_data_list').html(Html.join(''));
|
|
1041
|
+
}
|
|
1042
|
+
$(`#e_all`).click(function () {
|
|
1043
|
+
getDebugMessages();
|
|
1044
|
+
});
|
|
1045
|
+
$(`#l_all`).click(function () {
|
|
1046
|
+
debugInLog = !debugInLog;
|
|
1047
|
+
getDebugMessages();
|
|
1048
|
+
});
|
|
1049
|
+
$(`#f_all`).click(function () {
|
|
1050
|
+
if (dbgMsgfilter.size > 0) {
|
|
1051
|
+
dbgMsgfilter.clear();
|
|
1052
|
+
}
|
|
1053
|
+
else {
|
|
1054
|
+
for (const item of Object.keys(msg.byId)) {
|
|
1055
|
+
dbgMsgfilter.add(`o_${item}`)
|
|
1056
|
+
dbgMsgfilter.add(`i_${item}`)
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
displayDebugMessages(debugMessages);
|
|
1060
|
+
});
|
|
1061
|
+
$(`#h_all`).click(function () {
|
|
1062
|
+
if (dbgMsghide.size > 0) {
|
|
1063
|
+
dbgMsghide.clear();
|
|
1064
|
+
}
|
|
1065
|
+
else {
|
|
1066
|
+
for (const item of Object.keys(msg.byId)) {
|
|
1067
|
+
dbgMsghide.add(`o_${item}`)
|
|
1068
|
+
dbgMsghide.add(`i_${item}`)
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
displayDebugMessages(debugMessages);
|
|
1072
|
+
});
|
|
1073
|
+
for (const b of buttonNames) {
|
|
1074
|
+
$(`#e_${b}`).click(function () {
|
|
1075
|
+
getDebugMessages();
|
|
1076
|
+
});
|
|
1077
|
+
$(`#o_${b}`).click(function () {
|
|
1078
|
+
if (dbgMsgfilter.has(`o_${b}`)) dbgMsgfilter.delete(`o_${b}`); else dbgMsgfilter.add(`o_${b}`);
|
|
1079
|
+
displayDebugMessages(debugMessages);
|
|
1080
|
+
});
|
|
1081
|
+
$(`#i_${b}`).click(function () {
|
|
1082
|
+
if (dbgMsgfilter.has(`i_${b}`)) dbgMsgfilter.delete(`i_${b}`); else dbgMsgfilter.add(`i_${b}`);
|
|
1083
|
+
displayDebugMessages(debugMessages);
|
|
1084
|
+
});
|
|
1085
|
+
$(`#ho_${b}`).click(function () {
|
|
1086
|
+
if (dbgMsghide.has(`o_${b}`)) dbgMsghide.delete(`o_${b}`); else dbgMsghide.add(`o_${b}`);
|
|
1087
|
+
displayDebugMessages(debugMessages);
|
|
1088
|
+
});
|
|
1089
|
+
$(`#hi_${b}`).click(function () {
|
|
1090
|
+
if (dbgMsghide.has(`i_${b}`)) dbgMsghide.delete(`i_${b}`); else dbgMsghide.add(`i_${b}`);
|
|
1091
|
+
displayDebugMessages(debugMessages);
|
|
1092
|
+
});
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
function getDebugMessages() {
|
|
1098
|
+
sendTo(namespace, 'getDebugMessages', { inlog: debugInLog }, function(msg) {
|
|
1099
|
+
debugMessages = msg;
|
|
1100
|
+
if (msg) displayDebugMessages(debugMessages)
|
|
1101
|
+
})
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
|
|
872
1105
|
function getDevices() {
|
|
873
1106
|
getCoordinatorInfo();
|
|
874
|
-
sendTo(namespace, '
|
|
1107
|
+
sendTo(namespace, 'getDevices', {}, function (msg) {
|
|
875
1108
|
if (msg) {
|
|
1109
|
+
devices = msg.devices ? msg.devices : [];
|
|
1110
|
+
// check if stashed error messages are sent alongside
|
|
876
1111
|
if (msg.clean)
|
|
877
1112
|
$('#state_cleanup_btn').removeClass('hide');
|
|
878
1113
|
else
|
|
@@ -881,24 +1116,30 @@ function getDevices() {
|
|
|
881
1116
|
$('#show_errors_btn').removeClass('hide');
|
|
882
1117
|
errorData = msg.errors;
|
|
883
1118
|
}
|
|
884
|
-
else
|
|
1119
|
+
else {
|
|
885
1120
|
$('#show_errors_btn').addClass('hide');
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
//check if debug messages are sent alongside
|
|
1124
|
+
if (msg && typeof (msg.debugDevices == 'array')) {
|
|
1125
|
+
debugDevices = msg.debugDevices;
|
|
1126
|
+
console.warn('debug devices is sent')
|
|
1127
|
+
}
|
|
1128
|
+
else
|
|
1129
|
+
debugDevices = [];
|
|
1130
|
+
if (debugMessages.byId) {
|
|
1131
|
+
debugMessages.byId = msg;
|
|
1132
|
+
if (msg) displayDebugMessages(debugMessages)
|
|
1133
|
+
}
|
|
897
1134
|
if (msg.error) {
|
|
898
|
-
|
|
1135
|
+
errorData.push(msg.error);
|
|
1136
|
+
isHerdsmanRunning = false;
|
|
1137
|
+
updateStartButton();
|
|
899
1138
|
} else {
|
|
900
|
-
|
|
1139
|
+
isHerdsmanRunning = true;
|
|
1140
|
+
updateStartButton();
|
|
901
1141
|
showDevices();
|
|
1142
|
+
getDebugMessages();
|
|
902
1143
|
getExclude();
|
|
903
1144
|
getBinding();
|
|
904
1145
|
}
|
|
@@ -931,8 +1172,12 @@ function getMap() {
|
|
|
931
1172
|
$('#refresh').removeClass('disabled');
|
|
932
1173
|
if (msg) {
|
|
933
1174
|
if (msg.error) {
|
|
934
|
-
|
|
1175
|
+
errorData.push(msg.error);
|
|
1176
|
+
isHerdsmanRunning = false;
|
|
1177
|
+
updateStartButton();
|
|
935
1178
|
} else {
|
|
1179
|
+
isHerdsmanRunning = true;
|
|
1180
|
+
updateStartButton();
|
|
936
1181
|
if (msg.errors.length > 0 && $('#errorCollectionOn').is(':checked')) {
|
|
937
1182
|
showMessage(msg.errors.join('<p>'), 'Map generation messages');
|
|
938
1183
|
}
|
|
@@ -952,14 +1197,24 @@ function getRandomExtPanID()
|
|
|
952
1197
|
return bytes.join('');
|
|
953
1198
|
}
|
|
954
1199
|
|
|
1200
|
+
function getRandomChannel()
|
|
1201
|
+
{
|
|
1202
|
+
const channels = [11,15,20,25]
|
|
1203
|
+
return channels[Math.floor(Math.random() * 4)];
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
|
|
955
1207
|
|
|
956
1208
|
// the function loadSettings has to exist ...
|
|
957
1209
|
|
|
958
1210
|
function load(settings, onChange) {
|
|
959
|
-
if (settings.
|
|
1211
|
+
if (settings.extPanID === undefined || settings.extPanID == '') {
|
|
1212
|
+
settings.channel = getRandomChannel();
|
|
1213
|
+
}
|
|
1214
|
+
if (settings.panID === undefined || settings.panID == 0) {
|
|
960
1215
|
settings.panID = Math.floor(Math.random() * 10000);
|
|
961
1216
|
}
|
|
962
|
-
if (settings.extPanID === undefined) {
|
|
1217
|
+
if (settings.extPanID === undefined || settings.extPanID == '') {
|
|
963
1218
|
settings.extPanID = getRandomExtPanID();
|
|
964
1219
|
}
|
|
965
1220
|
// fix for previous wrong value
|
|
@@ -970,9 +1225,6 @@ function load(settings, onChange) {
|
|
|
970
1225
|
if (settings.precfgkey === undefined) {
|
|
971
1226
|
settings.precfgkey = '01030507090B0D0F00020406080A0C0D';
|
|
972
1227
|
}
|
|
973
|
-
if (settings.channel === undefined) {
|
|
974
|
-
settings.channel = 11;
|
|
975
|
-
}
|
|
976
1228
|
if (settings.disablePing === undefined) {
|
|
977
1229
|
settings.disablePing = false;
|
|
978
1230
|
}
|
|
@@ -982,6 +1234,7 @@ function load(settings, onChange) {
|
|
|
982
1234
|
if (settings.baudRate === undefined) {
|
|
983
1235
|
settings.baudRate = 115200;
|
|
984
1236
|
}
|
|
1237
|
+
if (settings.autostart === undefined) settings.autostart = false;
|
|
985
1238
|
|
|
986
1239
|
// example: select elements with id=key and class=value and insert value
|
|
987
1240
|
for (const key in settings) {
|
|
@@ -993,10 +1246,12 @@ function load(settings, onChange) {
|
|
|
993
1246
|
if (value.attr('type') === 'checkbox') {
|
|
994
1247
|
value.prop('checked', settings[key]).change(function () {
|
|
995
1248
|
onChange();
|
|
1249
|
+
validateNVRamBackup(false, key)
|
|
996
1250
|
});
|
|
997
1251
|
} else {
|
|
998
1252
|
value.val(settings[key]).change(function () {
|
|
999
1253
|
onChange();
|
|
1254
|
+
validateNVRamBackup(false, key)
|
|
1000
1255
|
}).keyup(function () {
|
|
1001
1256
|
$(this).trigger('change');
|
|
1002
1257
|
});
|
|
@@ -1009,12 +1264,44 @@ function load(settings, onChange) {
|
|
|
1009
1264
|
//dialog = new MatDialog({EndingTop: '50%'});
|
|
1010
1265
|
getDevices();
|
|
1011
1266
|
getNamedColors();
|
|
1267
|
+
readNVRamBackup(false);
|
|
1268
|
+
//getDebugMessages();
|
|
1012
1269
|
//getMap();
|
|
1013
1270
|
//addCard();
|
|
1014
1271
|
|
|
1015
1272
|
// Signal to admin, that no changes yet
|
|
1016
1273
|
onChange(false);
|
|
1017
1274
|
|
|
1275
|
+
$('#test-btn').click(function () {
|
|
1276
|
+
console.warn(`isHerdsmanRunning: ${isHerdsmanRunning}`)
|
|
1277
|
+
if (!isHerdsmanRunning) {
|
|
1278
|
+
const port = $('#port.value').val();
|
|
1279
|
+
console.warn(`port is ${port}`)
|
|
1280
|
+
showWaitingDialog(`Trying to connect to ${port}`, 300);
|
|
1281
|
+
sendTo(namespace, 'testConnection', { address:port }, function(msg) {
|
|
1282
|
+
console.warn(`send to returned with ${JSON.stringify(msg)}`);
|
|
1283
|
+
closeWaitingDialog();
|
|
1284
|
+
if (msg) {
|
|
1285
|
+
if (msg.error) {
|
|
1286
|
+
showMessage(msg.error, _('Error'));
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
})
|
|
1290
|
+
}
|
|
1291
|
+
else {
|
|
1292
|
+
showMessage('function unavailable while herdsman is running', _('Error'))
|
|
1293
|
+
}
|
|
1294
|
+
});
|
|
1295
|
+
|
|
1296
|
+
$('#readNVRam-btn').click(function() {
|
|
1297
|
+
readNVRamBackup(true);
|
|
1298
|
+
})
|
|
1299
|
+
// test start commands
|
|
1300
|
+
$('#show_test_run').click(function () {
|
|
1301
|
+
console.warn(`isHerdsmanRunning: ${isHerdsmanRunning}`)
|
|
1302
|
+
doTestStart(!isHerdsmanRunning);
|
|
1303
|
+
});
|
|
1304
|
+
|
|
1018
1305
|
$('#state_cleanup_btn').click(function () {
|
|
1019
1306
|
cleanConfirmation();
|
|
1020
1307
|
});
|
|
@@ -1043,6 +1330,10 @@ function load(settings, onChange) {
|
|
|
1043
1330
|
resetConfirmation();
|
|
1044
1331
|
});
|
|
1045
1332
|
|
|
1333
|
+
$('#deleteNVRam-btn').click(function () {
|
|
1334
|
+
deleteNvBackupConfirmation();
|
|
1335
|
+
});
|
|
1336
|
+
|
|
1046
1337
|
$('#viewconfig').click(function () {
|
|
1047
1338
|
showViewConfig();
|
|
1048
1339
|
});
|
|
@@ -1050,6 +1341,9 @@ function load(settings, onChange) {
|
|
|
1050
1341
|
$('#scan').click(function () {
|
|
1051
1342
|
showChannels();
|
|
1052
1343
|
});
|
|
1344
|
+
$('#scan_t').click(function () {
|
|
1345
|
+
showChannels();
|
|
1346
|
+
});
|
|
1053
1347
|
|
|
1054
1348
|
sendTo(namespace, 'getGroups', {}, function (data) {
|
|
1055
1349
|
groups = data.groups;
|
|
@@ -1076,6 +1370,10 @@ function load(settings, onChange) {
|
|
|
1076
1370
|
}
|
|
1077
1371
|
});
|
|
1078
1372
|
|
|
1373
|
+
$('#hardware').click(function() {
|
|
1374
|
+
validateNVRamBackup(false);
|
|
1375
|
+
});
|
|
1376
|
+
|
|
1079
1377
|
$(document).ready(function () {
|
|
1080
1378
|
$('.modal').modal({
|
|
1081
1379
|
startingTop: '30%',
|
|
@@ -1133,6 +1431,7 @@ function showMessages() {
|
|
|
1133
1431
|
data = mess + '\n' + data;
|
|
1134
1432
|
}
|
|
1135
1433
|
$('#stdout').text(data);
|
|
1434
|
+
$('#stdout_t').text(messages.join('\n'));
|
|
1136
1435
|
}
|
|
1137
1436
|
|
|
1138
1437
|
function showPairingProcess() {
|
|
@@ -1146,6 +1445,41 @@ function showPairingProcess() {
|
|
|
1146
1445
|
Materialize.updateTextFields();
|
|
1147
1446
|
}
|
|
1148
1447
|
|
|
1448
|
+
function doTestStart(start) {
|
|
1449
|
+
updateStartButton(true);
|
|
1450
|
+
if (start) {
|
|
1451
|
+
const ovr = { extPanID:$('#extPanID.value').val(),
|
|
1452
|
+
panID: $('#PanID.value').val(),
|
|
1453
|
+
channel: $('#channel.value').val(),
|
|
1454
|
+
port: $('#port.value').val(),
|
|
1455
|
+
adapterType: $('#adapterType.value').val(),
|
|
1456
|
+
baudRate: $('#baudRate.value').val(),
|
|
1457
|
+
precfgkey: $('#precfgkey.value').val(),
|
|
1458
|
+
flowCTRL: $('#flowCTRL.value').prop('checked')
|
|
1459
|
+
};
|
|
1460
|
+
// $('#testStartStart').addClass('disabled');
|
|
1461
|
+
messages = [];
|
|
1462
|
+
sendTo(namespace, 'testConnect', { start:true, zigbeeOptions:ovr }, function(msg) {
|
|
1463
|
+
if (msg) {
|
|
1464
|
+
if (msg.status)
|
|
1465
|
+
$('#testStartStop').removeClass('disabled');
|
|
1466
|
+
else
|
|
1467
|
+
$('#testStartStart').removeClass('disabled');
|
|
1468
|
+
}
|
|
1469
|
+
})
|
|
1470
|
+
}
|
|
1471
|
+
else {
|
|
1472
|
+
//$('#testStartStop').addClass('disabled');
|
|
1473
|
+
sendTo(namespace, 'testConnect', { start:false }, function(msg) {
|
|
1474
|
+
if (msg) {
|
|
1475
|
+
if (msg.status) $('#testStartStart').removeClass('disabled');
|
|
1476
|
+
else $('#testStartStop').removeClass('disabled');
|
|
1477
|
+
}
|
|
1478
|
+
})
|
|
1479
|
+
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1149
1483
|
// ... and the function save has to exist.
|
|
1150
1484
|
// you have to make sure the callback is called with the settings object as first param!
|
|
1151
1485
|
|
|
@@ -1172,6 +1506,36 @@ function getDevId(adapterDevId) {
|
|
|
1172
1506
|
return adapterDevId.split('.').slice(0, 3).join('.');
|
|
1173
1507
|
}
|
|
1174
1508
|
|
|
1509
|
+
|
|
1510
|
+
function updateStartButton(block) {
|
|
1511
|
+
if (block) {
|
|
1512
|
+
$('#show_test_run').addClass('disabled');
|
|
1513
|
+
$('#reset-btn').addClass('disabled');
|
|
1514
|
+
$('#deleteNVRam-btn').addClass('disabled');
|
|
1515
|
+
$('#ErrorNotificationBtn').removeClass('hide')
|
|
1516
|
+
$('#ErrorNotificationBtn').removeClass('blinking')
|
|
1517
|
+
$('#ErrorNotificationIcon').removeClass('icon-red')
|
|
1518
|
+
$('#ErrorNotificationIcon').addClass('icon-orange')
|
|
1519
|
+
return;
|
|
1520
|
+
}
|
|
1521
|
+
if (isHerdsmanRunning)
|
|
1522
|
+
{
|
|
1523
|
+
$('#ErrorNotificationBtn').addClass('hide')
|
|
1524
|
+
$('#ErrorNotificationBtn').removeClass('blinking');
|
|
1525
|
+
$('#show_test_run').removeClass('disabled');
|
|
1526
|
+
$('#deleteNVRam-btn').removeClass('disabled');
|
|
1527
|
+
$('#reset-btn').removeClass('disabled');
|
|
1528
|
+
}
|
|
1529
|
+
else {
|
|
1530
|
+
$('#ErrorNotificationIcon').addClass('icon-red')
|
|
1531
|
+
$('#ErrorNotificationIcon').removeClass('icon-orange')
|
|
1532
|
+
$('#ErrorNotificationBtn').removeClass('hide')
|
|
1533
|
+
$('#ErrorNotificationBtn').addClass('blinking');
|
|
1534
|
+
$('#show_test_run').removeClass('disabled');
|
|
1535
|
+
$('#deleteNVRam-btn').removeClass('disabled');
|
|
1536
|
+
$('#reset-btn').addClass('disabled');
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1175
1539
|
// subscribe to changes
|
|
1176
1540
|
socket.emit('subscribe', namespace + '.*');
|
|
1177
1541
|
socket.emit('subscribeObjects', namespace + '.*');
|
|
@@ -1200,8 +1564,21 @@ socket.on('stateChange', function (id, state) {
|
|
|
1200
1564
|
$('#progress_line').css('width', `${percent}%`);
|
|
1201
1565
|
}
|
|
1202
1566
|
} else if (id.match(/\.info\.pairingMessage$/)) {
|
|
1203
|
-
|
|
1204
|
-
|
|
1567
|
+
if (state.val == 'NewDebugMessage') {
|
|
1568
|
+
getDebugMessages();
|
|
1569
|
+
}
|
|
1570
|
+
else {
|
|
1571
|
+
messages.push(state.val);
|
|
1572
|
+
showMessages();
|
|
1573
|
+
if (state.val.startsWith('Zigbee-Herdsman started successfully')) {
|
|
1574
|
+
isHerdsmanRunning = true;
|
|
1575
|
+
updateStartButton();
|
|
1576
|
+
}
|
|
1577
|
+
if (state.val.startsWith('herdsman stopped') || state.val.startsWith('Error herdsman')) {
|
|
1578
|
+
isHerdsmanRunning = false;
|
|
1579
|
+
updateStartButton();
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1205
1582
|
} else {
|
|
1206
1583
|
const devId = getDevId(id);
|
|
1207
1584
|
putEventToNode(devId);
|
|
@@ -1226,6 +1603,7 @@ socket.on('stateChange', function (id, state) {
|
|
|
1226
1603
|
}
|
|
1227
1604
|
});
|
|
1228
1605
|
|
|
1606
|
+
|
|
1229
1607
|
socket.on('objectChange', function (id, obj) {
|
|
1230
1608
|
if (id.substring(0, namespaceLen) !== namespace) return;
|
|
1231
1609
|
//console.log('objectChange', id, obj);
|
|
@@ -1486,7 +1864,6 @@ function showNetworkMap(devices, map) {
|
|
|
1486
1864
|
const options = data.edges._data.get(id);
|
|
1487
1865
|
if (select) {
|
|
1488
1866
|
options.font.size = 15;
|
|
1489
|
-
console.warn(JSON.stringify(options.font));
|
|
1490
1867
|
} else {
|
|
1491
1868
|
options.font.size = 0;
|
|
1492
1869
|
}
|
|
@@ -2012,31 +2389,6 @@ function list2select(selector, list, selected, getText, getKey, getData) {
|
|
|
2012
2389
|
element.select();
|
|
2013
2390
|
}
|
|
2014
2391
|
|
|
2015
|
-
/*
|
|
2016
|
-
function showGroups() {
|
|
2017
|
-
$('#groups_table').find('.group').remove();
|
|
2018
|
-
if (!groups) return;
|
|
2019
|
-
const element = $('#groups_table');
|
|
2020
|
-
for (const j in groups) {
|
|
2021
|
-
if (groups.hasOwnProperty(j)) {
|
|
2022
|
-
element.append(`<tr id="group_${j}" class="group"><td>${j}</td><td><div>${groups[j]}<span class="right">` +
|
|
2023
|
-
`<a id="${j}" name="groupedit" class="waves-effect green btn-floating"><i class="material-icons">edit</i></a>` +
|
|
2024
|
-
`<a id="${j}" name="groupdelete" class="waves-effect red btn-floating"><i class="material-icons">delete</i></a></span></div></td></tr>`);
|
|
2025
|
-
}
|
|
2026
|
-
}
|
|
2027
|
-
$('a.btn-floating[name=\'groupedit\']').click(function () {
|
|
2028
|
-
const index = $(this).attr('id'),
|
|
2029
|
-
name = groups[index];
|
|
2030
|
-
editGroupName(index, name, false);
|
|
2031
|
-
});
|
|
2032
|
-
$('a.btn-floating[name=\'groupdelete\']').click(function () {
|
|
2033
|
-
const index = $(this).attr('id'),
|
|
2034
|
-
name = groups[index];
|
|
2035
|
-
deleteGroupConfirmation(index, name);
|
|
2036
|
-
});
|
|
2037
|
-
}
|
|
2038
|
-
*/
|
|
2039
|
-
|
|
2040
2392
|
function editGroup(id, name) {
|
|
2041
2393
|
const grp = devGroups[id];
|
|
2042
2394
|
let info = '';
|
|
@@ -2065,7 +2417,6 @@ function editGroup(id, name) {
|
|
|
2065
2417
|
removeMembers.push({id:member.ieee.replace('0x',''), ep:member.epid})
|
|
2066
2418
|
}
|
|
2067
2419
|
}
|
|
2068
|
-
console.warn(`ID: ${Id} name: ${newName} removeMembers: ${JSON.stringify(removeMembers)}`)
|
|
2069
2420
|
updateGroup(Id, newName, (removeMembers.length > 0 ? removeMembers: undefined));
|
|
2070
2421
|
// showGroups();
|
|
2071
2422
|
getDevices();
|
|
@@ -2625,7 +2976,7 @@ function genDevInfo(device) {
|
|
|
2625
2976
|
${genRow('date code', dev._dateCode)}
|
|
2626
2977
|
${genRow('build', dev._softwareBuildID)}
|
|
2627
2978
|
${genRow('interviewed', dev._interviewCompleted)}
|
|
2628
|
-
${genRow('configured', (
|
|
2979
|
+
${genRow('configured', (device.isConfigured), true)}
|
|
2629
2980
|
</ul>
|
|
2630
2981
|
</div>
|
|
2631
2982
|
</div>
|
|
@@ -2641,48 +2992,6 @@ function showDevInfo(id) {
|
|
|
2641
2992
|
$('#modaldevinfo').modal('open');
|
|
2642
2993
|
}
|
|
2643
2994
|
|
|
2644
|
-
/*
|
|
2645
|
-
function showGroupList(show) {
|
|
2646
|
-
const htmlsections = [];
|
|
2647
|
-
for (const groupid in devGroups) {
|
|
2648
|
-
const dev = devGroups[groupid];
|
|
2649
|
-
const grpname = (dev.common && dev.common.name ? dev.common.name : 'Group ' + groupid);
|
|
2650
|
-
const selectables = [];
|
|
2651
|
-
const members = [];
|
|
2652
|
-
if (dev && dev.memberinfo) {
|
|
2653
|
-
selectables.push(`<select id="members_${groupid}" multiple>`);
|
|
2654
|
-
for (let m = 0; m < dev.memberinfo.length; m++) {
|
|
2655
|
-
members.push(`${dev.memberinfo[m].device}.${dev.memberinfo[m].epid} (${dev.memberinfo[m].ieee})`);
|
|
2656
|
-
selectables.push(`<option value="${m}">${dev.memberinfo[m].device}.${dev.memberinfo[m].epid} (...${dev.memberinfo[m].ieee.slice(-4)})</option>`);
|
|
2657
|
-
}
|
|
2658
|
-
selectables.push('</select>');
|
|
2659
|
-
}
|
|
2660
|
-
htmlsections.push(`
|
|
2661
|
-
<div class="row">
|
|
2662
|
-
<div class="col s4 m4 l4">
|
|
2663
|
-
<h5>${grpname}<h5>
|
|
2664
|
-
</div>
|
|
2665
|
-
<div class=col s7 m7 l7">
|
|
2666
|
-
${members.join('<br>')}
|
|
2667
|
-
</div>
|
|
2668
|
-
</div>
|
|
2669
|
-
`);
|
|
2670
|
-
}
|
|
2671
|
-
|
|
2672
|
-
$('#grouplist').html(htmlsections.join(''));
|
|
2673
|
-
$('#add').click(function () {
|
|
2674
|
-
const maxind = parseInt(Object.getOwnPropertyNames(groups).reduce((a, b) => a > b ? a : b, 0));
|
|
2675
|
-
addGroup(maxind + 1, 'Group ' + maxind + 1, true);
|
|
2676
|
-
showGroupList(false);
|
|
2677
|
-
});
|
|
2678
|
-
|
|
2679
|
-
$('#modalgrouplist a.btn[name=\'save\']').unbind('click');
|
|
2680
|
-
$('#modalgrouplist a.btn[name=\'save\']').click(() => {
|
|
2681
|
-
});
|
|
2682
|
-
if (show) $('#modalgrouplist').modal('open');
|
|
2683
|
-
}
|
|
2684
|
-
*/
|
|
2685
|
-
|
|
2686
2995
|
let waitingTimeout, waitingInt;
|
|
2687
2996
|
|
|
2688
2997
|
function showWaitingDialog(text, timeout) {
|
|
@@ -2817,16 +3126,12 @@ function addExcludeDialog() {
|
|
|
2817
3126
|
$('#excludemodaledit a.btn[name=\'save\']').unbind('click');
|
|
2818
3127
|
$('#excludemodaledit a.btn[name=\'save\']').click(() => {
|
|
2819
3128
|
const exclude_id = $('#excludemodaledit').find('#exclude_target option:selected').val();
|
|
2820
|
-
|
|
2821
3129
|
const ids = devices.map(el => el._id);
|
|
2822
3130
|
const idx = ids.indexOf(exclude_id);
|
|
2823
3131
|
const exclude_model = devices[idx];
|
|
2824
|
-
console.warn('calling addExclude mit model ' + exclude_model)
|
|
2825
|
-
|
|
2826
3132
|
addExclude(exclude_model);
|
|
2827
3133
|
});
|
|
2828
3134
|
prepareExcludeDialog();
|
|
2829
|
-
console.warn('opening dialog');
|
|
2830
3135
|
$('#excludemodaledit').modal('open');
|
|
2831
3136
|
Materialize.updateTextFields();
|
|
2832
3137
|
}
|
|
@@ -2855,7 +3160,7 @@ function getExclude() {
|
|
|
2855
3160
|
excludes = msg.legacy;
|
|
2856
3161
|
showExclude();
|
|
2857
3162
|
}
|
|
2858
|
-
}
|
|
3163
|
+
}
|
|
2859
3164
|
});
|
|
2860
3165
|
}
|
|
2861
3166
|
|
|
@@ -3156,14 +3461,17 @@ function updateCardTimer() {
|
|
|
3156
3461
|
}
|
|
3157
3462
|
|
|
3158
3463
|
function updateDevice(id) {
|
|
3159
|
-
sendTo(namespace, 'getDevice', {id: id}, function (
|
|
3160
|
-
if (
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3464
|
+
sendTo(namespace, 'getDevice', {id: id}, function (msg) {
|
|
3465
|
+
if (msg) {
|
|
3466
|
+
const devs = msg.devices;
|
|
3467
|
+
if (devs) {
|
|
3468
|
+
if (devs.error) {
|
|
3469
|
+
showMessage(devs.error, _('Error'));
|
|
3470
|
+
} else {
|
|
3471
|
+
removeDevice(id);
|
|
3472
|
+
devs.forEach(dev => devices.push(dev));
|
|
3473
|
+
showDevices();
|
|
3474
|
+
}
|
|
3167
3475
|
}
|
|
3168
3476
|
}
|
|
3169
3477
|
});
|
|
@@ -3211,3 +3519,72 @@ function reconfigureDevice(id) {
|
|
|
3211
3519
|
});
|
|
3212
3520
|
showWaitingDialog('Device is being reconfigure', 30);
|
|
3213
3521
|
}
|
|
3522
|
+
|
|
3523
|
+
const warnLevel = {
|
|
3524
|
+
extPanID : function(v) { return !(v && v.toLowerCase().trim()!='dddddddddddddddd')},
|
|
3525
|
+
channel: function(v) { const num = parseInt(v); return !(num==11 || num==15 || num==20 || num==25)},
|
|
3526
|
+
}
|
|
3527
|
+
const validatableKeys = ['channel', 'precfgkey', 'extPanID', 'panID'];
|
|
3528
|
+
|
|
3529
|
+
function validateConfigData(key, val) {
|
|
3530
|
+
if (validatableKeys.indexOf(key) < 0 || !val) return;
|
|
3531
|
+
if (warnLevel[key]) {
|
|
3532
|
+
if (warnLevel[key](val)) {
|
|
3533
|
+
console.warn(`warning set for ${key} (${val})`)
|
|
3534
|
+
$(`#${key}_ALERT`).removeClass('hide')
|
|
3535
|
+
} else $(`#${key}_ALERT`).addClass('hide')
|
|
3536
|
+
}
|
|
3537
|
+
if (nvRamBackup[key]) {
|
|
3538
|
+
console.warn(`value of ${key} is ${val} (${nvRamBackup[key]})`);
|
|
3539
|
+
if (val == nvRamBackup[key])
|
|
3540
|
+
{
|
|
3541
|
+
console.warn(`ok set for ${key} (${val})`)
|
|
3542
|
+
$(`#${key}_OK`).removeClass('hide')
|
|
3543
|
+
$(`#${key}_NOK`).addClass('hide')
|
|
3544
|
+
}
|
|
3545
|
+
else
|
|
3546
|
+
{
|
|
3547
|
+
console.warn(`nok set for ${key} (${val})`)
|
|
3548
|
+
$(`#${key}_OK`).addClass('hide')
|
|
3549
|
+
$(`#${key}_NOK`).removeClass('hide')
|
|
3550
|
+
}
|
|
3551
|
+
}
|
|
3552
|
+
else {
|
|
3553
|
+
console.warn(`noval set for ${key} (${val})`)
|
|
3554
|
+
$(`#${key}_OK`).addClass('hide')
|
|
3555
|
+
$(`#${key}_NOK`).addClass('hide')
|
|
3556
|
+
}
|
|
3557
|
+
}
|
|
3558
|
+
|
|
3559
|
+
function validateNVRamBackup(update, src) {
|
|
3560
|
+
console.warn('validateNVRam');
|
|
3561
|
+
const validatedKeys = src ? [src] : validatableKeys;
|
|
3562
|
+
const validator = {};
|
|
3563
|
+
for (const key of validatedKeys) {
|
|
3564
|
+
const value = $('#' + key + '.value');
|
|
3565
|
+
if (nvRamBackup[key] && update) {
|
|
3566
|
+
if (value.attr('type') === 'checkbox') {
|
|
3567
|
+
value.prop('checked', nvRamBackup[key]);
|
|
3568
|
+
} else {
|
|
3569
|
+
value.val(nvRamBackup[key])
|
|
3570
|
+
}
|
|
3571
|
+
}
|
|
3572
|
+
validateConfigData(key, value.val());
|
|
3573
|
+
}
|
|
3574
|
+
}
|
|
3575
|
+
|
|
3576
|
+
|
|
3577
|
+
function readNVRamBackup(update) {
|
|
3578
|
+
console.warn('read nvRam')
|
|
3579
|
+
sendTo(namespace, 'readNVRam', {}, function(msg) {
|
|
3580
|
+
if (msg) {
|
|
3581
|
+
if (msg.error && update) {
|
|
3582
|
+
showMessages(msg.error, _('Error'));
|
|
3583
|
+
delete msg.error;
|
|
3584
|
+
}
|
|
3585
|
+
nvRamBackup = msg;
|
|
3586
|
+
validateNVRamBackup(update)
|
|
3587
|
+
}
|
|
3588
|
+
});
|
|
3589
|
+
|
|
3590
|
+
}
|