@matter-server/dashboard 0.3.2 → 0.3.3
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/dist/esm/pages/cluster-commands/base-cluster-commands.d.ts +2 -2
- package/dist/esm/pages/cluster-commands/base-cluster-commands.d.ts.map +1 -1
- package/dist/esm/pages/cluster-commands/base-cluster-commands.js.map +1 -1
- package/dist/esm/pages/cluster-commands/clusters/basic-information-commands.d.ts +36 -0
- package/dist/esm/pages/cluster-commands/clusters/basic-information-commands.d.ts.map +1 -0
- package/dist/esm/pages/cluster-commands/clusters/basic-information-commands.js +159 -0
- package/dist/esm/pages/cluster-commands/clusters/basic-information-commands.js.map +6 -0
- package/dist/esm/pages/cluster-commands/index.d.ts +1 -0
- package/dist/esm/pages/cluster-commands/index.d.ts.map +1 -1
- package/dist/esm/pages/cluster-commands/index.js +1 -0
- package/dist/esm/pages/cluster-commands/index.js.map +1 -1
- package/dist/esm/pages/components/footer.d.ts.map +1 -1
- package/dist/esm/pages/components/footer.js +4 -7
- package/dist/esm/pages/components/footer.js.map +1 -1
- package/dist/esm/pages/components/header.d.ts +5 -0
- package/dist/esm/pages/components/header.d.ts.map +1 -1
- package/dist/esm/pages/components/header.js +75 -0
- package/dist/esm/pages/components/header.js.map +1 -1
- package/dist/esm/pages/components/node-details.js +1 -1
- package/dist/esm/pages/components/node-details.js.map +1 -1
- package/dist/esm/pages/components/server-details.d.ts.map +1 -1
- package/dist/esm/pages/components/server-details.js +0 -1
- package/dist/esm/pages/components/server-details.js.map +1 -1
- package/dist/esm/pages/matter-dashboard-app.d.ts +12 -0
- package/dist/esm/pages/matter-dashboard-app.d.ts.map +1 -1
- package/dist/esm/pages/matter-dashboard-app.js +84 -4
- package/dist/esm/pages/matter-dashboard-app.js.map +1 -1
- package/dist/esm/pages/matter-network-view.d.ts +52 -0
- package/dist/esm/pages/matter-network-view.d.ts.map +1 -0
- package/dist/esm/pages/matter-network-view.js +309 -0
- package/dist/esm/pages/matter-network-view.js.map +6 -0
- package/dist/esm/pages/matter-node-view.d.ts.map +1 -1
- package/dist/esm/pages/matter-node-view.js +70 -1
- package/dist/esm/pages/matter-node-view.js.map +1 -1
- package/dist/esm/pages/matter-server-view.d.ts +4 -0
- package/dist/esm/pages/matter-server-view.d.ts.map +1 -1
- package/dist/esm/pages/matter-server-view.js +16 -1
- package/dist/esm/pages/matter-server-view.js.map +1 -1
- package/dist/esm/pages/network/base-network-graph.d.ts +74 -0
- package/dist/esm/pages/network/base-network-graph.d.ts.map +1 -0
- package/dist/esm/pages/network/base-network-graph.js +403 -0
- package/dist/esm/pages/network/base-network-graph.js.map +6 -0
- package/dist/esm/pages/network/device-icons.d.ts +52 -0
- package/dist/esm/pages/network/device-icons.d.ts.map +1 -0
- package/dist/esm/pages/network/device-icons.js +197 -0
- package/dist/esm/pages/network/device-icons.js.map +6 -0
- package/dist/esm/pages/network/device-panel.d.ts +31 -0
- package/dist/esm/pages/network/device-panel.d.ts.map +1 -0
- package/dist/esm/pages/network/device-panel.js +183 -0
- package/dist/esm/pages/network/device-panel.js.map +6 -0
- package/dist/esm/pages/network/network-details.d.ts +47 -0
- package/dist/esm/pages/network/network-details.d.ts.map +1 -0
- package/dist/esm/pages/network/network-details.js +686 -0
- package/dist/esm/pages/network/network-details.js.map +6 -0
- package/dist/esm/pages/network/network-types.d.ts +153 -0
- package/dist/esm/pages/network/network-types.d.ts.map +1 -0
- package/dist/esm/pages/network/network-types.js +19 -0
- package/dist/esm/pages/network/network-types.js.map +6 -0
- package/dist/esm/pages/network/network-utils.d.ts +170 -0
- package/dist/esm/pages/network/network-utils.d.ts.map +1 -0
- package/dist/esm/pages/network/network-utils.js +472 -0
- package/dist/esm/pages/network/network-utils.js.map +6 -0
- package/dist/esm/pages/network/thread-graph.d.ts +27 -0
- package/dist/esm/pages/network/thread-graph.d.ts.map +1 -0
- package/dist/esm/pages/network/thread-graph.js +134 -0
- package/dist/esm/pages/network/thread-graph.js.map +6 -0
- package/dist/esm/pages/network/wifi-graph.d.ts +27 -0
- package/dist/esm/pages/network/wifi-graph.d.ts.map +1 -0
- package/dist/esm/pages/network/wifi-graph.js +167 -0
- package/dist/esm/pages/network/wifi-graph.js.map +6 -0
- package/dist/web/js/{commission-node-dialog-CBSDiqRW.js → commission-node-dialog-B1_khzZb.js} +5 -5
- package/dist/web/js/{commission-node-existing-TP6s8Tez.js → commission-node-existing-RpdajrwF.js} +2 -5
- package/dist/web/js/{commission-node-thread-DOB8pu6x.js → commission-node-thread-5f2itkTG.js} +2 -5
- package/dist/web/js/{commission-node-wifi-tzavmk1j.js → commission-node-wifi-DZ_pWqsa.js} +2 -5
- package/dist/web/js/{dialog-box-Dknil_Be.js → dialog-box-DEUxM4B1.js} +2 -2
- package/dist/web/js/{fire_event-DRpOSjJR.js → fire_event-BczBMT8E.js} +1 -1
- package/dist/web/js/{log-level-dialog-TXkma-7Z.js → log-level-dialog-Cr3PfX1X.js} +2 -3
- package/dist/web/js/main.js +1 -1
- package/dist/web/js/matter-dashboard-app-BuCe_Jxf.js +29990 -0
- package/dist/web/js/{node-binding-dialog-D52FCBFP.js → node-binding-dialog-DMiHNDLA.js} +2 -4
- package/dist/web/js/{prevent_default-BPgSQsuY.js → prevent_default-D4FX_PIh.js} +2 -42
- package/package.json +5 -4
- package/src/pages/cluster-commands/base-cluster-commands.ts +2 -2
- package/src/pages/cluster-commands/clusters/basic-information-commands.ts +171 -0
- package/src/pages/cluster-commands/index.ts +1 -0
- package/src/pages/components/footer.ts +4 -7
- package/src/pages/components/header.ts +81 -0
- package/src/pages/components/node-details.ts +2 -2
- package/src/pages/components/server-details.ts +0 -1
- package/src/pages/matter-dashboard-app.ts +105 -5
- package/src/pages/matter-network-view.ts +325 -0
- package/src/pages/matter-node-view.ts +75 -1
- package/src/pages/matter-server-view.ts +17 -1
- package/src/pages/network/base-network-graph.ts +463 -0
- package/src/pages/network/device-icons.ts +283 -0
- package/src/pages/network/device-panel.ts +180 -0
- package/src/pages/network/network-details.ts +750 -0
- package/src/pages/network/network-types.ts +161 -0
- package/src/pages/network/network-utils.ts +752 -0
- package/src/pages/network/thread-graph.ts +164 -0
- package/src/pages/network/wifi-graph.ts +192 -0
- package/dist/web/js/matter-dashboard-app-B7GUghkC.js +0 -17254
- package/dist/web/js/outlined-text-field-D1DyKQY-.js +0 -968
- package/dist/web/js/validator-C735j770.js +0 -1122
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025-2026 Open Home Foundation
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
const WIFI_FEATURE = 1 << 0;
|
|
7
|
+
const THREAD_FEATURE = 1 << 1;
|
|
8
|
+
const ETHERNET_FEATURE = 1 << 2;
|
|
9
|
+
const SIGNAL_STRONG_THRESHOLD = -70;
|
|
10
|
+
const SIGNAL_MEDIUM_THRESHOLD = -85;
|
|
11
|
+
const LQI_STRONG_THRESHOLD = 200;
|
|
12
|
+
const LQI_MEDIUM_THRESHOLD = 100;
|
|
13
|
+
const SIGNAL_COLOR_STRONG = "#4caf50";
|
|
14
|
+
const SIGNAL_COLOR_MEDIUM = "#ff9800";
|
|
15
|
+
const SIGNAL_COLOR_WEAK = "#f44336";
|
|
16
|
+
function base64ToBigInt(base64) {
|
|
17
|
+
try {
|
|
18
|
+
const binary = atob(base64);
|
|
19
|
+
let result = 0n;
|
|
20
|
+
const start = binary.length > 8 ? binary.length - 8 : 0;
|
|
21
|
+
for (let i = start; i < binary.length; i++) {
|
|
22
|
+
result = result << 8n | BigInt(binary.charCodeAt(i));
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
} catch {
|
|
26
|
+
return 0n;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function normalizeExtAddress(value) {
|
|
30
|
+
if (typeof value === "bigint") {
|
|
31
|
+
return value;
|
|
32
|
+
}
|
|
33
|
+
if (typeof value === "string") {
|
|
34
|
+
return base64ToBigInt(value);
|
|
35
|
+
}
|
|
36
|
+
if (typeof value === "number") {
|
|
37
|
+
return BigInt(value);
|
|
38
|
+
}
|
|
39
|
+
return 0n;
|
|
40
|
+
}
|
|
41
|
+
function getNetworkType(node) {
|
|
42
|
+
const featureMap = node.attributes["0/49/65532"];
|
|
43
|
+
if (featureMap === void 0) {
|
|
44
|
+
return "unknown";
|
|
45
|
+
}
|
|
46
|
+
if (featureMap & THREAD_FEATURE) {
|
|
47
|
+
return "thread";
|
|
48
|
+
}
|
|
49
|
+
if (featureMap & WIFI_FEATURE) {
|
|
50
|
+
return "wifi";
|
|
51
|
+
}
|
|
52
|
+
if (featureMap & ETHERNET_FEATURE) {
|
|
53
|
+
return "ethernet";
|
|
54
|
+
}
|
|
55
|
+
return "unknown";
|
|
56
|
+
}
|
|
57
|
+
function categorizeDevices(nodes) {
|
|
58
|
+
const result = {
|
|
59
|
+
thread: [],
|
|
60
|
+
wifi: [],
|
|
61
|
+
ethernet: [],
|
|
62
|
+
unknown: []
|
|
63
|
+
};
|
|
64
|
+
for (const node of Object.values(nodes)) {
|
|
65
|
+
const nodeId = String(node.node_id);
|
|
66
|
+
const networkType = getNetworkType(node);
|
|
67
|
+
result[networkType].push(nodeId);
|
|
68
|
+
}
|
|
69
|
+
return result;
|
|
70
|
+
}
|
|
71
|
+
function getThreadRole(node) {
|
|
72
|
+
return node.attributes["0/53/1"];
|
|
73
|
+
}
|
|
74
|
+
function getThreadChannel(node) {
|
|
75
|
+
return node.attributes["0/53/0"];
|
|
76
|
+
}
|
|
77
|
+
function getThreadExtendedPanId(node) {
|
|
78
|
+
return node.attributes["0/53/4"];
|
|
79
|
+
}
|
|
80
|
+
function getThreadExtendedAddress(node) {
|
|
81
|
+
const networkInterfaces = node.attributes["0/51/0"];
|
|
82
|
+
if (!Array.isArray(networkInterfaces) || networkInterfaces.length === 0) {
|
|
83
|
+
return void 0;
|
|
84
|
+
}
|
|
85
|
+
const threadIface = networkInterfaces.find((i) => i["7"] === 4) || networkInterfaces[0];
|
|
86
|
+
if (!threadIface) {
|
|
87
|
+
return void 0;
|
|
88
|
+
}
|
|
89
|
+
const hwAddrB64 = threadIface["4"];
|
|
90
|
+
if (typeof hwAddrB64 !== "string" || !hwAddrB64) {
|
|
91
|
+
return void 0;
|
|
92
|
+
}
|
|
93
|
+
const extAddr = base64ToBigInt(hwAddrB64);
|
|
94
|
+
return extAddr !== 0n ? extAddr : void 0;
|
|
95
|
+
}
|
|
96
|
+
function getThreadExtendedAddressHex(node) {
|
|
97
|
+
const extAddr = getThreadExtendedAddress(node);
|
|
98
|
+
if (extAddr !== void 0) {
|
|
99
|
+
return extAddr.toString(16).padStart(16, "0").toUpperCase();
|
|
100
|
+
}
|
|
101
|
+
return void 0;
|
|
102
|
+
}
|
|
103
|
+
function parseNeighborTable(node) {
|
|
104
|
+
const neighborTable = node.attributes["0/53/7"];
|
|
105
|
+
if (!Array.isArray(neighborTable)) {
|
|
106
|
+
return [];
|
|
107
|
+
}
|
|
108
|
+
return neighborTable.map((entry) => {
|
|
109
|
+
const rawExtAddr = entry["0"] ?? entry.extAddress;
|
|
110
|
+
const extAddress = normalizeExtAddress(rawExtAddr);
|
|
111
|
+
return {
|
|
112
|
+
extAddress,
|
|
113
|
+
// Field 1: age
|
|
114
|
+
age: entry["1"] ?? entry.age ?? 0,
|
|
115
|
+
// Field 2: rloc16
|
|
116
|
+
rloc16: entry["2"] ?? entry.rloc16 ?? 0,
|
|
117
|
+
// Field 3: linkFrameCounter
|
|
118
|
+
linkFrameCounter: entry["3"] ?? entry.linkFrameCounter ?? 0,
|
|
119
|
+
// Field 4: mleFrameCounter
|
|
120
|
+
mleFrameCounter: entry["4"] ?? entry.mleFrameCounter ?? 0,
|
|
121
|
+
// Field 5: lqi
|
|
122
|
+
lqi: entry["5"] ?? entry.lqi ?? 0,
|
|
123
|
+
// Field 6: averageRssi (nullable)
|
|
124
|
+
avgRssi: entry["6"] ?? entry.averageRssi ?? null,
|
|
125
|
+
// Field 7: lastRssi (nullable)
|
|
126
|
+
lastRssi: entry["7"] ?? entry.lastRssi ?? null,
|
|
127
|
+
// Field 8: frameErrorRate
|
|
128
|
+
frameErrorRate: entry["8"] ?? entry.frameErrorRate ?? 0,
|
|
129
|
+
// Field 9: messageErrorRate
|
|
130
|
+
messageErrorRate: entry["9"] ?? entry.messageErrorRate ?? 0,
|
|
131
|
+
// Field 10: rxOnWhenIdle
|
|
132
|
+
rxOnWhenIdle: entry["10"] ?? entry.rxOnWhenIdle ?? false,
|
|
133
|
+
// Field 11: fullThreadDevice
|
|
134
|
+
fullThreadDevice: entry["11"] ?? entry.fullThreadDevice ?? false,
|
|
135
|
+
// Field 12: fullNetworkData
|
|
136
|
+
fullNetworkData: entry["12"] ?? entry.fullNetworkData ?? false,
|
|
137
|
+
// Field 13: isChild
|
|
138
|
+
isChild: entry["13"] ?? entry.isChild ?? false
|
|
139
|
+
};
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
function parseRouteTable(node) {
|
|
143
|
+
const routeTable = node.attributes["0/53/8"];
|
|
144
|
+
if (!Array.isArray(routeTable)) {
|
|
145
|
+
return [];
|
|
146
|
+
}
|
|
147
|
+
return routeTable.map((entry) => {
|
|
148
|
+
const rawExtAddr = entry["0"] ?? entry.extAddress;
|
|
149
|
+
const extAddress = normalizeExtAddress(rawExtAddr);
|
|
150
|
+
return {
|
|
151
|
+
extAddress,
|
|
152
|
+
// Field 1: rloc16
|
|
153
|
+
rloc16: entry["1"] ?? entry.rloc16 ?? 0,
|
|
154
|
+
// Field 2: routerId
|
|
155
|
+
routerId: entry["2"] ?? entry.routerId ?? 0,
|
|
156
|
+
// Field 3: nextHop
|
|
157
|
+
nextHop: entry["3"] ?? entry.nextHop ?? 0,
|
|
158
|
+
// Field 4: pathCost
|
|
159
|
+
pathCost: entry["4"] ?? entry.pathCost ?? 0,
|
|
160
|
+
// Field 5: lqiIn
|
|
161
|
+
lqiIn: entry["5"] ?? entry.lqiIn ?? 0,
|
|
162
|
+
// Field 6: lqiOut
|
|
163
|
+
lqiOut: entry["6"] ?? entry.lqiOut ?? 0,
|
|
164
|
+
// Field 7: age
|
|
165
|
+
age: entry["7"] ?? entry.age ?? 0,
|
|
166
|
+
// Field 8: allocated
|
|
167
|
+
allocated: entry["8"] ?? entry.allocated ?? false,
|
|
168
|
+
// Field 9: linkEstablished
|
|
169
|
+
linkEstablished: entry["9"] ?? entry.linkEstablished ?? false
|
|
170
|
+
};
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
function getThreadRloc16(node) {
|
|
174
|
+
const value = node.attributes["0/53/64"];
|
|
175
|
+
if (typeof value === "number") {
|
|
176
|
+
return value;
|
|
177
|
+
}
|
|
178
|
+
return void 0;
|
|
179
|
+
}
|
|
180
|
+
function buildExtAddrMap(nodes) {
|
|
181
|
+
const extAddrMap = /* @__PURE__ */ new Map();
|
|
182
|
+
for (const node of Object.values(nodes)) {
|
|
183
|
+
const nodeId = String(node.node_id);
|
|
184
|
+
const extAddr = getThreadExtendedAddress(node);
|
|
185
|
+
if (extAddr !== void 0) {
|
|
186
|
+
extAddrMap.set(extAddr, nodeId);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return extAddrMap;
|
|
190
|
+
}
|
|
191
|
+
function buildRloc16Map(nodes) {
|
|
192
|
+
const rloc16Map = /* @__PURE__ */ new Map();
|
|
193
|
+
for (const node of Object.values(nodes)) {
|
|
194
|
+
const nodeId = String(node.node_id);
|
|
195
|
+
const rloc16 = getThreadRloc16(node);
|
|
196
|
+
if (rloc16 !== void 0) {
|
|
197
|
+
rloc16Map.set(rloc16, nodeId);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return rloc16Map;
|
|
201
|
+
}
|
|
202
|
+
function findUnknownDevices(nodes, extAddrMap) {
|
|
203
|
+
const unknownMap = /* @__PURE__ */ new Map();
|
|
204
|
+
for (const node of Object.values(nodes)) {
|
|
205
|
+
const nodeId = String(node.node_id);
|
|
206
|
+
const neighbors = parseNeighborTable(node);
|
|
207
|
+
for (const neighbor of neighbors) {
|
|
208
|
+
if (extAddrMap.has(neighbor.extAddress)) {
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
const extAddressHex = neighbor.extAddress.toString(16).padStart(16, "0").toUpperCase();
|
|
212
|
+
const id = `unknown_${extAddressHex}`;
|
|
213
|
+
if (!unknownMap.has(id)) {
|
|
214
|
+
unknownMap.set(id, {
|
|
215
|
+
id,
|
|
216
|
+
extAddressHex,
|
|
217
|
+
extAddress: neighbor.extAddress,
|
|
218
|
+
seenBy: [],
|
|
219
|
+
isRouter: false,
|
|
220
|
+
bestRssi: null
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
const unknown = unknownMap.get(id);
|
|
224
|
+
if (!unknown.seenBy.includes(nodeId)) {
|
|
225
|
+
unknown.seenBy.push(nodeId);
|
|
226
|
+
}
|
|
227
|
+
if (neighbor.rxOnWhenIdle) {
|
|
228
|
+
unknown.isRouter = true;
|
|
229
|
+
}
|
|
230
|
+
const rssi = neighbor.avgRssi ?? neighbor.lastRssi;
|
|
231
|
+
if (rssi !== null && (unknown.bestRssi === null || rssi > unknown.bestRssi)) {
|
|
232
|
+
unknown.bestRssi = rssi;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return Array.from(unknownMap.values());
|
|
237
|
+
}
|
|
238
|
+
function getSignalColor(neighbor) {
|
|
239
|
+
const rssi = neighbor.avgRssi ?? neighbor.lastRssi;
|
|
240
|
+
if (rssi !== null) {
|
|
241
|
+
if (rssi > SIGNAL_STRONG_THRESHOLD) {
|
|
242
|
+
return SIGNAL_COLOR_STRONG;
|
|
243
|
+
}
|
|
244
|
+
if (rssi > SIGNAL_MEDIUM_THRESHOLD) {
|
|
245
|
+
return SIGNAL_COLOR_MEDIUM;
|
|
246
|
+
}
|
|
247
|
+
return SIGNAL_COLOR_WEAK;
|
|
248
|
+
}
|
|
249
|
+
if (neighbor.lqi > LQI_STRONG_THRESHOLD) {
|
|
250
|
+
return SIGNAL_COLOR_STRONG;
|
|
251
|
+
}
|
|
252
|
+
if (neighbor.lqi > LQI_MEDIUM_THRESHOLD) {
|
|
253
|
+
return SIGNAL_COLOR_MEDIUM;
|
|
254
|
+
}
|
|
255
|
+
return SIGNAL_COLOR_WEAK;
|
|
256
|
+
}
|
|
257
|
+
function getDeviceName(node) {
|
|
258
|
+
if (node.nodeLabel) {
|
|
259
|
+
return node.nodeLabel;
|
|
260
|
+
}
|
|
261
|
+
const productName = node.productName || "Unknown Device";
|
|
262
|
+
const serialNumber = node.serialNumber;
|
|
263
|
+
if (serialNumber) {
|
|
264
|
+
return `${productName} (${serialNumber})`;
|
|
265
|
+
}
|
|
266
|
+
return productName;
|
|
267
|
+
}
|
|
268
|
+
function getThreadRoleName(role) {
|
|
269
|
+
switch (role) {
|
|
270
|
+
case 0:
|
|
271
|
+
return "Unspecified";
|
|
272
|
+
case 1:
|
|
273
|
+
return "Unassigned";
|
|
274
|
+
case 2:
|
|
275
|
+
return "Sleepy End Device";
|
|
276
|
+
case 3:
|
|
277
|
+
return "End Device";
|
|
278
|
+
case 4:
|
|
279
|
+
return "REED";
|
|
280
|
+
case 5:
|
|
281
|
+
return "Router";
|
|
282
|
+
case 6:
|
|
283
|
+
return "Leader";
|
|
284
|
+
default:
|
|
285
|
+
return "Unknown";
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
function getWiFiDiagnostics(node) {
|
|
289
|
+
const bssidRaw = node.attributes["0/54/0"];
|
|
290
|
+
let bssid = null;
|
|
291
|
+
if (bssidRaw) {
|
|
292
|
+
try {
|
|
293
|
+
const binary = atob(bssidRaw);
|
|
294
|
+
bssid = Array.from(binary).map((c) => c.charCodeAt(0).toString(16).padStart(2, "0").toUpperCase()).join(":");
|
|
295
|
+
} catch {
|
|
296
|
+
bssid = null;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
const rssi = node.attributes["0/54/4"];
|
|
300
|
+
const channel = node.attributes["0/54/3"];
|
|
301
|
+
const securityType = node.attributes["0/54/1"];
|
|
302
|
+
const wifiVersion = node.attributes["0/54/2"];
|
|
303
|
+
return {
|
|
304
|
+
bssid,
|
|
305
|
+
rssi: rssi ?? null,
|
|
306
|
+
channel: channel ?? null,
|
|
307
|
+
securityType: securityType ?? null,
|
|
308
|
+
wifiVersion: wifiVersion ?? null
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
function getSignalColorFromRssi(rssi) {
|
|
312
|
+
if (rssi === null) {
|
|
313
|
+
return SIGNAL_COLOR_MEDIUM;
|
|
314
|
+
}
|
|
315
|
+
if (rssi > SIGNAL_STRONG_THRESHOLD) {
|
|
316
|
+
return SIGNAL_COLOR_STRONG;
|
|
317
|
+
}
|
|
318
|
+
if (rssi > SIGNAL_MEDIUM_THRESHOLD) {
|
|
319
|
+
return SIGNAL_COLOR_MEDIUM;
|
|
320
|
+
}
|
|
321
|
+
return SIGNAL_COLOR_WEAK;
|
|
322
|
+
}
|
|
323
|
+
function getWiFiSecurityTypeName(securityType) {
|
|
324
|
+
switch (securityType) {
|
|
325
|
+
case 0:
|
|
326
|
+
return "Unspecified";
|
|
327
|
+
case 1:
|
|
328
|
+
return "None";
|
|
329
|
+
case 2:
|
|
330
|
+
return "WEP";
|
|
331
|
+
case 3:
|
|
332
|
+
return "WPA Personal";
|
|
333
|
+
case 4:
|
|
334
|
+
return "WPA2 Personal";
|
|
335
|
+
case 5:
|
|
336
|
+
return "WPA3 Personal";
|
|
337
|
+
default:
|
|
338
|
+
return "Unknown";
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
function getWiFiVersionName(version) {
|
|
342
|
+
switch (version) {
|
|
343
|
+
case 0:
|
|
344
|
+
return "802.11a";
|
|
345
|
+
case 1:
|
|
346
|
+
return "802.11b";
|
|
347
|
+
case 2:
|
|
348
|
+
return "802.11g";
|
|
349
|
+
case 3:
|
|
350
|
+
return "802.11n";
|
|
351
|
+
case 4:
|
|
352
|
+
return "802.11ac";
|
|
353
|
+
case 5:
|
|
354
|
+
return "802.11ax";
|
|
355
|
+
case 6:
|
|
356
|
+
return "802.11ah";
|
|
357
|
+
default:
|
|
358
|
+
return "Unknown";
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
function buildThreadConnections(nodes, extAddrMap, unknownDevices) {
|
|
362
|
+
const connections = [];
|
|
363
|
+
const seenConnections = /* @__PURE__ */ new Set();
|
|
364
|
+
const unknownExtAddrMap = /* @__PURE__ */ new Map();
|
|
365
|
+
for (const unknown of unknownDevices) {
|
|
366
|
+
unknownExtAddrMap.set(unknown.extAddress, unknown.id);
|
|
367
|
+
}
|
|
368
|
+
for (const node of Object.values(nodes)) {
|
|
369
|
+
const fromNodeId = String(node.node_id);
|
|
370
|
+
const neighbors = parseNeighborTable(node);
|
|
371
|
+
for (const neighbor of neighbors) {
|
|
372
|
+
let toNodeId = extAddrMap.get(neighbor.extAddress);
|
|
373
|
+
if (toNodeId === void 0) {
|
|
374
|
+
toNodeId = unknownExtAddrMap.get(neighbor.extAddress);
|
|
375
|
+
}
|
|
376
|
+
if (toNodeId === void 0) {
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
if (fromNodeId === toNodeId) {
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
const connectionKey = `${fromNodeId}-${toNodeId}`;
|
|
383
|
+
const reverseKey = `${toNodeId}-${fromNodeId}`;
|
|
384
|
+
if (seenConnections.has(connectionKey) || seenConnections.has(reverseKey)) {
|
|
385
|
+
continue;
|
|
386
|
+
}
|
|
387
|
+
seenConnections.add(connectionKey);
|
|
388
|
+
connections.push({
|
|
389
|
+
fromNodeId,
|
|
390
|
+
toNodeId,
|
|
391
|
+
signalColor: getSignalColor(neighbor),
|
|
392
|
+
lqi: neighbor.lqi,
|
|
393
|
+
rssi: neighbor.avgRssi ?? neighbor.lastRssi
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return connections;
|
|
398
|
+
}
|
|
399
|
+
function getNodeConnections(nodeId, nodes, extAddrMap) {
|
|
400
|
+
const connections = [];
|
|
401
|
+
const seenConnectedIds = /* @__PURE__ */ new Set();
|
|
402
|
+
const node = nodes[nodeId];
|
|
403
|
+
if (!node) return connections;
|
|
404
|
+
const thisExtAddr = getThreadExtendedAddress(node);
|
|
405
|
+
const neighbors = parseNeighborTable(node);
|
|
406
|
+
for (const neighbor of neighbors) {
|
|
407
|
+
const connectedNodeId = extAddrMap.get(neighbor.extAddress);
|
|
408
|
+
const connectedNode = connectedNodeId ? nodes[connectedNodeId] : void 0;
|
|
409
|
+
const isUnknown = connectedNodeId === void 0;
|
|
410
|
+
const displayId = isUnknown ? `unknown_${neighbor.extAddress.toString(16).toUpperCase().padStart(16, "0")}` : connectedNodeId;
|
|
411
|
+
seenConnectedIds.add(displayId);
|
|
412
|
+
connections.push({
|
|
413
|
+
connectedNodeId: displayId,
|
|
414
|
+
connectedNode,
|
|
415
|
+
extAddressHex: neighbor.extAddress.toString(16).toUpperCase().padStart(16, "0"),
|
|
416
|
+
signalColor: getSignalColor(neighbor),
|
|
417
|
+
lqi: neighbor.lqi,
|
|
418
|
+
rssi: neighbor.avgRssi ?? neighbor.lastRssi,
|
|
419
|
+
isOutgoing: true,
|
|
420
|
+
isUnknown
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
if (thisExtAddr !== void 0) {
|
|
424
|
+
for (const otherNode of Object.values(nodes)) {
|
|
425
|
+
const otherNodeId = String(otherNode.node_id);
|
|
426
|
+
if (otherNodeId === nodeId) continue;
|
|
427
|
+
if (seenConnectedIds.has(otherNodeId)) continue;
|
|
428
|
+
const otherNeighbors = parseNeighborTable(otherNode);
|
|
429
|
+
const reverseEntry = otherNeighbors.find((n) => n.extAddress === thisExtAddr);
|
|
430
|
+
if (reverseEntry) {
|
|
431
|
+
const otherExtAddr = getThreadExtendedAddress(otherNode);
|
|
432
|
+
const extAddrHex = otherExtAddr ? otherExtAddr.toString(16).toUpperCase().padStart(16, "0") : "Unknown";
|
|
433
|
+
connections.push({
|
|
434
|
+
connectedNodeId: otherNodeId,
|
|
435
|
+
connectedNode: otherNode,
|
|
436
|
+
extAddressHex: extAddrHex,
|
|
437
|
+
signalColor: getSignalColor(reverseEntry),
|
|
438
|
+
lqi: reverseEntry.lqi,
|
|
439
|
+
rssi: reverseEntry.avgRssi ?? reverseEntry.lastRssi,
|
|
440
|
+
isOutgoing: false,
|
|
441
|
+
isUnknown: false
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
return connections;
|
|
447
|
+
}
|
|
448
|
+
export {
|
|
449
|
+
buildExtAddrMap,
|
|
450
|
+
buildRloc16Map,
|
|
451
|
+
buildThreadConnections,
|
|
452
|
+
categorizeDevices,
|
|
453
|
+
findUnknownDevices,
|
|
454
|
+
getDeviceName,
|
|
455
|
+
getNetworkType,
|
|
456
|
+
getNodeConnections,
|
|
457
|
+
getSignalColor,
|
|
458
|
+
getSignalColorFromRssi,
|
|
459
|
+
getThreadChannel,
|
|
460
|
+
getThreadExtendedAddress,
|
|
461
|
+
getThreadExtendedAddressHex,
|
|
462
|
+
getThreadExtendedPanId,
|
|
463
|
+
getThreadRloc16,
|
|
464
|
+
getThreadRole,
|
|
465
|
+
getThreadRoleName,
|
|
466
|
+
getWiFiDiagnostics,
|
|
467
|
+
getWiFiSecurityTypeName,
|
|
468
|
+
getWiFiVersionName,
|
|
469
|
+
parseNeighborTable,
|
|
470
|
+
parseRouteTable
|
|
471
|
+
};
|
|
472
|
+
//# sourceMappingURL=network-utils.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/pages/network/network-utils.ts"],
|
|
4
|
+
"mappings": "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",
|
|
5
|
+
"names": []
|
|
6
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025-2026 Open Home Foundation
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { BaseNetworkGraph } from "./base-network-graph.js";
|
|
7
|
+
declare global {
|
|
8
|
+
interface HTMLElementTagNameMap {
|
|
9
|
+
"thread-graph": ThreadGraph;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export declare class ThreadGraph extends BaseNetworkGraph {
|
|
13
|
+
/** Cache of unknown devices for the current render */
|
|
14
|
+
private _unknownDevices;
|
|
15
|
+
/** Cached map of unknown devices (rebuilt in _updateGraph) */
|
|
16
|
+
private _unknownDevicesMapCache;
|
|
17
|
+
/** Get unknown devices as a map for use by details panel */
|
|
18
|
+
get unknownDevicesMap(): Map<string, {
|
|
19
|
+
extAddressHex: string;
|
|
20
|
+
isRouter: boolean;
|
|
21
|
+
seenBy: string[];
|
|
22
|
+
bestRssi: number | null;
|
|
23
|
+
}>;
|
|
24
|
+
protected _updateGraph(): void;
|
|
25
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=thread-graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread-graph.d.ts","sourceRoot":"","sources":["../../../../src/pages/network/thread-graph.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAY3D,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,qBAAqB;QAC3B,cAAc,EAAE,WAAW,CAAC;KAC/B;CACJ;AAED,qBACa,WAAY,SAAQ,gBAAgB;IAC7C,sDAAsD;IACtD,OAAO,CAAC,eAAe,CAA6B;IAEpD,8DAA8D;IAC9D,OAAO,CAAC,uBAAuB,CAGjB;IAEd,4DAA4D;IAC5D,IAAW,iBAAiB,IAAI,GAAG,CAC/B,MAAM,EACN;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAC1F,CAEA;cAEkB,YAAY,IAAI,IAAI;IAwG9B,MAAM;CAclB"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
9
|
+
return result;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* @license
|
|
13
|
+
* Copyright 2025-2026 Open Home Foundation
|
|
14
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
15
|
+
*/
|
|
16
|
+
import { html } from "lit";
|
|
17
|
+
import { customElement } from "lit/decorators.js";
|
|
18
|
+
import { BaseNetworkGraph } from "./base-network-graph.js";
|
|
19
|
+
import { createNodeIconDataUrl, createUnknownDeviceIconDataUrl } from "./device-icons.js";
|
|
20
|
+
import {
|
|
21
|
+
buildExtAddrMap,
|
|
22
|
+
buildThreadConnections,
|
|
23
|
+
findUnknownDevices,
|
|
24
|
+
getDeviceName,
|
|
25
|
+
getNetworkType,
|
|
26
|
+
getThreadRole
|
|
27
|
+
} from "./network-utils.js";
|
|
28
|
+
let ThreadGraph = class extends BaseNetworkGraph {
|
|
29
|
+
constructor() {
|
|
30
|
+
super(...arguments);
|
|
31
|
+
/** Cache of unknown devices for the current render */
|
|
32
|
+
this._unknownDevices = [];
|
|
33
|
+
/** Cached map of unknown devices (rebuilt in _updateGraph) */
|
|
34
|
+
this._unknownDevicesMapCache = /* @__PURE__ */ new Map();
|
|
35
|
+
}
|
|
36
|
+
/** Get unknown devices as a map for use by details panel */
|
|
37
|
+
get unknownDevicesMap() {
|
|
38
|
+
return this._unknownDevicesMapCache;
|
|
39
|
+
}
|
|
40
|
+
_updateGraph() {
|
|
41
|
+
if (!this._nodesDataSet || !this._edgesDataSet) return;
|
|
42
|
+
this._clearOriginalEdgeColors();
|
|
43
|
+
const threadNodes = Object.values(this.nodes).filter((node) => getNetworkType(node) === "thread");
|
|
44
|
+
if (threadNodes.length === 0) {
|
|
45
|
+
this._nodesDataSet.clear();
|
|
46
|
+
this._edgesDataSet.clear();
|
|
47
|
+
this._unknownDevices = [];
|
|
48
|
+
this._unknownDevicesMapCache.clear();
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const extAddrMap = buildExtAddrMap(this.nodes);
|
|
52
|
+
this._unknownDevices = findUnknownDevices(this.nodes, extAddrMap);
|
|
53
|
+
this._unknownDevicesMapCache.clear();
|
|
54
|
+
for (const device of this._unknownDevices) {
|
|
55
|
+
this._unknownDevicesMapCache.set(device.id, {
|
|
56
|
+
extAddressHex: device.extAddressHex,
|
|
57
|
+
isRouter: device.isRouter,
|
|
58
|
+
seenBy: device.seenBy,
|
|
59
|
+
bestRssi: device.bestRssi
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
const connections = buildThreadConnections(this.nodes, extAddrMap, this._unknownDevices);
|
|
63
|
+
const graphNodes = threadNodes.map((node) => {
|
|
64
|
+
const nodeId = String(node.node_id);
|
|
65
|
+
const threadRole = getThreadRole(node);
|
|
66
|
+
const isSelected = nodeId === String(this._selectedNodeId);
|
|
67
|
+
const isOffline = node.available === false;
|
|
68
|
+
return {
|
|
69
|
+
id: nodeId,
|
|
70
|
+
label: getDeviceName(node),
|
|
71
|
+
image: createNodeIconDataUrl(node, threadRole, isSelected, isOffline),
|
|
72
|
+
shape: "image",
|
|
73
|
+
networkType: "thread",
|
|
74
|
+
threadRole,
|
|
75
|
+
offline: isOffline
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
for (const unknown of this._unknownDevices) {
|
|
79
|
+
const isSelected = unknown.id === this._selectedNodeId;
|
|
80
|
+
graphNodes.push({
|
|
81
|
+
id: unknown.id,
|
|
82
|
+
label: `Unknown (${unknown.extAddressHex.slice(-8)})`,
|
|
83
|
+
image: createUnknownDeviceIconDataUrl(unknown.isRouter, isSelected),
|
|
84
|
+
shape: "image",
|
|
85
|
+
networkType: "thread",
|
|
86
|
+
isUnknown: true
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
const graphEdges = connections.map((conn, index) => {
|
|
90
|
+
const isToUnknown = typeof conn.toNodeId === "string" && conn.toNodeId.startsWith("unknown_");
|
|
91
|
+
return {
|
|
92
|
+
id: `edge_${index}`,
|
|
93
|
+
from: conn.fromNodeId,
|
|
94
|
+
to: conn.toNodeId,
|
|
95
|
+
color: {
|
|
96
|
+
color: conn.signalColor,
|
|
97
|
+
highlight: conn.signalColor
|
|
98
|
+
},
|
|
99
|
+
width: 2,
|
|
100
|
+
title: conn.rssi !== null ? `RSSI: ${conn.rssi} dBm, LQI: ${conn.lqi}` : `LQI: ${conn.lqi}`,
|
|
101
|
+
dashes: isToUnknown
|
|
102
|
+
// Dashed lines to unknown devices
|
|
103
|
+
};
|
|
104
|
+
});
|
|
105
|
+
const existingNodeIds = this._nodesDataSet.getIds();
|
|
106
|
+
const newNodeIds = new Set(graphNodes.map((n) => n.id));
|
|
107
|
+
const nodesToRemove = existingNodeIds.filter((id) => !newNodeIds.has(id));
|
|
108
|
+
if (nodesToRemove.length > 0) {
|
|
109
|
+
this._nodesDataSet.remove(nodesToRemove);
|
|
110
|
+
}
|
|
111
|
+
this._nodesDataSet.update(graphNodes);
|
|
112
|
+
this._edgesDataSet.clear();
|
|
113
|
+
this._edgesDataSet.add(graphEdges);
|
|
114
|
+
}
|
|
115
|
+
render() {
|
|
116
|
+
const threadNodes = Object.values(this.nodes).filter((node) => getNetworkType(node) === "thread");
|
|
117
|
+
if (threadNodes.length === 0) {
|
|
118
|
+
return html`
|
|
119
|
+
<div class="empty-state">
|
|
120
|
+
<p>No Thread devices found</p>
|
|
121
|
+
<p class="hint">Thread devices will appear here once commissioned</p>
|
|
122
|
+
</div>
|
|
123
|
+
`;
|
|
124
|
+
}
|
|
125
|
+
return html`<div class="graph-container"></div>`;
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
ThreadGraph = __decorateClass([
|
|
129
|
+
customElement("thread-graph")
|
|
130
|
+
], ThreadGraph);
|
|
131
|
+
export {
|
|
132
|
+
ThreadGraph
|
|
133
|
+
};
|
|
134
|
+
//# sourceMappingURL=thread-graph.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/pages/network/thread-graph.ts"],
|
|
4
|
+
"mappings": "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",
|
|
5
|
+
"names": []
|
|
6
|
+
}
|