@smarthome.exchange/integrations 3.0.0 → 4.0.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.
- package/changelog.md +11 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/integrations/hue/hue.classes.client.d.ts +26 -3
- package/dist_ts/integrations/hue/hue.classes.client.js +254 -55
- package/dist_ts/integrations/hue/hue.classes.configflow.d.ts +6 -1
- package/dist_ts/integrations/hue/hue.classes.configflow.js +73 -30
- package/dist_ts/integrations/hue/hue.classes.integration.d.ts +2 -2
- package/dist_ts/integrations/hue/hue.classes.integration.js +58 -110
- package/dist_ts/integrations/hue/hue.mapper.d.ts +2 -0
- package/dist_ts/integrations/hue/hue.mapper.js +8 -6
- package/dist_ts/integrations/hue/hue.types.d.ts +32 -1
- package/dist_ts/integrations/hue/hue.validation.d.ts +8 -3
- package/dist_ts/integrations/hue/hue.validation.js +100 -9
- package/package.json +3 -3
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/integrations/hue/hue.classes.client.ts +213 -49
- package/ts/integrations/hue/hue.classes.configflow.ts +64 -27
- package/ts/integrations/hue/hue.classes.integration.ts +52 -97
- package/ts/integrations/hue/hue.mapper.ts +8 -5
- package/ts/integrations/hue/hue.types.ts +37 -1
- package/ts/integrations/hue/hue.validation.ts +89 -10
- package/ts/integrations/hue/readme.md +48 -11
|
@@ -1,14 +1,29 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { NativeIntegrationOwner } from '../../core/classes.nativeintegrationowner.js';
|
|
2
|
+
import { HueClient, HuePairingError } from './hue.classes.client.js';
|
|
3
|
+
import { captureHueOptions, hueBridgeId, hueData, hueKey, normalizeHueConfig, normalizeHueHost } from './hue.validation.js';
|
|
3
4
|
export class HueConfigFlow {
|
|
5
|
+
#options;
|
|
6
|
+
#owner;
|
|
7
|
+
#scope;
|
|
8
|
+
#ownsOwner;
|
|
9
|
+
#terminal = false;
|
|
10
|
+
#submitted = false;
|
|
11
|
+
constructor(optionsArg = {}, ownerArg) {
|
|
12
|
+
this.#options = captureHueOptions(optionsArg);
|
|
13
|
+
this.#ownsOwner = !ownerArg;
|
|
14
|
+
this.#owner = ownerArg ?? new NativeIntegrationOwner('hue', { homeId: this.#options.homeId, capacity: this.#options.capacity });
|
|
15
|
+
this.#scope = this.#owner.createFlowScope();
|
|
16
|
+
}
|
|
4
17
|
async start(candidateArg, contextArg) {
|
|
5
|
-
|
|
6
|
-
|
|
18
|
+
const context = this.#scope.admit(contextArg);
|
|
19
|
+
if (this.#terminal)
|
|
20
|
+
throw new Error('Hue config flow is closed.');
|
|
21
|
+
const candidate = hueData(candidateArg, ['id', 'source', 'host', 'port', 'name', 'integrationDomain', 'manufacturer', 'model', 'serialNumber', 'macAddress', 'metadata']);
|
|
7
22
|
if (candidate.integrationDomain !== 'hue')
|
|
8
23
|
throw new Error('Hue flow requires a Hue candidate.');
|
|
9
24
|
const bridgeId = hueBridgeId(candidate.id) ? candidate.id : undefined;
|
|
10
25
|
const port = candidate.port;
|
|
11
|
-
if (port !== undefined && typeof port !== 'number')
|
|
26
|
+
if (port !== undefined && (typeof port !== 'number' || !Number.isInteger(port) || port < 1 || port > 65535))
|
|
12
27
|
throw new Error('Hue discovered port is invalid.');
|
|
13
28
|
let host;
|
|
14
29
|
try {
|
|
@@ -17,37 +32,65 @@ export class HueConfigFlow {
|
|
|
17
32
|
catch {
|
|
18
33
|
host = undefined;
|
|
19
34
|
}
|
|
35
|
+
const submit = async (valuesArg) => {
|
|
36
|
+
if (this.#terminal || this.#submitted)
|
|
37
|
+
return { kind: 'error', title: 'Hue flow closed', error: 'Hue config flow is closed or already submitting.' };
|
|
38
|
+
this.#submitted = true;
|
|
39
|
+
let paired = false;
|
|
40
|
+
let capturedValues;
|
|
41
|
+
try {
|
|
42
|
+
const values = hueData(valuesArg, ['homeId', 'bridgeId', 'host', 'credentialReference', 'appKey', 'trustedCa']);
|
|
43
|
+
if (values.homeId !== undefined && values.homeId !== context.homeId)
|
|
44
|
+
throw new Error('Hue form home does not match the host home.');
|
|
45
|
+
capturedValues = Object.freeze(values);
|
|
46
|
+
const config = normalizeHueConfig({ homeId: context.homeId, bridgeId: bridgeId ?? values.bridgeId,
|
|
47
|
+
host: host ?? values.host, port: port,
|
|
48
|
+
credentialReference: values.credentialReference, trustedCa: values.trustedCa === '' ? undefined : values.trustedCa });
|
|
49
|
+
const suppliedKey = values.appKey === undefined || values.appKey === '' ? undefined : hueKey(values.appKey);
|
|
50
|
+
const result = await this.#scope.run(context, config.homeId, async (lease) => {
|
|
51
|
+
const client = new HueClient(config, { ...lease.context, abortSignal: lease.signal }, this.#options, this.#owner);
|
|
52
|
+
let cleanupStarted = false;
|
|
53
|
+
lease.own(() => { if (cleanupStarted)
|
|
54
|
+
return client.retryCleanup(); cleanupStarted = true; return client.destroy(); });
|
|
55
|
+
if (!client.canCreateCredential)
|
|
56
|
+
throw new Error('Hue flow requires credential creation by the selected provider or encrypted store.');
|
|
57
|
+
const key = suppliedKey ?? await client.acquireAppKey(undefined, lease.signal);
|
|
58
|
+
paired = !suppliedKey;
|
|
59
|
+
await client.createCredential(key, lease.signal);
|
|
60
|
+
lease.assertOpen();
|
|
61
|
+
return { kind: 'done', title: 'Hue bridge verified', config };
|
|
62
|
+
});
|
|
63
|
+
this.#terminal = true;
|
|
64
|
+
await this.#scope.close();
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
if (error instanceof HuePairingError && error.linkButtonRequired && !paired) {
|
|
69
|
+
return { kind: 'wait', title: 'Press the Hue link button', description: 'Press the physical link button on the selected bridge, then retry.', submit: () => submit(capturedValues) };
|
|
70
|
+
}
|
|
71
|
+
if (paired || error instanceof HuePairingError) {
|
|
72
|
+
this.#terminal = true;
|
|
73
|
+
await this.#scope.close();
|
|
74
|
+
}
|
|
75
|
+
return { kind: 'error', title: 'Hue bridge could not be verified', error: paired || error instanceof HuePairingError ? 'Hue pairing or credential creation was dispatched; do not replay it.' : 'Check the host home, bridge ID, HTTPS endpoint, trusted CA, credential reference and permissions. The bridge must support Hue API v2.' };
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
this.#submitted = false;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
20
81
|
return {
|
|
21
82
|
kind: 'form', title: 'Connect Philips Hue Bridge',
|
|
22
|
-
description: '
|
|
83
|
+
description: 'Select a credential reference. Press the physical link button to pair, or supply an existing application key for one-time insertion into the host credential store. Setup verifies TLS identity and live resources.',
|
|
23
84
|
fields: [
|
|
24
85
|
...(!bridgeId ? [{ name: 'bridgeId', label: 'Hue bridge ID', type: 'text', required: true }] : []),
|
|
25
86
|
...(!host ? [{ name: 'host', label: 'Bridge hostname or IP address', type: 'text', required: true }] : []),
|
|
26
|
-
{ name: '
|
|
87
|
+
{ name: 'credentialReference', label: 'Credential reference', type: 'text', required: true },
|
|
88
|
+
{ name: 'appKey', label: 'Existing Hue app key (optional)', type: 'password' },
|
|
27
89
|
{ name: 'trustedCa', label: 'Trusted Hue CA certificate (PEM)', type: 'text' },
|
|
28
|
-
],
|
|
29
|
-
submit: async (valuesArg) => {
|
|
30
|
-
let client;
|
|
31
|
-
try {
|
|
32
|
-
const values = hueRecord(valuesArg);
|
|
33
|
-
if (Reflect.ownKeys(values).some((keyArg) => !['bridgeId', 'host', 'appKey', 'trustedCa'].includes(String(keyArg))))
|
|
34
|
-
throw new Error('Hue flow values contain unsupported fields.');
|
|
35
|
-
const config = normalizeHueConfig({ bridgeId: bridgeId ?? values.bridgeId,
|
|
36
|
-
host: host ?? values.host, port: port ?? 443,
|
|
37
|
-
appKey: values.appKey, trustedCa: values.trustedCa === '' ? undefined : values.trustedCa });
|
|
38
|
-
client = new HueClient(config);
|
|
39
|
-
await client.getResources();
|
|
40
|
-
return { kind: 'done', title: 'Hue bridge verified', config };
|
|
41
|
-
}
|
|
42
|
-
catch {
|
|
43
|
-
return { kind: 'error', title: 'Hue bridge could not be verified',
|
|
44
|
-
error: 'Check the bridge ID, HTTPS endpoint, trusted CA and application key. The bridge must support Hue API v2.' };
|
|
45
|
-
}
|
|
46
|
-
finally {
|
|
47
|
-
await client?.destroy();
|
|
48
|
-
}
|
|
49
|
-
},
|
|
90
|
+
], submit,
|
|
50
91
|
};
|
|
51
92
|
}
|
|
93
|
+
destroy() { this.#terminal = true; return this.#ownsOwner ? this.#owner.close() : this.#scope.close(); }
|
|
94
|
+
retryCleanup() { return this.#ownsOwner ? this.#owner.retryCleanup() : this.#scope.retryCleanup(); }
|
|
52
95
|
}
|
|
53
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
96
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHVlLmNsYXNzZXMuY29uZmlnZmxvdy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL2ludGVncmF0aW9ucy9odWUvaHVlLmNsYXNzZXMuY29uZmlnZmxvdy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsc0JBQXNCLEVBQStCLE1BQU0sOENBQThDLENBQUM7QUFFbkgsT0FBTyxFQUFFLFNBQVMsRUFBRSxlQUFlLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNyRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsa0JBQWtCLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUc1SCxNQUFNLE9BQU8sYUFBYTtJQUNmLFFBQVEsQ0FBbUM7SUFDM0MsTUFBTSxDQUF5QjtJQUMvQixNQUFNLENBQXlCO0lBQy9CLFVBQVUsQ0FBVTtJQUM3QixTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ2xCLFVBQVUsR0FBRyxLQUFLLENBQUM7SUFFbkIsWUFBWSxVQUFVLEdBQTJCLEVBQUUsRUFBRSxRQUFpQztRQUNwRixJQUFJLENBQUMsUUFBUSxHQUFHLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQzlDLElBQUksQ0FBQyxVQUFVLEdBQUcsQ0FBQyxRQUFRLENBQUM7UUFDNUIsSUFBSSxDQUFDLE1BQU0sR0FBRyxRQUFRLElBQUksSUFBSSxzQkFBc0IsQ0FBQyxLQUFLLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUNoSSxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxFQUFFLENBQUM7SUFDOUMsQ0FBQztJQUVNLEtBQUssQ0FBQyxLQUFLLENBQUMsWUFBaUMsRUFBRSxVQUE4QjtRQUNs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
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BaseIntegration } from '../../core/classes.baseintegration.js';
|
|
2
2
|
import type { IIntegrationRuntime, IIntegrationSetupContext } from '../../core/types.js';
|
|
3
3
|
import { HueConfigFlow } from './hue.classes.configflow.js';
|
|
4
|
-
import type { IHueConfig } from './hue.types.js';
|
|
4
|
+
import type { IHueConfig, IHueIntegrationOptions } from './hue.types.js';
|
|
5
5
|
export declare class HueIntegration extends BaseIntegration<IHueConfig> {
|
|
6
6
|
#private;
|
|
7
7
|
readonly domain = "hue";
|
|
@@ -9,8 +9,8 @@ export declare class HueIntegration extends BaseIntegration<IHueConfig> {
|
|
|
9
9
|
readonly status: 'control-runtime';
|
|
10
10
|
readonly discoveryDescriptor: import("../../index.js").DiscoveryDescriptor;
|
|
11
11
|
readonly configFlow: HueConfigFlow;
|
|
12
|
+
constructor(optionsArg?: IHueIntegrationOptions);
|
|
12
13
|
setup(configArg: IHueConfig, contextArg: IIntegrationSetupContext): Promise<IIntegrationRuntime>;
|
|
13
14
|
destroy(): Promise<void>;
|
|
14
15
|
retryCleanup(): Promise<void>;
|
|
15
|
-
private drain;
|
|
16
16
|
}
|
|
@@ -1,88 +1,49 @@
|
|
|
1
|
+
import { NativeIntegrationOwner } from '../../core/classes.nativeintegrationowner.js';
|
|
1
2
|
import { BaseIntegration } from '../../core/classes.baseintegration.js';
|
|
2
3
|
import { HueClient } from './hue.classes.client.js';
|
|
3
4
|
import { HueConfigFlow } from './hue.classes.configflow.js';
|
|
4
5
|
import { createHueDiscoveryDescriptor } from './hue.discovery.js';
|
|
5
6
|
import { HueMapper } from './hue.mapper.js';
|
|
6
|
-
import { hueRecord } from './hue.validation.js';
|
|
7
|
+
import { captureHueOptions, hueRecord, normalizeHueConfig } from './hue.validation.js';
|
|
7
8
|
export class HueIntegration extends BaseIntegration {
|
|
8
9
|
domain = 'hue';
|
|
9
10
|
displayName = 'Philips Hue';
|
|
10
11
|
status = 'control-runtime';
|
|
11
12
|
discoveryDescriptor = createHueDiscoveryDescriptor();
|
|
12
|
-
configFlow
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
configFlow;
|
|
14
|
+
#owner;
|
|
15
|
+
#options;
|
|
16
|
+
constructor(optionsArg = {}) {
|
|
17
|
+
super();
|
|
18
|
+
this.#options = captureHueOptions(optionsArg);
|
|
19
|
+
this.#owner = new NativeIntegrationOwner('hue', { homeId: this.#options.homeId, capacity: this.#options.capacity });
|
|
20
|
+
this.configFlow = new HueConfigFlow(this.#options, this.#owner);
|
|
21
|
+
}
|
|
18
22
|
async setup(configArg, contextArg) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (this.#closed || signal?.aborted)
|
|
32
|
-
throw new Error('Hue setup was cancelled.');
|
|
33
|
-
return runtime;
|
|
34
|
-
}
|
|
35
|
-
catch (error) {
|
|
36
|
-
try {
|
|
37
|
-
await runtime.destroy();
|
|
38
|
-
}
|
|
39
|
-
catch (cleanupError) {
|
|
40
|
-
throw new AggregateError([error, cleanupError], 'Hue setup and cleanup failed.');
|
|
41
|
-
}
|
|
42
|
-
throw error;
|
|
43
|
-
}
|
|
23
|
+
const config = normalizeHueConfig(configArg);
|
|
24
|
+
return this.#owner.runSetup(contextArg, config.homeId, async (lease) => {
|
|
25
|
+
const client = new HueClient(config, { ...lease.context, abortSignal: lease.signal }, this.#options, this.#owner);
|
|
26
|
+
let cleanupStarted = false;
|
|
27
|
+
lease.own(() => { if (cleanupStarted)
|
|
28
|
+
return client.retryCleanup(); cleanupStarted = true; return client.destroy(); });
|
|
29
|
+
await client.getResources();
|
|
30
|
+
lease.assertOpen();
|
|
31
|
+
if (!client.isHealthy())
|
|
32
|
+
throw new Error('Hue setup cancelled.');
|
|
33
|
+
lease.promoteToRuntime();
|
|
34
|
+
return new HueIntegrationRuntime(client, lease);
|
|
44
35
|
});
|
|
45
|
-
this.#setups.add(setup);
|
|
46
|
-
void setup.then(() => this.#setups.delete(setup), () => this.#setups.delete(setup));
|
|
47
|
-
return setup;
|
|
48
|
-
}
|
|
49
|
-
destroy() {
|
|
50
|
-
if (!this.#destroyPromise) {
|
|
51
|
-
this.#closed = true;
|
|
52
|
-
this.#destroyPromise = Promise.resolve().then(() => this.drain(false));
|
|
53
|
-
}
|
|
54
|
-
return this.#destroyPromise;
|
|
55
|
-
}
|
|
56
|
-
retryCleanup() {
|
|
57
|
-
if (!this.#destroyPromise)
|
|
58
|
-
throw new Error('Hue cleanup retry requires a terminal integration.');
|
|
59
|
-
if (!this.#retryPromise) {
|
|
60
|
-
this.#retryPromise = Promise.resolve().then(async () => {
|
|
61
|
-
await this.#destroyPromise.catch(() => undefined);
|
|
62
|
-
await this.drain(true);
|
|
63
|
-
});
|
|
64
|
-
const settled = () => { this.#retryPromise = undefined; };
|
|
65
|
-
void this.#retryPromise.then(settled, settled);
|
|
66
|
-
}
|
|
67
|
-
return this.#retryPromise;
|
|
68
|
-
}
|
|
69
|
-
async drain(retryArg) {
|
|
70
|
-
const cleanup = Promise.allSettled([...this.#runtimes].map((runtimeArg) => retryArg ? runtimeArg.retryCleanup() : runtimeArg.destroy()));
|
|
71
|
-
const [results] = await Promise.all([cleanup, Promise.allSettled([...this.#setups])]);
|
|
72
|
-
const errors = results.filter((resultArg) => resultArg.status === 'rejected').map((resultArg) => resultArg.reason);
|
|
73
|
-
if (errors.length)
|
|
74
|
-
throw new AggregateError(errors, 'Hue integration cleanup failed; resources remain retained for explicit retry.');
|
|
75
36
|
}
|
|
37
|
+
destroy() { return this.#owner.close(); }
|
|
38
|
+
retryCleanup() { return this.#owner.retryCleanup(); }
|
|
76
39
|
}
|
|
77
40
|
class HueIntegrationRuntime {
|
|
78
41
|
client;
|
|
79
|
-
|
|
42
|
+
lease;
|
|
80
43
|
domain = 'hue';
|
|
81
|
-
|
|
82
|
-
#retryPromise;
|
|
83
|
-
constructor(client, released) {
|
|
44
|
+
constructor(client, lease) {
|
|
84
45
|
this.client = client;
|
|
85
|
-
this.
|
|
46
|
+
this.lease = lease;
|
|
86
47
|
}
|
|
87
48
|
isHealthy() { return this.client.isHealthy(); }
|
|
88
49
|
async devices(abortSignalArg) {
|
|
@@ -121,12 +82,14 @@ class HueIntegrationRuntime {
|
|
|
121
82
|
if (request.service === 'set_percentage')
|
|
122
83
|
state.on = brightness > 0;
|
|
123
84
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
85
|
+
return this.client.execute(async (session) => {
|
|
86
|
+
const snapshot = await session.getResources();
|
|
87
|
+
const lightId = this.resolveLight(snapshot, target.entityId, target.deviceId);
|
|
88
|
+
if (!lightId)
|
|
89
|
+
return { success: false, error: 'Hue service requires one known, unambiguous light target.' };
|
|
90
|
+
await session.setLightState(lightId, state);
|
|
91
|
+
return { success: true };
|
|
92
|
+
});
|
|
130
93
|
}
|
|
131
94
|
async writeFeature(requestArg, abortSignalArg) {
|
|
132
95
|
const request = hueRecord(requestArg);
|
|
@@ -141,50 +104,35 @@ class HueIntegrationRuntime {
|
|
|
141
104
|
if (selectedDevice.integrationDomain !== this.domain || typeof deviceId !== 'string' || typeof featureId !== 'string') {
|
|
142
105
|
return { success: false, error: 'Hue feature requires one exact Hue device and feature.' };
|
|
143
106
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
this.#destroyPromise ??= Promise.resolve().then(async () => { await this.client.destroy(); this.released(); });
|
|
162
|
-
return this.#destroyPromise;
|
|
163
|
-
}
|
|
164
|
-
retryCleanup() {
|
|
165
|
-
if (!this.#destroyPromise)
|
|
166
|
-
throw new Error('Hue cleanup retry requires a terminal runtime.');
|
|
167
|
-
if (!this.#retryPromise) {
|
|
168
|
-
this.#retryPromise = Promise.resolve().then(async () => {
|
|
169
|
-
await this.#destroyPromise.catch(() => undefined);
|
|
170
|
-
await this.client.retryCleanup();
|
|
171
|
-
this.released();
|
|
172
|
-
});
|
|
173
|
-
const settled = () => { this.#retryPromise = undefined; };
|
|
174
|
-
void this.#retryPromise.then(settled, settled);
|
|
175
|
-
}
|
|
176
|
-
return this.#retryPromise;
|
|
107
|
+
return this.client.execute(async (session) => {
|
|
108
|
+
const snapshot = await session.getResources(abortSignalArg);
|
|
109
|
+
const device = HueMapper.toDevices(snapshot).find((deviceArg) => deviceArg.id === deviceId);
|
|
110
|
+
const feature = device?.features.find((featureArg) => featureArg.id === featureId && featureArg.capability === capability && featureArg.writable);
|
|
111
|
+
const lightId = this.resolveLight(snapshot, undefined, device?.id);
|
|
112
|
+
if (!device || !device.online || !feature || !lightId)
|
|
113
|
+
return { success: false, error: 'Hue feature target is unknown, unavailable or not writable.' };
|
|
114
|
+
let state;
|
|
115
|
+
if (feature.id === 'on' && typeof value === 'boolean')
|
|
116
|
+
state = { on: value };
|
|
117
|
+
else if (feature.id === 'brightness' && typeof value === 'number')
|
|
118
|
+
state = { brightness: value };
|
|
119
|
+
else
|
|
120
|
+
return { success: false, error: 'Hue feature value has an invalid type.' };
|
|
121
|
+
await session.setLightState(lightId, state, abortSignalArg);
|
|
122
|
+
return { success: true };
|
|
123
|
+
}, abortSignalArg);
|
|
177
124
|
}
|
|
125
|
+
destroy() { return this.lease.close(); }
|
|
178
126
|
resolveLight(snapshotArg, entityIdArg, deviceIdArg) {
|
|
179
127
|
if (entityIdArg === undefined && deviceIdArg === undefined)
|
|
180
128
|
return undefined;
|
|
181
129
|
const entity = entityIdArg === undefined ? undefined : HueMapper.toEntities(snapshotArg).find((entityArg) => entityArg.id === entityIdArg);
|
|
182
|
-
const device = deviceIdArg === undefined ? undefined : snapshotArg.lights.find((lightArg) =>
|
|
130
|
+
const device = deviceIdArg === undefined ? undefined : snapshotArg.lights.find((lightArg) => HueMapper.lightDeviceId(snapshotArg.homeId, lightArg.id) === deviceIdArg);
|
|
183
131
|
if (entityIdArg !== undefined && !entity || deviceIdArg !== undefined && !device)
|
|
184
132
|
return undefined;
|
|
185
|
-
if (entity && device && entity.deviceId !==
|
|
133
|
+
if (entity && device && entity.deviceId !== HueMapper.lightDeviceId(snapshotArg.homeId, device.id))
|
|
186
134
|
return undefined;
|
|
187
|
-
return device?.id || (entity ? snapshotArg.lights.find((lightArg) => entity.deviceId ===
|
|
135
|
+
return device?.id || (entity ? snapshotArg.lights.find((lightArg) => entity.deviceId === HueMapper.lightDeviceId(snapshotArg.homeId, lightArg.id))?.id : undefined);
|
|
188
136
|
}
|
|
189
137
|
}
|
|
190
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHVlLmNsYXNzZXMuaW50ZWdyYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9pbnRlZ3JhdGlvbnMvaHVlL2h1ZS5jbGFzc2VzLmludGVncmF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUV4RSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDcEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzVELE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM1QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFHaEQsTUFBTSxPQUFPLGNBQWUsU0FBUSxlQUEyQjtJQUM3QyxNQUFNLEdBQUcsS0FBSyxDQUFDO0lBQ2YsV0FBVyxHQUFHLGFBQWEsQ0FBQztJQUM1QixNQUFNLEdBQUcsaUJBQTBCLENBQUM7SUFDcEMsbUJBQW1CLEdBQUcsNEJBQTRCLEVBQUUsQ0FBQztJQUNyRCxVQUFVLEdBQUcsSUFBSSxhQUFhLEVBQUUsQ0FBQztJQUN4QyxTQUFTLEdBQUcsSUFBSSxHQUFHLEVBQXlCLENBQUM7SUFDN0MsT0FBTyxHQUFHLElBQUksR0FBRyxFQUFnQyxDQUFDO0lBQzNELE9BQU8sR0FBRyxLQUFLLENBQUM7SUFDaEIsZUFBZSxDQUFpQjtJQUNoQyxhQUFhLENBQWlCO0lBRXZCLEtBQUssQ0FBQyxLQUFLLENBQUMsU0FBcUIsRUFBRSxVQUFvQztRQUM1RSxJQUFJLElBQUksQ0FBQyxPQUFPO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO1FBQ2hFLE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUN0QyxNQUFN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
|
|
138
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHVlLmNsYXNzZXMuaW50ZWdyYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9pbnRlZ3JhdGlvbnMvaHVlL2h1ZS5jbGFzc2VzLmludGVncmF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxzQkFBc0IsRUFBMEIsTUFBTSw4Q0FBOEMsQ0FBQztBQUM5RyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFFeEUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3BELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNsRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDNUMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLFNBQVMsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBR3ZGLE1BQU0sT0FBTyxjQUFlLFNBQVEsZUFBMkI7SUFDN0MsTUFBTSxHQUFHLEtBQUssQ0FBQztJQUNmLFdBQVcsR0FBRyxhQUFhLENBQUM7SUFDNUIsTUFBTSxHQUFHLGlCQUEwQixDQUFDO0lBQ3BDLG1CQUFtQixHQUFHLDRCQUE0QixFQUFFLENBQUM7SUFDckQsVUFBVSxDQUFnQjtJQUNqQyxNQUFNLENBQXlCO0lBQy9CLFFBQVEsQ0FBbUM7SUFFcEQsWUFBWSxVQUFVLEdBQTJCLEVBQUU7UUFDakQsS0FBSyxFQUFFLENBQUM7UUFDUixJQUFJLENBQUMsUUFBUSxHQUFHLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQzlDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxzQkFBc0IsQ0FBQyxLQUFLLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FB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LElBQUksV0FBVyxLQUFLLFNBQVM7WUFBRSxPQUFPLFNBQVMsQ0FBQztRQUM3RSxNQUFNLE1BQU0sR0FBRyxXQUFXLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxTQUFTLENBQUMsRUFBRSxLQUFLLFdBQVcsQ0FBQyxDQUFDO1FBQzNJLE1BQU0sTUFBTSxHQUFHLFdBQVcsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsRUFBRSxDQUFDLEtBQUssV0FBVyxDQUFDLENBQUM7UUFDdkssSUFBSSxXQUFXLEtBQUssU0FBUyxJQUFJLENBQUMsTUFBTSxJQUFJLFdBQVcsS0FBSyxTQUFTLElBQUksQ0FBQyxNQUFNO1lBQUUsT0FBTyxTQUFTLENBQUM7UUFDbkcsSUFBSSxNQUFNLElBQUksTUFBTSxJQUFJLE1BQU0sQ0FBQyxRQUFRLEtBQUssU0FBUyxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFBRSxPQUFPLFNBQVMsQ0FBQztRQUNySCxPQUFPLE1BQU0sRUFBRSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUSxLQUFLLFNBQVMsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3RLLENBQUM7Q0FDRiJ9
|
|
@@ -2,6 +2,8 @@ import * as plugins from '../../plugins.js';
|
|
|
2
2
|
import type { IIntegrationEntity, IIntegrationEvent } from '../../core/types.js';
|
|
3
3
|
import type { IHueEvent, IHueResourceResponse } from './hue.types.js';
|
|
4
4
|
export declare class HueMapper {
|
|
5
|
+
static lightDeviceId(homeIdArg: string, lightIdArg: string): string;
|
|
6
|
+
static lightEntityId(homeIdArg: string, lightIdArg: string): string;
|
|
5
7
|
static toDevices(resourcesArg: IHueResourceResponse): plugins.shxInterfaces.data.IDeviceDefinition[];
|
|
6
8
|
static toEntities(resourcesArg: IHueResourceResponse): IIntegrationEntity[];
|
|
7
9
|
static toIntegrationEvent(eventArg: IHueEvent): IIntegrationEvent;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import * as plugins from '../../plugins.js';
|
|
2
2
|
export class HueMapper {
|
|
3
|
+
static lightDeviceId(homeIdArg, lightIdArg) { return `hue.light.${encodeURIComponent(homeIdArg)}.${lightIdArg}`; }
|
|
4
|
+
static lightEntityId(homeIdArg, lightIdArg) { return `light.hue.${encodeURIComponent(homeIdArg)}.${lightIdArg}`; }
|
|
3
5
|
static toDevices(resourcesArg) {
|
|
4
6
|
const timestamp = new Date().toISOString();
|
|
5
7
|
const devices = [{
|
|
6
|
-
id: `hue.bridge.${resourcesArg.bridge.id}`,
|
|
8
|
+
id: `hue.bridge.${encodeURIComponent(resourcesArg.homeId)}.${resourcesArg.bridge.id}`,
|
|
7
9
|
integrationDomain: 'hue', name: resourcesArg.bridge.metadata?.name || 'Hue Bridge', protocol: 'hue',
|
|
8
10
|
manufacturer: resourcesArg.bridge.productData?.manufacturerName,
|
|
9
11
|
model: resourcesArg.bridge.productData?.productName || resourcesArg.bridge.productData?.modelId,
|
|
@@ -14,7 +16,7 @@ export class HueMapper {
|
|
|
14
16
|
for (const light of resourcesArg.lights) {
|
|
15
17
|
const owner = resourcesArg.devices.find((deviceArg) => deviceArg.id === light.owner.rid);
|
|
16
18
|
devices.push({
|
|
17
|
-
id:
|
|
19
|
+
id: HueMapper.lightDeviceId(resourcesArg.homeId, light.id), integrationDomain: 'hue',
|
|
18
20
|
name: light.metadata?.name || owner?.metadata?.name || `Hue Light ${light.id}`, protocol: 'hue',
|
|
19
21
|
manufacturer: owner?.productData?.manufacturerName,
|
|
20
22
|
model: owner?.productData?.productName || owner?.productData?.modelId,
|
|
@@ -23,15 +25,15 @@ export class HueMapper {
|
|
|
23
25
|
...(light.dimming ? [{ id: 'brightness', capability: 'light', name: 'Brightness', readable: true, writable: true, unit: '%' }] : [])],
|
|
24
26
|
state: [{ featureId: 'on', value: light.on.on, updatedAt: timestamp },
|
|
25
27
|
...(light.dimming ? [{ featureId: 'brightness', value: light.dimming.brightness, updatedAt: timestamp }] : [])],
|
|
26
|
-
metadata: { hueOwnerRid: light.owner.rid },
|
|
28
|
+
metadata: { homeId: resourcesArg.homeId, hueOwnerRid: light.owner.rid },
|
|
27
29
|
});
|
|
28
30
|
}
|
|
29
31
|
return devices;
|
|
30
32
|
}
|
|
31
33
|
static toEntities(resourcesArg) {
|
|
32
34
|
return resourcesArg.lights.map((lightArg) => ({
|
|
33
|
-
id:
|
|
34
|
-
deviceId:
|
|
35
|
+
id: HueMapper.lightEntityId(resourcesArg.homeId, lightArg.id), uniqueId: `hue_light_${encodeURIComponent(resourcesArg.homeId)}_${lightArg.id}`, integrationDomain: 'hue',
|
|
36
|
+
deviceId: HueMapper.lightDeviceId(resourcesArg.homeId, lightArg.id), platform: 'light',
|
|
35
37
|
name: lightArg.metadata?.name || resourcesArg.devices.find((deviceArg) => deviceArg.id === lightArg.owner.rid)?.metadata?.name || `Hue Light ${lightArg.id}`,
|
|
36
38
|
state: lightArg.on.on ? 'on' : 'off',
|
|
37
39
|
attributes: lightArg.dimming ? { brightness: lightArg.dimming.brightness } : {}, available: lightArg.available,
|
|
@@ -42,4 +44,4 @@ export class HueMapper {
|
|
|
42
44
|
integrationDomain: 'hue', data: eventArg, timestamp: Date.now() };
|
|
43
45
|
}
|
|
44
46
|
}
|
|
45
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
47
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHVlLm1hcHBlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL2ludGVncmF0aW9ucy9odWUvaHVlLm1hcHBlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBSTVDLE1BQU0sT0FBTyxTQUFTO0lBQ2IsTUFBTSxDQUFDLGFBQWEsQ0FBQyxTQUFpQixFQUFFLFVBQWtCLElBQVksT0FBTyxhQUFhLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxJQUFJLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUMxSSxNQUFNLENBQUMsYUFBYSxDQUFDLFNBQWlCLEVBQUUsVUFBa0IsSUFBWSxPQUFPLGFBQWEsa0JBQWtCLENBQUMsU0FBUyxDQUFDLElBQUksVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRTFJLE1BQU0sQ0FBQyxTQUFTLENBQUMsWUFBa0M7UUFDeEQsTUFBTSxTQUFTLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUMzQyxNQUFNLE9BQU8sR0FBbUQsQ0FBQztnQkFDL0QsRUFBRSxFQUFFLGNBQWMsa0JBQWtCLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxJQUFJLFlBQVksQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFO2dCQUNyRixpQkFBaUIsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFlBQVksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLElBQUksSUFBSSxZQUFZLEVBQUUsUUFBUSxFQUFFLEtBQUs7Z0JBQ25HLFlBQVksRUFBRSxZQUFZLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxnQkFBZ0I7Z0JBQy9ELEtBQUssRUFBRSxZQUFZLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxXQUFXLElBQUksWUFBWSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsT0FBTztnQkFDL0YsTUFBTSxFQUFFLElBQUk7Z0JBQ1osUUFBUSxFQUFF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
|
|
@@ -1,12 +1,42 @@
|
|
|
1
|
+
import type * as plugins from '../../plugins.js';
|
|
2
|
+
import type { IConfigEncryptionKeyProvider } from '../../core/classes.configstore.js';
|
|
1
3
|
export interface IHueConfig {
|
|
4
|
+
homeId: string;
|
|
2
5
|
bridgeId: string;
|
|
3
6
|
host: string;
|
|
4
|
-
|
|
7
|
+
credentialReference: string;
|
|
5
8
|
port?: number;
|
|
6
9
|
/** PEM CA supplied by the operator from a trusted source. */
|
|
7
10
|
trustedCa?: string;
|
|
8
11
|
requestTimeoutMs?: number;
|
|
9
12
|
}
|
|
13
|
+
export interface IHueCredentialRequest {
|
|
14
|
+
readonly homeId: string;
|
|
15
|
+
readonly origin: string;
|
|
16
|
+
readonly bridgeId: string;
|
|
17
|
+
readonly credentialReference: string;
|
|
18
|
+
readonly signal: AbortSignal;
|
|
19
|
+
/** Monotonic deadline shared by provider work and HTTPS dispatch. */
|
|
20
|
+
readonly deadline: number;
|
|
21
|
+
}
|
|
22
|
+
export interface IHueCredentialProvider {
|
|
23
|
+
resolve(requestArg: IHueCredentialRequest): Promise<string>;
|
|
24
|
+
/** Creates a reference without replacing an existing credential. */
|
|
25
|
+
create?(requestArg: IHueCredentialRequest, appKeyArg: string): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
export interface IHueControlPermission {
|
|
28
|
+
readonly resource: 'config' | 'lights';
|
|
29
|
+
readonly resourceId: string;
|
|
30
|
+
readonly fields: readonly string[];
|
|
31
|
+
}
|
|
32
|
+
export interface IHueIntegrationOptions {
|
|
33
|
+
readonly homeId?: string;
|
|
34
|
+
readonly capacity?: number;
|
|
35
|
+
readonly credentialProvider?: IHueCredentialProvider;
|
|
36
|
+
readonly controlPermissions?: readonly IHueControlPermission[];
|
|
37
|
+
readonly db?: plugins.nosqldb.SmartdataDb;
|
|
38
|
+
readonly keyProvider?: IConfigEncryptionKeyProvider;
|
|
39
|
+
}
|
|
10
40
|
export interface IHueLightStatePatch {
|
|
11
41
|
on?: boolean;
|
|
12
42
|
/** Hue v2 brightness is a percentage, from 0 through 100. */
|
|
@@ -46,6 +76,7 @@ export interface IHueLightResource {
|
|
|
46
76
|
available: boolean;
|
|
47
77
|
}
|
|
48
78
|
export interface IHueResourceResponse {
|
|
79
|
+
homeId: string;
|
|
49
80
|
bridge: IHueDeviceResource;
|
|
50
81
|
devices: IHueDeviceResource[];
|
|
51
82
|
lights: IHueLightResource[];
|
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
import type { IHueConfig, IHueEvent, IHueLightStatePatch, IHueResourceResponse } from './hue.types.js';
|
|
1
|
+
import type { IHueConfig, IHueEvent, IHueLightStatePatch, IHueResourceResponse, IHueIntegrationOptions } from './hue.types.js';
|
|
2
2
|
export declare const hueContentType: (valueArg: unknown, expectedArg: string) => boolean;
|
|
3
3
|
export declare const hueUuid: (valueArg: unknown) => valueArg is string;
|
|
4
4
|
export declare const hueBridgeId: (valueArg: unknown) => valueArg is string;
|
|
5
5
|
/** Capture plain data fields without invoking caller accessors or retaining mutable objects. */
|
|
6
6
|
export declare const hueRecord: (valueArg: unknown) => Record<string, unknown>;
|
|
7
|
+
export declare const hueData: (valueArg: unknown, allowedArg: readonly string[]) => Record<string, unknown>;
|
|
8
|
+
export declare const hueText: (valueArg: unknown, nameArg: string, maximumArg?: number) => string;
|
|
9
|
+
export declare const hueKey: (valueArg: unknown) => string;
|
|
10
|
+
export declare const hueOrigin: (configArg: IHueConfig) => string;
|
|
11
|
+
export declare function captureHueOptions(valueArg?: IHueIntegrationOptions): Readonly<IHueIntegrationOptions>;
|
|
7
12
|
export declare const normalizeHueHost: (valueArg: unknown) => string;
|
|
8
|
-
export declare const normalizeHueConfig: (configArg: IHueConfig) => Required<
|
|
13
|
+
export declare const normalizeHueConfig: (configArg: IHueConfig) => Readonly<Required<Omit<IHueConfig, 'trustedCa'>> & Pick<IHueConfig, 'trustedCa'>>;
|
|
9
14
|
export declare const validateHuePatch: (patchArg: IHueLightStatePatch) => void;
|
|
10
15
|
export declare const parseHueEnvelope: (valueArg: unknown) => unknown[];
|
|
11
|
-
export declare const parseHueResources: (dataArg: unknown[], bridgeIdArg: string) => IHueResourceResponse;
|
|
16
|
+
export declare const parseHueResources: (dataArg: unknown[], bridgeIdArg: string, homeIdArg: string) => IHueResourceResponse;
|
|
12
17
|
export declare const parseHueEvents: (valueArg: unknown) => IHueEvent[];
|