@camstack/types 1.2.144 → 1.2.146
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/device/container-primary-child.d.ts +24 -1
- package/dist/index.js +43 -2
- package/dist/index.mjs +43 -2
- package/package.json +1 -1
|
@@ -66,11 +66,34 @@ export interface ContainerChildRef {
|
|
|
66
66
|
*/
|
|
67
67
|
readonly entityId?: string;
|
|
68
68
|
readonly type: string;
|
|
69
|
+
/**
|
|
70
|
+
* The child's `DeviceRole`, when the provider stamped one. Ranked BEFORE
|
|
71
|
+
* `type` — see {@link CONTAINER_CHILD_ROLE_PRIORITY}. Absent is normal and
|
|
72
|
+
* simply defers to type priority.
|
|
73
|
+
*/
|
|
74
|
+
readonly role?: string;
|
|
75
|
+
/** The child's operator-facing name, used only for the namesake tiebreak. */
|
|
76
|
+
readonly name?: string;
|
|
69
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Roles that say what a container IS, most→least defining. Consulted BEFORE
|
|
80
|
+
* type priority, because `DeviceType` cannot tell them apart: Home Assistant
|
|
81
|
+
* maps a door contact, a battery level, a temperature reading and a "last seen"
|
|
82
|
+
* timestamp all to `DeviceType.Sensor`. Measured on container 4127 — children
|
|
83
|
+
* `battery-sensor`, `temperature-sensor`, `datetime-sensor`, `contact-sensor`
|
|
84
|
+
* and a role-less `button` — the type list ranked `button` above `sensor` and
|
|
85
|
+
* the container stood for its "Identifica" button instead of the door contact
|
|
86
|
+
* it is named after.
|
|
87
|
+
*
|
|
88
|
+
* Only STATE-DEFINING roles belong here. A diagnostic reading (battery,
|
|
89
|
+
* temperature, humidity, signal, last-seen) is never what a container is, so
|
|
90
|
+
* they are deliberately absent and fall through to type priority.
|
|
91
|
+
*/
|
|
92
|
+
export declare const CONTAINER_CHILD_ROLE_PRIORITY: readonly string[];
|
|
70
93
|
/**
|
|
71
94
|
* The child a container stands for: the operator's pick when it still exists,
|
|
72
95
|
* else the highest-priority type. `null` for a childless container — a caller
|
|
73
96
|
* must decide what an empty container means for it, rather than being handed a
|
|
74
97
|
* child that is not there.
|
|
75
98
|
*/
|
|
76
|
-
export declare function resolveContainerPrimaryChild(children: readonly ContainerChildRef[], overrideEntityId: string | null | undefined): ContainerChildRef | null;
|
|
99
|
+
export declare function resolveContainerPrimaryChild(children: readonly ContainerChildRef[], overrideEntityId: string | null | undefined, containerName?: string): ContainerChildRef | null;
|
package/dist/index.js
CHANGED
|
@@ -35551,6 +35551,46 @@ var CONTAINER_CHILD_PRIORITY = [
|
|
|
35551
35551
|
"image",
|
|
35552
35552
|
"sensor"
|
|
35553
35553
|
];
|
|
35554
|
+
/**
|
|
35555
|
+
* Roles that say what a container IS, most→least defining. Consulted BEFORE
|
|
35556
|
+
* type priority, because `DeviceType` cannot tell them apart: Home Assistant
|
|
35557
|
+
* maps a door contact, a battery level, a temperature reading and a "last seen"
|
|
35558
|
+
* timestamp all to `DeviceType.Sensor`. Measured on container 4127 — children
|
|
35559
|
+
* `battery-sensor`, `temperature-sensor`, `datetime-sensor`, `contact-sensor`
|
|
35560
|
+
* and a role-less `button` — the type list ranked `button` above `sensor` and
|
|
35561
|
+
* the container stood for its "Identifica" button instead of the door contact
|
|
35562
|
+
* it is named after.
|
|
35563
|
+
*
|
|
35564
|
+
* Only STATE-DEFINING roles belong here. A diagnostic reading (battery,
|
|
35565
|
+
* temperature, humidity, signal, last-seen) is never what a container is, so
|
|
35566
|
+
* they are deliberately absent and fall through to type priority.
|
|
35567
|
+
*/
|
|
35568
|
+
var CONTAINER_CHILD_ROLE_PRIORITY = [
|
|
35569
|
+
"contact-sensor",
|
|
35570
|
+
"motion-sensor",
|
|
35571
|
+
"occupancy-sensor",
|
|
35572
|
+
"smoke-sensor",
|
|
35573
|
+
"co-sensor",
|
|
35574
|
+
"gas-sensor",
|
|
35575
|
+
"leak-sensor",
|
|
35576
|
+
"vibration-sensor",
|
|
35577
|
+
"tamper-sensor",
|
|
35578
|
+
"sound-sensor"
|
|
35579
|
+
];
|
|
35580
|
+
/**
|
|
35581
|
+
* NOT in the list, deliberately: `binary-sensor` and `binary-helper`. They are
|
|
35582
|
+
* GENERIC — they say "this reports a boolean", not what the container is — and
|
|
35583
|
+
* ranking them above type priority is a live regression, not a hypothetical:
|
|
35584
|
+
* container 1837 holds a real `lock` (features `['lock-open']`) alongside a
|
|
35585
|
+
* child named "Actuator" whose only role is `binary-sensor`, and the generic
|
|
35586
|
+
* role beat the lock. A role earns a place here by naming a SUBJECT (a contact,
|
|
35587
|
+
* a leak, smoke), never by naming a datatype.
|
|
35588
|
+
*/
|
|
35589
|
+
function roleRank(role) {
|
|
35590
|
+
if (role === void 0) return CONTAINER_CHILD_ROLE_PRIORITY.length;
|
|
35591
|
+
const i = CONTAINER_CHILD_ROLE_PRIORITY.indexOf(role);
|
|
35592
|
+
return i === -1 ? CONTAINER_CHILD_ROLE_PRIORITY.length : i;
|
|
35593
|
+
}
|
|
35554
35594
|
function rank(type) {
|
|
35555
35595
|
const i = CONTAINER_CHILD_PRIORITY.indexOf(type);
|
|
35556
35596
|
return i === -1 ? CONTAINER_CHILD_PRIORITY.length : i;
|
|
@@ -35561,12 +35601,13 @@ function rank(type) {
|
|
|
35561
35601
|
* must decide what an empty container means for it, rather than being handed a
|
|
35562
35602
|
* child that is not there.
|
|
35563
35603
|
*/
|
|
35564
|
-
function resolveContainerPrimaryChild(children, overrideEntityId) {
|
|
35604
|
+
function resolveContainerPrimaryChild(children, overrideEntityId, containerName) {
|
|
35565
35605
|
if (overrideEntityId !== void 0 && overrideEntityId !== null) {
|
|
35566
35606
|
const picked = children.find((c) => c.stableId === overrideEntityId) ?? children.find((c) => c.entityId !== void 0 && c.entityId === overrideEntityId);
|
|
35567
35607
|
if (picked !== void 0) return picked;
|
|
35568
35608
|
}
|
|
35569
|
-
|
|
35609
|
+
const namesake = (c) => containerName !== void 0 && containerName.length > 0 && c.name !== void 0 && c.name.toLowerCase() === containerName.toLowerCase() ? 0 : 1;
|
|
35610
|
+
return [...children].toSorted((a, b) => roleRank(a.role) - roleRank(b.role) || namesake(a) - namesake(b) || rank(a.type) - rank(b.type))[0] ?? null;
|
|
35570
35611
|
}
|
|
35571
35612
|
//#endregion
|
|
35572
35613
|
//#region src/device/accessory.ts
|
package/dist/index.mjs
CHANGED
|
@@ -35543,6 +35543,46 @@ var CONTAINER_CHILD_PRIORITY = [
|
|
|
35543
35543
|
"image",
|
|
35544
35544
|
"sensor"
|
|
35545
35545
|
];
|
|
35546
|
+
/**
|
|
35547
|
+
* Roles that say what a container IS, most→least defining. Consulted BEFORE
|
|
35548
|
+
* type priority, because `DeviceType` cannot tell them apart: Home Assistant
|
|
35549
|
+
* maps a door contact, a battery level, a temperature reading and a "last seen"
|
|
35550
|
+
* timestamp all to `DeviceType.Sensor`. Measured on container 4127 — children
|
|
35551
|
+
* `battery-sensor`, `temperature-sensor`, `datetime-sensor`, `contact-sensor`
|
|
35552
|
+
* and a role-less `button` — the type list ranked `button` above `sensor` and
|
|
35553
|
+
* the container stood for its "Identifica" button instead of the door contact
|
|
35554
|
+
* it is named after.
|
|
35555
|
+
*
|
|
35556
|
+
* Only STATE-DEFINING roles belong here. A diagnostic reading (battery,
|
|
35557
|
+
* temperature, humidity, signal, last-seen) is never what a container is, so
|
|
35558
|
+
* they are deliberately absent and fall through to type priority.
|
|
35559
|
+
*/
|
|
35560
|
+
var CONTAINER_CHILD_ROLE_PRIORITY = [
|
|
35561
|
+
"contact-sensor",
|
|
35562
|
+
"motion-sensor",
|
|
35563
|
+
"occupancy-sensor",
|
|
35564
|
+
"smoke-sensor",
|
|
35565
|
+
"co-sensor",
|
|
35566
|
+
"gas-sensor",
|
|
35567
|
+
"leak-sensor",
|
|
35568
|
+
"vibration-sensor",
|
|
35569
|
+
"tamper-sensor",
|
|
35570
|
+
"sound-sensor"
|
|
35571
|
+
];
|
|
35572
|
+
/**
|
|
35573
|
+
* NOT in the list, deliberately: `binary-sensor` and `binary-helper`. They are
|
|
35574
|
+
* GENERIC — they say "this reports a boolean", not what the container is — and
|
|
35575
|
+
* ranking them above type priority is a live regression, not a hypothetical:
|
|
35576
|
+
* container 1837 holds a real `lock` (features `['lock-open']`) alongside a
|
|
35577
|
+
* child named "Actuator" whose only role is `binary-sensor`, and the generic
|
|
35578
|
+
* role beat the lock. A role earns a place here by naming a SUBJECT (a contact,
|
|
35579
|
+
* a leak, smoke), never by naming a datatype.
|
|
35580
|
+
*/
|
|
35581
|
+
function roleRank(role) {
|
|
35582
|
+
if (role === void 0) return CONTAINER_CHILD_ROLE_PRIORITY.length;
|
|
35583
|
+
const i = CONTAINER_CHILD_ROLE_PRIORITY.indexOf(role);
|
|
35584
|
+
return i === -1 ? CONTAINER_CHILD_ROLE_PRIORITY.length : i;
|
|
35585
|
+
}
|
|
35546
35586
|
function rank(type) {
|
|
35547
35587
|
const i = CONTAINER_CHILD_PRIORITY.indexOf(type);
|
|
35548
35588
|
return i === -1 ? CONTAINER_CHILD_PRIORITY.length : i;
|
|
@@ -35553,12 +35593,13 @@ function rank(type) {
|
|
|
35553
35593
|
* must decide what an empty container means for it, rather than being handed a
|
|
35554
35594
|
* child that is not there.
|
|
35555
35595
|
*/
|
|
35556
|
-
function resolveContainerPrimaryChild(children, overrideEntityId) {
|
|
35596
|
+
function resolveContainerPrimaryChild(children, overrideEntityId, containerName) {
|
|
35557
35597
|
if (overrideEntityId !== void 0 && overrideEntityId !== null) {
|
|
35558
35598
|
const picked = children.find((c) => c.stableId === overrideEntityId) ?? children.find((c) => c.entityId !== void 0 && c.entityId === overrideEntityId);
|
|
35559
35599
|
if (picked !== void 0) return picked;
|
|
35560
35600
|
}
|
|
35561
|
-
|
|
35601
|
+
const namesake = (c) => containerName !== void 0 && containerName.length > 0 && c.name !== void 0 && c.name.toLowerCase() === containerName.toLowerCase() ? 0 : 1;
|
|
35602
|
+
return [...children].toSorted((a, b) => roleRank(a.role) - roleRank(b.role) || namesake(a) - namesake(b) || rank(a.type) - rank(b.type))[0] ?? null;
|
|
35562
35603
|
}
|
|
35563
35604
|
//#endregion
|
|
35564
35605
|
//#region src/device/accessory.ts
|