iobroker.zigbee 3.0.5 → 3.1.2
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 +21 -0
- package/admin/admin.js +153 -86
- package/admin/i18n/de/translations.json +16 -16
- package/admin/index_m.html +59 -90
- package/admin/tab_m.html +7 -5
- package/docs/de/readme.md +1 -1
- package/docs/en/readme.md +4 -2
- package/io-package.json +45 -41
- package/lib/binding.js +1 -1
- package/lib/commands.js +112 -82
- package/lib/developer.js +1 -1
- package/lib/devices.js +11 -7
- package/lib/exposes.js +2 -0
- package/lib/groups.js +400 -63
- package/lib/localConfig.js +16 -5
- package/lib/states.js +32 -2
- package/lib/statescontroller.js +254 -146
- package/lib/utils.js +7 -5
- package/lib/zbDeviceAvailability.js +78 -21
- package/lib/zbDeviceEvent.js +1 -1
- package/lib/zigbeecontroller.js +485 -56
- package/main.js +139 -469
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -152,6 +152,27 @@ You can thank the authors by these links:
|
|
|
152
152
|
|
|
153
153
|
-----------------------------------------------------------------------------------------------------
|
|
154
154
|
## Changelog
|
|
155
|
+
### 3.1.2 (2025-09-15)
|
|
156
|
+
* (asgothian) Fix pairing bug
|
|
157
|
+
* (asgothian) add ping messages to device debug to verify ping failure reasons
|
|
158
|
+
*
|
|
159
|
+
|
|
160
|
+
### 3.1.1 (2025-09-14)
|
|
161
|
+
* (asgothian) ZHC 25.x ZH 6.x
|
|
162
|
+
* (asgothian) Refactor main/statescontroller/zigbeecontroller
|
|
163
|
+
* (asgothian) Allow groups to trigger member state reads (via state memberupdate)
|
|
164
|
+
* (asgothian) Allow groups to set state based on accumulated member states (via state stateupdate)
|
|
165
|
+
* (asgothian) Trigger state read at device announce (via Settings: Read states at device announce)
|
|
166
|
+
* (asgothian) Trigger state read at adapter start for all pingable devices (via settings: 'try to read all states at adapter start' and 'read delay' (in seconds))
|
|
167
|
+
* (asgothian) Bugfix: Error in automatic restart function
|
|
168
|
+
* (asgothian) Bugfix: Error in device_query blocked certain states from being read
|
|
169
|
+
* (asgothian) Change to device Query: 15 second delay between queries only for automated queries. Manual queries are not affected
|
|
170
|
+
|
|
171
|
+
### 3.1.0 (2025-08-02)
|
|
172
|
+
* (asgothian) ZHC 24.9.0
|
|
173
|
+
* (asgothian) ZH 5.x
|
|
174
|
+
* (asgothian) extend and stop pairing countdown
|
|
175
|
+
|
|
155
176
|
### 3.0.5 (2025-08-27)
|
|
156
177
|
* (asgothian) fix random error where devices are not shown due to illegal groups
|
|
157
178
|
* (asgothian) drop support for node 18
|
package/admin/admin.js
CHANGED
|
@@ -22,11 +22,15 @@ let devices = [],
|
|
|
22
22
|
binding = [],
|
|
23
23
|
excludes = [],
|
|
24
24
|
coordinatorinfo = {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
installSource: 'IADefault_1',
|
|
26
|
+
channel: '-1',
|
|
27
|
+
port: 'Default_1',
|
|
28
|
+
installedVersion: 'Default_1',
|
|
29
|
+
type: 'Default_1',
|
|
30
|
+
revision: 'Default_1',
|
|
31
|
+
version: '9-9.9.9.9',
|
|
32
|
+
herdsman: '4.0.0',
|
|
33
|
+
converters: '24.0.0',
|
|
30
34
|
},
|
|
31
35
|
cidList,
|
|
32
36
|
shuffleInstance,
|
|
@@ -58,7 +62,7 @@ const networkOptions = {
|
|
|
58
62
|
const savedSettings = [
|
|
59
63
|
'port', 'panID', 'channel', 'disableLed', 'countDown', 'groups', 'extPanID', 'precfgkey', 'transmitPower',
|
|
60
64
|
'adapterType', 'debugHerdsman', 'disableBackup', 'disablePing', 'external', 'startWithInconsistent',
|
|
61
|
-
'warnOnDeviceAnnouncement', 'baudRate', 'flowCTRL', 'autostart'
|
|
65
|
+
'warnOnDeviceAnnouncement', 'baudRate', 'flowCTRL', 'autostart', 'readAtAnnounce', 'startReadDelay', 'readAllAtStart',
|
|
62
66
|
];
|
|
63
67
|
|
|
64
68
|
function getDeviceByID(ID) {
|
|
@@ -111,14 +115,14 @@ function getLQICls(value) {
|
|
|
111
115
|
|
|
112
116
|
function getCoordinatorCard(dev) {
|
|
113
117
|
const title = 'Zigbee Coordinator',
|
|
114
|
-
id = dev._id,
|
|
118
|
+
id = dev && dev._id ? dev._id : '0x00000000',
|
|
115
119
|
img_src = 'zigbee.png',
|
|
116
120
|
rid = id.split('.').join('_'),
|
|
117
121
|
image = `<img src="${img_src}" width="80px">`,
|
|
118
122
|
paired = '',
|
|
119
|
-
status = `<div class="col tool"><i class="material-icons icon-green">check_circle</i></div>`,
|
|
120
|
-
lqi_cls = getLQICls(dev.link_quality),
|
|
121
|
-
lq = (dev.link_quality) ? `<div class="col tool"><i id="${rid}_link_quality_icon" class="material-icons ${lqi_cls}">network_check</i><div id="${rid}_link_quality" class="center" style="font-size:0.7em">${dev.link_quality}</div></div>` : '',
|
|
123
|
+
status = dev ? `<div class="col tool"><i class="material-icons icon-green">check_circle</i></div>` : `<div class="col tool"><i class="material-icons icon-red">remove_circle</i></div>`,
|
|
124
|
+
lqi_cls = dev ? getLQICls(dev.link_quality) : -1,
|
|
125
|
+
lq = (dev && dev.link_quality) ? `<div class="col tool"><i id="${rid}_link_quality_icon" class="material-icons ${lqi_cls}">network_check</i><div id="${rid}_link_quality" class="center" style="font-size:0.7em">${dev.link_quality}</div></div>` : '',
|
|
122
126
|
info = `<div style="min-height:88px; font-size: 0.8em" class="truncate">
|
|
123
127
|
<ul>
|
|
124
128
|
<li><span class="label">type:</span><span>${coordinatorinfo.type}</span></li>
|
|
@@ -126,9 +130,13 @@ function getCoordinatorCard(dev) {
|
|
|
126
130
|
<li><span class="label">revision:</span><span>${coordinatorinfo.revision}</span></li>
|
|
127
131
|
<li><span class="label">port:</span><span>${coordinatorinfo.port}</span></li>
|
|
128
132
|
<li><span class="label">channel:</span><span>${coordinatorinfo.channel}</span></li>
|
|
133
|
+
<li><span class="label">------------</span><span>Software versions </span></li>
|
|
134
|
+
<li><span class="label">adapter:</span><span>${coordinatorinfo.installedVersion}</span></li>
|
|
135
|
+
<li><span class="label">installed from:</span><span>${coordinatorinfo.installSource}</span></li>
|
|
136
|
+
<li><span class="label">ZHC / ZH:</span><span>${coordinatorinfo.converters} / ${coordinatorinfo.herdsman}</span></li>
|
|
129
137
|
</ul>
|
|
130
138
|
</div>`,
|
|
131
|
-
permitJoinBtn = (dev.info && dev.info.device._type == 'Router') ? '<button name="join" class="btn-floating btn-small waves-effect waves-light right hoverable green"><i class="material-icons tiny">leak_add</i></button>' : '',
|
|
139
|
+
permitJoinBtn = (dev && dev.info && dev.info.device._type == 'Router') ? '<button name="join" class="btn-floating btn-small waves-effect waves-light right hoverable green"><i class="material-icons tiny">leak_add</i></button>' : '',
|
|
132
140
|
card = `<div id="${id}" class="device">
|
|
133
141
|
<div class="card hoverable">
|
|
134
142
|
<div class="card-content zcard">
|
|
@@ -396,7 +404,8 @@ function deleteNvBackupConfirmation() {
|
|
|
396
404
|
closeWaitingDialog();
|
|
397
405
|
if (msg) {
|
|
398
406
|
if (msg.error) {
|
|
399
|
-
|
|
407
|
+
if (msg.error.includes('ENOENT')) showMessage('No nvRam backup available for deletion.', _('Error'))
|
|
408
|
+
else showMessage(msg.error, _('Error'));
|
|
400
409
|
} else {
|
|
401
410
|
getDevices();
|
|
402
411
|
}
|
|
@@ -671,7 +680,9 @@ function renameDevice(id, name) {
|
|
|
671
680
|
}
|
|
672
681
|
|
|
673
682
|
function showDevices() {
|
|
683
|
+
console.warn('show Devices called')
|
|
674
684
|
let html = '';
|
|
685
|
+
let hasCoordinator = false;
|
|
675
686
|
const lang = systemLang || 'en';
|
|
676
687
|
// sort by rooms
|
|
677
688
|
devices.sort((a, b) => {
|
|
@@ -703,15 +714,13 @@ function showDevices() {
|
|
|
703
714
|
});
|
|
704
715
|
for (let i = 0; i < devices.length; i++) {
|
|
705
716
|
const d = devices[i];
|
|
706
|
-
if (
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
;
|
|
714
|
-
if (d.info && d.info.device._type == 'Coordinator') {
|
|
717
|
+
if (d.common && d.common.type == 'group') {
|
|
718
|
+
const card = getGroupCard(d);
|
|
719
|
+
html += card;
|
|
720
|
+
continue;
|
|
721
|
+
};
|
|
722
|
+
if (d.info && d.info.device && d.info.device._type == 'Coordinator') {
|
|
723
|
+
hasCoordinator=true;
|
|
715
724
|
const card = getCoordinatorCard(d);
|
|
716
725
|
html += card;
|
|
717
726
|
} else {
|
|
@@ -730,6 +739,8 @@ function showDevices() {
|
|
|
730
739
|
html += card;
|
|
731
740
|
}
|
|
732
741
|
}
|
|
742
|
+
if (!hasCoordinator) html += getCoordinatorCard();
|
|
743
|
+
|
|
733
744
|
$('#devices').html(html);
|
|
734
745
|
hookControls();
|
|
735
746
|
|
|
@@ -771,6 +782,7 @@ function showDevices() {
|
|
|
771
782
|
return dev_block.find('#dName').text();
|
|
772
783
|
};
|
|
773
784
|
const getDevId = function (dev_block) {
|
|
785
|
+
console.warn(`getDevId called with ${JSON.stringify(dev_block)}`)
|
|
774
786
|
return dev_block.attr('id');
|
|
775
787
|
};
|
|
776
788
|
$('.card-reveal-buttons button[name=\'delete\']').click(function () {
|
|
@@ -814,6 +826,12 @@ function showDevices() {
|
|
|
814
826
|
}
|
|
815
827
|
showPairingProcess();
|
|
816
828
|
});
|
|
829
|
+
$('#modalpairing a.btn[name=\'extendpairing\']').click(function () {
|
|
830
|
+
letsPairing();
|
|
831
|
+
});
|
|
832
|
+
$('#modalpairing a.btn[name=\'endpairing\']').click(function () {
|
|
833
|
+
stopPairing();
|
|
834
|
+
});
|
|
817
835
|
$('.card-reveal-buttons button[name=\'info\']').click(function () {
|
|
818
836
|
const dev_block = $(this).parents('div.device');
|
|
819
837
|
showDevInfo(getDevId(dev_block));
|
|
@@ -888,7 +906,7 @@ function checkFwUpdate() {
|
|
|
888
906
|
|
|
889
907
|
function letsPairingWithCode(code) {
|
|
890
908
|
messages = [];
|
|
891
|
-
sendTo(namespace, 'letsPairing', {code: code}, function (msg) {
|
|
909
|
+
sendTo(namespace, 'letsPairing', {code: code, stop:false}, function (msg) {
|
|
892
910
|
if (msg && msg.error) {
|
|
893
911
|
showMessage(msg.error, _('Error'));
|
|
894
912
|
}
|
|
@@ -900,7 +918,16 @@ function letsPairingWithCode(code) {
|
|
|
900
918
|
|
|
901
919
|
function letsPairing() {
|
|
902
920
|
messages = [];
|
|
903
|
-
sendTo(namespace, 'letsPairing', {}, function (msg) {
|
|
921
|
+
sendTo(namespace, 'letsPairing', {stop:false}, function (msg) {
|
|
922
|
+
if (msg && msg.error) {
|
|
923
|
+
showMessage(msg.error, _('Error'));
|
|
924
|
+
}
|
|
925
|
+
});
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
function stopPairing() {
|
|
929
|
+
messages = [];
|
|
930
|
+
sendTo(namespace, 'letsPairing', {stop:true}, function (msg) {
|
|
904
931
|
if (msg && msg.error) {
|
|
905
932
|
showMessage(msg.error, _('Error'));
|
|
906
933
|
}
|
|
@@ -918,7 +945,7 @@ function touchlinkReset() {
|
|
|
918
945
|
|
|
919
946
|
function joinProcess(devId) {
|
|
920
947
|
messages = [];
|
|
921
|
-
sendTo(namespace, 'letsPairing', {id: devId}, function (msg) {
|
|
948
|
+
sendTo(namespace, 'letsPairing', {id: devId, stop:false}, function (msg) {
|
|
922
949
|
if (msg && msg.error) {
|
|
923
950
|
showMessage(msg.error, _('Error'));
|
|
924
951
|
}
|
|
@@ -926,17 +953,19 @@ function joinProcess(devId) {
|
|
|
926
953
|
}
|
|
927
954
|
|
|
928
955
|
function getCoordinatorInfo() {
|
|
956
|
+
console.warn('calling getCoordinatorInfo');
|
|
929
957
|
sendTo(namespace, 'getCoordinatorInfo', {}, function (msg) {
|
|
930
958
|
if (msg) {
|
|
959
|
+
console.warn(JSON.stringify(msg))
|
|
931
960
|
if (msg.error) {
|
|
932
961
|
errorData.push(msg.error);
|
|
962
|
+
delete msg.error;
|
|
933
963
|
isHerdsmanRunning = false;
|
|
934
|
-
updateStartButton();
|
|
935
964
|
} else {
|
|
936
|
-
coordinatorinfo = msg;
|
|
937
965
|
isHerdsmanRunning = true;
|
|
938
|
-
updateStartButton()
|
|
939
966
|
}
|
|
967
|
+
coordinatorinfo = msg;
|
|
968
|
+
updateStartButton()
|
|
940
969
|
}
|
|
941
970
|
});
|
|
942
971
|
}
|
|
@@ -1223,47 +1252,63 @@ function getDebugMessages() {
|
|
|
1223
1252
|
|
|
1224
1253
|
|
|
1225
1254
|
function getDevices() {
|
|
1226
|
-
|
|
1227
|
-
sendTo(namespace, '
|
|
1255
|
+
console.warn('getDevices called')
|
|
1256
|
+
sendTo(namespace, 'getCoordinatorInfo', {}, function (msg) {
|
|
1257
|
+
console.warn(`getCoordinatorInfo returned ${JSON.stringify(msg)}`)
|
|
1228
1258
|
if (msg) {
|
|
1229
|
-
|
|
1230
|
-
// check if stashed error messages are sent alongside
|
|
1231
|
-
if (msg.clean)
|
|
1232
|
-
$('#state_cleanup_btn').removeClass('hide');
|
|
1233
|
-
else
|
|
1234
|
-
$('#state_cleanup_btn').addClass('hide');
|
|
1235
|
-
if (msg.errors && msg.errors.length > 0) {
|
|
1236
|
-
$('#show_errors_btn').removeClass('hide');
|
|
1237
|
-
errorData = msg.errors;
|
|
1238
|
-
}
|
|
1239
|
-
else {
|
|
1240
|
-
$('#show_errors_btn').addClass('hide');
|
|
1241
|
-
}
|
|
1242
|
-
|
|
1243
|
-
//check if debug messages are sent alongside
|
|
1244
|
-
if (msg && typeof (msg.debugDevices == 'array')) {
|
|
1245
|
-
debugDevices = msg.debugDevices;
|
|
1246
|
-
console.warn('debug devices is sent')
|
|
1247
|
-
}
|
|
1248
|
-
else
|
|
1249
|
-
debugDevices = [];
|
|
1250
|
-
if (debugMessages.byId) {
|
|
1251
|
-
debugMessages.byId = msg;
|
|
1252
|
-
if (msg) displayDebugMessages(debugMessages)
|
|
1253
|
-
}
|
|
1259
|
+
console.warn(JSON.stringify(msg))
|
|
1254
1260
|
if (msg.error) {
|
|
1255
1261
|
errorData.push(msg.error);
|
|
1262
|
+
delete msg.error;
|
|
1256
1263
|
isHerdsmanRunning = false;
|
|
1257
|
-
updateStartButton();
|
|
1258
1264
|
} else {
|
|
1259
1265
|
isHerdsmanRunning = true;
|
|
1260
|
-
updateStartButton();
|
|
1261
|
-
showDevices();
|
|
1262
|
-
getDebugMessages();
|
|
1263
|
-
getExclude();
|
|
1264
|
-
getBinding();
|
|
1265
1266
|
}
|
|
1267
|
+
coordinatorinfo = msg;
|
|
1268
|
+
updateStartButton()
|
|
1266
1269
|
}
|
|
1270
|
+
sendTo(namespace, 'getDevices', {}, function (msg) {
|
|
1271
|
+
if (msg) {
|
|
1272
|
+
devices = msg.devices ? msg.devices : [];
|
|
1273
|
+
// check if stashed error messages are sent alongside
|
|
1274
|
+
if (msg.clean)
|
|
1275
|
+
$('#state_cleanup_btn').removeClass('hide');
|
|
1276
|
+
else
|
|
1277
|
+
$('#state_cleanup_btn').addClass('hide');
|
|
1278
|
+
if (msg.errors && msg.errors.length > 0) {
|
|
1279
|
+
$('#show_errors_btn').removeClass('hide');
|
|
1280
|
+
errorData = msg.errors;
|
|
1281
|
+
}
|
|
1282
|
+
else {
|
|
1283
|
+
$('#show_errors_btn').addClass('hide');
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
//check if debug messages are sent alongside
|
|
1287
|
+
if (msg && typeof (msg.debugDevices == 'array')) {
|
|
1288
|
+
debugDevices = msg.debugDevices;
|
|
1289
|
+
console.warn('debug devices is sent')
|
|
1290
|
+
}
|
|
1291
|
+
else
|
|
1292
|
+
debugDevices = [];
|
|
1293
|
+
if (debugMessages.byId) {
|
|
1294
|
+
debugMessages.byId = msg;
|
|
1295
|
+
if (msg) displayDebugMessages(debugMessages)
|
|
1296
|
+
}
|
|
1297
|
+
if (msg.error) {
|
|
1298
|
+
errorData.push(msg.error);
|
|
1299
|
+
isHerdsmanRunning = false;
|
|
1300
|
+
updateStartButton();
|
|
1301
|
+
showDevices();
|
|
1302
|
+
} else {
|
|
1303
|
+
isHerdsmanRunning = true;
|
|
1304
|
+
updateStartButton();
|
|
1305
|
+
showDevices();
|
|
1306
|
+
getDebugMessages();
|
|
1307
|
+
getExclude();
|
|
1308
|
+
getBinding();
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
});
|
|
1267
1312
|
});
|
|
1268
1313
|
}
|
|
1269
1314
|
|
|
@@ -1288,24 +1333,27 @@ function getDeviceCard(devId) {
|
|
|
1288
1333
|
|
|
1289
1334
|
function getMap() {
|
|
1290
1335
|
$('#refresh').addClass('disabled');
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
if (msg
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1336
|
+
if (isHerdsmanRunning) {
|
|
1337
|
+
sendTo(namespace, 'getMap', {}, function (msg) {
|
|
1338
|
+
$('#refresh').removeClass('disabled');
|
|
1339
|
+
if (msg) {
|
|
1340
|
+
if (msg.error) {
|
|
1341
|
+
errorData.push(msg.error);
|
|
1342
|
+
isHerdsmanRunning = false;
|
|
1343
|
+
updateStartButton();
|
|
1344
|
+
} else {
|
|
1345
|
+
isHerdsmanRunning = true;
|
|
1346
|
+
updateStartButton();
|
|
1347
|
+
if (msg.errors.length > 0 && $('#errorCollectionOn').is(':checked')) {
|
|
1348
|
+
showMessage(msg.errors.join('<p>'), 'Map generation messages');
|
|
1349
|
+
}
|
|
1350
|
+
map = msg;
|
|
1351
|
+
showNetworkMap(devices, map);
|
|
1303
1352
|
}
|
|
1304
|
-
map = msg;
|
|
1305
|
-
showNetworkMap(devices, map);
|
|
1306
1353
|
}
|
|
1307
|
-
}
|
|
1308
|
-
}
|
|
1354
|
+
});
|
|
1355
|
+
}
|
|
1356
|
+
else showMessage('Unable to generate map, the zigbee subsystem is inactive', 'Map generation error');
|
|
1309
1357
|
}
|
|
1310
1358
|
|
|
1311
1359
|
function getRandomExtPanID()
|
|
@@ -1328,6 +1376,7 @@ function getRandomChannel()
|
|
|
1328
1376
|
// the function loadSettings has to exist ...
|
|
1329
1377
|
|
|
1330
1378
|
function load(settings, onChange) {
|
|
1379
|
+
console.warn(JSON.stringify(settings));
|
|
1331
1380
|
if (settings.extPanID === undefined || settings.extPanID == '') {
|
|
1332
1381
|
settings.channel = getRandomChannel();
|
|
1333
1382
|
}
|
|
@@ -1439,6 +1488,7 @@ function load(settings, onChange) {
|
|
|
1439
1488
|
if (!$('#pairing').hasClass('pulse')) {
|
|
1440
1489
|
letsPairing();
|
|
1441
1490
|
}
|
|
1491
|
+
console.warn('lets pairing');
|
|
1442
1492
|
showPairingProcess();
|
|
1443
1493
|
});
|
|
1444
1494
|
|
|
@@ -1454,6 +1504,10 @@ function load(settings, onChange) {
|
|
|
1454
1504
|
deleteNvBackupConfirmation();
|
|
1455
1505
|
});
|
|
1456
1506
|
|
|
1507
|
+
$('#ErrorNotificationBtn').click(function () {
|
|
1508
|
+
if (!isHerdsmanRunning) showMessage('The zigbee subsystem is not running. Please ensure that the configuration is correct and either start the subsystem manually from the hardware tab or set it to automatically start in the settings.', _('Zigbee subsystem error'));
|
|
1509
|
+
})
|
|
1510
|
+
|
|
1457
1511
|
$('#viewconfig').click(function () {
|
|
1458
1512
|
showViewConfig();
|
|
1459
1513
|
});
|
|
@@ -1555,7 +1609,7 @@ function showMessages() {
|
|
|
1555
1609
|
}
|
|
1556
1610
|
|
|
1557
1611
|
function showPairingProcess() {
|
|
1558
|
-
$('#modalpairing').modal({
|
|
1612
|
+
if (isHerdsmanRunning) $('#modalpairing').modal({
|
|
1559
1613
|
startingTop: '4%',
|
|
1560
1614
|
endingTop: '10%',
|
|
1561
1615
|
dismissible: false
|
|
@@ -1628,6 +1682,7 @@ function getDevId(adapterDevId) {
|
|
|
1628
1682
|
|
|
1629
1683
|
|
|
1630
1684
|
function updateStartButton(block) {
|
|
1685
|
+
console.warn(`update start button with${isHerdsmanRunning ? ' Herdsman' : 'out Herdsman'}`);
|
|
1631
1686
|
if (block) {
|
|
1632
1687
|
$('#show_test_run').addClass('disabled');
|
|
1633
1688
|
$('#reset-btn').addClass('disabled');
|
|
@@ -1645,6 +1700,11 @@ function updateStartButton(block) {
|
|
|
1645
1700
|
$('#show_test_run').removeClass('disabled');
|
|
1646
1701
|
$('#deleteNVRam-btn').removeClass('disabled');
|
|
1647
1702
|
$('#reset-btn').removeClass('disabled');
|
|
1703
|
+
$('#fw_check_btn').removeClass('hide');
|
|
1704
|
+
$('#add_grp_btn').removeClass('hide');
|
|
1705
|
+
$('#touchlink_btn').removeClass('hide');
|
|
1706
|
+
$('#code_pairing').removeClass('hide');
|
|
1707
|
+
//$('#pairing').removeClass('hide');
|
|
1648
1708
|
}
|
|
1649
1709
|
else {
|
|
1650
1710
|
$('#ErrorNotificationIcon').addClass('icon-red')
|
|
@@ -1654,6 +1714,11 @@ function updateStartButton(block) {
|
|
|
1654
1714
|
$('#show_test_run').removeClass('disabled');
|
|
1655
1715
|
$('#deleteNVRam-btn').removeClass('disabled');
|
|
1656
1716
|
$('#reset-btn').addClass('disabled');
|
|
1717
|
+
$('#fw_check_btn').addClass('hide');
|
|
1718
|
+
$('#add_grp_btn').addClass('hide');
|
|
1719
|
+
$('#touchlink_btn').addClass('hide');
|
|
1720
|
+
$('#code_pairing').addClass('hide');
|
|
1721
|
+
//$('#pairing').addClass('hide');
|
|
1657
1722
|
}
|
|
1658
1723
|
}
|
|
1659
1724
|
// subscribe to changes
|
|
@@ -2676,7 +2741,7 @@ function prepareBindingDialog(bindObj) {
|
|
|
2676
2741
|
// check for output clusters
|
|
2677
2742
|
let allow = false;
|
|
2678
2743
|
for (const cluster of allowClusters) {
|
|
2679
|
-
for (const ep of device.info.endpoints) {
|
|
2744
|
+
if (device.info.endpoints) for (const ep of device.info.endpoints) {
|
|
2680
2745
|
if (ep.outputClusters.includes(cluster)) {
|
|
2681
2746
|
allow = true;
|
|
2682
2747
|
break;
|
|
@@ -2727,7 +2792,7 @@ function prepareBindingDialog(bindObj) {
|
|
|
2727
2792
|
// check for input clusters
|
|
2728
2793
|
let allow = false;
|
|
2729
2794
|
for (const cluster of allowClusters) {
|
|
2730
|
-
for (const ep of device.info.endpoints) {
|
|
2795
|
+
if (device.info.endpoints) for (const ep of device.info.endpoints) {
|
|
2731
2796
|
if (ep.inputClusters.includes(cluster)) {
|
|
2732
2797
|
allow = true;
|
|
2733
2798
|
break;
|
|
@@ -3656,34 +3721,34 @@ function validateConfigData(key, val) {
|
|
|
3656
3721
|
if (validatableKeys.indexOf(key) < 0 || !val) return;
|
|
3657
3722
|
if (warnLevel[key]) {
|
|
3658
3723
|
if (warnLevel[key](val)) {
|
|
3659
|
-
console.warn(`warning set for ${key} (${val})`)
|
|
3724
|
+
//console.warn(`warning set for ${key} (${val})`)
|
|
3660
3725
|
$(`#${key}_ALERT`).removeClass('hide')
|
|
3661
3726
|
} else $(`#${key}_ALERT`).addClass('hide')
|
|
3662
3727
|
}
|
|
3663
3728
|
if (nvRamBackup[key]) {
|
|
3664
|
-
console.warn(`value of ${key} is ${val} (${nvRamBackup[key]})`);
|
|
3729
|
+
//console.warn(`value of ${key} is ${val} (${nvRamBackup[key]})`);
|
|
3665
3730
|
if ((typeof val == 'string' && typeof nvRamBackup[key] == 'string' && val.toLowerCase == nvRamBackup[key].toLowerCase) || val == nvRamBackup[key])
|
|
3666
3731
|
{
|
|
3667
|
-
console.warn(`ok set for ${key} (${val})`)
|
|
3732
|
+
//console.warn(`ok set for ${key} (${val})`)
|
|
3668
3733
|
$(`#${key}_OK`).removeClass('hide')
|
|
3669
3734
|
$(`#${key}_NOK`).addClass('hide')
|
|
3670
3735
|
}
|
|
3671
3736
|
else
|
|
3672
3737
|
{
|
|
3673
|
-
console.warn(`nok set for ${key} (${val})`)
|
|
3738
|
+
//console.warn(`nok set for ${key} (${val})`)
|
|
3674
3739
|
$(`#${key}_OK`).addClass('hide')
|
|
3675
3740
|
$(`#${key}_NOK`).removeClass('hide')
|
|
3676
3741
|
}
|
|
3677
3742
|
}
|
|
3678
3743
|
else {
|
|
3679
|
-
console.warn(`noval set for ${key} (${val})`)
|
|
3744
|
+
//console.warn(`noval set for ${key} (${val})`)
|
|
3680
3745
|
$(`#${key}_OK`).addClass('hide')
|
|
3681
3746
|
$(`#${key}_NOK`).addClass('hide')
|
|
3682
3747
|
}
|
|
3683
3748
|
}
|
|
3684
3749
|
|
|
3685
3750
|
function validateNVRamBackup(update, src) {
|
|
3686
|
-
console.warn('validateNVRam');
|
|
3751
|
+
//console.warn('validateNVRam');
|
|
3687
3752
|
const validatedKeys = src ? [src] : validatableKeys;
|
|
3688
3753
|
const validator = {};
|
|
3689
3754
|
for (const key of validatedKeys) {
|
|
@@ -3703,9 +3768,11 @@ function validateNVRamBackup(update, src) {
|
|
|
3703
3768
|
function readNVRamBackup(update) {
|
|
3704
3769
|
console.warn('read nvRam')
|
|
3705
3770
|
sendTo(namespace, 'readNVRam', {}, function(msg) {
|
|
3771
|
+
console.warn(JSON.stringify(msg));
|
|
3706
3772
|
if (msg) {
|
|
3707
3773
|
if (msg.error && update) {
|
|
3708
|
-
|
|
3774
|
+
if (msg.error.includes('ENOENT')) showMessage('Unable to read nvRam backup - no backup available.',_('Error'))
|
|
3775
|
+
else showMessage(msg.error, _('Error'));
|
|
3709
3776
|
delete msg.error;
|
|
3710
3777
|
}
|
|
3711
3778
|
nvRamBackup = msg;
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
{
|
|
2
|
-
"Add binding": "
|
|
3
|
-
"Add group": "
|
|
2
|
+
"Add binding": "Bindung hinzufügen",
|
|
3
|
+
"Add group": "Gruppe erstellen",
|
|
4
4
|
"Attribute ID": "Attribut-ID",
|
|
5
|
-
"Binding": "
|
|
6
|
-
"Binding configuration": "
|
|
7
|
-
"COM port name": "
|
|
5
|
+
"Binding": "Bindung",
|
|
6
|
+
"Binding configuration": "Bindung konfigurieren",
|
|
7
|
+
"COM port name": "Serieller Anschluss / Netzwerk IP/Port",
|
|
8
8
|
"Cancel": "Abbrechen",
|
|
9
9
|
"Channel": "Kanal",
|
|
10
|
-
"ChannelChangeText": "Kanal
|
|
10
|
+
"ChannelChangeText": "Der Kanal bestimmt die verwendete Funkfrequenz im 2.4 GHz Band. Er sollte so gewählt werden dass keine Konflikte mit vorhandenen WLan Netzwerken auftreten. <b>Nach einem Kanalwechsel müssen verschiedene Geräte neu am Netzwerk angelernt werden</b>",
|
|
11
11
|
"Check firmware updates": "Auf Firmware-Updates überprüfen",
|
|
12
|
-
"Check if your Command needs to submit a value. For example, cmd 'write' needs the value you want to write to your device.": "
|
|
12
|
+
"Check if your Command needs to submit a value. For example, cmd 'write' needs the value you want to write to your device.": "Aktivieren Sie diese Option falls Ihr Befehl einen Wert senden muss. Zum Beispiel benötigt cmd 'write' den Wert, den Sie auf Ihr Gerät schreiben möchten.",
|
|
13
13
|
"Choose channel": "Kanal auswählen",
|
|
14
14
|
"Choose type": "Typ auswählen",
|
|
15
15
|
"Cluster ID": "Cluster-ID",
|
|
16
16
|
"Command": "Befehl",
|
|
17
17
|
"Command Type": "Befehlstyp",
|
|
18
|
-
"Configure reporting": "Konfigurieren
|
|
19
|
-
"Countdown": "
|
|
18
|
+
"Configure reporting": "Konfigurieren der Gerätebenachrichtigungen",
|
|
19
|
+
"Countdown": "Zeit für die das Netzwerk geöffnet wird - muss zwischen 10 und 240 sekunden betragen!",
|
|
20
20
|
"Delete confirmation": "Löschen bestätigen",
|
|
21
21
|
"Developer": "Entwickler",
|
|
22
22
|
"Device": "Gerät",
|
|
@@ -32,12 +32,12 @@
|
|
|
32
32
|
"Examples:": "Beispiele:",
|
|
33
33
|
"Expert Mode": "Expertenmodus",
|
|
34
34
|
"ExtPanID": "Erweiterte Pan ID",
|
|
35
|
-
"ExtPanIDText": "Die erweiterte PAN-ID ist die Hauptnetzwerk-ID, vergleichbar mit der SSID von WLAN-Netzwerken. Diese ID darf sich für vorhandene Netzwerke niemals ändern, da Sie sonst deine Geräte zurücksetzen und Sie neu koppeln müssen. Wenn Sie mehrere ZigBee-Adapter verwenden, <b>müssen Sie sicherstellen,</b> dass diese eindeutige ExtPanIDs verwenden. Geben Sie einfach 16 zufällige Hex-Zeichen ein (a-f und 0-9).",
|
|
36
|
-
"Force delete (for lost devices)": "Löschen erzwingen (für
|
|
35
|
+
"ExtPanIDText": "Die erweiterte PAN-ID ist die Hauptnetzwerk-ID, vergleichbar mit der SSID von WLAN-Netzwerken. Diese ID darf sich für vorhandene Netzwerke niemals ändern, da Sie sonst deine Geräte zurücksetzen und Sie neu koppeln müssen. Wenn Sie mehrere ZigBee-Adapter verwenden, <b>müssen Sie sicherstellen,</b> dass diese eindeutige ExtPanIDs verwenden. Geben Sie einfach 16 zufällige Hex-Zeichen ein (a-f und 0-9). Von der Verwendung von DDDDDDDDDDDDDDDD als ExtPanID wird <b>explizit abgeraten</b>,",
|
|
36
|
+
"Force delete (for lost devices)": "Löschen erzwingen (für nicht verbundene Geräte)",
|
|
37
37
|
"Groups": "Gruppen",
|
|
38
38
|
"Hard-Reset": "Hard-Reset",
|
|
39
39
|
"Hide": "Ausblenden",
|
|
40
|
-
"Let's pairing!": "Kopplung
|
|
40
|
+
"Let's pairing!": "Kopplung starten!",
|
|
41
41
|
"Map view config": "Kartenansicht konfigurieren",
|
|
42
42
|
"Name": "Name",
|
|
43
43
|
"Needs value": "Ein Wert wird benötigt",
|
|
@@ -46,11 +46,11 @@
|
|
|
46
46
|
"PanID": "Pan ID",
|
|
47
47
|
"PanIDText": "Pan ID ist eine vereinfachte ID (wird von Zigbee anstelle von ExtPanID verwendet, wo immer dies möglich ist). Dies sollte auch einzigartig sein. Hinweis: Das ZigBee-Netzwerk wählt möglicherweise eine andere Pan-ID als die hier angegebene, falls ID-Konflikte erkannt werden.",
|
|
48
48
|
"Parent/Child/Unknown": "Parent/Child/Unbekannt",
|
|
49
|
-
"Previous Parents": "
|
|
49
|
+
"Previous Parents": "Vorherige Parents",
|
|
50
50
|
"Read Firmware": "Firmware lesen",
|
|
51
51
|
"Refresh": "Aktualisieren",
|
|
52
52
|
"Rename device": "Gerät umbenennen",
|
|
53
|
-
"Reset Info": "Ein Soft-Reset startet den Coordinator und den Adapter neu. Ein Hard-Reset setzt die Liste
|
|
53
|
+
"Reset Info": "Ein Soft-Reset startet den Coordinator und den Adapter neu. Ein Hard-Reset setzt die Liste <b>aller</b> gekoppelten Geräte und den Coordinator zurück! Alle Geräte müssen anschließend neu gekoppelt werden!",
|
|
54
54
|
"Reset confirmation": "Reset bestätigen",
|
|
55
55
|
"Reset...": "Zurücksetzen…",
|
|
56
56
|
"Results": "Ergebnisse",
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"Yes": "Ja",
|
|
91
91
|
"You find good explanations what the settings mean": "Sie finden gute Erklärungen, was die Einstellungen bedeuten",
|
|
92
92
|
"Zigbee adapter": "Zigbee-Adapter",
|
|
93
|
-
"Zigbee-herdsman debug info": "Zigbee-herdsman Debug
|
|
93
|
+
"Zigbee-herdsman debug info": "Zigbee-herdsman Debug Meldungen",
|
|
94
94
|
"transmitPower": "CC1352P and CC26X2R1 Sendeleistung",
|
|
95
95
|
"№": "Nr.",
|
|
96
96
|
"and in": "und in",
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
"notImplementedText": "Sie können hier eigene Befehle an Ihre Geräte senden, die noch nicht als Objekte implementiert sind. Es kann auch verwendet werden, um undokumentierte Einstellungen Ihrer Geräte zu finden. Oder um die Auswirkungen von Einstellungen zu testen und zu entscheiden, ob es sich lohnt, sie als Objekt zu implementieren. Und so weiter...",
|
|
99
99
|
"to make it available for other user too": "um es auch für andere Benutzer verfügbar zu machen",
|
|
100
100
|
"Excludes": "ausschließen",
|
|
101
|
-
"ExcludeTextTranslation": "
|
|
101
|
+
"ExcludeTextTranslation": "Über die \"Local Overrides\" können Sie für bestimmte Gerätetypen Optionen setzen. Einstellungen die hier gemacht werden sind erst aktiv nachdem der Adapter neu gestartet wurde.",
|
|
102
102
|
"Please contribute your discoveries": "Bitte geben Sie uns Ihre Vorschläge",
|
|
103
103
|
"zigbee-shepherd": "Sie können die zu sendenden Rohdaten hier bearbeiten. Verwenden Sie diese nicht, wenn Sie sich nicht sicher sind, was Sie tun! Verwenden Sie das JSON-Format (Attributnamen in doppelten Anführungszeichen!). Es können auch zusätzliche Eigenschaften hinzugefügt werden. Siehe Beispiele oben. (Format wie von zigbee-shepherd verwendet)",
|
|
104
104
|
"SettingsExclude": "Den Start des Adapters mit inkonsistenter Konfiguration erzwingen(nicht empfohlen). Bitte aktualisieren Sie den Adapter auf kompatible Firmware und erstellen Sie Ihr Netzwerk so schnell wie möglich neu.",
|