@digital-alchemy/hass 0.2.0

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.
Files changed (68) hide show
  1. package/LICENSE +21 -0
  2. package/dist/dynamic.d.ts +1126 -0
  3. package/dist/dynamic.js +153 -0
  4. package/dist/dynamic.js.map +1 -0
  5. package/dist/extensions/call-proxy.extension.d.ts +4 -0
  6. package/dist/extensions/call-proxy.extension.js +88 -0
  7. package/dist/extensions/call-proxy.extension.js.map +1 -0
  8. package/dist/extensions/config.extension.d.ts +2 -0
  9. package/dist/extensions/config.extension.js +53 -0
  10. package/dist/extensions/config.extension.js.map +1 -0
  11. package/dist/extensions/entity-manager.extension.d.ts +61 -0
  12. package/dist/extensions/entity-manager.extension.js +212 -0
  13. package/dist/extensions/entity-manager.extension.js.map +1 -0
  14. package/dist/extensions/fetch-api.extension.d.ts +29 -0
  15. package/dist/extensions/fetch-api.extension.js +174 -0
  16. package/dist/extensions/fetch-api.extension.js.map +1 -0
  17. package/dist/extensions/index.d.ts +6 -0
  18. package/dist/extensions/index.js +10 -0
  19. package/dist/extensions/index.js.map +1 -0
  20. package/dist/extensions/utilities.extension.d.ts +9 -0
  21. package/dist/extensions/utilities.extension.js +43 -0
  22. package/dist/extensions/utilities.extension.js.map +1 -0
  23. package/dist/extensions/websocket-api.extension.d.ts +39 -0
  24. package/dist/extensions/websocket-api.extension.js +363 -0
  25. package/dist/extensions/websocket-api.extension.js.map +1 -0
  26. package/dist/hass.module.d.ts +80 -0
  27. package/dist/hass.module.js +83 -0
  28. package/dist/hass.module.js.map +1 -0
  29. package/dist/helpers/backup.helper.d.ts +11 -0
  30. package/dist/helpers/backup.helper.js +3 -0
  31. package/dist/helpers/backup.helper.js.map +1 -0
  32. package/dist/helpers/constants.helper.d.ts +54 -0
  33. package/dist/helpers/constants.helper.js +63 -0
  34. package/dist/helpers/constants.helper.js.map +1 -0
  35. package/dist/helpers/entity-state.helper.d.ts +45 -0
  36. package/dist/helpers/entity-state.helper.js +9 -0
  37. package/dist/helpers/entity-state.helper.js.map +1 -0
  38. package/dist/helpers/fetch/calendar.d.ts +54 -0
  39. package/dist/helpers/fetch/calendar.js +3 -0
  40. package/dist/helpers/fetch/calendar.js.map +1 -0
  41. package/dist/helpers/fetch/configuration.d.ts +34 -0
  42. package/dist/helpers/fetch/configuration.js +3 -0
  43. package/dist/helpers/fetch/configuration.js.map +1 -0
  44. package/dist/helpers/fetch/index.d.ts +4 -0
  45. package/dist/helpers/fetch/index.js +8 -0
  46. package/dist/helpers/fetch/index.js.map +1 -0
  47. package/dist/helpers/fetch/server-log.d.ts +10 -0
  48. package/dist/helpers/fetch/server-log.js +20 -0
  49. package/dist/helpers/fetch/server-log.js.map +1 -0
  50. package/dist/helpers/fetch/service-list.d.ts +51 -0
  51. package/dist/helpers/fetch/service-list.js +3 -0
  52. package/dist/helpers/fetch/service-list.js.map +1 -0
  53. package/dist/helpers/index.d.ts +7 -0
  54. package/dist/helpers/index.js +11 -0
  55. package/dist/helpers/index.js.map +1 -0
  56. package/dist/helpers/metrics.helper.d.ts +13 -0
  57. package/dist/helpers/metrics.helper.js +30 -0
  58. package/dist/helpers/metrics.helper.js.map +1 -0
  59. package/dist/helpers/utility.helper.d.ts +53 -0
  60. package/dist/helpers/utility.helper.js +30 -0
  61. package/dist/helpers/utility.helper.js.map +1 -0
  62. package/dist/helpers/websocket.helper.d.ts +129 -0
  63. package/dist/helpers/websocket.helper.js +3 -0
  64. package/dist/helpers/websocket.helper.js.map +1 -0
  65. package/dist/index.d.ts +4 -0
  66. package/dist/index.js +8 -0
  67. package/dist/index.js.map +1 -0
  68. package/package.json +63 -0
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ENTITY_SETUP = void 0;
4
+ /**
5
+ * ## THIS FILE IS INTENDED TO BE REPLACED
6
+ *
7
+ * ! IF YOU STILL SEE THIS IN YOUR `node_modules`, run `npx type-writer`
8
+ *
9
+ * The purpose it to represent the configuration of Home Assistant
10
+ *
11
+ * - entities, with their available attributes & states
12
+ * - services, and what parameters they take
13
+ *
14
+ * This information is TYPES ONLY, and is used to add type safety to
15
+ * methods exported from this library through the use of utility types that
16
+ * take advantage of this information
17
+ *
18
+ * A post-install hook will regenerate these with real values.
19
+ *
20
+ * The service definition is the switch, light, scene domains from a previously generated file.
21
+ * These are required to make typescript happy for internal library definitions
22
+ */
23
+ exports.ENTITY_SETUP = {
24
+ binary_sensor: {
25
+ is_day: {
26
+ attributes: {
27
+ friendly_name: "Is day",
28
+ },
29
+ context: {
30
+ id: "01HNZ7RV5ZRHF4R6EVTX210Z82",
31
+ parent_id: null,
32
+ user_id: null,
33
+ },
34
+ entity_id: "binary_sensor.is_day",
35
+ last_changed: "2024-02-06T12:55:00.031067+00:00",
36
+ last_updated: "2024-02-06T12:55:00.031067+00:00",
37
+ state: "on",
38
+ },
39
+ },
40
+ button: {
41
+ click_me: {
42
+ attributes: {
43
+ friendly_name: "Click me",
44
+ },
45
+ context: {
46
+ id: "01HNZ7RV5ZRHF4R6EVTX210Z83",
47
+ parent_id: null,
48
+ user_id: null,
49
+ },
50
+ entity_id: "button.click_me",
51
+ last_changed: "2024-02-06T12:55:00.031068+00:00",
52
+ },
53
+ },
54
+ calendar: {
55
+ personal: {
56
+ attributes: {
57
+ friendly_name: "Personal",
58
+ offset_reached: false,
59
+ },
60
+ context: {
61
+ id: "01HJYK0H8P96SCF35ZVZGXKRT0",
62
+ parent_id: null,
63
+ user_id: null,
64
+ },
65
+ entity_id: "calendar.personal",
66
+ last_changed: "2023-12-31T00:00:06.145302+00:00",
67
+ last_updated: "2023-12-31T00:05:06.454423+00:00",
68
+ state: "off",
69
+ },
70
+ },
71
+ light: {
72
+ womp: {
73
+ attributes: {
74
+ brightness: 255,
75
+ color_mode: "color_temp",
76
+ color_temp: 253,
77
+ color_temp_kelvin: 3952,
78
+ dynamics: "none",
79
+ friendly_name: "Womp",
80
+ hs_color: [26.835, 35.746],
81
+ max_color_temp_kelvin: 6535,
82
+ max_mireds: 500,
83
+ min_color_temp_kelvin: 2000,
84
+ min_mireds: 153,
85
+ mode: "normal",
86
+ rgb_color: [255, 204, 163],
87
+ supported_color_modes: ["color_temp", "xy"],
88
+ supported_features: 40,
89
+ xy_color: [0.424, 0.366],
90
+ },
91
+ context: {
92
+ id: "01HK0TW9610XX5C5EZWE6ZEWJ0",
93
+ parent_id: null,
94
+ user_id: "72b5dc1d14484f9bb54df2de3ab95773",
95
+ },
96
+ entity_id: "light.womp",
97
+ last_changed: "2023-12-31T16:23:21.270862+00:00",
98
+ last_updated: "2023-12-31T21:01:05.179072+00:00",
99
+ state: "on",
100
+ },
101
+ },
102
+ scene: {
103
+ bedroom_auto: {
104
+ attributes: {
105
+ friendly_name: "Bedroom Auto",
106
+ },
107
+ context: {
108
+ id: "01HK02X46S76A2C7JJMENBHF55",
109
+ parent_id: null,
110
+ user_id: "72b5dc1d14484f9bb54df2de3ab95773",
111
+ },
112
+ entity_id: "scene.bedroom_auto",
113
+ last_changed: "2023-12-31T14:02:06.428935+00:00",
114
+ last_updated: "2023-12-31T14:02:06.428935+00:00",
115
+ state: "2023-12-31T14:02:06.428760+00:00",
116
+ },
117
+ },
118
+ sensor: {
119
+ loft_current_scene: {
120
+ attributes: {
121
+ friendly_name: "Loft current scene",
122
+ managed_by: "home-automation",
123
+ scene: "high",
124
+ },
125
+ context: {
126
+ id: "01HNZE7KCPMNXAK1N6G9MWC5M4",
127
+ parent_id: null,
128
+ user_id: null,
129
+ },
130
+ entity_id: "sensor.loft_current_scene",
131
+ last_changed: "2024-02-06T14:47:55.030369+00:00",
132
+ last_updated: "2024-02-06T14:47:55.030369+00:00",
133
+ state: "High",
134
+ },
135
+ },
136
+ switch: {
137
+ guest_mode: {
138
+ attributes: {
139
+ friendly_name: "Guest mode",
140
+ },
141
+ context: {
142
+ id: "01HK1AAJ4PW4SNPBFV35EDTJME",
143
+ parent_id: null,
144
+ user_id: "72b5dc1d14484f9bb54df2de3ab95773",
145
+ },
146
+ entity_id: "switch.guest_mode",
147
+ last_changed: "2024-01-01T01:25:47.375385+00:00",
148
+ last_updated: "2024-01-01T01:31:01.142980+00:00",
149
+ state: "off",
150
+ },
151
+ },
152
+ };
153
+ //# sourceMappingURL=dynamic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dynamic.js","sourceRoot":"","sources":["../src/dynamic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { TServiceParams } from "@digital-alchemy/core";
2
+ import { iCallService } from "..";
3
+ export declare function CallProxy({ logger, lifecycle, context, hass, config, }: TServiceParams): iCallService;
4
+ export default CallProxy;
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CallProxy = void 0;
4
+ const core_1 = require("@digital-alchemy/core");
5
+ const process_1 = require("process");
6
+ const __1 = require("..");
7
+ const FAILED_LOAD_DELAY = 5;
8
+ const MAX_ATTEMPTS = 50;
9
+ const FAILED = 1;
10
+ const NOT_A_DOMAIN = new Set(["then"]);
11
+ function CallProxy({ logger, lifecycle, context, hass, config, }) {
12
+ let domains;
13
+ let services;
14
+ /**
15
+ * Describe the current services, and build up a proxy api based on that.
16
+ *
17
+ * This API matches the api at the time the this function is run, which may be different from any generated typescript definitions from the past.
18
+ */
19
+ lifecycle.onBootstrap(async () => {
20
+ if (!config.hass.AUTO_SCAN_CALL_PROXY) {
21
+ logger.debug(`skip service populate`);
22
+ return;
23
+ }
24
+ logger.debug(`runtime populate service interfaces`);
25
+ await loadServiceList();
26
+ });
27
+ function getDomain(domain) {
28
+ if (!domains || !domains?.includes(domain)) {
29
+ if (!NOT_A_DOMAIN.has(domain)) {
30
+ logger.error({ domain }, `unknown domain`);
31
+ }
32
+ return undefined;
33
+ }
34
+ const domainItem = services.find(i => i.domain === domain);
35
+ if (!domainItem) {
36
+ throw new core_1.InternalError(context, "HALLUCINATED_DOMAIN", `Cannot access call_service#${domain}. Home Assistant doesn't list it as a real domain.`);
37
+ }
38
+ return Object.fromEntries(Object.entries(domainItem.services).map(([key]) => [
39
+ key,
40
+ async (parameters) => await sendMessage(`${domain}.${key}`, {
41
+ ...parameters,
42
+ }),
43
+ ]));
44
+ }
45
+ async function loadServiceList(recursion = core_1.START) {
46
+ logger.info(`fetching service list`);
47
+ services = await hass.fetch.listServices();
48
+ if (core_1.is.empty(services)) {
49
+ if (recursion > MAX_ATTEMPTS) {
50
+ logger.fatal(`Failed to load service list from Home Assistant. Validate configuration`);
51
+ (0, process_1.exit)(FAILED);
52
+ }
53
+ logger.warn("failed to retrieve {service} list. Retrying {%s}/[%s]", recursion, MAX_ATTEMPTS);
54
+ await (0, core_1.sleep)(FAILED_LOAD_DELAY * core_1.SECOND);
55
+ await loadServiceList(recursion + core_1.INCREMENT);
56
+ return;
57
+ }
58
+ domains = services.map(i => i.domain);
59
+ services.forEach(value => {
60
+ logger.trace({ services: Object.keys(value.services) }, `loaded domain [%s]`, value.domain);
61
+ });
62
+ }
63
+ /**
64
+ * Prefer sending via socket, if available.
65
+ */
66
+ async function sendMessage(serviceName, service_data) {
67
+ if (!hass.socket.getConnectionActive()) {
68
+ return await hass.fetch.callService(serviceName, service_data);
69
+ }
70
+ const [domain, service] = serviceName.split(".");
71
+ // User can just not await this call if they don't care about the "waitForChange"
72
+ return await hass.socket.sendMessage({
73
+ domain,
74
+ service,
75
+ service_data,
76
+ type: __1.HASSIO_WS_COMMAND.call_service,
77
+ }, true);
78
+ }
79
+ function buildCallProxy() {
80
+ return new Proxy({}, {
81
+ get: (_, domain) => getDomain(domain),
82
+ });
83
+ }
84
+ return buildCallProxy();
85
+ }
86
+ exports.CallProxy = CallProxy;
87
+ exports.default = CallProxy;
88
+ //# sourceMappingURL=call-proxy.extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call-proxy.extension.js","sourceRoot":"","sources":["../../src/extensions/call-proxy.extension.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { TServiceParams } from "@digital-alchemy/core";
2
+ export declare function Configure({ logger, lifecycle, hass, config, internal, }: TServiceParams): void;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Configure = void 0;
4
+ /* eslint-disable @typescript-eslint/no-magic-numbers */
5
+ const core_1 = require("@digital-alchemy/core");
6
+ const process_1 = require("process");
7
+ const __1 = require("..");
8
+ function Configure({ logger, lifecycle, hass, config, internal, }) {
9
+ /**
10
+ * Check for environment defined tokens provided by Home Assistant
11
+ *
12
+ * If available, override defaults to match
13
+ */
14
+ lifecycle.onPreInit(() => {
15
+ const token = process_1.env.HASSIO_TOKEN || process_1.env.SUPERVISOR_TOKEN;
16
+ if (core_1.is.empty(token)) {
17
+ return;
18
+ }
19
+ logger.debug(`auto configuring from addon environment`);
20
+ internal.config.set("hass", "BASE_URL", process_1.env.HASS_SERVER || "http://supervisor/core");
21
+ internal.config.set("hass", "TOKEN", token);
22
+ });
23
+ /**
24
+ * Request by someone to validate the provided credentials are valid
25
+ *
26
+ * Send a test request, and provide feedback on what happened
27
+ */
28
+ lifecycle.onPostConfig(async () => {
29
+ if (!config.hass.VALIDATE_CONFIGURATION) {
30
+ return;
31
+ }
32
+ core_1.ZCC.logger.setLogLevel("trace");
33
+ logger.info(`validating credentials`);
34
+ try {
35
+ const result = await hass.fetch.checkCredentials();
36
+ if (core_1.is.object(result)) {
37
+ // * all good
38
+ logger.info(result.message);
39
+ (0, process_1.exit)(1);
40
+ }
41
+ // * bad token
42
+ logger.error(String(result));
43
+ (0, process_1.exit)(0);
44
+ }
45
+ catch (error) {
46
+ // * bad BASE_URL
47
+ logger.error({ error }, "failed to send request");
48
+ (0, process_1.exit)(0);
49
+ }
50
+ }, __1.PostConfigPriorities.VALIDATE);
51
+ }
52
+ exports.Configure = Configure;
53
+ //# sourceMappingURL=config.extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.extension.js","sourceRoot":"","sources":["../../src/extensions/config.extension.ts"],"names":[],"mappings":";;;AAAA,wDAAwD;AACxD,gDAAgE;AAChE,qCAAoC;AAEpC,0BAA0C;AAC1C,SAAgB,SAAS,CAAC,EACxB,MAAM,EACN,SAAS,EACT,IAAI,EACJ,MAAM,EACN,QAAQ,GACO;IACf;;;;OAIG;IACH,SAAS,CAAC,SAAS,CAAC,GAAG,EAAE;QACvB,MAAM,KAAK,GAAG,aAAG,CAAC,YAAY,IAAI,aAAG,CAAC,gBAAgB,CAAC;QACvD,IAAI,SAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACpB,OAAO;QACT,CAAC;QACD,MAAM,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;QACxD,QAAQ,CAAC,MAAM,CAAC,GAAG,CACjB,MAAM,EACN,UAAU,EACV,aAAG,CAAC,WAAW,IAAI,wBAAwB,CAC5C,CAAC;QACF,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH;;;;OAIG;IACH,SAAS,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;QAChC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,sBAAsB,EAAE,CAAC;YACxC,OAAO;QACT,CAAC;QACD,UAAG,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAChC,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QACtC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC;YACnD,IAAI,SAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;gBACtB,aAAa;gBACb,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBAC5B,IAAA,cAAI,EAAC,CAAC,CAAC,CAAC;YACV,CAAC;YACD,cAAc;YACd,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;YAC7B,IAAA,cAAI,EAAC,CAAC,CAAC,CAAC;QACV,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,iBAAiB;YACjB,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,wBAAwB,CAAC,CAAC;YAClD,IAAA,cAAI,EAAC,CAAC,CAAC,CAAC;QACV,CAAC;IACH,CAAC,EAAE,wBAAoB,CAAC,QAAQ,CAAC,CAAC;AACpC,CAAC;AArDD,8BAqDC"}
@@ -0,0 +1,61 @@
1
+ import { TBlackHole, TServiceParams } from "@digital-alchemy/core";
2
+ import { ENTITY_STATE, EntityHistoryDTO, EntityHistoryResult, PICK_ENTITY } from "..";
3
+ export declare const ENTITY_UPDATE_RECEIVER: unique symbol;
4
+ export type ByIdProxy<ENTITY_ID extends PICK_ENTITY> = ENTITY_STATE<ENTITY_ID> & {
5
+ entity_id: ENTITY_ID;
6
+ /**
7
+ * Run callback
8
+ */
9
+ onUpdate: (callback: (state: NonNullable<ENTITY_STATE<ENTITY_ID>>) => TBlackHole) => void;
10
+ /**
11
+ * Run callback once, for next update
12
+ */
13
+ once: (callback: (state: NonNullable<ENTITY_STATE<ENTITY_ID>>) => TBlackHole) => void;
14
+ /**
15
+ * Will resolve with the next state of the next value. No time limit
16
+ */
17
+ nextState: () => Promise<ENTITY_STATE<ENTITY_ID>>;
18
+ };
19
+ export declare function EntityManager({ logger, hass, lifecycle }: TServiceParams): {
20
+ /**
21
+ * Internal library use only
22
+ */
23
+ [ENTITY_UPDATE_RECEIVER]: <ENTITY extends PICK_ENTITY = PICK_ENTITY>(entity_id: PICK_ENTITY, new_state: ENTITY_STATE<ENTITY>, old_state: ENTITY_STATE<ENTITY>) => void;
24
+ /**
25
+ * Retrieves a proxy object for a specified entity. This proxy object
26
+ * provides current values and event hooks for the entity.
27
+ */
28
+ byId: <ENTITY_ID extends PICK_ENTITY>(entity_id: ENTITY_ID) => ByIdProxy<ENTITY_ID>;
29
+ /**
30
+ * Lists all entities within a specified domain. This is useful for
31
+ * domain-specific operations or queries.
32
+ */
33
+ findByDomain: <DOMAIN extends "binary_sensor" | "button" | "calendar" | "light" | "scene" | "sensor" | "switch">(domain: DOMAIN) => ByIdProxy<PICK_ENTITY>[];
34
+ /**
35
+ * Retrieves the current state of a given entity. This method returns
36
+ * raw data, offering a direct view of the entity's state at a given moment.
37
+ */
38
+ getCurrentState: <ENTITY_ID_1 extends PICK_ENTITY>(entity_id: ENTITY_ID_1) => NonNullable<ENTITY_STATE<ENTITY_ID_1>>;
39
+ /**
40
+ * Retrieves the historical state data of entities over a specified time
41
+ * period. Useful for analysis or tracking changes over time.
42
+ */
43
+ history: <ENTITES extends PICK_ENTITY[]>(payload: Omit<EntityHistoryDTO<ENTITES>, "type">) => Promise<{
44
+ [k: string]: EntityHistoryResult[];
45
+ }>;
46
+ /**
47
+ * Provides a simple listing of all entity IDs. Useful for enumeration
48
+ * and quick reference to all available entities.
49
+ */
50
+ listEntities: () => PICK_ENTITY[];
51
+ /**
52
+ * Initiates a refresh of the current entity states. Useful for ensuring
53
+ * synchronization with the latest state data from Home Assistant.
54
+ */
55
+ refresh: (recursion?: number) => Promise<void>;
56
+ };
57
+ declare module "@digital-alchemy/core" {
58
+ interface IsIt {
59
+ entity(entity: PICK_ENTITY): entity is PICK_ENTITY;
60
+ }
61
+ }
@@ -0,0 +1,212 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EntityManager = exports.ENTITY_UPDATE_RECEIVER = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const core_1 = require("@digital-alchemy/core");
6
+ const dayjs_1 = tslib_1.__importDefault(require("dayjs"));
7
+ const events_1 = tslib_1.__importDefault(require("events"));
8
+ const process_1 = require("process");
9
+ const __1 = require("..");
10
+ exports.ENTITY_UPDATE_RECEIVER = Symbol.for("entityUpdateReceiver");
11
+ const MAX_ATTEMPTS = 50;
12
+ const FAILED_LOAD_DELAY = 5;
13
+ const UNLIMITED = 0;
14
+ const RECENT = 5;
15
+ function EntityManager({ logger, hass, lifecycle }) {
16
+ // # Local vars
17
+ /**
18
+ * MASTER_STATE.switch.desk_light = {entity_id,state,attributes,...}
19
+ */
20
+ let MASTER_STATE = {};
21
+ const ENTITY_PROXIES = new Map();
22
+ let lastRefresh;
23
+ // * Local event emitter for coordination of socket events
24
+ // Other libraries will internally take advantage of this eventemitter
25
+ const event = new events_1.default();
26
+ event.setMaxListeners(UNLIMITED);
27
+ let init = false;
28
+ // # Methods
29
+ // ## Retrieve raw state object for entity
30
+ function getCurrentState(entity_id) {
31
+ return core_1.ZCC.utils.object.get(MASTER_STATE, entity_id);
32
+ }
33
+ // ## Proxy version of the logic
34
+ function proxyGetLogic(entity, property) {
35
+ if (!init) {
36
+ return undefined;
37
+ }
38
+ const valid = ["state", "attributes", "last"].some(i => property.startsWith(i));
39
+ if (!valid) {
40
+ logger.error({ entity, property }, `invalid property lookup`);
41
+ return undefined;
42
+ }
43
+ const current = getCurrentState(entity);
44
+ const defaultValue = (property === "state" ? undefined : {});
45
+ if (!current) {
46
+ logger.error({ defaultValue, name: entity, property }, `proxyGetLogic cannot find entity`);
47
+ }
48
+ return core_1.ZCC.utils.object.get(current, property) || defaultValue;
49
+ }
50
+ // ## Retrieve a proxy by id
51
+ function byId(entity_id) {
52
+ if (!ENTITY_PROXIES.has(entity_id)) {
53
+ ENTITY_PROXIES.set(entity_id, new Proxy({ entity_id }, {
54
+ // things that shouldn't be needed: this extract
55
+ get: (_, property) => {
56
+ if (property === "onUpdate") {
57
+ return (callback) => event.on(entity_id, async (a, b) => callback(a, b));
58
+ }
59
+ if (property === "once") {
60
+ return (callback) => event.once(entity_id, async (a, b) => callback(a, b));
61
+ }
62
+ if (property === "entity_id") {
63
+ return entity_id;
64
+ }
65
+ if (property === "nextState") {
66
+ return new Promise(done => {
67
+ event.once(entity_id, (entity) => done(entity));
68
+ });
69
+ }
70
+ return proxyGetLogic(entity_id, property);
71
+ },
72
+ }));
73
+ }
74
+ return ENTITY_PROXIES.get(entity_id);
75
+ }
76
+ // ## Retrieve entity history (via socket)
77
+ async function history(payload) {
78
+ logger.trace({ payload }, `looking up entity history`);
79
+ const result = (await hass.socket.sendMessage({
80
+ ...payload,
81
+ end_time: (0, dayjs_1.default)(payload.end_time).toISOString(),
82
+ start_time: (0, dayjs_1.default)(payload.start_time).toISOString(),
83
+ type: __1.HASSIO_WS_COMMAND.history_during_period,
84
+ }));
85
+ const entities = Object.keys(result);
86
+ return Object.fromEntries(entities.map((entity_id) => {
87
+ const key = entity_id;
88
+ const states = result[entity_id];
89
+ const value = states.map(data => {
90
+ return {
91
+ attributes: data.a,
92
+ date: new Date(data.lu * core_1.SECOND),
93
+ state: data.s,
94
+ };
95
+ });
96
+ return [key, value];
97
+ }));
98
+ }
99
+ // ## Build a string array of all known entity ids
100
+ function listEntities() {
101
+ return Object.keys(MASTER_STATE).flatMap(domain => Object.keys(MASTER_STATE[domain]).map(id => `${domain}.${id}`));
102
+ }
103
+ // ## Gather all entity proxies for a domain
104
+ function findByDomain(domain) {
105
+ return Object.keys(MASTER_STATE[domain] ?? {}).map(i => byId(`${domain}.${i}`));
106
+ }
107
+ // ## Load all entity state information from hass
108
+ async function refresh(recursion = core_1.START) {
109
+ const now = (0, dayjs_1.default)();
110
+ if (lastRefresh) {
111
+ const diff = lastRefresh.diff(now, "ms");
112
+ if (diff >= RECENT * core_1.SECOND) {
113
+ logger.warn({ diff }, `multiple refreshes in close time`);
114
+ }
115
+ }
116
+ lastRefresh = now;
117
+ // - Fetch list of entities
118
+ const states = await hass.fetch.getAllEntities();
119
+ // - Keep retrying until max failures reached
120
+ if (core_1.is.empty(states)) {
121
+ if (recursion > MAX_ATTEMPTS) {
122
+ logger.fatal(`failed to load service list from Home Assistant. Validate configuration`);
123
+ (0, process_1.exit)();
124
+ }
125
+ logger.warn("failed to retrieve entity list. Retrying {%s}/[%s]", recursion, MAX_ATTEMPTS);
126
+ await (0, core_1.sleep)(FAILED_LOAD_DELAY * core_1.SECOND);
127
+ await refresh(recursion + core_1.INCREMENT);
128
+ return;
129
+ }
130
+ // - Preserve old state for comparison
131
+ const oldState = MASTER_STATE;
132
+ MASTER_STATE = {};
133
+ const emitUpdates = [];
134
+ // - Go through all entities, setting the state
135
+ // ~ If this is a refresh (not an initial boot), track what changed so events can be emitted
136
+ states.forEach(entity => {
137
+ // ? Set first, ensure data is populated
138
+ // `nextTick` will fire AFTER loop finishes
139
+ core_1.ZCC.utils.object.set(MASTER_STATE, entity.entity_id, entity, core_1.is.undefined(core_1.ZCC.utils.object.get(oldState, entity.entity_id)));
140
+ if (!init) {
141
+ return;
142
+ }
143
+ const old = core_1.ZCC.utils.object.get(oldState, entity.entity_id);
144
+ if (core_1.is.equal(old, entity)) {
145
+ logger.trace({ name: entity.entity_id }, `no change on refresh`);
146
+ return;
147
+ }
148
+ emitUpdates.push(entity);
149
+ });
150
+ // Attempt to not blow up the system?
151
+ // TODO: does this gain anything? is a debounce needed somewhere else instead?
152
+ setImmediate(async () => {
153
+ await (0, core_1.each)(emitUpdates, async (entity) => await EntityUpdateReceiver(entity.entity_id, entity, core_1.ZCC.utils.object.get(oldState, entity.entity_id)));
154
+ });
155
+ init = true;
156
+ }
157
+ // ## is.entity definition
158
+ // Actually tie the type casting to real state
159
+ core_1.is.entity = (entityId) => core_1.is.undefined(core_1.ZCC.utils.object.get(MASTER_STATE, entityId));
160
+ // ## Receiver function for incoming entity updates
161
+ function EntityUpdateReceiver(entity_id, new_state, old_state) {
162
+ if (new_state === null) {
163
+ logger.warn({ name: entity_id }, `removing deleted entity from {MASTER_STATE}`);
164
+ core_1.ZCC.utils.object.del(MASTER_STATE, entity_id);
165
+ return;
166
+ }
167
+ core_1.ZCC.utils.object.set(MASTER_STATE, entity_id, new_state);
168
+ event.emit(entity_id, new_state, old_state);
169
+ }
170
+ lifecycle.onPostConfig(async () => {
171
+ logger.debug(`pre populate {MASTER_STATE}`);
172
+ await refresh();
173
+ });
174
+ return {
175
+ /**
176
+ * Internal library use only
177
+ */
178
+ [exports.ENTITY_UPDATE_RECEIVER]: EntityUpdateReceiver,
179
+ /**
180
+ * Retrieves a proxy object for a specified entity. This proxy object
181
+ * provides current values and event hooks for the entity.
182
+ */
183
+ byId,
184
+ /**
185
+ * Lists all entities within a specified domain. This is useful for
186
+ * domain-specific operations or queries.
187
+ */
188
+ findByDomain,
189
+ /**
190
+ * Retrieves the current state of a given entity. This method returns
191
+ * raw data, offering a direct view of the entity's state at a given moment.
192
+ */
193
+ getCurrentState,
194
+ /**
195
+ * Retrieves the historical state data of entities over a specified time
196
+ * period. Useful for analysis or tracking changes over time.
197
+ */
198
+ history,
199
+ /**
200
+ * Provides a simple listing of all entity IDs. Useful for enumeration
201
+ * and quick reference to all available entities.
202
+ */
203
+ listEntities,
204
+ /**
205
+ * Initiates a refresh of the current entity states. Useful for ensuring
206
+ * synchronization with the latest state data from Home Assistant.
207
+ */
208
+ refresh,
209
+ };
210
+ }
211
+ exports.EntityManager = EntityManager;
212
+ //# sourceMappingURL=entity-manager.extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-manager.extension.js","sourceRoot":"","sources":["../../src/extensions/entity-manager.extension.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { FilteredFetchArguments, TFetch, TServiceParams } from "@digital-alchemy/core";
2
+ import { CalendarEvent, CalendarFetchOptions, CheckConfigResult, ENTITY_STATE, HassConfig, HassServiceDTO, HomeAssistantServerLogItem, PICK_ENTITY, PICK_SERVICE, PICK_SERVICE_PARAMETERS } from "..";
3
+ type SendBody<STATE extends string | number = string, ATTRIBUTES extends object = object> = {
4
+ attributes?: ATTRIBUTES;
5
+ state?: STATE;
6
+ };
7
+ export declare function FetchAPI({ logger, lifecycle, context, config, }: TServiceParams): {
8
+ calendarSearch: ({ calendar, start, end, }: CalendarFetchOptions) => Promise<CalendarEvent[]>;
9
+ callService: <SERVICE extends PICK_SERVICE>(serviceName: SERVICE, data: PICK_SERVICE_PARAMETERS<SERVICE>) => Promise<ENTITY_STATE<PICK_ENTITY>[]>;
10
+ checkConfig: () => Promise<CheckConfigResult>;
11
+ checkCredentials: () => Promise<{
12
+ message: string;
13
+ } | string>;
14
+ download: (destination: string, fetchWith: FilteredFetchArguments) => Promise<void>;
15
+ fetch: TFetch;
16
+ fetchEntityCustomizations: <T extends Record<never, unknown> = Record<"local" | "global", Record<string, string>>>(entityId: string | string[]) => Promise<T>;
17
+ fetchEntityHistory: <ENTITY extends PICK_ENTITY = PICK_ENTITY, T_1 extends ENTITY_STATE<ENTITY> = ENTITY_STATE<ENTITY>>(entity_id: ENTITY, from: Date, to: Date, extra?: {
18
+ minimal_response?: "";
19
+ }) => Promise<T_1[]>;
20
+ fireEvent: <DATA extends object = object>(event: string, data?: DATA) => Promise<void>;
21
+ getAllEntities: () => Promise<ENTITY_STATE<PICK_ENTITY>[]>;
22
+ getConfig: () => Promise<HassConfig>;
23
+ getLogs: () => Promise<HomeAssistantServerLogItem[]>;
24
+ getRawLogs: () => Promise<string>;
25
+ listServices: () => Promise<HassServiceDTO[]>;
26
+ updateEntity: <STATE extends string | number = string, ATTRIBUTES extends object = object>(entity_id: PICK_ENTITY, { attributes, state }: SendBody<STATE, ATTRIBUTES>) => Promise<void>;
27
+ webhook: (name: string, data?: object) => Promise<void>;
28
+ };
29
+ export {};