iobroker.zigbee 1.8.5 → 1.8.7
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 +3 -0
- package/admin/adapter-settings.js +244 -0
- package/admin/admin.js +13 -6
- package/admin/tab_m.html +2 -1
- package/io-package.json +18 -9
- package/lib/exposes.js +6 -5
- package/lib/states.js +526 -511
- package/lib/utils.js +5 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/*global $, location, socket, document, window, io, alert, load, systemDictionary, systemLang, translateAll*/
|
|
2
|
+
const path = location.pathname;
|
|
3
|
+
const parts = path.split('/');
|
|
4
|
+
parts.splice(-3);
|
|
5
|
+
|
|
6
|
+
const socket = io.connect('/', { path: parts.join('/') + '/socket.io' });
|
|
7
|
+
var query = (window.location.search || '').replace(/^\?/, '').replace(/#.*$/, '');
|
|
8
|
+
var args = {};
|
|
9
|
+
let theme = null;
|
|
10
|
+
|
|
11
|
+
// parse parameters
|
|
12
|
+
query.trim().split('&').filter(function (t) { return t.trim(); }).forEach(function (b, i) {
|
|
13
|
+
const parts = b.split('=');
|
|
14
|
+
if (!i && parts.length === 1 && !isNaN(parseInt(b, 10))) {
|
|
15
|
+
args.instance = parseInt(b, 10);
|
|
16
|
+
}
|
|
17
|
+
var name = parts[0];
|
|
18
|
+
args[name] = parts.length === 2 ? parts[1] : true;
|
|
19
|
+
|
|
20
|
+
if (name === 'instance') {
|
|
21
|
+
args.instance = parseInt(args.instance, 10) || 0;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (args[name] === 'true') {
|
|
25
|
+
args[name] = true;
|
|
26
|
+
} else if (args[name] === 'false') {
|
|
27
|
+
args[name] = false;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
var instance = args.instance;
|
|
32
|
+
|
|
33
|
+
let common = null; // common information of adapter
|
|
34
|
+
const host = null; // host object on which the adapter runs
|
|
35
|
+
const changed = false;
|
|
36
|
+
let systemConfig;
|
|
37
|
+
let certs = [];
|
|
38
|
+
let adapter = '';
|
|
39
|
+
const onChangeSupported = false;
|
|
40
|
+
|
|
41
|
+
const tmp = window.location.pathname.split('/');
|
|
42
|
+
adapter = tmp[tmp.length - 2];
|
|
43
|
+
const _adapterInstance = 'system.adapter.' + adapter + '.' + instance;
|
|
44
|
+
|
|
45
|
+
$(document).ready(function () {
|
|
46
|
+
'use strict';
|
|
47
|
+
loadSystemConfig(function () {
|
|
48
|
+
if (typeof translateAll === 'function') translateAll();
|
|
49
|
+
loadSettings(prepareTooltips);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
// Read language settings
|
|
55
|
+
function loadSystemConfig(callback) {
|
|
56
|
+
socket.emit('getObject', 'system.config', function (err, res) {
|
|
57
|
+
if (!err && res && res.common) {
|
|
58
|
+
systemLang = res.common.language || systemLang;
|
|
59
|
+
systemConfig = res;
|
|
60
|
+
}
|
|
61
|
+
socket.emit('getObject', 'system.certificates', function (err, res) {
|
|
62
|
+
if (!err && res) {
|
|
63
|
+
if (res.native && res.native.certificates) {
|
|
64
|
+
certs = [];
|
|
65
|
+
for (const c in res.native.certificates) {
|
|
66
|
+
if (res.native.certificates.hasOwnProperty(c) && !res.native.certificates[c]) continue;
|
|
67
|
+
const _cert = {
|
|
68
|
+
name: c,
|
|
69
|
+
type: (res.native.certificates[c].substring(0, '-----BEGIN RSA PRIVATE KEY'.length) === '-----BEGIN RSA PRIVATE KEY' || res.native.certificates[c].substring(0, '-----BEGIN PRIVATE KEY'.length) === '-----BEGIN PRIVATE KEY') ? 'private' : 'public'
|
|
70
|
+
};
|
|
71
|
+
if (_cert.type === 'public') {
|
|
72
|
+
const m = res.native.certificates[c].split('-----END CERTIFICATE-----');
|
|
73
|
+
let count = 0;
|
|
74
|
+
for (let _m = 0; _m < m.length; _m++) {
|
|
75
|
+
if (m[_m].replace(/[\r\n|\r|\n]+/, '').trim()) count++;
|
|
76
|
+
}
|
|
77
|
+
if (count > 1) _cert.type = 'chained';
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
certs.push(_cert);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (callback) callback();
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function loadSettings(callback) {
|
|
90
|
+
socket.emit('getObject', _adapterInstance, function (err, res) {
|
|
91
|
+
if (!err && res && res.native) {
|
|
92
|
+
$('.adapter-instance').html(adapter + '.' + instance);
|
|
93
|
+
$('.adapter-config').html('system.adapter.' + adapter + '.' + instance);
|
|
94
|
+
common = res.common;
|
|
95
|
+
if (res.common && res.common.name) $('.adapter-name').html(res.common.name);
|
|
96
|
+
if (typeof load === 'undefined') {
|
|
97
|
+
alert('Please implement save function in your admin/index.html');
|
|
98
|
+
} else {
|
|
99
|
+
// detect, that we are now in react container (themeNames = ['dark', 'blue', 'colored', 'light'])
|
|
100
|
+
|
|
101
|
+
const _query = query.split('&');
|
|
102
|
+
|
|
103
|
+
for (var q = 0; q < _query.length; q++) {
|
|
104
|
+
if (_query[q].indexOf('react=') !== -1) {
|
|
105
|
+
$('.adapter-container').addClass('react-' + _query[q].substring(6));
|
|
106
|
+
theme = 'react-' + _query[q].substring(6);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
load(res.native, onChange);
|
|
111
|
+
}
|
|
112
|
+
if (typeof callback === 'function') {
|
|
113
|
+
callback();
|
|
114
|
+
}
|
|
115
|
+
} else {
|
|
116
|
+
if (typeof callback === 'function') {
|
|
117
|
+
callback();
|
|
118
|
+
}
|
|
119
|
+
alert('error loading settings for ' + _adapterInstance + '\n\n' + err);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function prepareTooltips() {
|
|
125
|
+
$('.admin-icon').each(function () {
|
|
126
|
+
let id = $(this).data('id');
|
|
127
|
+
if (!id) {
|
|
128
|
+
let $prev = $(this).prev();
|
|
129
|
+
let $input = $prev.find('input');
|
|
130
|
+
if (!$input.length) $input = $prev.find('select');
|
|
131
|
+
if (!$input.length) $input = $prev.find('textarea');
|
|
132
|
+
|
|
133
|
+
if (!$input.length) {
|
|
134
|
+
$prev = $prev.parent();
|
|
135
|
+
$input = $prev.find('input');
|
|
136
|
+
if (!$input.length) $input = $prev.find('select');
|
|
137
|
+
if (!$input.length) $input = $prev.find('textarea');
|
|
138
|
+
}
|
|
139
|
+
if ($input.length) id = $input.attr('id');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (!id) return;
|
|
143
|
+
|
|
144
|
+
let tooltip = '';
|
|
145
|
+
if (systemDictionary['tooltip_' + id]) {
|
|
146
|
+
tooltip = systemDictionary['tooltip_' + id][systemLang] || systemDictionary['tooltip_' + id].en;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
let icon = '';
|
|
150
|
+
let link = $(this).data('link');
|
|
151
|
+
if (link) {
|
|
152
|
+
if (link === true) {
|
|
153
|
+
if (common.readme) {
|
|
154
|
+
link = common.readme + '#' + id;
|
|
155
|
+
} else {
|
|
156
|
+
link = 'https://github.com/ioBroker/ioBroker.' + common.name + '#' + id;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (!link.match('^https?:\/\/')) {
|
|
160
|
+
if (common.readme) {
|
|
161
|
+
link = common.readme + '#' + link;
|
|
162
|
+
} else {
|
|
163
|
+
link = 'https://github.com/ioBroker/ioBroker.' + common.name + '#' + link;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
icon += '<a class="admin-tooltip-link" target="config_help" href="' + link + '" title="' + (tooltip || systemDictionary.htooltip[systemLang]) + '"><img class="admin-tooltip-icon" src="../../img/info.png" /></a>';
|
|
167
|
+
} else if (tooltip) {
|
|
168
|
+
icon += '<img class="admin-tooltip-icon" title="' + tooltip + '" src="../../img/info.png"/>';
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (icon) {
|
|
172
|
+
$(this).html(icon);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
$('.admin-text').each(function () {
|
|
176
|
+
let id = $(this).data('id');
|
|
177
|
+
if (!id) {
|
|
178
|
+
let $prev = $(this).prev();
|
|
179
|
+
let $input = $prev.find('input');
|
|
180
|
+
if (!$input.length) $input = $prev.find('select');
|
|
181
|
+
if (!$input.length) $input = $prev.find('textarea');
|
|
182
|
+
if (!$input.length) {
|
|
183
|
+
$prev = $prev.parent();
|
|
184
|
+
$input = $prev.find('input');
|
|
185
|
+
if (!$input.length) $input = $prev.find('select');
|
|
186
|
+
if (!$input.length) $input = $prev.find('textarea');
|
|
187
|
+
}
|
|
188
|
+
if ($input.length) id = $input.attr('id');
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (!id) return;
|
|
192
|
+
|
|
193
|
+
// check if translation for this exist
|
|
194
|
+
if (systemDictionary['info_' + id]) {
|
|
195
|
+
$(this).html('<span class="admin-tooltip-text">' + (systemDictionary['info_' + id][systemLang] || systemDictionary['info_' + id].en) + '</span>');
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
function sendTo(_adapter_instance, command, message, callback) {
|
|
202
|
+
socket.emit('sendTo', (_adapter_instance || adapter + '.' + instance), command, message, callback);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function sendToHost(host, command, message, callback) {
|
|
206
|
+
socket.emit('sendToHost', host || common.host, command, message, callback);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function onChange(isChanged) {
|
|
210
|
+
//
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function showMessage(message, title, icon) {
|
|
214
|
+
var $dialogMessage;
|
|
215
|
+
// noinspection JSJQueryEfficiency
|
|
216
|
+
$dialogMessage = $('#dialog-message');
|
|
217
|
+
if (!$dialogMessage.length) {
|
|
218
|
+
$('body').append(
|
|
219
|
+
'<div class="m"><div id="dialog-message" class="modal modal-fixed-footer">' +
|
|
220
|
+
' <div class="modal-content">' +
|
|
221
|
+
' <h6 class="dialog-title title"></h6>' +
|
|
222
|
+
' <p><i class="large material-icons dialog-icon"></i><span class="dialog-text"></span></p>' +
|
|
223
|
+
' </div>' +
|
|
224
|
+
' <div class="modal-footer">' +
|
|
225
|
+
' <a class="modal-action modal-close waves-effect waves-green btn-flat translate">Ok</a>' +
|
|
226
|
+
' </div>' +
|
|
227
|
+
'</div></div>');
|
|
228
|
+
$dialogMessage = $('#dialog-message');
|
|
229
|
+
}
|
|
230
|
+
if (icon) {
|
|
231
|
+
$dialogMessage.find('.dialog-icon')
|
|
232
|
+
.show()
|
|
233
|
+
.html(icon);
|
|
234
|
+
} else {
|
|
235
|
+
$dialogMessage.find('.dialog-icon').hide();
|
|
236
|
+
}
|
|
237
|
+
if (title) {
|
|
238
|
+
$dialogMessage.find('.dialog-title').html(title).show();
|
|
239
|
+
} else {
|
|
240
|
+
$dialogMessage.find('.dialog-title').hide();
|
|
241
|
+
}
|
|
242
|
+
$dialogMessage.find('.dialog-text').html(message);
|
|
243
|
+
$dialogMessage.modal().modal('open');
|
|
244
|
+
}
|
package/admin/admin.js
CHANGED
|
@@ -767,20 +767,27 @@ function getMap() {
|
|
|
767
767
|
// the function loadSettings has to exist ...
|
|
768
768
|
// eslint-disable-next-line no-unused-vars
|
|
769
769
|
function load(settings, onChange) {
|
|
770
|
-
settings.panID
|
|
771
|
-
|
|
770
|
+
if (settings.panID === undefined) {
|
|
771
|
+
settings.panID = 6754;
|
|
772
|
+
}
|
|
773
|
+
if (settings.extPanID === undefined) {
|
|
774
|
+
settings.extPanID = 'DDDDDDDDDDDDDDDD';
|
|
775
|
+
}
|
|
772
776
|
// fix for previous wrong value
|
|
773
777
|
if (settings.extPanID === 'DDDDDDDDDDDDDDD') {
|
|
774
778
|
settings.extPanID = 'DDDDDDDDDDDDDDDD';
|
|
775
779
|
}
|
|
776
|
-
|
|
777
|
-
if (settings.
|
|
780
|
+
|
|
781
|
+
if (settings.precfgkey === undefined) {
|
|
782
|
+
settings.precfgkey = '01030507090B0D0F00020406080A0C0D';
|
|
783
|
+
}
|
|
784
|
+
if (settings.channel === undefined) {
|
|
778
785
|
settings.channel = 11;
|
|
779
786
|
}
|
|
780
787
|
if (settings.disablePing === undefined) {
|
|
781
788
|
settings.disablePing = false;
|
|
782
789
|
}
|
|
783
|
-
|
|
790
|
+
|
|
784
791
|
// example: select elements with id=key and class=value and insert value
|
|
785
792
|
for (const key in settings) {
|
|
786
793
|
if (savedSettings.indexOf(key) === -1) {
|
|
@@ -2803,7 +2810,7 @@ function getDashCard(dev, groupImage) {
|
|
|
2803
2810
|
options.push(`<option value="${key}" ${(val == key) ? 'selected' : ''}>${value}</option>`);
|
|
2804
2811
|
}
|
|
2805
2812
|
}
|
|
2806
|
-
val = `<select class="browser-default enum" style="height: 16px; padding: 0; width: auto; display: inline-block">${options.join('')}</select>`;
|
|
2813
|
+
val = `<select class="browser-default enum" style="color : white; background-color: grey; height: 16px; padding: 0; width: auto; display: inline-block">${options.join('')}</select>`;
|
|
2807
2814
|
} else {
|
|
2808
2815
|
val = `<span class="dash value">${val} ${(stateDef.unit) ? stateDef.unit : ''}</span>`;
|
|
2809
2816
|
}
|
package/admin/tab_m.html
CHANGED
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
<script type="text/javascript" src="../../js/translate.js"></script>
|
|
16
16
|
<script type="text/javascript" src="../../lib/js/materialize.js"></script>
|
|
17
17
|
<script type="text/javascript" >var noConfigDialog = true;</script><!-- Deactivate buttons -->
|
|
18
|
-
<script type="text/javascript" src="
|
|
18
|
+
<script type="text/javascript" src="adapter-settings.js"></script>
|
|
19
|
+
|
|
19
20
|
<script>
|
|
20
21
|
// overload showMessage
|
|
21
22
|
function showMessage(message, title, icon) {
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "zigbee",
|
|
4
|
-
"version": "1.8.
|
|
4
|
+
"version": "1.8.7",
|
|
5
5
|
"news": {
|
|
6
|
+
"1.8.7": {
|
|
7
|
+
"en": "fix exposes",
|
|
8
|
+
"de": "belichtet fix",
|
|
9
|
+
"ru": "исправить экспозиции",
|
|
10
|
+
"pt": "corrigir expões",
|
|
11
|
+
"nl": "vertaling:",
|
|
12
|
+
"fr": "fix expose",
|
|
13
|
+
"it": "fix espone",
|
|
14
|
+
"es": "arreglar expone",
|
|
15
|
+
"pl": "naprawić",
|
|
16
|
+
"uk": "фіксувати висадки",
|
|
17
|
+
"zh-cn": "fix 暴露"
|
|
18
|
+
},
|
|
19
|
+
"1.8.6": {
|
|
20
|
+
"en": "fix exposes",
|
|
21
|
+
"de": "fix exposes"
|
|
22
|
+
},
|
|
6
23
|
"1.8.5": {
|
|
7
24
|
"en": "fix for new code",
|
|
8
25
|
"de": "fix für neuen code",
|
|
@@ -48,14 +65,6 @@
|
|
|
48
65
|
"pl": "Pakiet\nDodane nazwy portów seryjnych w dialogach konfiguracyjnych",
|
|
49
66
|
"uk": "Пакети оновлені\nДодано імена серійних портів у діалоговому вікні конфігурації",
|
|
50
67
|
"zh-cn": "更新的包装\n加 口号港口"
|
|
51
|
-
},
|
|
52
|
-
"1.7.7": {
|
|
53
|
-
"en": "Update dependencies",
|
|
54
|
-
"de": "Update dependencies"
|
|
55
|
-
},
|
|
56
|
-
"1.7.6": {
|
|
57
|
-
"en": "ikea fix ",
|
|
58
|
-
"de": "ikea fix "
|
|
59
68
|
}
|
|
60
69
|
},
|
|
61
70
|
"title": "Zigbee",
|
package/lib/exposes.js
CHANGED
|
@@ -803,16 +803,17 @@ function applyExposes(mappedDevices, byModel, allExcludesObj) {
|
|
|
803
803
|
const allExcludesStr = JSON.stringify(allExcludesObj);
|
|
804
804
|
// create or update device from exposes
|
|
805
805
|
for (const deviceDef of zigbeeHerdsmanConverters.definitions) {
|
|
806
|
-
|
|
806
|
+
|
|
807
|
+
const stripModel = utils.getModelRegEx(deviceDef.model);
|
|
807
808
|
// check if device is mapped
|
|
808
|
-
const existsMap = byModel.get(
|
|
809
|
+
const existsMap = byModel.get(stripModel);
|
|
809
810
|
|
|
810
|
-
if ((deviceDef.hasOwnProperty('exposes') && (!existsMap || !existsMap.hasOwnProperty('states'))) || allExcludesStr.indexOf(
|
|
811
|
+
if ((deviceDef.hasOwnProperty('exposes') && (!existsMap || !existsMap.hasOwnProperty('states'))) || allExcludesStr.indexOf(stripModel) > 0) {
|
|
811
812
|
try {
|
|
812
|
-
const newDevice = createFromExposes(
|
|
813
|
+
const newDevice = createFromExposes(stripModel, deviceDef);
|
|
813
814
|
if (!existsMap) {
|
|
814
815
|
mappedDevices.push(newDevice);
|
|
815
|
-
byModel.set(
|
|
816
|
+
byModel.set(stripModel, newDevice);
|
|
816
817
|
} else {
|
|
817
818
|
existsMap.states = newDevice.states;
|
|
818
819
|
existsMap.exposed = true;
|