iobroker.zigbee 2.0.3 → 2.0.4
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 +38 -51
- package/admin/admin.js +19 -211
- package/admin/img/philips_hue_lom001.png +0 -0
- package/admin/tab_m.html +8 -13
- 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 +62 -28
- package/lib/commands.js +1 -16
- package/lib/developer.js +0 -0
- package/lib/exposes.js +1 -1
- package/lib/groups.js +8 -6
- package/lib/localConfig.js +2 -1
- package/lib/ota.js +6 -6
- package/lib/statescontroller.js +97 -270
- package/lib/zbDeviceAvailability.js +2 -2
- package/lib/zbDeviceConfigure.js +15 -22
- package/lib/zigbeecontroller.js +6 -13
- package/main.js +193 -131
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -9,15 +9,18 @@
|
|
|
9
9
|
[](https://weblate.iobroker.net/engage/adapters/?utm_source=widget)
|
|
10
10
|
[](https://www.npmjs.com/package/iobroker.zigbee)
|
|
11
11
|
|
|
12
|
-
## ioBroker adapter for Zigbee devices via
|
|
12
|
+
## ioBroker adapter for Zigbee devices via TI cc26x2r/cc2538/cc26x2px and deCONZ ConBee/RaspBee.
|
|
13
|
+
### cc2531/cc2530 are obsolet
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
With the Zigbee-coordinator based on Texas Instruments SoC, deCONZ ConBee/RaspBee modules, Silicon Labs EZSP v8 or ZIGate USB-TTL it creates its own zigbee-network, into which zigbee-devices are connected.
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
|
|
18
|
+
By working directly with the coordinator, the driver allows you to manage devices without additional application / gateways / bridge from device manufacturers (Xiaomi / TRADFRI / Hue / Tuya). About the device Zigbee-network can be read [here (in English)](https://www.zigbee2mqtt.io/information/zigbee_network.html).
|
|
17
19
|
|
|
18
20
|
## Hardware
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
|
|
23
|
+
One coordinator device is required for each zigbee Adapter instance. The device must be flashed with the respective coordinator firmware. A list of supported coordinators, the necessary equipment for the firmware and the device preparation process for different coordinator devices are described [here in English](https://www.zigbee2mqtt.io/guide/adapters/) or [smarthomescene.com ](https://smarthomescene.com/blog/best-zigbee-dongles-for-home-assistant-2023/) or [here in Russian](https://myzigbee.ru/books/%D0%BF%D1%80%D0%BE%D1%88%D0%B8%D0%B2%D0%BA%D0%B8/page/%D0%BF%D1%80%D0%BE%D1%88%D0%B8%D0%B2%D0%BA%D0%B0-cc2531cc2530)
|
|
21
24
|
|
|
22
25
|
|
|
23
26
|
### Texas Instruments SoC
|
|
@@ -32,6 +35,7 @@ Current firmware files for these devices can be found [on GitHub](https://github
|
|
|
32
35
|
<span><img src="https://raw.githubusercontent.com/ioBroker/ioBroker.zigbee/master/docs/de/img/CC2538_CC2592_PA.PNG" width="100"></span>
|
|
33
36
|
<span><img src="https://raw.githubusercontent.com/ioBroker/ioBroker.zigbee/master/docs/de/img/cc26x2r.PNG" width="100"></span>
|
|
34
37
|
|
|
38
|
+
tutorial/zigbee.png
|
|
35
39
|
### Dresden Elektronik SoC
|
|
36
40
|
<span><img src="https://raw.githubusercontent.com/ioBroker/ioBroker.zigbee/master/docs/en/img/deconz.png" width="180"></span>
|
|
37
41
|
|
|
@@ -58,82 +62,62 @@ Support for [Silicon Lab Zigbee](https://www.silabs.com/wireless/zigbee) based a
|
|
|
58
62
|
Support for [ZiGate](https://zigate.fr) based adapters is experimental. The initial support for ZiGate is still not yet considered stable, and the project is in need of more developers volunteering to help with this integration. Please refer to the respective documentation on [this page](https://www.zigbee2mqtt.io/guide/adapters/) and [ongoing development discussion](https://github.com/Koenkk/zigbee-herdsman/issues/242) with regards to the state of ZiGate adapter implementation into the zigbee-herdsman and zigbee-herdsman-converters libraries which it depends on.
|
|
59
63
|
|
|
60
64
|
|
|
61
|
-
##
|
|
62
|
-
|
|
63
|
-
The adapter should **always** be installed from within the ioBroker Admin. Direct npm and GitHub installations are **not recommended**.
|
|
64
|
-
|
|
65
|
-
At first start, it is vital to set up the adapter settings. These include:
|
|
66
|
-
- the communication to the zigbee Coordinator (COM Port). This can be a device identifier or a network address for Network-based coordinators
|
|
67
|
-
- the required firmware-Type
|
|
68
|
-
- the network parameters PanID (a number between 0 and 65565), extended PanID (a 16 digit HEX number) and the zigbee Channel **important: Do not run the adapter without changing the values for PanID (6754) and Extended PanID (DDDDDDDDDDDDDDDD) to unique values for your Zigbee Installation.**
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-

|
|
72
|
-
Please refer to the [in depth documentation](docs/en/readme.md) ([german version](docs/de/readme.md), [russian version](docs/ru/readme.md)) for a detailed explanation on how to configure the adapter.
|
|
73
|
-
|
|
74
|
-
Once the adapter is up and running, the desired devices need to be integrated into the network. This requires for both the adapter and the device to be in pairing mode. Most new devices will be in pairing-mode when they are powered up for the first time, but some will require a special procedure for this. Please refer to the device manual for information on this.
|
|
65
|
+
## Work with adapter
|
|
75
66
|
|
|
76
|
-
|
|
77
|
-

|
|
67
|
+

|
|
78
68
|
|
|
79
|
-
|
|
69
|
+
To start the driver, you must specify the name of the port on which the Zigbee module (stick) is connected. Usually this is the port `/dev/ttyACM0` or `/dev/ttyUSB0` for the UART-connection. Or you can find with `ls -l /dev/serial/by-id` the device direct.
|
|
80
70
|
|
|
81
|
-
|
|
71
|
+
open the settings and change port
|
|
72
|
+

|
|
82
73
|
|
|
83
|
-
### Groups
|
|
84
74
|
|
|
85
|
-
|
|
86
|
-
Groups have the advantage that a single command is sent to control all group members. This is especially helpful when changing the groups brightness and/or color settings.
|
|
87
|
-
Note that not all devices may be added to groups - the device itself needs to support this feature.
|
|
75
|
+
For Windows, this will be the COM port number.
|
|
88
76
|
|
|
89
|
-
|
|
77
|
+
Starting from version 1.0.0, you can also use *tcp connection* for cases using esp8266 (or other microcontrollers) as serial-bridge. For example `tcp://192.168.1.46:8880`. Read more info here https://www.zigbee2mqtt.io/information/connecting_cc2530#via-an-esp8266
|
|
90
78
|
|
|
91
|
-
|
|
79
|
+
To connect devices, you need to switch the Zigbee coordinator to pairing mode by pressing the green button. The countdown will begin (60 seconds) until the device connectivity is available.
|
|
80
|
+
To connect Zigbee devices in most cases, just press the pairing button on the device itself. But there are features for some devices. More information about pairing with devices can be found [here (in English)](https://www.zigbee2mqtt.io/getting_started/pairing_devices.html)
|
|
92
81
|
|
|
93
|
-
|
|
94
|
-
Note that not all devices may be part of a binding - the devices themselves need to support this feature.
|
|
82
|
+
After successful pairing, the device appears in the configuration panel. If the device appears in the configuration panel but has the type "undefined", then this is an unknown device and cannot be worked with it. If the device is in the list of available devices, but added as "undefined", then try to remove the device and add it again.
|
|
95
83
|
|
|
96
|
-
The
|
|
84
|
+
The devices connected to the Zigbee-network and inform the coordinator of their status and events (button presses, motion detection, temperature change). This information is reflected in the ioBroker object-states. Some ioBroker states have feedback and send commands to the zigbee-device when the value changes (switching the state of the outlet or lamp, changing the scene or the brightness of the lamp).
|
|
97
85
|
|
|
98
|
-
###
|
|
86
|
+
### Device Groups
|
|
87
|
+
You may create groups of devices.
|
|
99
88
|
|
|
100
|
-
|
|
89
|
+

|
|
101
90
|
|
|
102
|
-
|
|
91
|
+
It is a Zigbee feature, intended for example to switch bulbs synchronized. Assign groups via device tabs edit button. A group will show as own "device" in Objects.
|
|
103
92
|
|
|
104
|
-
|
|
93
|
+

|
|
105
94
|
|
|
106
|
-
|
|
95
|
+
Note: Not all devices support groups (not supported by end devices like sensors).
|
|
107
96
|
|
|
108
|
-
The debug information is only available from the zigbee tab.
|
|
109
97
|
|
|
110
|
-
###
|
|
98
|
+
### Binding
|
|
111
99
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
The local overrides are only available from the instance configuration
|
|
115
|
-
|
|
116
|
-
### Developer Mode
|
|
117
|
-
|
|
118
|
-
The developer mode offers the ability to communicate with any paired device solely based on the details of the Zigbee communication rules. Use of this requires an insight into Zigbee Clusters, Attributes and messaging structure. It can be used to control devices which are not currently supported. An in depth desctiption of the developer Tab is available in the documentation.
|
|
119
|
-
|
|
120
|
-
The developer tab is only available from the instance configuration
|
|
100
|
+
https://www.zigbee2mqtt.io/information/binding
|
|
121
101
|
|
|
102
|
+
### Developer Tab
|
|
122
103
|
|
|
104
|
+
This is a tool for advanced users to test currently unsupported devices or enhance this adapter's functionality. More instructions can be found on the tab.
|
|
105
|
+

|
|
123
106
|
|
|
124
107
|
## Additional info
|
|
125
108
|
|
|
126
|
-
There is a [friendly project](https://github.com/koenkk/zigbee2mqtt) with similar functionality
|
|
109
|
+
There is a [friendly project](https://github.com/koenkk/zigbee2mqtt) with similar functionality on the same technologies, where you can work with the same devices using the MQTT protocol. Therefore, if any improvements or support for new zigbee-devices occur in the Zigbee2MQTT project, we can transfer and add the same functionality to this adapter. If you notice this, then write the issue - we'll postpone it.
|
|
127
110
|
|
|
128
111
|
There are knowledge bases that can be useful for working with Zigbee-devices and equipment:
|
|
129
|
-
* in English https://www.zigbee2mqtt.io/
|
|
112
|
+
* in English https://www.zigbee2mqtt.io/
|
|
130
113
|
* in Russian https://myzigbee.ru/
|
|
131
114
|
|
|
132
115
|
## Supported devices
|
|
133
116
|
|
|
134
|
-
|
|
117
|
+
[Works with devices from this list](https://github.com/ioBroker/ioBroker.zigbee/wiki/Supported-devices)
|
|
118
|
+
|
|
135
119
|
|
|
136
|
-
##
|
|
120
|
+
## More Information
|
|
137
121
|
|
|
138
122
|
[in Deutsch](https://github.com/ioBroker/ioBroker.zigbee/blob/master/docs/de/readme.md)
|
|
139
123
|
|
|
@@ -152,6 +136,9 @@ You can thank the authors by these links:
|
|
|
152
136
|
|
|
153
137
|
-----------------------------------------------------------------------------------------------------
|
|
154
138
|
## Changelog
|
|
139
|
+
### 2.0.4 (2025-03-09)
|
|
140
|
+
* back to 2.0.2
|
|
141
|
+
|
|
155
142
|
### 2.0.3 (2025-03-07)
|
|
156
143
|
* fix configured info
|
|
157
144
|
* fix battery voltage (V -> mV)
|
package/admin/admin.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/*global $, M, _, sendTo, systemLang, translateWord, translateAll, showMessage, socket, document, instance, vis, Option*/
|
|
2
|
+
|
|
2
3
|
/*
|
|
3
4
|
* you must run 'iobroker upload zigbee' if you edited this file to make changes visible
|
|
4
5
|
*/
|
|
@@ -30,10 +31,7 @@ let devices = [],
|
|
|
30
31
|
},
|
|
31
32
|
cidList,
|
|
32
33
|
shuffleInstance,
|
|
33
|
-
errorData = []
|
|
34
|
-
debugMessages = {};
|
|
35
|
-
const dbgMsgfilter = new Set();
|
|
36
|
-
const dbgMsghide = new Set();
|
|
34
|
+
errorData = [];
|
|
37
35
|
const updateCardInterval = setInterval(updateCardTimer, 6000);
|
|
38
36
|
|
|
39
37
|
const networkOptions = {
|
|
@@ -242,6 +240,7 @@ function getCard(dev) {
|
|
|
242
240
|
rooms.push(dev.rooms[r]);
|
|
243
241
|
}
|
|
244
242
|
}
|
|
243
|
+
console.warn('debug for ' + ieee + ' is ' + isDebug);
|
|
245
244
|
const room = rooms.join(',') || ' ';
|
|
246
245
|
const paired = (dev.paired) ? '' : '<i class="material-icons right">leak_remove</i>';
|
|
247
246
|
const rid = id.split('.').join('_');
|
|
@@ -401,7 +400,7 @@ function EndPointIDfromEndPoint(ep) {
|
|
|
401
400
|
}
|
|
402
401
|
|
|
403
402
|
function editName(id, name) {
|
|
404
|
-
console.
|
|
403
|
+
console.log('editName called with ' + name);
|
|
405
404
|
const dev = devices.find((d) => d._id == id);
|
|
406
405
|
$('#modaledit').find('input[id=\'d_name\']').val(name);
|
|
407
406
|
const groupables = [];
|
|
@@ -831,6 +830,7 @@ async function selectImageOverride(id) {
|
|
|
831
830
|
sendTo(namespace, 'getLocalImages', {}, function(msg) {
|
|
832
831
|
if (msg && msg.imageData) {
|
|
833
832
|
const imagedata = msg.imageData;
|
|
833
|
+
console.warn(JSON.stringify(dev.common));
|
|
834
834
|
const default_icon = (dev.common.type === 'group' ? dev.common.modelIcon : `img/${dev.common.type.replace(/\//g, '-')}.png`);
|
|
835
835
|
if (dev.legacyIcon) imagedata.unshift( { file:dev.legacyIcon, name:'legacy', data:dev.legacyIcon});
|
|
836
836
|
imagedata.unshift( { file:'none', name:'default', data:default_icon});
|
|
@@ -844,10 +844,10 @@ async function selectImageOverride(id) {
|
|
|
844
844
|
return image.file;
|
|
845
845
|
},
|
|
846
846
|
function (key, image) {
|
|
847
|
-
if (image.
|
|
848
|
-
return `data-icon="data:image/png; base64, ${image.data}"`;
|
|
849
|
-
} else {
|
|
847
|
+
if (image.file.length < 50) {
|
|
850
848
|
return `data-icon="${image.data}"`;
|
|
849
|
+
} else {
|
|
850
|
+
return `data-icon="data:image/png; base64, ${image.data}"`;
|
|
851
851
|
}
|
|
852
852
|
},
|
|
853
853
|
);
|
|
@@ -857,6 +857,7 @@ async function selectImageOverride(id) {
|
|
|
857
857
|
const image = $('#chooseimage').find('#images option:selected').val();
|
|
858
858
|
const global = $('#chooseimage').find('#globaloverride').prop('checked');
|
|
859
859
|
const name = $('#chooseimage').find('input[id=\'d_name\']').val();
|
|
860
|
+
console.warn(`update device image : ${id} : ${image} : ${global} : ${name} : ${dev.common.name}`);
|
|
860
861
|
const data = {};
|
|
861
862
|
if (image != 'current') data.icon= image;
|
|
862
863
|
if (name != dev.common.name) data.name = name;
|
|
@@ -868,197 +869,6 @@ async function selectImageOverride(id) {
|
|
|
868
869
|
});
|
|
869
870
|
}
|
|
870
871
|
|
|
871
|
-
|
|
872
|
-
function safestring(val) {
|
|
873
|
-
const t = typeof val;
|
|
874
|
-
if (t==='object') return JSON.stringify(val).replaceAll(',',', ');
|
|
875
|
-
if (t==='string') return val.replaceAll(',',', ');
|
|
876
|
-
if (t==='function') return 'function';
|
|
877
|
-
return val;
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
function fne(item) {
|
|
881
|
-
const rv = [];
|
|
882
|
-
if (item.flags) {
|
|
883
|
-
if (item.flags.includes('SUCCESS')) rv.push('SUCCESS');
|
|
884
|
-
else rv.push(...item.flags);
|
|
885
|
-
}
|
|
886
|
-
if (item.errors && item.errors.length > 0) {
|
|
887
|
-
if (item.errors.length > 1) rv.push('errors: '+item.errors.join(','));
|
|
888
|
-
else rv.push('error: '+item.errors[0]);
|
|
889
|
-
}
|
|
890
|
-
return rv.join(', ');
|
|
891
|
-
}
|
|
892
|
-
|
|
893
|
-
function HtmlFromInDebugMessages(messages, devID, filter) {
|
|
894
|
-
const Html = [];
|
|
895
|
-
const filterSet = new Set();
|
|
896
|
-
let isodd = true;
|
|
897
|
-
if (dbgMsghide.has('i_'+devID)) {
|
|
898
|
-
console.warn('in all filtered out')
|
|
899
|
-
Html.push(' ')
|
|
900
|
-
} else for (const item of messages) {
|
|
901
|
-
if (item.states.length > 0) {
|
|
902
|
-
const rowspan = item.states.length > 1 ? ` rowspan="${item.states.length}"` : '';
|
|
903
|
-
let idx = item.states.length;
|
|
904
|
-
const IHtml = [];
|
|
905
|
-
let fs = '';
|
|
906
|
-
for (const state of item.states) {
|
|
907
|
-
fs = fs+state.id+'.'+fne(item);
|
|
908
|
-
const redText = (item.errors && item.errors.length > 0 ? ' id="dbgred"' : '');
|
|
909
|
-
idx--;
|
|
910
|
-
const LHtml = [(`<tr id="${isodd ? 'dbgrowodd' : 'dbgroweven'}">`)];
|
|
911
|
-
if (idx==0)
|
|
912
|
-
LHtml.push(`<td${rowspan}>${item.dataID.toString(16).slice(-4)}</td><td${rowspan}>${safestring(item.payload)}</td>`);
|
|
913
|
-
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>`);
|
|
914
|
-
IHtml.unshift(...LHtml)
|
|
915
|
-
}
|
|
916
|
-
if (filter)
|
|
917
|
-
if (filterSet.has(fs)) continue; else filterSet.add(fs);
|
|
918
|
-
Html.unshift(...IHtml);
|
|
919
|
-
isodd=!isodd;
|
|
920
|
-
}
|
|
921
|
-
}
|
|
922
|
-
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>`
|
|
923
|
-
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>`
|
|
924
|
-
const dataHide = dbgMsgfilter.has('hi_'+devID) ? 'Data hidden' : ' ';
|
|
925
|
-
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>`;
|
|
926
|
-
}
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
function HtmlFromOutDebugMessages(messages, devID, filter) {
|
|
930
|
-
const Html = [];
|
|
931
|
-
const filterSet = new Set();
|
|
932
|
-
let isodd=true;
|
|
933
|
-
if (dbgMsghide.has('o_'+devID)) {
|
|
934
|
-
console.warn('out all filtered out')
|
|
935
|
-
Html.push(' ')
|
|
936
|
-
}
|
|
937
|
-
else for (const item of messages) {
|
|
938
|
-
if (item.states.length > 0) {
|
|
939
|
-
const rowspan = item.states.length > 1 ? ` rowspan="${item.states.length}"` : '';
|
|
940
|
-
let idx = item.states.length;
|
|
941
|
-
let fs = '';
|
|
942
|
-
const IHtml = [];
|
|
943
|
-
for (const state of item.states) {
|
|
944
|
-
fs = fs+state.id+'.'+fne(item);
|
|
945
|
-
const redText = (item.errors && item.errors.length > 0 ? ' id="dbgred"' : '');
|
|
946
|
-
const LHtml = [(`<tr id="${isodd ? 'dbgrowodd' : 'dbgroweven'}">`)];
|
|
947
|
-
idx--;
|
|
948
|
-
if (idx==0)
|
|
949
|
-
LHtml.push(`<td${rowspan}>${item.dataID.toString(16).slice(-4)}</td><td${rowspan}>${safestring(item.payload)}</td>`);
|
|
950
|
-
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>`);
|
|
951
|
-
IHtml.unshift(...LHtml);
|
|
952
|
-
|
|
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="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>`
|
|
961
|
-
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>`
|
|
962
|
-
const dataHide = dbgMsgfilter.has('ho_'+devID) ? 'Data hidden' : ' ';
|
|
963
|
-
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>`;
|
|
964
|
-
}
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
function displayDebugMessages(msg) {
|
|
968
|
-
const buttonNames = [];
|
|
969
|
-
if (msg.byId) {
|
|
970
|
-
const dbgData = msg.byId;
|
|
971
|
-
const keys = Object.keys(dbgData);
|
|
972
|
-
const keylength = keys.length;
|
|
973
|
-
const Html = [];
|
|
974
|
-
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>`;
|
|
975
|
-
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>`;
|
|
976
|
-
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>`;
|
|
977
|
-
Html.push(`<li><table><thead id="dbgtable"><tr><td colspan="4">Debug information by device</td><td>${fbutton}</td><td>${hbutton}</td><td>${button}</td></tr></thead><tbody>`);
|
|
978
|
-
if (!keylength) {
|
|
979
|
-
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>')
|
|
980
|
-
$('#dbg_data_list').html(Html.join(''));
|
|
981
|
-
}
|
|
982
|
-
else {
|
|
983
|
-
Html.push('</tbody></table></li>')
|
|
984
|
-
for (const devID of Object.keys(dbgData)) {
|
|
985
|
-
const dev = devices.find((d) => d._id.endsWith(devID.slice(-16)));
|
|
986
|
-
const type_url = (dev && dev.common && dev.common.type ? sanitizeModelParameter(dev.common.type) : 'unknown');
|
|
987
|
-
const image = `<img src="${dev.common.icon || dev.icon}" width="40px" onerror="this.onerror=null;this.src='img/unavailable.png';">`
|
|
988
|
-
const modelUrl = (type_url === 'unknown') ? 'unknown' : `<a href="https://www.zigbee2mqtt.io/devices/${type_url}.html" target="_blank" rel="noopener noreferrer">${image}</a>`;
|
|
989
|
-
const devName = (dev && dev.common && dev.common.name) ? dev.common.name : 'unnamed';
|
|
990
|
-
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>`
|
|
991
|
-
buttonNames.push(devID);
|
|
992
|
-
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>`);
|
|
993
|
-
if (dbgData[devID].IN.length > 0) {
|
|
994
|
-
Html.push(`${HtmlFromInDebugMessages(dbgData[devID].IN, devID, dbgMsgfilter.has('i_'+devID))}`);
|
|
995
|
-
}
|
|
996
|
-
if (dbgData[devID].OUT.length > 0) {
|
|
997
|
-
Html.push(`${HtmlFromOutDebugMessages(dbgData[devID].OUT, devID, dbgMsgfilter.has('o_'+devID))}`);
|
|
998
|
-
}
|
|
999
|
-
Html.push('</tbody></table></li>');
|
|
1000
|
-
}
|
|
1001
|
-
$('#dbg_data_list').html(Html.join(''));
|
|
1002
|
-
}
|
|
1003
|
-
$(`#e_all`).click(function () {
|
|
1004
|
-
getDebugMessages();
|
|
1005
|
-
});
|
|
1006
|
-
$(`#f_all`).click(function () {
|
|
1007
|
-
if (dbgMsgfilter.size > 0) {
|
|
1008
|
-
dbgMsgfilter.clear();
|
|
1009
|
-
}
|
|
1010
|
-
else {
|
|
1011
|
-
for (const item of Object.keys(msg.byId)) {
|
|
1012
|
-
dbgMsgfilter.add(`o_${item}`)
|
|
1013
|
-
dbgMsgfilter.add(`i_${item}`)
|
|
1014
|
-
}
|
|
1015
|
-
}
|
|
1016
|
-
displayDebugMessages(debugMessages);
|
|
1017
|
-
});
|
|
1018
|
-
$(`#h_all`).click(function () {
|
|
1019
|
-
if (dbgMsghide.size > 0) {
|
|
1020
|
-
dbgMsghide.clear();
|
|
1021
|
-
}
|
|
1022
|
-
else {
|
|
1023
|
-
for (const item of Object.keys(msg.byId)) {
|
|
1024
|
-
dbgMsghide.add(`o_${item}`)
|
|
1025
|
-
dbgMsghide.add(`i_${item}`)
|
|
1026
|
-
}
|
|
1027
|
-
}
|
|
1028
|
-
displayDebugMessages(debugMessages);
|
|
1029
|
-
});
|
|
1030
|
-
for (const b of buttonNames) {
|
|
1031
|
-
$(`#e_${b}`).click(function () {
|
|
1032
|
-
getDebugMessages();
|
|
1033
|
-
});
|
|
1034
|
-
$(`#o_${b}`).click(function () {
|
|
1035
|
-
if (dbgMsgfilter.has(`o_${b}`)) dbgMsgfilter.delete(`o_${b}`); else dbgMsgfilter.add(`o_${b}`);
|
|
1036
|
-
displayDebugMessages(debugMessages);
|
|
1037
|
-
});
|
|
1038
|
-
$(`#i_${b}`).click(function () {
|
|
1039
|
-
if (dbgMsgfilter.has(`i_${b}`)) dbgMsgfilter.delete(`i_${b}`); else dbgMsgfilter.add(`i_${b}`);
|
|
1040
|
-
displayDebugMessages(debugMessages);
|
|
1041
|
-
});
|
|
1042
|
-
$(`#ho_${b}`).click(function () {
|
|
1043
|
-
if (dbgMsghide.has(`o_${b}`)) dbgMsghide.delete(`o_${b}`); else dbgMsghide.add(`o_${b}`);
|
|
1044
|
-
displayDebugMessages(debugMessages);
|
|
1045
|
-
});
|
|
1046
|
-
$(`#hi_${b}`).click(function () {
|
|
1047
|
-
if (dbgMsghide.has(`i_${b}`)) dbgMsghide.delete(`i_${b}`); else dbgMsghide.add(`i_${b}`);
|
|
1048
|
-
displayDebugMessages(debugMessages);
|
|
1049
|
-
});
|
|
1050
|
-
}
|
|
1051
|
-
}
|
|
1052
|
-
}
|
|
1053
|
-
|
|
1054
|
-
function getDebugMessages() {
|
|
1055
|
-
sendTo(namespace, 'getDebugMessages', {}, function(msg) {
|
|
1056
|
-
debugMessages = msg;
|
|
1057
|
-
if (msg) displayDebugMessages(debugMessages)
|
|
1058
|
-
})
|
|
1059
|
-
}
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
872
|
function getDevices() {
|
|
1063
873
|
getCoordinatorInfo();
|
|
1064
874
|
sendTo(namespace, 'getDeviceCleanupRequired', {}, function(msg) {
|
|
@@ -1089,7 +899,6 @@ function getDevices() {
|
|
|
1089
899
|
} else {
|
|
1090
900
|
devices = msg;
|
|
1091
901
|
showDevices();
|
|
1092
|
-
getDebugMessages();
|
|
1093
902
|
getExclude();
|
|
1094
903
|
getBinding();
|
|
1095
904
|
}
|
|
@@ -1200,7 +1009,6 @@ function load(settings, onChange) {
|
|
|
1200
1009
|
//dialog = new MatDialog({EndingTop: '50%'});
|
|
1201
1010
|
getDevices();
|
|
1202
1011
|
getNamedColors();
|
|
1203
|
-
//getDebugMessages();
|
|
1204
1012
|
//getMap();
|
|
1205
1013
|
//addCard();
|
|
1206
1014
|
|
|
@@ -1392,13 +1200,8 @@ socket.on('stateChange', function (id, state) {
|
|
|
1392
1200
|
$('#progress_line').css('width', `${percent}%`);
|
|
1393
1201
|
}
|
|
1394
1202
|
} else if (id.match(/\.info\.pairingMessage$/)) {
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
}
|
|
1398
|
-
else {
|
|
1399
|
-
messages.push(state.val);
|
|
1400
|
-
showMessages();
|
|
1401
|
-
}
|
|
1203
|
+
messages.push(state.val);
|
|
1204
|
+
showMessages();
|
|
1402
1205
|
} else {
|
|
1403
1206
|
const devId = getDevId(id);
|
|
1404
1207
|
putEventToNode(devId);
|
|
@@ -1423,7 +1226,6 @@ socket.on('stateChange', function (id, state) {
|
|
|
1423
1226
|
}
|
|
1424
1227
|
});
|
|
1425
1228
|
|
|
1426
|
-
|
|
1427
1229
|
socket.on('objectChange', function (id, obj) {
|
|
1428
1230
|
if (id.substring(0, namespaceLen) !== namespace) return;
|
|
1429
1231
|
//console.log('objectChange', id, obj);
|
|
@@ -1684,6 +1486,7 @@ function showNetworkMap(devices, map) {
|
|
|
1684
1486
|
const options = data.edges._data.get(id);
|
|
1685
1487
|
if (select) {
|
|
1686
1488
|
options.font.size = 15;
|
|
1489
|
+
console.warn(JSON.stringify(options.font));
|
|
1687
1490
|
} else {
|
|
1688
1491
|
options.font.size = 0;
|
|
1689
1492
|
}
|
|
@@ -2262,6 +2065,7 @@ function editGroup(id, name) {
|
|
|
2262
2065
|
removeMembers.push({id:member.ieee.replace('0x',''), ep:member.epid})
|
|
2263
2066
|
}
|
|
2264
2067
|
}
|
|
2068
|
+
console.warn(`ID: ${Id} name: ${newName} removeMembers: ${JSON.stringify(removeMembers)}`)
|
|
2265
2069
|
updateGroup(Id, newName, (removeMembers.length > 0 ? removeMembers: undefined));
|
|
2266
2070
|
// showGroups();
|
|
2267
2071
|
getDevices();
|
|
@@ -2821,7 +2625,7 @@ function genDevInfo(device) {
|
|
|
2821
2625
|
${genRow('date code', dev._dateCode)}
|
|
2822
2626
|
${genRow('build', dev._softwareBuildID)}
|
|
2823
2627
|
${genRow('interviewed', dev._interviewCompleted)}
|
|
2824
|
-
${genRow('configured', (
|
|
2628
|
+
${genRow('configured', (dev.meta.configured === 1), true)}
|
|
2825
2629
|
</ul>
|
|
2826
2630
|
</div>
|
|
2827
2631
|
</div>
|
|
@@ -3013,12 +2817,16 @@ function addExcludeDialog() {
|
|
|
3013
2817
|
$('#excludemodaledit a.btn[name=\'save\']').unbind('click');
|
|
3014
2818
|
$('#excludemodaledit a.btn[name=\'save\']').click(() => {
|
|
3015
2819
|
const exclude_id = $('#excludemodaledit').find('#exclude_target option:selected').val();
|
|
2820
|
+
|
|
3016
2821
|
const ids = devices.map(el => el._id);
|
|
3017
2822
|
const idx = ids.indexOf(exclude_id);
|
|
3018
2823
|
const exclude_model = devices[idx];
|
|
2824
|
+
console.warn('calling addExclude mit model ' + exclude_model)
|
|
2825
|
+
|
|
3019
2826
|
addExclude(exclude_model);
|
|
3020
2827
|
});
|
|
3021
2828
|
prepareExcludeDialog();
|
|
2829
|
+
console.warn('opening dialog');
|
|
3022
2830
|
$('#excludemodaledit').modal('open');
|
|
3023
2831
|
Materialize.updateTextFields();
|
|
3024
2832
|
}
|
|
@@ -3047,7 +2855,7 @@ function getExclude() {
|
|
|
3047
2855
|
excludes = msg.legacy;
|
|
3048
2856
|
showExclude();
|
|
3049
2857
|
}
|
|
3050
|
-
}
|
|
2858
|
+
} else console.warn('getExclude without msg')
|
|
3051
2859
|
});
|
|
3052
2860
|
}
|
|
3053
2861
|
|
|
File without changes
|
package/admin/tab_m.html
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis.min.js"></script>
|
|
10
10
|
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis.min.css"/> -->
|
|
11
11
|
<script type="text/javascript" src="vis-network.min.js"></script>
|
|
12
|
+
<script type="text/javascript" src="webcolors.js"></script>
|
|
12
13
|
<link rel="stylesheet" type="text/css" href="vis-network.min.css"/>
|
|
13
14
|
|
|
14
15
|
<!-- these files always have to be included -->
|
|
@@ -230,18 +231,16 @@
|
|
|
230
231
|
color: blue;
|
|
231
232
|
}
|
|
232
233
|
.m.react-blue div.bg_red {
|
|
233
|
-
|
|
234
|
-
|
|
234
|
+
background-color: #400000;
|
|
235
|
+
color: DimGray;
|
|
236
|
+
}
|
|
237
|
+
.m div.bg_red {
|
|
238
|
+
background-color: LightGray;
|
|
239
|
+
color: DimGray;
|
|
235
240
|
}
|
|
236
241
|
.m.react-dark div.bg_red {
|
|
237
|
-
|
|
238
|
-
color: DimGray;
|
|
242
|
+
background-color: #400000;
|
|
239
243
|
}
|
|
240
|
-
#dbgroweven { background-color: #404040; color: #c0c0c0 !important; }
|
|
241
|
-
#dbgrowodd { background-color: #c0c0c0; color: #404040 !important; }
|
|
242
|
-
#dbgtable { background-color: #3090c0; color: #404040 !important; }
|
|
243
|
-
#dbgred { color: #C00000 !important;}
|
|
244
|
-
|
|
245
244
|
.m.react-dark i.icon-blue {
|
|
246
245
|
color: rgb(100, 181, 246)!important;
|
|
247
246
|
}
|
|
@@ -912,10 +911,6 @@
|
|
|
912
911
|
<div id="exclude" class="row">
|
|
913
912
|
</div>
|
|
914
913
|
</div>
|
|
915
|
-
<div id="tab-debug" class="col s12 page">
|
|
916
|
-
<ul id="dbg_data_list">
|
|
917
|
-
</ul>
|
|
918
|
-
</div>
|
|
919
914
|
</div>
|
|
920
915
|
</div>
|
|
921
916
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|