@matter/node 0.17.5-alpha.0-20260702-a2cd6f764 → 0.17.5-alpha.0-20260706-fd4c49e2e
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/cjs/node/NodePhysicalProperties.d.ts.map +1 -1
- package/dist/cjs/node/NodePhysicalProperties.js +48 -41
- package/dist/cjs/node/NodePhysicalProperties.js.map +1 -1
- package/dist/cjs/node/client/ClientNodePhysicalProperties.d.ts.map +1 -1
- package/dist/cjs/node/client/ClientNodePhysicalProperties.js +6 -0
- package/dist/cjs/node/client/ClientNodePhysicalProperties.js.map +1 -1
- package/dist/esm/node/NodePhysicalProperties.d.ts.map +1 -1
- package/dist/esm/node/NodePhysicalProperties.js +48 -41
- package/dist/esm/node/NodePhysicalProperties.js.map +1 -1
- package/dist/esm/node/client/ClientNodePhysicalProperties.d.ts.map +1 -1
- package/dist/esm/node/client/ClientNodePhysicalProperties.js +6 -0
- package/dist/esm/node/client/ClientNodePhysicalProperties.js.map +1 -1
- package/package.json +6 -6
- package/src/node/NodePhysicalProperties.ts +68 -68
- package/src/node/client/ClientNodePhysicalProperties.ts +8 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodePhysicalProperties.d.ts","sourceRoot":"","sources":["../../../src/node/NodePhysicalProperties.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"NodePhysicalProperties.d.ts","sourceRoot":"","sources":["../../../src/node/NodePhysicalProperties.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAK5D;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,4BAmBhD"}
|
|
@@ -21,6 +21,7 @@ __export(NodePhysicalProperties_exports, {
|
|
|
21
21
|
NodePhysicalProperties: () => NodePhysicalProperties
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(NodePhysicalProperties_exports);
|
|
24
|
+
var import_basic_information = require("#behaviors/basic-information");
|
|
24
25
|
var import_descriptor = require("#behaviors/descriptor");
|
|
25
26
|
var import_network_commissioning = require("#behaviors/network-commissioning");
|
|
26
27
|
var import_power_source = require("#behaviors/power-source");
|
|
@@ -44,59 +45,65 @@ function NodePhysicalProperties(node) {
|
|
|
44
45
|
isMainsPowered: false,
|
|
45
46
|
isBatteryPowered: false,
|
|
46
47
|
isIntermittentlyConnected: rootEndpointServerList.includes(import_model.IcdManagement.id),
|
|
47
|
-
isThreadSleepyEndDevice: false
|
|
48
|
+
isThreadSleepyEndDevice: false,
|
|
49
|
+
specificationVersion: node.maybeStateOf(import_basic_information.BasicInformationClient)?.specificationVersion,
|
|
50
|
+
deviceTypes: /* @__PURE__ */ new Set()
|
|
48
51
|
};
|
|
49
52
|
inspectEndpoint(node, properties);
|
|
50
53
|
return properties;
|
|
51
54
|
}
|
|
52
|
-
function inspectEndpoint(endpoint, properties) {
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
properties.supportsWifi = true;
|
|
57
|
-
}
|
|
58
|
-
if (networkFeatures.threadNetworkInterface) {
|
|
59
|
-
properties.supportsThread = true;
|
|
60
|
-
}
|
|
61
|
-
if (networkFeatures.ethernetNetworkInterface) {
|
|
62
|
-
properties.supportsEthernet = true;
|
|
63
|
-
}
|
|
55
|
+
function inspectEndpoint(endpoint, properties, behindAggregator = false) {
|
|
56
|
+
const deviceTypes = properties.deviceTypes ??= /* @__PURE__ */ new Set();
|
|
57
|
+
for (const { deviceType } of endpoint.maybeStateOf(import_descriptor.DescriptorClient)?.deviceTypeList ?? []) {
|
|
58
|
+
deviceTypes.add(deviceType);
|
|
64
59
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (status === import_power_source2.PowerSource.PowerSourceStatus.Active) {
|
|
71
|
-
properties.isMainsPowered = true;
|
|
60
|
+
if (!behindAggregator) {
|
|
61
|
+
const networkFeatures = endpoint.maybeFeaturesOf(import_network_commissioning.NetworkCommissioningClient);
|
|
62
|
+
if (networkFeatures) {
|
|
63
|
+
if (networkFeatures.wiFiNetworkInterface) {
|
|
64
|
+
properties.supportsWifi = true;
|
|
72
65
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
properties.
|
|
66
|
+
if (networkFeatures.threadNetworkInterface) {
|
|
67
|
+
properties.supportsThread = true;
|
|
68
|
+
}
|
|
69
|
+
if (networkFeatures.ethernetNetworkInterface) {
|
|
70
|
+
properties.supportsEthernet = true;
|
|
78
71
|
}
|
|
79
72
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
73
|
+
const powerSourceFeatures = endpoint.maybeFeaturesOf(import_power_source.PowerSourceClient);
|
|
74
|
+
const powerSourceState = powerSourceFeatures ? endpoint.maybeStateOf(import_power_source.PowerSourceClient) : void 0;
|
|
75
|
+
if (powerSourceFeatures && powerSourceState) {
|
|
76
|
+
const { status } = powerSourceState;
|
|
77
|
+
if (powerSourceFeatures.wired) {
|
|
78
|
+
if (status === import_power_source2.PowerSource.PowerSourceStatus.Active) {
|
|
79
|
+
properties.isMainsPowered = true;
|
|
80
|
+
}
|
|
81
|
+
} else if (powerSourceFeatures.battery || // Perform additional checks because we've encountered devices with incorrect features
|
|
82
|
+
!powerSourceFeatures.wired || endpoint.behaviors.elementsOf(import_power_source.PowerSourceClient).attributes.has("batChargeLevel")) {
|
|
83
|
+
if (status === import_power_source2.PowerSource.PowerSourceStatus.Active || // Some devices do not properly specify state as active
|
|
84
|
+
status === import_power_source2.PowerSource.PowerSourceStatus.Unspecified) {
|
|
85
|
+
properties.isBatteryPowered = true;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
86
88
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
89
|
+
const threadNetworkDiagnostics = endpoint.behaviors.typeFor(import_thread_network_diagnostics.ThreadNetworkDiagnosticsClient);
|
|
90
|
+
const tnd = threadNetworkDiagnostics ? endpoint.maybeStateOf(threadNetworkDiagnostics) : void 0;
|
|
91
|
+
if (tnd) {
|
|
92
|
+
if (tnd.routingRole === import_thread_network_diagnostics2.ThreadNetworkDiagnostics.RoutingRole.SleepyEndDevice) {
|
|
93
|
+
properties.isThreadSleepyEndDevice = true;
|
|
94
|
+
}
|
|
95
|
+
if (tnd.extendedPanId !== void 0 && tnd.extendedPanId !== null) {
|
|
96
|
+
properties.threadActive = true;
|
|
97
|
+
properties.threadPan = BigInt(tnd.extendedPanId);
|
|
98
|
+
properties.threadChannel = tnd.channel ?? void 0;
|
|
99
|
+
} else {
|
|
100
|
+
properties.threadActive = false;
|
|
101
|
+
}
|
|
93
102
|
}
|
|
94
103
|
}
|
|
95
104
|
for (const part of endpoint.parts) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
inspectEndpoint(part, properties);
|
|
105
|
+
const partBehindAggregator = behindAggregator || part.number !== 0 && part.type.deviceType === import_aggregator.AggregatorEndpoint.deviceType;
|
|
106
|
+
inspectEndpoint(part, properties, partBehindAggregator);
|
|
100
107
|
}
|
|
101
108
|
}
|
|
102
109
|
//# sourceMappingURL=NodePhysicalProperties.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/node/NodePhysicalProperties.ts"],
|
|
4
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,wBAAiC;AACjC,mCAA2C;AAC3C,0BAAkC;AAClC,wCAA+C;AAE/C,wBAAmC;AAEnC,mBAA8B;AAG9B,IAAAA,uBAA4B;AAC5B,IAAAC,qCAAyC;
|
|
4
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,+BAAuC;AACvC,wBAAiC;AACjC,mCAA2C;AAC3C,0BAAkC;AAClC,wCAA+C;AAE/C,wBAAmC;AAEnC,mBAA8B;AAG9B,IAAAA,uBAA4B;AAC5B,IAAAC,qCAAyC;AAlBzC;AAAA;AAAA;AAAA;AAAA;AAuBO,SAAS,uBAAuB,MAAY;AAC/C,QAAM,yBAAyB,CAAC,GAAI,KAAK,aAAa,kCAAgB,GAAG,cAAc,CAAC,CAAE;AAE1F,QAAM,aAAuC;AAAA,IACzC,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,kBAAkB;AAAA,IAClB;AAAA,IACA,gBAAgB;AAAA,IAChB,kBAAkB;AAAA,IAClB,2BAA2B,uBAAuB,SAAS,2BAAc,EAAe;AAAA,IACxF,yBAAyB;AAAA,IACzB,sBAAsB,KAAK,aAAa,+CAAsB,GAAG;AAAA,IACjE,aAAa,oBAAI,IAAkB;AAAA,EACvC;AAEA,kBAAgB,MAAM,UAAU;AAEhC,SAAO;AACX;AAKA,SAAS,gBAAgB,UAAoB,YAAsC,mBAAmB,OAAO;AAEzG,QAAM,cAAe,WAAW,gBAAgB,oBAAI,IAAkB;AACtE,aAAW,EAAE,WAAW,KAAK,SAAS,aAAa,kCAAgB,GAAG,kBAAkB,CAAC,GAAG;AACxF,gBAAY,IAAI,UAAU;AAAA,EAC9B;AAEA,MAAI,CAAC,kBAAkB;AAEnB,UAAM,kBAAkB,SAAS,gBAAgB,uDAA0B;AAC3E,QAAI,iBAAiB;AACjB,UAAI,gBAAgB,sBAAsB;AACtC,mBAAW,eAAe;AAAA,MAC9B;AACA,UAAI,gBAAgB,wBAAwB;AACxC,mBAAW,iBAAiB;AAAA,MAChC;AACA,UAAI,gBAAgB,0BAA0B;AAC1C,mBAAW,mBAAmB;AAAA,MAClC;AAAA,IACJ;AAGA,UAAM,sBAAsB,SAAS,gBAAgB,qCAAiB;AACtE,UAAM,mBAAmB,sBAAsB,SAAS,aAAa,qCAAiB,IAAI;AAC1F,QAAI,uBAAuB,kBAAkB;AACzC,YAAM,EAAE,OAAO,IAAI;AACnB,UAAI,oBAAoB,OAAO;AAC3B,YAAI,WAAW,iCAAY,kBAAkB,QAAQ;AAGjD,qBAAW,iBAAiB;AAAA,QAChC;AAAA,MACJ,WACI,oBAAoB;AAAA,MAEpB,CAAC,oBAAoB,SACrB,SAAS,UAAU,WAAW,qCAAiB,EAAE,WAAW,IAAI,gBAAgB,GAClF;AACE,YACI,WAAW,iCAAY,kBAAkB;AAAA,QAEzC,WAAW,iCAAY,kBAAkB,aAC3C;AACE,qBAAW,mBAAmB;AAAA,QAClC;AAAA,MACJ;AAAA,IACJ;AAGA,UAAM,2BAA2B,SAAS,UAAU,QAAQ,gEAA8B;AAC1F,UAAM,MAAM,2BAA2B,SAAS,aAAa,wBAAwB,IAAI;AACzF,QAAI,KAAK;AACL,UAAI,IAAI,gBAAgB,4DAAyB,YAAY,iBAAiB;AAC1E,mBAAW,0BAA0B;AAAA,MACzC;AACA,UAAI,IAAI,kBAAkB,UAAa,IAAI,kBAAkB,MAAM;AAC/D,mBAAW,eAAe;AAC1B,mBAAW,YAAY,OAAO,IAAI,aAAa;AAC/C,mBAAW,gBAAgB,IAAI,WAAW;AAAA,MAC9C,OAAO;AACH,mBAAW,eAAe;AAAA,MAC9B;AAAA,IACJ;AAAA,EACJ;AAIA,aAAW,QAAQ,SAAS,OAAO;AAC/B,UAAM,uBACF,oBAAqB,KAAK,WAAW,KAAK,KAAK,KAAK,eAAe,qCAAmB;AAC1F,oBAAgB,MAAM,YAAY,oBAAoB;AAAA,EAC1D;AACJ;",
|
|
5
5
|
"names": ["import_power_source", "import_thread_network_diagnostics"]
|
|
6
6
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClientNodePhysicalProperties.d.ts","sourceRoot":"","sources":["../../../../src/node/client/ClientNodePhysicalProperties.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGjD,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAK5D;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"ClientNodePhysicalProperties.d.ts","sourceRoot":"","sources":["../../../../src/node/client/ClientNodePhysicalProperties.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGjD,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAK5D;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,UAAU,4BAmG5D"}
|
|
@@ -62,6 +62,12 @@ function ClientNodePhysicalProperties(node) {
|
|
|
62
62
|
get isThreadSleepyEndDevice() {
|
|
63
63
|
return props().isThreadSleepyEndDevice;
|
|
64
64
|
},
|
|
65
|
+
get specificationVersion() {
|
|
66
|
+
return props().specificationVersion;
|
|
67
|
+
},
|
|
68
|
+
get deviceTypes() {
|
|
69
|
+
return props().deviceTypes;
|
|
70
|
+
},
|
|
65
71
|
get threadActive() {
|
|
66
72
|
return props().threadActive;
|
|
67
73
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/node/client/ClientNodePhysicalProperties.ts"],
|
|
4
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,iCAAoC;AAEpC,oCAAuC;AACvC,qBAAyB;AATzB;AAAA;AAAA;AAAA;AAAA;AAaA,MAAM,QAAQ,oBAAI,QAA8C;AAKzD,SAAS,6BAA6B,MAAkB;AAC3D,QAAM,WAAW,MAAM,IAAI,IAAI;AAC/B,MAAI,UAAU;AACV,WAAO;AAAA,EACX;AAEA,MAAI;AACJ,MAAI,SAAS;AAEb,QAAM,SAAmC;AAAA,IACrC,IAAI,iBAAiB;AACjB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,eAAe;AACf,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,mBAAmB;AACnB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,yBAAyB;AACzB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,iBAAiB;AACjB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,mBAAmB;AACnB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,4BAA4B;AAC5B,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,0BAA0B;AAC1B,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,eAAe;AACf,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,YAAY;AACZ,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,gBAAgB;AAChB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,EACJ;AAEA,QAAM,IAAI,MAAM,MAAM;AAEtB,QAAM,YAAa,KAAK,IAAI,IAAI,8CAAmB,EAAgC;AACnF,YAAU,QAAQ,GAAG,MAAM;AACvB,QAAI,OAAQ;AACZ,iBAAa;AAAA,EACjB,CAAC;AAGD,OAAK,UAAU,aAAa,GAAG,MAAM,OAAO,CAAC;AAC7C,OAAK,UAAU,OAAO,GAAG,MAAM;AAC3B,aAAS;AACT,iBAAa;AAAA,EACjB,CAAC;AAID,OAAK,UAAU,UAAU,KAAK,MAAM;AAChC,WAAO;AACP,UAAM,OAAO,IAAI;AAAA,EACrB,CAAC;AAED,SAAO;AAEP,WAAS,QAAQ;AACb,QAAI,eAAe,QAAW;AAC1B,uBAAa,sDAAuB,IAAI;AAAA,IAC5C;AACA,WAAO;AAAA,EACX;AAEA,WAAS,SAAS;AACd,QAAI,OAAQ;AACZ,qBAAa,yBAAS,MAAM,CAAC;AAC7B,aAAS;AAAA,EACb;AACJ;",
|
|
4
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,iCAAoC;AAEpC,oCAAuC;AACvC,qBAAyB;AATzB;AAAA;AAAA;AAAA;AAAA;AAaA,MAAM,QAAQ,oBAAI,QAA8C;AAKzD,SAAS,6BAA6B,MAAkB;AAC3D,QAAM,WAAW,MAAM,IAAI,IAAI;AAC/B,MAAI,UAAU;AACV,WAAO;AAAA,EACX;AAEA,MAAI;AACJ,MAAI,SAAS;AAEb,QAAM,SAAmC;AAAA,IACrC,IAAI,iBAAiB;AACjB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,eAAe;AACf,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,mBAAmB;AACnB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,yBAAyB;AACzB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,iBAAiB;AACjB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,mBAAmB;AACnB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,4BAA4B;AAC5B,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,0BAA0B;AAC1B,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,uBAAuB;AACvB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,cAAc;AACd,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,eAAe;AACf,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,YAAY;AACZ,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,gBAAgB;AAChB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,EACJ;AAEA,QAAM,IAAI,MAAM,MAAM;AAEtB,QAAM,YAAa,KAAK,IAAI,IAAI,8CAAmB,EAAgC;AACnF,YAAU,QAAQ,GAAG,MAAM;AACvB,QAAI,OAAQ;AACZ,iBAAa;AAAA,EACjB,CAAC;AAGD,OAAK,UAAU,aAAa,GAAG,MAAM,OAAO,CAAC;AAC7C,OAAK,UAAU,OAAO,GAAG,MAAM;AAC3B,aAAS;AACT,iBAAa;AAAA,EACjB,CAAC;AAID,OAAK,UAAU,UAAU,KAAK,MAAM;AAChC,WAAO;AACP,UAAM,OAAO,IAAI;AAAA,EACrB,CAAC;AAED,SAAO;AAEP,WAAS,QAAQ;AACb,QAAI,eAAe,QAAW;AAC1B,uBAAa,sDAAuB,IAAI;AAAA,IAC5C;AACA,WAAO;AAAA,EACX;AAEA,WAAS,SAAS;AACd,QAAI,OAAQ;AACZ,qBAAa,yBAAS,MAAM,CAAC;AAC7B,aAAS;AAAA,EACb;AACJ;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodePhysicalProperties.d.ts","sourceRoot":"","sources":["../../../src/node/NodePhysicalProperties.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"NodePhysicalProperties.d.ts","sourceRoot":"","sources":["../../../src/node/NodePhysicalProperties.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAK5D;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,4BAmBhD"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Copyright 2022-2026 Matter.js Authors
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
+
import { BasicInformationClient } from "#behaviors/basic-information";
|
|
6
7
|
import { DescriptorClient } from "#behaviors/descriptor";
|
|
7
8
|
import { NetworkCommissioningClient } from "#behaviors/network-commissioning";
|
|
8
9
|
import { PowerSourceClient } from "#behaviors/power-source";
|
|
@@ -21,59 +22,65 @@ function NodePhysicalProperties(node) {
|
|
|
21
22
|
isMainsPowered: false,
|
|
22
23
|
isBatteryPowered: false,
|
|
23
24
|
isIntermittentlyConnected: rootEndpointServerList.includes(IcdManagement.id),
|
|
24
|
-
isThreadSleepyEndDevice: false
|
|
25
|
+
isThreadSleepyEndDevice: false,
|
|
26
|
+
specificationVersion: node.maybeStateOf(BasicInformationClient)?.specificationVersion,
|
|
27
|
+
deviceTypes: /* @__PURE__ */ new Set()
|
|
25
28
|
};
|
|
26
29
|
inspectEndpoint(node, properties);
|
|
27
30
|
return properties;
|
|
28
31
|
}
|
|
29
|
-
function inspectEndpoint(endpoint, properties) {
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
properties.supportsWifi = true;
|
|
34
|
-
}
|
|
35
|
-
if (networkFeatures.threadNetworkInterface) {
|
|
36
|
-
properties.supportsThread = true;
|
|
37
|
-
}
|
|
38
|
-
if (networkFeatures.ethernetNetworkInterface) {
|
|
39
|
-
properties.supportsEthernet = true;
|
|
40
|
-
}
|
|
32
|
+
function inspectEndpoint(endpoint, properties, behindAggregator = false) {
|
|
33
|
+
const deviceTypes = properties.deviceTypes ??= /* @__PURE__ */ new Set();
|
|
34
|
+
for (const { deviceType } of endpoint.maybeStateOf(DescriptorClient)?.deviceTypeList ?? []) {
|
|
35
|
+
deviceTypes.add(deviceType);
|
|
41
36
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (status === PowerSource.PowerSourceStatus.Active) {
|
|
48
|
-
properties.isMainsPowered = true;
|
|
37
|
+
if (!behindAggregator) {
|
|
38
|
+
const networkFeatures = endpoint.maybeFeaturesOf(NetworkCommissioningClient);
|
|
39
|
+
if (networkFeatures) {
|
|
40
|
+
if (networkFeatures.wiFiNetworkInterface) {
|
|
41
|
+
properties.supportsWifi = true;
|
|
49
42
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
properties.
|
|
43
|
+
if (networkFeatures.threadNetworkInterface) {
|
|
44
|
+
properties.supportsThread = true;
|
|
45
|
+
}
|
|
46
|
+
if (networkFeatures.ethernetNetworkInterface) {
|
|
47
|
+
properties.supportsEthernet = true;
|
|
55
48
|
}
|
|
56
49
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
50
|
+
const powerSourceFeatures = endpoint.maybeFeaturesOf(PowerSourceClient);
|
|
51
|
+
const powerSourceState = powerSourceFeatures ? endpoint.maybeStateOf(PowerSourceClient) : void 0;
|
|
52
|
+
if (powerSourceFeatures && powerSourceState) {
|
|
53
|
+
const { status } = powerSourceState;
|
|
54
|
+
if (powerSourceFeatures.wired) {
|
|
55
|
+
if (status === PowerSource.PowerSourceStatus.Active) {
|
|
56
|
+
properties.isMainsPowered = true;
|
|
57
|
+
}
|
|
58
|
+
} else if (powerSourceFeatures.battery || // Perform additional checks because we've encountered devices with incorrect features
|
|
59
|
+
!powerSourceFeatures.wired || endpoint.behaviors.elementsOf(PowerSourceClient).attributes.has("batChargeLevel")) {
|
|
60
|
+
if (status === PowerSource.PowerSourceStatus.Active || // Some devices do not properly specify state as active
|
|
61
|
+
status === PowerSource.PowerSourceStatus.Unspecified) {
|
|
62
|
+
properties.isBatteryPowered = true;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
63
65
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
const threadNetworkDiagnostics = endpoint.behaviors.typeFor(ThreadNetworkDiagnosticsClient);
|
|
67
|
+
const tnd = threadNetworkDiagnostics ? endpoint.maybeStateOf(threadNetworkDiagnostics) : void 0;
|
|
68
|
+
if (tnd) {
|
|
69
|
+
if (tnd.routingRole === ThreadNetworkDiagnostics.RoutingRole.SleepyEndDevice) {
|
|
70
|
+
properties.isThreadSleepyEndDevice = true;
|
|
71
|
+
}
|
|
72
|
+
if (tnd.extendedPanId !== void 0 && tnd.extendedPanId !== null) {
|
|
73
|
+
properties.threadActive = true;
|
|
74
|
+
properties.threadPan = BigInt(tnd.extendedPanId);
|
|
75
|
+
properties.threadChannel = tnd.channel ?? void 0;
|
|
76
|
+
} else {
|
|
77
|
+
properties.threadActive = false;
|
|
78
|
+
}
|
|
70
79
|
}
|
|
71
80
|
}
|
|
72
81
|
for (const part of endpoint.parts) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
inspectEndpoint(part, properties);
|
|
82
|
+
const partBehindAggregator = behindAggregator || part.number !== 0 && part.type.deviceType === AggregatorEndpoint.deviceType;
|
|
83
|
+
inspectEndpoint(part, properties, partBehindAggregator);
|
|
77
84
|
}
|
|
78
85
|
}
|
|
79
86
|
export {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/node/NodePhysicalProperties.ts"],
|
|
4
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,SAAS,wBAAwB;AACjC,SAAS,kCAAkC;AAC3C,SAAS,yBAAyB;AAClC,SAAS,sCAAsC;AAE/C,SAAS,0BAA0B;AAEnC,SAAS,qBAAqB;AAG9B,SAAS,mBAAmB;AAC5B,SAAS,gCAAgC;AAKlC,SAAS,uBAAuB,MAAY;AAC/C,QAAM,yBAAyB,CAAC,GAAI,KAAK,aAAa,gBAAgB,GAAG,cAAc,CAAC,CAAE;AAE1F,QAAM,aAAuC;AAAA,IACzC,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,kBAAkB;AAAA,IAClB;AAAA,IACA,gBAAgB;AAAA,IAChB,kBAAkB;AAAA,IAClB,2BAA2B,uBAAuB,SAAS,cAAc,EAAe;AAAA,IACxF,yBAAyB;AAAA,
|
|
4
|
+
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,SAAS,8BAA8B;AACvC,SAAS,wBAAwB;AACjC,SAAS,kCAAkC;AAC3C,SAAS,yBAAyB;AAClC,SAAS,sCAAsC;AAE/C,SAAS,0BAA0B;AAEnC,SAAS,qBAAqB;AAG9B,SAAS,mBAAmB;AAC5B,SAAS,gCAAgC;AAKlC,SAAS,uBAAuB,MAAY;AAC/C,QAAM,yBAAyB,CAAC,GAAI,KAAK,aAAa,gBAAgB,GAAG,cAAc,CAAC,CAAE;AAE1F,QAAM,aAAuC;AAAA,IACzC,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,kBAAkB;AAAA,IAClB;AAAA,IACA,gBAAgB;AAAA,IAChB,kBAAkB;AAAA,IAClB,2BAA2B,uBAAuB,SAAS,cAAc,EAAe;AAAA,IACxF,yBAAyB;AAAA,IACzB,sBAAsB,KAAK,aAAa,sBAAsB,GAAG;AAAA,IACjE,aAAa,oBAAI,IAAkB;AAAA,EACvC;AAEA,kBAAgB,MAAM,UAAU;AAEhC,SAAO;AACX;AAKA,SAAS,gBAAgB,UAAoB,YAAsC,mBAAmB,OAAO;AAEzG,QAAM,cAAe,WAAW,gBAAgB,oBAAI,IAAkB;AACtE,aAAW,EAAE,WAAW,KAAK,SAAS,aAAa,gBAAgB,GAAG,kBAAkB,CAAC,GAAG;AACxF,gBAAY,IAAI,UAAU;AAAA,EAC9B;AAEA,MAAI,CAAC,kBAAkB;AAEnB,UAAM,kBAAkB,SAAS,gBAAgB,0BAA0B;AAC3E,QAAI,iBAAiB;AACjB,UAAI,gBAAgB,sBAAsB;AACtC,mBAAW,eAAe;AAAA,MAC9B;AACA,UAAI,gBAAgB,wBAAwB;AACxC,mBAAW,iBAAiB;AAAA,MAChC;AACA,UAAI,gBAAgB,0BAA0B;AAC1C,mBAAW,mBAAmB;AAAA,MAClC;AAAA,IACJ;AAGA,UAAM,sBAAsB,SAAS,gBAAgB,iBAAiB;AACtE,UAAM,mBAAmB,sBAAsB,SAAS,aAAa,iBAAiB,IAAI;AAC1F,QAAI,uBAAuB,kBAAkB;AACzC,YAAM,EAAE,OAAO,IAAI;AACnB,UAAI,oBAAoB,OAAO;AAC3B,YAAI,WAAW,YAAY,kBAAkB,QAAQ;AAGjD,qBAAW,iBAAiB;AAAA,QAChC;AAAA,MACJ,WACI,oBAAoB;AAAA,MAEpB,CAAC,oBAAoB,SACrB,SAAS,UAAU,WAAW,iBAAiB,EAAE,WAAW,IAAI,gBAAgB,GAClF;AACE,YACI,WAAW,YAAY,kBAAkB;AAAA,QAEzC,WAAW,YAAY,kBAAkB,aAC3C;AACE,qBAAW,mBAAmB;AAAA,QAClC;AAAA,MACJ;AAAA,IACJ;AAGA,UAAM,2BAA2B,SAAS,UAAU,QAAQ,8BAA8B;AAC1F,UAAM,MAAM,2BAA2B,SAAS,aAAa,wBAAwB,IAAI;AACzF,QAAI,KAAK;AACL,UAAI,IAAI,gBAAgB,yBAAyB,YAAY,iBAAiB;AAC1E,mBAAW,0BAA0B;AAAA,MACzC;AACA,UAAI,IAAI,kBAAkB,UAAa,IAAI,kBAAkB,MAAM;AAC/D,mBAAW,eAAe;AAC1B,mBAAW,YAAY,OAAO,IAAI,aAAa;AAC/C,mBAAW,gBAAgB,IAAI,WAAW;AAAA,MAC9C,OAAO;AACH,mBAAW,eAAe;AAAA,MAC9B;AAAA,IACJ;AAAA,EACJ;AAIA,aAAW,QAAQ,SAAS,OAAO;AAC/B,UAAM,uBACF,oBAAqB,KAAK,WAAW,KAAK,KAAK,KAAK,eAAe,mBAAmB;AAC1F,oBAAgB,MAAM,YAAY,oBAAoB;AAAA,EAC1D;AACJ;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClientNodePhysicalProperties.d.ts","sourceRoot":"","sources":["../../../../src/node/client/ClientNodePhysicalProperties.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGjD,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAK5D;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"ClientNodePhysicalProperties.d.ts","sourceRoot":"","sources":["../../../../src/node/client/ClientNodePhysicalProperties.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGjD,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAK5D;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,UAAU,4BAmG5D"}
|
|
@@ -39,6 +39,12 @@ function ClientNodePhysicalProperties(node) {
|
|
|
39
39
|
get isThreadSleepyEndDevice() {
|
|
40
40
|
return props().isThreadSleepyEndDevice;
|
|
41
41
|
},
|
|
42
|
+
get specificationVersion() {
|
|
43
|
+
return props().specificationVersion;
|
|
44
|
+
},
|
|
45
|
+
get deviceTypes() {
|
|
46
|
+
return props().deviceTypes;
|
|
47
|
+
},
|
|
42
48
|
get threadActive() {
|
|
43
49
|
return props().threadActive;
|
|
44
50
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/node/client/ClientNodePhysicalProperties.ts"],
|
|
4
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,SAAS,2BAA2B;AAEpC,SAAS,8BAA8B;AACvC,SAAS,gBAAgB;AAIzB,MAAM,QAAQ,oBAAI,QAA8C;AAKzD,SAAS,6BAA6B,MAAkB;AAC3D,QAAM,WAAW,MAAM,IAAI,IAAI;AAC/B,MAAI,UAAU;AACV,WAAO;AAAA,EACX;AAEA,MAAI;AACJ,MAAI,SAAS;AAEb,QAAM,SAAmC;AAAA,IACrC,IAAI,iBAAiB;AACjB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,eAAe;AACf,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,mBAAmB;AACnB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,yBAAyB;AACzB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,iBAAiB;AACjB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,mBAAmB;AACnB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,4BAA4B;AAC5B,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,0BAA0B;AAC1B,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,eAAe;AACf,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,YAAY;AACZ,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,gBAAgB;AAChB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,EACJ;AAEA,QAAM,IAAI,MAAM,MAAM;AAEtB,QAAM,YAAa,KAAK,IAAI,IAAI,mBAAmB,EAAgC;AACnF,YAAU,QAAQ,GAAG,MAAM;AACvB,QAAI,OAAQ;AACZ,iBAAa;AAAA,EACjB,CAAC;AAGD,OAAK,UAAU,aAAa,GAAG,MAAM,OAAO,CAAC;AAC7C,OAAK,UAAU,OAAO,GAAG,MAAM;AAC3B,aAAS;AACT,iBAAa;AAAA,EACjB,CAAC;AAID,OAAK,UAAU,UAAU,KAAK,MAAM;AAChC,WAAO;AACP,UAAM,OAAO,IAAI;AAAA,EACrB,CAAC;AAED,SAAO;AAEP,WAAS,QAAQ;AACb,QAAI,eAAe,QAAW;AAC1B,mBAAa,uBAAuB,IAAI;AAAA,IAC5C;AACA,WAAO;AAAA,EACX;AAEA,WAAS,SAAS;AACd,QAAI,OAAQ;AACZ,iBAAa,SAAS,MAAM,CAAC;AAC7B,aAAS;AAAA,EACb;AACJ;",
|
|
4
|
+
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,SAAS,2BAA2B;AAEpC,SAAS,8BAA8B;AACvC,SAAS,gBAAgB;AAIzB,MAAM,QAAQ,oBAAI,QAA8C;AAKzD,SAAS,6BAA6B,MAAkB;AAC3D,QAAM,WAAW,MAAM,IAAI,IAAI;AAC/B,MAAI,UAAU;AACV,WAAO;AAAA,EACX;AAEA,MAAI;AACJ,MAAI,SAAS;AAEb,QAAM,SAAmC;AAAA,IACrC,IAAI,iBAAiB;AACjB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,eAAe;AACf,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,mBAAmB;AACnB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,yBAAyB;AACzB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,iBAAiB;AACjB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,mBAAmB;AACnB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,4BAA4B;AAC5B,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,0BAA0B;AAC1B,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,uBAAuB;AACvB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,cAAc;AACd,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,eAAe;AACf,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,YAAY;AACZ,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,IAEA,IAAI,gBAAgB;AAChB,aAAO,MAAM,EAAE;AAAA,IACnB;AAAA,EACJ;AAEA,QAAM,IAAI,MAAM,MAAM;AAEtB,QAAM,YAAa,KAAK,IAAI,IAAI,mBAAmB,EAAgC;AACnF,YAAU,QAAQ,GAAG,MAAM;AACvB,QAAI,OAAQ;AACZ,iBAAa;AAAA,EACjB,CAAC;AAGD,OAAK,UAAU,aAAa,GAAG,MAAM,OAAO,CAAC;AAC7C,OAAK,UAAU,OAAO,GAAG,MAAM;AAC3B,aAAS;AACT,iBAAa;AAAA,EACjB,CAAC;AAID,OAAK,UAAU,UAAU,KAAK,MAAM;AAChC,WAAO;AACP,UAAM,OAAO,IAAI;AAAA,EACrB,CAAC;AAED,SAAO;AAEP,WAAS,QAAQ;AACb,QAAI,eAAe,QAAW;AAC1B,mBAAa,uBAAuB,IAAI;AAAA,IAC5C;AACA,WAAO;AAAA,EACX;AAEA,WAAS,SAAS;AACd,QAAI,OAAQ;AACZ,iBAAa,SAAS,MAAM,CAAC;AAC7B,aAAS;AAAA,EACb;AACJ;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matter/node",
|
|
3
|
-
"version": "0.17.5-alpha.0-
|
|
3
|
+
"version": "0.17.5-alpha.0-20260706-fd4c49e2e",
|
|
4
4
|
"description": "API for building Matter nodes",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"iot",
|
|
@@ -36,14 +36,14 @@
|
|
|
36
36
|
"#*": "./src/*"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@matter/general": "0.17.5-alpha.0-
|
|
40
|
-
"@matter/model": "0.17.5-alpha.0-
|
|
41
|
-
"@matter/types": "0.17.5-alpha.0-
|
|
42
|
-
"@matter/protocol": "0.17.5-alpha.0-
|
|
39
|
+
"@matter/general": "0.17.5-alpha.0-20260706-fd4c49e2e",
|
|
40
|
+
"@matter/model": "0.17.5-alpha.0-20260706-fd4c49e2e",
|
|
41
|
+
"@matter/types": "0.17.5-alpha.0-20260706-fd4c49e2e",
|
|
42
|
+
"@matter/protocol": "0.17.5-alpha.0-20260706-fd4c49e2e"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@nacho-iot/js-tools": "^0.1.7",
|
|
46
|
-
"@matter/testing": "0.17.5-alpha.0-
|
|
46
|
+
"@matter/testing": "0.17.5-alpha.0-20260706-fd4c49e2e"
|
|
47
47
|
},
|
|
48
48
|
"files": [
|
|
49
49
|
"dist/**/*",
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { BasicInformationClient } from "#behaviors/basic-information";
|
|
7
8
|
import { DescriptorClient } from "#behaviors/descriptor";
|
|
8
9
|
import { NetworkCommissioningClient } from "#behaviors/network-commissioning";
|
|
9
10
|
import { PowerSourceClient } from "#behaviors/power-source";
|
|
@@ -13,7 +14,7 @@ import { AggregatorEndpoint } from "#endpoints/aggregator";
|
|
|
13
14
|
import { Node } from "#node/Node.js";
|
|
14
15
|
import { IcdManagement } from "@matter/model";
|
|
15
16
|
import { PhysicalDeviceProperties } from "@matter/protocol";
|
|
16
|
-
import { ClusterId } from "@matter/types";
|
|
17
|
+
import { ClusterId, DeviceTypeId } from "@matter/types";
|
|
17
18
|
import { PowerSource } from "@matter/types/clusters/power-source";
|
|
18
19
|
import { ThreadNetworkDiagnostics } from "@matter/types/clusters/thread-network-diagnostics";
|
|
19
20
|
|
|
@@ -32,6 +33,8 @@ export function NodePhysicalProperties(node: Node) {
|
|
|
32
33
|
isBatteryPowered: false,
|
|
33
34
|
isIntermittentlyConnected: rootEndpointServerList.includes(IcdManagement.id as ClusterId),
|
|
34
35
|
isThreadSleepyEndDevice: false,
|
|
36
|
+
specificationVersion: node.maybeStateOf(BasicInformationClient)?.specificationVersion,
|
|
37
|
+
deviceTypes: new Set<DeviceTypeId>(),
|
|
35
38
|
};
|
|
36
39
|
|
|
37
40
|
inspectEndpoint(node, properties);
|
|
@@ -39,83 +42,80 @@ export function NodePhysicalProperties(node: Node) {
|
|
|
39
42
|
return properties;
|
|
40
43
|
}
|
|
41
44
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
properties.supportsThread = true;
|
|
51
|
-
}
|
|
52
|
-
if (networkFeatures.ethernetNetworkInterface) {
|
|
53
|
-
properties.supportsEthernet = true;
|
|
54
|
-
}
|
|
45
|
+
// Device types are collected node-wide (including bridged endpoints behind an aggregator) so consumers such as the
|
|
46
|
+
// subscription-interval policy can react to them. Power/network/thread properties describe the physical node itself,
|
|
47
|
+
// so bridged endpoints (behindAggregator) must not contribute to them.
|
|
48
|
+
function inspectEndpoint(endpoint: Endpoint, properties: PhysicalDeviceProperties, behindAggregator = false) {
|
|
49
|
+
// Device types present on this endpoint
|
|
50
|
+
const deviceTypes = (properties.deviceTypes ??= new Set<DeviceTypeId>());
|
|
51
|
+
for (const { deviceType } of endpoint.maybeStateOf(DescriptorClient)?.deviceTypeList ?? []) {
|
|
52
|
+
deviceTypes.add(deviceType);
|
|
55
53
|
}
|
|
56
54
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (status === PowerSource.PowerSourceStatus.Active) {
|
|
64
|
-
// Should we only consider A/C "mains" powered? What is a DC adapter? What is an external battery?
|
|
65
|
-
// For now assuming "wired" means "don't worry about power consumption"
|
|
66
|
-
properties.isMainsPowered = true;
|
|
55
|
+
if (!behindAggregator) {
|
|
56
|
+
// Network interface support
|
|
57
|
+
const networkFeatures = endpoint.maybeFeaturesOf(NetworkCommissioningClient);
|
|
58
|
+
if (networkFeatures) {
|
|
59
|
+
if (networkFeatures.wiFiNetworkInterface) {
|
|
60
|
+
properties.supportsWifi = true;
|
|
67
61
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
) {
|
|
74
|
-
if (
|
|
75
|
-
status === PowerSource.PowerSourceStatus.Active ||
|
|
76
|
-
// Some devices do not properly specify state as active
|
|
77
|
-
status === PowerSource.PowerSourceStatus.Unspecified
|
|
78
|
-
) {
|
|
79
|
-
properties.isBatteryPowered = true;
|
|
62
|
+
if (networkFeatures.threadNetworkInterface) {
|
|
63
|
+
properties.supportsThread = true;
|
|
64
|
+
}
|
|
65
|
+
if (networkFeatures.ethernetNetworkInterface) {
|
|
66
|
+
properties.supportsEthernet = true;
|
|
80
67
|
}
|
|
81
68
|
}
|
|
82
|
-
}
|
|
83
69
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
70
|
+
// Battery power
|
|
71
|
+
const powerSourceFeatures = endpoint.maybeFeaturesOf(PowerSourceClient);
|
|
72
|
+
const powerSourceState = powerSourceFeatures ? endpoint.maybeStateOf(PowerSourceClient) : undefined;
|
|
73
|
+
if (powerSourceFeatures && powerSourceState) {
|
|
74
|
+
const { status } = powerSourceState;
|
|
75
|
+
if (powerSourceFeatures.wired) {
|
|
76
|
+
if (status === PowerSource.PowerSourceStatus.Active) {
|
|
77
|
+
// Should we only consider A/C "mains" powered? What is a DC adapter? What is an external battery?
|
|
78
|
+
// For now assuming "wired" means "don't worry about power consumption"
|
|
79
|
+
properties.isMainsPowered = true;
|
|
80
|
+
}
|
|
81
|
+
} else if (
|
|
82
|
+
powerSourceFeatures.battery ||
|
|
83
|
+
// Perform additional checks because we've encountered devices with incorrect features
|
|
84
|
+
!powerSourceFeatures.wired ||
|
|
85
|
+
endpoint.behaviors.elementsOf(PowerSourceClient).attributes.has("batChargeLevel")
|
|
86
|
+
) {
|
|
87
|
+
if (
|
|
88
|
+
status === PowerSource.PowerSourceStatus.Active ||
|
|
89
|
+
// Some devices do not properly specify state as active
|
|
90
|
+
status === PowerSource.PowerSourceStatus.Unspecified
|
|
91
|
+
) {
|
|
92
|
+
properties.isBatteryPowered = true;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
90
95
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
96
|
+
|
|
97
|
+
// Sleepy thread device
|
|
98
|
+
const threadNetworkDiagnostics = endpoint.behaviors.typeFor(ThreadNetworkDiagnosticsClient);
|
|
99
|
+
const tnd = threadNetworkDiagnostics ? endpoint.maybeStateOf(threadNetworkDiagnostics) : undefined;
|
|
100
|
+
if (tnd) {
|
|
101
|
+
if (tnd.routingRole === ThreadNetworkDiagnostics.RoutingRole.SleepyEndDevice) {
|
|
102
|
+
properties.isThreadSleepyEndDevice = true;
|
|
103
|
+
}
|
|
104
|
+
if (tnd.extendedPanId !== undefined && tnd.extendedPanId !== null) {
|
|
105
|
+
properties.threadActive = true;
|
|
106
|
+
properties.threadPan = BigInt(tnd.extendedPanId);
|
|
107
|
+
properties.threadChannel = tnd.channel ?? undefined;
|
|
108
|
+
} else {
|
|
109
|
+
properties.threadActive = false;
|
|
110
|
+
}
|
|
97
111
|
}
|
|
98
112
|
}
|
|
99
113
|
|
|
100
|
-
// Recurse into children
|
|
101
|
-
//
|
|
102
|
-
// Do not recurse into aggregator endpoints as bridged nodes are not relevant. The check for mains power should
|
|
103
|
-
// otherwise cover us for properly structured devices. For other devices err on the side of caution and assume
|
|
104
|
-
// mention of a battery on any endpoint means the entire node is battery powered.
|
|
105
|
-
//
|
|
106
|
-
// Technically according to spec we are handling the following incorrectly:
|
|
107
|
-
//
|
|
108
|
-
// * Power source on application endpoint without EndpointList attribute (per spec power source does not apply to
|
|
109
|
-
// node as a whole)
|
|
110
|
-
//
|
|
111
|
-
// * Power source on any endpoint with non-empty EndpointList that does not include endpoint 0 (per spec this does
|
|
112
|
-
// not indicate node is battery powered)
|
|
113
|
-
//
|
|
114
|
-
// The only downside of getting this wrong is that we will operate with degraded response time to changes.
|
|
114
|
+
// Recurse into children. Endpoints at or below an aggregator are bridged nodes: their device types are still
|
|
115
|
+
// collected, but they do not describe the physical node so power/network/thread inspection is suppressed for them.
|
|
115
116
|
for (const part of endpoint.parts) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
inspectEndpoint(part, properties);
|
|
117
|
+
const partBehindAggregator =
|
|
118
|
+
behindAggregator || (part.number !== 0 && part.type.deviceType === AggregatorEndpoint.deviceType);
|
|
119
|
+
inspectEndpoint(part, properties, partBehindAggregator);
|
|
120
120
|
}
|
|
121
121
|
}
|
|
@@ -58,6 +58,14 @@ export function ClientNodePhysicalProperties(node: ClientNode) {
|
|
|
58
58
|
return props().isThreadSleepyEndDevice;
|
|
59
59
|
},
|
|
60
60
|
|
|
61
|
+
get specificationVersion() {
|
|
62
|
+
return props().specificationVersion;
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
get deviceTypes() {
|
|
66
|
+
return props().deviceTypes;
|
|
67
|
+
},
|
|
68
|
+
|
|
61
69
|
get threadActive() {
|
|
62
70
|
return props().threadActive;
|
|
63
71
|
},
|