@digital-alchemy/hass 25.2.2 → 25.3.2
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/dev/index.d.mts +3 -0
- package/dist/dev/index.mjs +4 -0
- package/dist/dev/index.mjs.map +1 -0
- package/dist/dev/mappings.d.mts +70 -0
- package/dist/dev/mappings.mjs +2 -0
- package/dist/dev/mappings.mjs.map +1 -0
- package/dist/dev/registry.d.mts +328 -0
- package/dist/dev/registry.mjs +2 -0
- package/dist/dev/registry.mjs.map +1 -0
- package/dist/dev/services.d.mts +2431 -0
- package/dist/dev/services.mjs +5 -0
- package/dist/dev/services.mjs.map +1 -0
- package/dist/helpers/device.d.mts +1 -1
- package/dist/helpers/entity-state.d.mts +2 -2
- package/dist/helpers/fetch/calendar.d.mts +1 -1
- package/dist/helpers/fetch/configuration.d.mts +1 -1
- package/dist/helpers/fetch/service-list.d.mts +28 -3
- package/dist/helpers/id-by.d.mts +2 -3
- package/dist/helpers/interfaces.d.mts +4 -5
- package/dist/helpers/interfaces.mjs.map +1 -1
- package/dist/helpers/registry.d.mts +1 -2
- package/dist/helpers/registry.mjs.map +1 -1
- package/dist/helpers/utility.d.mts +5 -21
- package/dist/helpers/utility.mjs +0 -5
- package/dist/helpers/utility.mjs.map +1 -1
- package/dist/helpers/websocket.d.mts +2 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.mjs +2 -1
- package/dist/index.mjs.map +1 -1
- package/dist/mock_assistant/helpers/fixtures.d.mts +2 -1
- package/dist/mock_assistant/services/device.service.mjs.map +1 -1
- package/dist/mock_assistant/services/entity-registry.service.d.mts +1 -1
- package/dist/mock_assistant/services/entity.service.d.mts +2 -2
- package/dist/mock_assistant/services/events.service.d.mts +2 -1
- package/dist/mock_assistant/services/events.service.mjs.map +1 -1
- package/dist/mock_assistant/services/fixtures.service.d.mts +3 -2
- package/dist/mock_assistant/services/fixtures.service.mjs.map +1 -1
- package/dist/mock_assistant/services/zone.service.mjs +1 -1
- package/dist/mock_assistant/services/zone.service.mjs.map +1 -1
- package/dist/services/area.service.d.mts +1 -1
- package/dist/services/area.service.mjs +1 -1
- package/dist/services/area.service.mjs.map +1 -1
- package/dist/services/call-proxy.service.d.mts +1 -1
- package/dist/services/call-proxy.service.mjs.map +1 -1
- package/dist/services/config.service.mjs.map +1 -1
- package/dist/services/entity.service.d.mts +1 -1
- package/dist/services/entity.service.mjs +1 -1
- package/dist/services/entity.service.mjs.map +1 -1
- package/dist/services/fetch-api.service.d.mts +3 -2
- package/dist/services/fetch-api.service.mjs.map +1 -1
- package/dist/services/floor.service.mjs.map +1 -1
- package/dist/services/id-by.service.d.mts +1 -1
- package/dist/services/id-by.service.mjs +28 -3
- package/dist/services/id-by.service.mjs.map +1 -1
- package/dist/services/label.service.mjs.map +1 -1
- package/dist/services/reference.service.mjs +4 -3
- package/dist/services/reference.service.mjs.map +1 -1
- package/dist/services/websocket-api.service.mjs +2 -2
- package/dist/services/websocket-api.service.mjs.map +1 -1
- package/dist/testing/area.spec.mjs.map +1 -1
- package/dist/testing/entity.spec.mjs.map +1 -1
- package/dist/testing/floor.spec.mjs.map +1 -1
- package/dist/testing/id-by.spec.mjs.map +1 -1
- package/dist/testing/label.spec.mjs.map +1 -1
- package/dist/testing/ref-by.spec.mjs.map +1 -1
- package/dist/user.d.mts +43 -0
- package/dist/user.mjs +4 -0
- package/dist/user.mjs.map +1 -0
- package/package.json +18 -17
- package/src/dev/index.mts +3 -0
- package/src/dev/mappings.mts +121 -0
- package/src/dev/registry.mts +330 -0
- package/src/dev/services.mts +2759 -0
- package/src/helpers/device.mts +1 -1
- package/src/helpers/entity-state.mts +6 -9
- package/src/helpers/fetch/calendar.mts +1 -1
- package/src/helpers/fetch/configuration.mts +1 -1
- package/src/helpers/fetch/service-list.mts +23 -3
- package/src/helpers/id-by.mts +11 -13
- package/src/helpers/interfaces.mts +14 -18
- package/src/helpers/registry.mts +9 -2
- package/src/helpers/utility.mts +13 -67
- package/src/helpers/websocket.mts +2 -1
- package/src/index.mts +2 -1
- package/src/mock_assistant/helpers/fixtures.mts +1 -1
- package/src/mock_assistant/services/area.service.mts +1 -1
- package/src/mock_assistant/services/device.service.mts +1 -1
- package/src/mock_assistant/services/entity-registry.service.mts +1 -1
- package/src/mock_assistant/services/entity.service.mts +2 -2
- package/src/mock_assistant/services/events.service.mts +2 -1
- package/src/mock_assistant/services/fixtures.service.mts +2 -1
- package/src/mock_assistant/services/floor.service.mts +1 -1
- package/src/mock_assistant/services/label.service.mts +1 -1
- package/src/mock_assistant/services/zone.service.mts +13 -10
- package/src/services/area.service.mts +2 -3
- package/src/services/call-proxy.service.mts +2 -2
- package/src/services/config.service.mts +1 -1
- package/src/services/entity.service.mts +2 -4
- package/src/services/fetch-api.service.mts +1 -1
- package/src/services/floor.service.mts +1 -1
- package/src/services/id-by.service.mts +47 -19
- package/src/services/label.service.mts +1 -1
- package/src/services/reference.service.mts +19 -18
- package/src/services/websocket-api.service.mts +2 -2
- package/src/testing/area.spec.mts +1 -1
- package/src/testing/entity.spec.mts +2 -1
- package/src/testing/floor.spec.mts +1 -1
- package/src/testing/id-by.spec.mts +1 -1
- package/src/testing/label.spec.mts +1 -1
- package/src/testing/ref-by.spec.mts +2 -1
- package/src/user.mts +97 -0
- package/dist/dynamic.d.mts +0 -3764
- package/dist/dynamic.mjs +0 -7
- package/dist/dynamic.mjs.map +0 -1
- package/src/dynamic.mts +0 -4302
|
@@ -1,26 +1,23 @@
|
|
|
1
|
-
import { TServiceParams } from "@digital-alchemy/core";
|
|
1
|
+
import { FIRST, SINGLE, TServiceParams } from "@digital-alchemy/core";
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
TAreaId,
|
|
5
|
-
TDeviceId,
|
|
6
|
-
TFloorId,
|
|
7
|
-
TLabelId,
|
|
8
|
-
TPlatformId,
|
|
9
|
-
TUniqueId,
|
|
10
|
-
TUniqueIDMapping,
|
|
11
|
-
} from "../dynamic.mts";
|
|
3
|
+
import { domain, EntityRegistryItem, IDByInterface } from "../index.mts";
|
|
12
4
|
import {
|
|
13
5
|
ALL_DOMAINS,
|
|
14
6
|
ANY_ENTITY,
|
|
15
|
-
|
|
16
|
-
IDByInterface,
|
|
7
|
+
HassUniqueIdMapping,
|
|
17
8
|
PICK_ENTITY,
|
|
18
9
|
PICK_FROM_AREA,
|
|
19
10
|
PICK_FROM_DEVICE,
|
|
20
11
|
PICK_FROM_FLOOR,
|
|
21
12
|
PICK_FROM_LABEL,
|
|
22
13
|
PICK_FROM_PLATFORM,
|
|
23
|
-
|
|
14
|
+
TAreaId,
|
|
15
|
+
TDeviceId,
|
|
16
|
+
TFloorId,
|
|
17
|
+
TLabelId,
|
|
18
|
+
TPlatformId,
|
|
19
|
+
TUniqueId,
|
|
20
|
+
} from "../user.mts";
|
|
24
21
|
|
|
25
22
|
export function IDByExtension({
|
|
26
23
|
hass,
|
|
@@ -44,22 +41,53 @@ export function IDByExtension({
|
|
|
44
41
|
);
|
|
45
42
|
}
|
|
46
43
|
|
|
47
|
-
|
|
44
|
+
/**
|
|
45
|
+
* unique_id
|
|
46
|
+
*
|
|
47
|
+
* ## Dev note on logic here
|
|
48
|
+
*
|
|
49
|
+
* unique_ids are not ACTUALLY unique when iterating through the registry from here
|
|
50
|
+
* hacs does this a bunch, using a sensor with the same unique_id as an update entity
|
|
51
|
+
*
|
|
52
|
+
* The logic here will look up ALL entities with the "unique"_id, then check to see if there are multiple results
|
|
53
|
+
* It is assumed by both this code and type-writer that the unique_id lookup will refer to the not update entity
|
|
54
|
+
*/
|
|
48
55
|
function unique_id<
|
|
49
56
|
UNIQUE_ID extends TUniqueId,
|
|
50
|
-
ENTITY_ID extends Extract<
|
|
51
|
-
|
|
57
|
+
ENTITY_ID extends Extract<HassUniqueIdMapping[UNIQUE_ID], ANY_ENTITY> = Extract<
|
|
58
|
+
HassUniqueIdMapping[UNIQUE_ID],
|
|
52
59
|
ANY_ENTITY
|
|
53
60
|
>,
|
|
54
61
|
>(unique_id: UNIQUE_ID): ENTITY_ID {
|
|
55
62
|
hass.entity.warnEarly("byUniqueId");
|
|
56
|
-
|
|
63
|
+
let list = hass.entity.registry.current.filter(
|
|
57
64
|
i => i.unique_id === unique_id,
|
|
58
|
-
) as EntityRegistryItem<ENTITY_ID
|
|
59
|
-
if (
|
|
65
|
+
) as EntityRegistryItem<ENTITY_ID>[];
|
|
66
|
+
if (is.empty(list)) {
|
|
60
67
|
logger.error({ name: unique_id, unique_id }, `could not find an entity`);
|
|
61
68
|
return undefined;
|
|
62
69
|
}
|
|
70
|
+
if (list.length > SINGLE) {
|
|
71
|
+
const trimmed = list.filter(
|
|
72
|
+
i =>
|
|
73
|
+
// @ts-expect-error issue in dev types
|
|
74
|
+
domain(i.entity_id) !== "update",
|
|
75
|
+
);
|
|
76
|
+
if (trimmed.length > SINGLE) {
|
|
77
|
+
logger.warn(
|
|
78
|
+
{ available_entity_ids: trimmed.map(i => i.entity_id), unique_id },
|
|
79
|
+
`unique_id collision during lookup (chose first in list)`,
|
|
80
|
+
);
|
|
81
|
+
} else {
|
|
82
|
+
logger.trace(
|
|
83
|
+
{ unique_id },
|
|
84
|
+
`chose {%s} over update entity during lookup`,
|
|
85
|
+
trimmed[FIRST].entity_id,
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
list = trimmed;
|
|
89
|
+
}
|
|
90
|
+
const [entity] = list;
|
|
63
91
|
return entity?.entity_id;
|
|
64
92
|
}
|
|
65
93
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { debounce, TServiceParams } from "@digital-alchemy/core";
|
|
2
2
|
|
|
3
|
-
import { TLabelId } from "../dynamic.mts";
|
|
4
3
|
import {
|
|
5
4
|
EARLY_ON_READY,
|
|
6
5
|
HassLabelService,
|
|
@@ -8,6 +7,7 @@ import {
|
|
|
8
7
|
LabelDefinition,
|
|
9
8
|
LabelOptions,
|
|
10
9
|
} from "../helpers/index.mts";
|
|
10
|
+
import { TLabelId } from "../user.mts";
|
|
11
11
|
|
|
12
12
|
export function Label({
|
|
13
13
|
hass,
|
|
@@ -2,31 +2,31 @@ import { DOWN, NONE, sleep, TAnyFunction, TServiceParams, UP } from "@digital-al
|
|
|
2
2
|
import dayjs, { Dayjs } from "dayjs";
|
|
3
3
|
import { Get } from "type-fest";
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
TAreaId,
|
|
7
|
-
TDeviceId,
|
|
8
|
-
TFloorId,
|
|
9
|
-
TLabelId,
|
|
10
|
-
TPlatformId,
|
|
11
|
-
TRawDomains,
|
|
12
|
-
TUniqueId,
|
|
13
|
-
TUniqueIDMapping,
|
|
14
|
-
} from "../dynamic.mts";
|
|
15
5
|
import {
|
|
16
6
|
ALL_SERVICE_DOMAINS,
|
|
17
|
-
ANY_ENTITY,
|
|
18
7
|
ByIdProxy,
|
|
19
8
|
domain,
|
|
20
9
|
ENTITY_STATE,
|
|
21
10
|
HassReferenceService,
|
|
11
|
+
RemoveCallback,
|
|
12
|
+
} from "../helpers/index.mts";
|
|
13
|
+
import {
|
|
14
|
+
ANY_ENTITY,
|
|
15
|
+
HassUniqueIdMapping,
|
|
22
16
|
PICK_ENTITY,
|
|
23
17
|
PICK_FROM_AREA,
|
|
24
18
|
PICK_FROM_DEVICE,
|
|
25
19
|
PICK_FROM_FLOOR,
|
|
26
20
|
PICK_FROM_LABEL,
|
|
27
21
|
PICK_FROM_PLATFORM,
|
|
28
|
-
|
|
29
|
-
|
|
22
|
+
TAreaId,
|
|
23
|
+
TDeviceId,
|
|
24
|
+
TFloorId,
|
|
25
|
+
TLabelId,
|
|
26
|
+
TPlatformId,
|
|
27
|
+
TRawDomains,
|
|
28
|
+
TUniqueId,
|
|
29
|
+
} from "../user.mts";
|
|
30
30
|
import { SERVICE_LIST_UPDATED } from "./config.service.mts";
|
|
31
31
|
import { SOCKET_CONNECTED } from "./websocket-api.service.mts";
|
|
32
32
|
|
|
@@ -187,7 +187,7 @@ export function ReferenceService({
|
|
|
187
187
|
event.on(SOCKET_CONNECTED, removableCallback);
|
|
188
188
|
listeners.add(remove);
|
|
189
189
|
|
|
190
|
-
return
|
|
190
|
+
return internal.removeFn(remove);
|
|
191
191
|
};
|
|
192
192
|
}
|
|
193
193
|
|
|
@@ -227,7 +227,7 @@ export function ReferenceService({
|
|
|
227
227
|
};
|
|
228
228
|
listeners.add(remove);
|
|
229
229
|
event.once(entity_id, wrapped);
|
|
230
|
-
return
|
|
230
|
+
return internal.removeFn(remove);
|
|
231
231
|
};
|
|
232
232
|
}
|
|
233
233
|
|
|
@@ -304,6 +304,7 @@ export function ReferenceService({
|
|
|
304
304
|
listeners.add(remove);
|
|
305
305
|
|
|
306
306
|
const complete = (entity: ENTITY_STATE<ENTITY_ID>) => {
|
|
307
|
+
// eslint-disable-next-line sonarjs/different-types-comparison
|
|
307
308
|
if (entity.state !== state) {
|
|
308
309
|
logger.trace(
|
|
309
310
|
{
|
|
@@ -339,7 +340,7 @@ export function ReferenceService({
|
|
|
339
340
|
// #MARK: service calls
|
|
340
341
|
if (hass.configure.isService(entity_domain, property)) {
|
|
341
342
|
return async function (data = {}) {
|
|
342
|
-
// @ts-expect-error
|
|
343
|
+
// @ts-expect-error i don't care, this is fine
|
|
343
344
|
return await hass.call[entity_domain][property]({
|
|
344
345
|
entity_id,
|
|
345
346
|
...data,
|
|
@@ -434,8 +435,8 @@ export function ReferenceService({
|
|
|
434
435
|
|
|
435
436
|
unique_id: <
|
|
436
437
|
UNIQUE_ID extends TUniqueId,
|
|
437
|
-
ENTITY_ID extends Extract<
|
|
438
|
-
|
|
438
|
+
ENTITY_ID extends Extract<HassUniqueIdMapping[UNIQUE_ID], ANY_ENTITY> = Extract<
|
|
439
|
+
HassUniqueIdMapping[UNIQUE_ID],
|
|
439
440
|
ANY_ENTITY
|
|
440
441
|
>,
|
|
441
442
|
>(
|
|
@@ -508,7 +508,7 @@ export function WebsocketAPI({
|
|
|
508
508
|
} else {
|
|
509
509
|
socketEvents.on(event, callback);
|
|
510
510
|
}
|
|
511
|
-
return
|
|
511
|
+
return internal.removeFn(() => {
|
|
512
512
|
logger.trace({ context, event, name: onEvent }, `removing socket event listener`);
|
|
513
513
|
socketEvents.removeListener(event, callback);
|
|
514
514
|
});
|
|
@@ -542,7 +542,7 @@ export function WebsocketAPI({
|
|
|
542
542
|
// attach anyways, for restarts or whatever
|
|
543
543
|
}
|
|
544
544
|
event.on(SOCKET_CONNECTED, wrapped);
|
|
545
|
-
return
|
|
545
|
+
return internal.removeFn(() => event.removeListener(SOCKET_CONNECTED, wrapped));
|
|
546
546
|
}
|
|
547
547
|
|
|
548
548
|
// #MARK: return object
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { sleep } from "@digital-alchemy/core";
|
|
2
2
|
|
|
3
|
-
import { TAreaId } from "../dynamic.mts";
|
|
4
3
|
import { AREA_REGISTRY_UPDATED, AreaDetails } from "../helpers/index.mts";
|
|
5
4
|
import { hassTestRunner, INTERNAL_MESSAGE } from "../mock_assistant/index.mts";
|
|
5
|
+
import { TAreaId } from "../user.mts";
|
|
6
6
|
|
|
7
7
|
describe("Area", () => {
|
|
8
8
|
const EXAMPLE_AREA = {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { sleep } from "@digital-alchemy/core";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { ENTITY_STATE } from "../index.mts";
|
|
4
4
|
import { hassTestRunner } from "../mock_assistant/index.mts";
|
|
5
|
+
import { ANY_ENTITY } from "../user.mts";
|
|
5
6
|
|
|
6
7
|
describe("Entity", () => {
|
|
7
8
|
afterEach(async () => {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { sleep } from "@digital-alchemy/core";
|
|
2
2
|
|
|
3
|
-
import { TFloorId } from "../dynamic.mts";
|
|
4
3
|
import { FLOOR_REGISTRY_UPDATED, FloorDetails } from "../helpers/index.mts";
|
|
5
4
|
import { hassTestRunner } from "../mock_assistant/index.mts";
|
|
5
|
+
import { TFloorId } from "../user.mts";
|
|
6
6
|
|
|
7
7
|
describe("Floor", () => {
|
|
8
8
|
const EXAMPLE_FLOOR = {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { sleep } from "@digital-alchemy/core";
|
|
2
2
|
|
|
3
|
-
import { TLabelId } from "../dynamic.mts";
|
|
4
3
|
import { LABEL_REGISTRY_UPDATED, LabelDefinition } from "../helpers/index.mts";
|
|
5
4
|
import { hassTestRunner } from "../mock_assistant/index.mts";
|
|
5
|
+
import { TLabelId } from "../user.mts";
|
|
6
6
|
|
|
7
7
|
describe("Label", () => {
|
|
8
8
|
const EXAMPLE_LABEL = {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import dayjs from "dayjs";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { ENTITY_STATE } from "../helpers/index.mts";
|
|
4
4
|
import { hassTestRunner } from "../mock_assistant/index.mts";
|
|
5
|
+
import { ANY_ENTITY } from "../user.mts";
|
|
5
6
|
|
|
6
7
|
describe("References", () => {
|
|
7
8
|
afterEach(async () => {
|
package/src/user.mts
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/* eslint-disable sonarjs/class-name */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-empty-object-type */
|
|
3
|
+
|
|
4
|
+
// #MARK: utility
|
|
5
|
+
type UnPrefix<T> = T extends `_${infer Platform}` ? Platform : never;
|
|
6
|
+
|
|
7
|
+
// #MARK: merging
|
|
8
|
+
export interface HassUniqueIdMapping {
|
|
9
|
+
// "{unique_id}": "{entity_id}"
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface HassDomainMapping {
|
|
13
|
+
// "{domain}": "{entity_id}" | "{entity_id}" | ....
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// ? prefix everything with "_" to ensure valid keys
|
|
17
|
+
export interface HassPlatformMapping {
|
|
18
|
+
// "_{platform}": "{entity_id}" | "{entity_id}" | ....
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface HassDeviceMapping {
|
|
22
|
+
// "_{device}": "{entity_id}" | "{entity_id}" | ....
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface HassAreaMapping {
|
|
26
|
+
// "_{area}": "{entity_id}" | "{entity_id}" | ....
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface HassLabelMapping {
|
|
30
|
+
// "_{label}": "{entity_id}" | "{entity_id}" | ....
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface HassFloorMapping {
|
|
34
|
+
// "_{label}": "{entity_id}" | "{entity_id}" | ....
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface HassEntitySetupMapping {
|
|
38
|
+
// "{entity_id}": { attributes, context, entity_id, state }
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface iCallService {
|
|
42
|
+
// "{service_domain}": { "{service}": fn }
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface HassZoneMapping {
|
|
46
|
+
// "zone": true
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// #MARK: extract
|
|
50
|
+
export type TAreaId = UnPrefix<keyof HassAreaMapping>;
|
|
51
|
+
export type TDeviceId = UnPrefix<keyof HassDeviceMapping>;
|
|
52
|
+
export type TFloorId = UnPrefix<keyof HassFloorMapping>;
|
|
53
|
+
export type TLabelId = UnPrefix<keyof HassLabelMapping>;
|
|
54
|
+
export type TPlatformId = UnPrefix<keyof HassPlatformMapping>;
|
|
55
|
+
|
|
56
|
+
export type TRawDomains = keyof HassDomainMapping;
|
|
57
|
+
export type TZoneId = keyof HassZoneMapping;
|
|
58
|
+
export type ALL_DOMAINS = keyof HassDomainMapping;
|
|
59
|
+
export type TUniqueId = keyof HassUniqueIdMapping;
|
|
60
|
+
export type ANY_ENTITY = keyof HassEntitySetupMapping;
|
|
61
|
+
export type TRawEntityIds = keyof HassEntitySetupMapping;
|
|
62
|
+
|
|
63
|
+
export type PICK_FROM_AREA<ID extends TAreaId, DOMAIN extends ALL_DOMAINS = ALL_DOMAINS> = Extract<
|
|
64
|
+
HassAreaMapping[`_${ID}`],
|
|
65
|
+
PICK_ENTITY<DOMAIN>
|
|
66
|
+
>;
|
|
67
|
+
|
|
68
|
+
export type PICK_FROM_LABEL<
|
|
69
|
+
ID extends TLabelId,
|
|
70
|
+
DOMAIN extends ALL_DOMAINS = ALL_DOMAINS,
|
|
71
|
+
> = Extract<HassLabelMapping[`_${ID}`], PICK_ENTITY<DOMAIN>>;
|
|
72
|
+
|
|
73
|
+
export type PICK_FROM_FLOOR<
|
|
74
|
+
ID extends TFloorId,
|
|
75
|
+
DOMAIN extends ALL_DOMAINS = ALL_DOMAINS,
|
|
76
|
+
> = Extract<HassFloorMapping[`_${ID}`], PICK_ENTITY<DOMAIN>>;
|
|
77
|
+
|
|
78
|
+
export type PICK_FROM_DEVICE<
|
|
79
|
+
ID extends TDeviceId,
|
|
80
|
+
DOMAIN extends ALL_DOMAINS = ALL_DOMAINS,
|
|
81
|
+
> = Extract<HassDeviceMapping[`_${ID}`], PICK_ENTITY<DOMAIN>>;
|
|
82
|
+
|
|
83
|
+
export type PICK_FROM_PLATFORM<
|
|
84
|
+
ID extends TPlatformId,
|
|
85
|
+
DOMAIN extends ALL_DOMAINS = ALL_DOMAINS,
|
|
86
|
+
> = Extract<HassPlatformMapping[`_${ID}`], PICK_ENTITY<DOMAIN>>;
|
|
87
|
+
|
|
88
|
+
export type GetDomain<ENTITY extends `${ALL_DOMAINS}.${string}`> =
|
|
89
|
+
ENTITY extends `${infer domain}.${string}` ? domain : never;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Pick any valid entity, optionally limiting by domain
|
|
93
|
+
*/
|
|
94
|
+
export type PICK_ENTITY<DOMAIN extends ALL_DOMAINS = ALL_DOMAINS> = Extract<
|
|
95
|
+
TRawEntityIds,
|
|
96
|
+
`${DOMAIN}.${string}`
|
|
97
|
+
>;
|