@mp-consulting/homebridge-daikin-cloud 1.5.2 → 1.6.1
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/README.md +40 -27
- package/config.schema.json +66 -12
- package/dist/src/accessories/air-conditioning-accessory.js +1 -1
- package/dist/src/accessories/air-conditioning-accessory.js.map +1 -1
- package/dist/src/accessories/altherma-accessory.js +1 -1
- package/dist/src/accessories/altherma-accessory.js.map +1 -1
- package/dist/src/accessories/base-accessory.d.ts +5 -4
- package/dist/src/accessories/base-accessory.d.ts.map +1 -1
- package/dist/src/accessories/base-accessory.js +9 -10
- package/dist/src/accessories/base-accessory.js.map +1 -1
- package/dist/src/api/daikin-api.d.ts +22 -6
- package/dist/src/api/daikin-api.d.ts.map +1 -1
- package/dist/src/api/daikin-api.js +49 -23
- package/dist/src/api/daikin-api.js.map +1 -1
- package/dist/src/api/daikin-controller.d.ts +4 -48
- package/dist/src/api/daikin-controller.d.ts.map +1 -1
- package/dist/src/api/daikin-controller.js +14 -84
- package/dist/src/api/daikin-controller.js.map +1 -1
- package/dist/src/api/daikin-mobile-oauth.d.ts +11 -40
- package/dist/src/api/daikin-mobile-oauth.d.ts.map +1 -1
- package/dist/src/api/daikin-mobile-oauth.js +36 -160
- package/dist/src/api/daikin-mobile-oauth.js.map +1 -1
- package/dist/src/api/daikin-oauth.d.ts +10 -37
- package/dist/src/api/daikin-oauth.d.ts.map +1 -1
- package/dist/src/api/daikin-oauth.js +36 -166
- package/dist/src/api/daikin-oauth.js.map +1 -1
- package/dist/src/api/daikin-schemas.d.ts +20 -22
- package/dist/src/api/daikin-schemas.d.ts.map +1 -1
- package/dist/src/api/daikin-schemas.js +17 -49
- package/dist/src/api/daikin-schemas.js.map +1 -1
- package/dist/src/api/daikin-types.d.ts +11 -23
- package/dist/src/api/daikin-types.d.ts.map +1 -1
- package/dist/src/api/daikin-types.js.map +1 -1
- package/dist/src/api/daikin-websocket.d.ts +4 -5
- package/dist/src/api/daikin-websocket.d.ts.map +1 -1
- package/dist/src/api/daikin-websocket.js +62 -34
- package/dist/src/api/daikin-websocket.js.map +1 -1
- package/dist/src/api/http-defaults.d.ts +3 -2
- package/dist/src/api/http-defaults.d.ts.map +1 -1
- package/dist/src/api/http-defaults.js.map +1 -1
- package/dist/src/api/http-transport.d.ts +14 -2
- package/dist/src/api/http-transport.d.ts.map +1 -1
- package/dist/src/api/http-transport.js +32 -9
- package/dist/src/api/http-transport.js.map +1 -1
- package/dist/src/api/token-client.d.ts +82 -0
- package/dist/src/api/token-client.d.ts.map +1 -0
- package/dist/src/api/token-client.js +188 -0
- package/dist/src/api/token-client.js.map +1 -0
- package/dist/src/api/token-storage.d.ts +6 -0
- package/dist/src/api/token-storage.d.ts.map +1 -1
- package/dist/src/api/token-storage.js +27 -1
- package/dist/src/api/token-storage.js.map +1 -1
- package/dist/src/config/config-manager.d.ts +69 -125
- package/dist/src/config/config-manager.d.ts.map +1 -1
- package/dist/src/config/config-manager.js +288 -225
- package/dist/src/config/config-manager.js.map +1 -1
- package/dist/src/constants/api.constants.d.ts +6 -0
- package/dist/src/constants/api.constants.d.ts.map +1 -1
- package/dist/src/constants/api.constants.js +7 -1
- package/dist/src/constants/api.constants.js.map +1 -1
- package/dist/src/constants/auth.constants.d.ts +11 -0
- package/dist/src/constants/auth.constants.d.ts.map +1 -1
- package/dist/src/constants/auth.constants.js +12 -1
- package/dist/src/constants/auth.constants.js.map +1 -1
- package/dist/src/constants/device.constants.d.ts +1 -7
- package/dist/src/constants/device.constants.d.ts.map +1 -1
- package/dist/src/constants/device.constants.js +2 -11
- package/dist/src/constants/device.constants.js.map +1 -1
- package/dist/src/constants/time.constants.d.ts +0 -2
- package/dist/src/constants/time.constants.d.ts.map +1 -1
- package/dist/src/constants/time.constants.js +1 -3
- package/dist/src/constants/time.constants.js.map +1 -1
- package/dist/src/device/accessory-factory.d.ts +0 -5
- package/dist/src/device/accessory-factory.d.ts.map +1 -1
- package/dist/src/device/accessory-factory.js +0 -7
- package/dist/src/device/accessory-factory.js.map +1 -1
- package/dist/src/device/capability-detector.d.ts +9 -1
- package/dist/src/device/capability-detector.d.ts.map +1 -1
- package/dist/src/device/capability-detector.js +32 -28
- package/dist/src/device/capability-detector.js.map +1 -1
- package/dist/src/device/capability-docs.d.ts.map +1 -1
- package/dist/src/device/capability-docs.js +3 -0
- package/dist/src/device/capability-docs.js.map +1 -1
- package/dist/src/device/data-paths.d.ts +18 -0
- package/dist/src/device/data-paths.d.ts.map +1 -0
- package/dist/src/device/data-paths.js +20 -0
- package/dist/src/device/data-paths.js.map +1 -0
- package/dist/src/device/profiles/device-profile.d.ts +0 -5
- package/dist/src/device/profiles/device-profile.d.ts.map +1 -1
- package/dist/src/device/profiles/device-profile.js +0 -21
- package/dist/src/device/profiles/device-profile.js.map +1 -1
- package/dist/src/features/base-feature.d.ts +53 -9
- package/dist/src/features/base-feature.d.ts.map +1 -1
- package/dist/src/features/base-feature.js +93 -40
- package/dist/src/features/base-feature.js.map +1 -1
- package/dist/src/features/feature-manager.d.ts +27 -15
- package/dist/src/features/feature-manager.d.ts.map +1 -1
- package/dist/src/features/feature-manager.js +27 -24
- package/dist/src/features/feature-manager.js.map +1 -1
- package/dist/src/features/index.d.ts +1 -0
- package/dist/src/features/index.d.ts.map +1 -1
- package/dist/src/features/index.js +1 -0
- package/dist/src/features/index.js.map +1 -1
- package/dist/src/features/modes/auto-fan-mode.feature.d.ts +16 -10
- package/dist/src/features/modes/auto-fan-mode.feature.d.ts.map +1 -1
- package/dist/src/features/modes/auto-fan-mode.feature.js +16 -40
- package/dist/src/features/modes/auto-fan-mode.feature.js.map +1 -1
- package/dist/src/features/modes/dry-operation-mode.feature.d.ts +12 -9
- package/dist/src/features/modes/dry-operation-mode.feature.d.ts.map +1 -1
- package/dist/src/features/modes/dry-operation-mode.feature.js +11 -30
- package/dist/src/features/modes/dry-operation-mode.feature.js.map +1 -1
- package/dist/src/features/modes/econo-mode.feature.d.ts +12 -9
- package/dist/src/features/modes/econo-mode.feature.d.ts.map +1 -1
- package/dist/src/features/modes/econo-mode.feature.js +11 -31
- package/dist/src/features/modes/econo-mode.feature.js.map +1 -1
- package/dist/src/features/modes/fan-only-operation-mode.feature.d.ts +12 -9
- package/dist/src/features/modes/fan-only-operation-mode.feature.d.ts.map +1 -1
- package/dist/src/features/modes/fan-only-operation-mode.feature.js +11 -30
- package/dist/src/features/modes/fan-only-operation-mode.feature.js.map +1 -1
- package/dist/src/features/modes/firmware-update.feature.d.ts +7 -6
- package/dist/src/features/modes/firmware-update.feature.d.ts.map +1 -1
- package/dist/src/features/modes/firmware-update.feature.js +15 -22
- package/dist/src/features/modes/firmware-update.feature.js.map +1 -1
- package/dist/src/features/modes/holiday-mode.feature.d.ts +2 -1
- package/dist/src/features/modes/holiday-mode.feature.d.ts.map +1 -1
- package/dist/src/features/modes/holiday-mode.feature.js +5 -15
- package/dist/src/features/modes/holiday-mode.feature.js.map +1 -1
- package/dist/src/features/modes/indoor-silent-mode.feature.d.ts +15 -12
- package/dist/src/features/modes/indoor-silent-mode.feature.d.ts.map +1 -1
- package/dist/src/features/modes/indoor-silent-mode.feature.js +15 -39
- package/dist/src/features/modes/indoor-silent-mode.feature.js.map +1 -1
- package/dist/src/features/modes/oscillation-mode.feature.d.ts +5 -6
- package/dist/src/features/modes/oscillation-mode.feature.d.ts.map +1 -1
- package/dist/src/features/modes/oscillation-mode.feature.js +14 -36
- package/dist/src/features/modes/oscillation-mode.feature.js.map +1 -1
- package/dist/src/features/modes/outdoor-silent-mode.feature.d.ts +12 -9
- package/dist/src/features/modes/outdoor-silent-mode.feature.d.ts.map +1 -1
- package/dist/src/features/modes/outdoor-silent-mode.feature.js +11 -31
- package/dist/src/features/modes/outdoor-silent-mode.feature.js.map +1 -1
- package/dist/src/features/modes/powerful-mode.feature.d.ts +14 -10
- package/dist/src/features/modes/powerful-mode.feature.d.ts.map +1 -1
- package/dist/src/features/modes/powerful-mode.feature.js +13 -32
- package/dist/src/features/modes/powerful-mode.feature.js.map +1 -1
- package/dist/src/features/modes/streamer-mode.feature.d.ts +12 -9
- package/dist/src/features/modes/streamer-mode.feature.d.ts.map +1 -1
- package/dist/src/features/modes/streamer-mode.feature.js +11 -31
- package/dist/src/features/modes/streamer-mode.feature.js.map +1 -1
- package/dist/src/features/on-off-data-point-feature.d.ts +43 -0
- package/dist/src/features/on-off-data-point-feature.d.ts.map +1 -0
- package/dist/src/features/on-off-data-point-feature.js +49 -0
- package/dist/src/features/on-off-data-point-feature.js.map +1 -0
- package/dist/src/platform.d.ts +56 -9
- package/dist/src/platform.d.ts.map +1 -1
- package/dist/src/platform.js +248 -128
- package/dist/src/platform.js.map +1 -1
- package/dist/src/services/climate-control/fan-speed.d.ts +45 -0
- package/dist/src/services/climate-control/fan-speed.d.ts.map +1 -0
- package/dist/src/services/climate-control/fan-speed.js +104 -0
- package/dist/src/services/climate-control/fan-speed.js.map +1 -0
- package/dist/src/services/climate-control/separate-fan.service.d.ts +45 -0
- package/dist/src/services/climate-control/separate-fan.service.d.ts.map +1 -0
- package/dist/src/services/climate-control/separate-fan.service.js +82 -0
- package/dist/src/services/climate-control/separate-fan.service.js.map +1 -0
- package/dist/src/services/climate-control/setpoint-resolver.d.ts +68 -0
- package/dist/src/services/climate-control/setpoint-resolver.d.ts.map +1 -0
- package/dist/src/services/climate-control/setpoint-resolver.js +170 -0
- package/dist/src/services/climate-control/setpoint-resolver.js.map +1 -0
- package/dist/src/services/climate-control/swing-controller.d.ts +28 -0
- package/dist/src/services/climate-control/swing-controller.d.ts.map +1 -0
- package/dist/src/services/climate-control/swing-controller.js +65 -0
- package/dist/src/services/climate-control/swing-controller.js.map +1 -0
- package/dist/src/services/climate-control.service.d.ts +39 -48
- package/dist/src/services/climate-control.service.d.ts.map +1 -1
- package/dist/src/services/climate-control.service.js +223 -554
- package/dist/src/services/climate-control.service.js.map +1 -1
- package/dist/src/services/hot-water-tank.service.d.ts +17 -8
- package/dist/src/services/hot-water-tank.service.d.ts.map +1 -1
- package/dist/src/services/hot-water-tank.service.js +102 -157
- package/dist/src/services/hot-water-tank.service.js.map +1 -1
- package/dist/src/types/daikin-enums.d.ts +0 -5
- package/dist/src/types/daikin-enums.d.ts.map +1 -1
- package/dist/src/types/daikin-enums.js +1 -7
- package/dist/src/types/daikin-enums.js.map +1 -1
- package/dist/src/types/device-capabilities.d.ts +1 -0
- package/dist/src/types/device-capabilities.d.ts.map +1 -1
- package/dist/src/utils/errors.d.ts +9 -0
- package/dist/src/utils/errors.d.ts.map +1 -0
- package/dist/src/utils/errors.js +25 -0
- package/dist/src/utils/errors.js.map +1 -0
- package/dist/src/utils/hap-write.d.ts +22 -0
- package/dist/src/utils/hap-write.d.ts.map +1 -0
- package/dist/src/utils/hap-write.js +33 -0
- package/dist/src/utils/hap-write.js.map +1 -0
- package/dist/src/utils/sleep.d.ts +5 -0
- package/dist/src/utils/sleep.d.ts.map +1 -0
- package/dist/src/utils/sleep.js +10 -0
- package/dist/src/utils/sleep.js.map +1 -0
- package/homebridge-ui/README.md +25 -2
- package/homebridge-ui/public/index.html +19 -17
- package/homebridge-ui/public/script.js +95 -32
- package/homebridge-ui/public/styles.css +109 -0
- package/homebridge-ui/server.js +687 -453
- package/package.json +3 -3
- package/dist/src/utils/log-context.d.ts +0 -105
- package/dist/src/utils/log-context.d.ts.map +0 -1
- package/dist/src/utils/log-context.js +0 -206
- package/dist/src/utils/log-context.js.map +0 -1
- package/dist/src/utils/update-mapper.d.ts +0 -59
- package/dist/src/utils/update-mapper.d.ts.map +0 -1
- package/dist/src/utils/update-mapper.js +0 -192
- package/dist/src/utils/update-mapper.js.map +0 -1
|
@@ -6,9 +6,25 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { CharacteristicValue, PlatformAccessory, Service, Logger } from 'homebridge';
|
|
8
8
|
import type { DaikinCloudAccessoryContext, DaikinCloudPlatform } from '../platform';
|
|
9
|
+
import type { DaikinCloudDevice, DeviceDataPoint } from '../api';
|
|
10
|
+
import type { DeviceCapabilities } from '../types';
|
|
11
|
+
import type { FeatureConfigKey } from '../config/config-manager';
|
|
9
12
|
/**
|
|
10
13
|
* Abstract base class for feature modules.
|
|
11
14
|
* Features are optional capabilities that can be enabled/disabled via switches.
|
|
15
|
+
*
|
|
16
|
+
* Switch services are identified by (Service.Switch, subtype), never by display
|
|
17
|
+
* name, and the subtype is namespaced per management point
|
|
18
|
+
* (`<managementPointId>:<serviceSubtype>`), so features of different management
|
|
19
|
+
* points (e.g. the Altherma climateControl and domesticHotWaterTank, which both
|
|
20
|
+
* know a "Powerful mode") can never find or remove each other's switches.
|
|
21
|
+
*
|
|
22
|
+
* Backwards compatibility: accessories cached before namespacing carry switches
|
|
23
|
+
* with the bare `serviceSubtype`. HomeKit identifies a service by its type and
|
|
24
|
+
* subtype, so renaming the subtype would show up as a brand-new switch and break
|
|
25
|
+
* existing automations/scenes. Instead the legacy switch is adopted as-is by the
|
|
26
|
+
* single management point that owns it (see ownsLegacyService), and only new
|
|
27
|
+
* switches get the namespaced subtype.
|
|
12
28
|
*/
|
|
13
29
|
export declare abstract class BaseFeature {
|
|
14
30
|
protected readonly platform: DaikinCloudPlatform;
|
|
@@ -17,20 +33,21 @@ export declare abstract class BaseFeature {
|
|
|
17
33
|
protected readonly log: Logger;
|
|
18
34
|
protected readonly name: string;
|
|
19
35
|
protected switchService?: Service;
|
|
20
|
-
|
|
36
|
+
private detectedCapabilities?;
|
|
37
|
+
constructor(platform: DaikinCloudPlatform, accessory: PlatformAccessory<DaikinCloudAccessoryContext>, managementPointId: string, capabilities?: DeviceCapabilities);
|
|
21
38
|
/**
|
|
22
39
|
* The display name for this feature (used for the switch service).
|
|
23
40
|
*/
|
|
24
41
|
abstract get featureName(): string;
|
|
25
42
|
/**
|
|
26
|
-
* The
|
|
43
|
+
* The (un-namespaced) identifier for this feature's switch service.
|
|
27
44
|
*/
|
|
28
45
|
abstract get serviceSubtype(): string;
|
|
29
46
|
/**
|
|
30
|
-
* The config key for this feature (e.g., 'showPowerfulMode')
|
|
31
|
-
* Used to enable/disable individual features.
|
|
47
|
+
* The config key for this feature (e.g., 'showPowerfulMode'), one of
|
|
48
|
+
* FEATURE_CONFIG_KEYS. Used to enable/disable individual features.
|
|
32
49
|
*/
|
|
33
|
-
abstract get configKey():
|
|
50
|
+
abstract get configKey(): FeatureConfigKey;
|
|
34
51
|
/**
|
|
35
52
|
* Check if this feature is supported by the device.
|
|
36
53
|
*/
|
|
@@ -43,9 +60,17 @@ export declare abstract class BaseFeature {
|
|
|
43
60
|
* Set the state of the feature.
|
|
44
61
|
*/
|
|
45
62
|
abstract handleSet(value: CharacteristicValue): Promise<void>;
|
|
63
|
+
/** Subtype of switches created by this feature: namespaced per management point. */
|
|
64
|
+
get namespacedSubtype(): string;
|
|
65
|
+
/**
|
|
66
|
+
* Capabilities detected once for this management point (passed in by the
|
|
67
|
+
* FeatureManager; detected lazily when the feature is constructed on its own).
|
|
68
|
+
*/
|
|
69
|
+
protected get capabilities(): DeviceCapabilities;
|
|
70
|
+
protected get device(): DaikinCloudDevice;
|
|
46
71
|
/**
|
|
47
|
-
* Check if this feature is enabled in config
|
|
48
|
-
*
|
|
72
|
+
* Check if this feature is enabled in config: the per-feature toggle, with the
|
|
73
|
+
* legacy `showExtraFeatures` fallback for extra features (see ConfigManager).
|
|
49
74
|
*/
|
|
50
75
|
protected isEnabledInConfig(): boolean;
|
|
51
76
|
/**
|
|
@@ -57,9 +82,26 @@ export declare abstract class BaseFeature {
|
|
|
57
82
|
*/
|
|
58
83
|
protected createOrUpdateSwitchService(): void;
|
|
59
84
|
/**
|
|
60
|
-
* Remove
|
|
85
|
+
* Remove this feature's switch service(s) if they exist.
|
|
61
86
|
*/
|
|
62
87
|
protected removeServiceIfExists(): void;
|
|
88
|
+
/** This feature's switches on the accessory: the namespaced one first, then an owned legacy one. */
|
|
89
|
+
private findExistingServices;
|
|
90
|
+
/**
|
|
91
|
+
* Data point that decides which management point owns the legacy
|
|
92
|
+
* (un-namespaced) switch. Undefined ⇒ climateControl owns it, as every legacy
|
|
93
|
+
* feature switch was created for climateControl — except the Altherma
|
|
94
|
+
* "Powerful mode", which lives on the domesticHotWaterTank.
|
|
95
|
+
*/
|
|
96
|
+
protected get legacyOwnershipDataPoint(): string | undefined;
|
|
97
|
+
/**
|
|
98
|
+
* Whether the legacy un-namespaced switch belongs to this management point.
|
|
99
|
+
* Owner: the first feature-hosting management point (climateControl before
|
|
100
|
+
* domesticHotWaterTank) that supports legacyOwnershipDataPoint; otherwise the
|
|
101
|
+
* climateControl management point. Exactly one management point owns it, so
|
|
102
|
+
* features of different management points never adopt or remove the same switch.
|
|
103
|
+
*/
|
|
104
|
+
protected ownsLegacyService(): boolean;
|
|
63
105
|
/**
|
|
64
106
|
* Push current device state to the switch's On characteristic.
|
|
65
107
|
* Called after every poll / WebSocket update so HomeKit reflects state
|
|
@@ -70,7 +112,7 @@ export declare abstract class BaseFeature {
|
|
|
70
112
|
/**
|
|
71
113
|
* Get device data from the Daikin Cloud.
|
|
72
114
|
*/
|
|
73
|
-
protected getData(dataPoint: string, path?: string):
|
|
115
|
+
protected getData(dataPoint: string, path?: string): DeviceDataPoint;
|
|
74
116
|
/**
|
|
75
117
|
* Set device data on the Daikin Cloud.
|
|
76
118
|
* Note: device.setData has different parameter order depending on whether path is used:
|
|
@@ -78,5 +120,7 @@ export declare abstract class BaseFeature {
|
|
|
78
120
|
* - With path: setData(managementPointId, dataPoint, path, value)
|
|
79
121
|
*/
|
|
80
122
|
protected setData(dataPoint: string, value: unknown, path?: string): Promise<void>;
|
|
123
|
+
/** Run a device write with HAP error handling (see withHapWrite). */
|
|
124
|
+
protected write<T>(what: string, op: () => Promise<T>, refresh?: boolean): Promise<T>;
|
|
81
125
|
}
|
|
82
126
|
//# sourceMappingURL=base-feature.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-feature.d.ts","sourceRoot":"","sources":["../../../src/features/base-feature.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAC1F,OAAO,KAAK,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"base-feature.d.ts","sourceRoot":"","sources":["../../../src/features/base-feature.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAC1F,OAAO,KAAK,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACpF,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACjE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAQjE;;;;;;;;;;;;;;;;GAgBG;AACH,8BAAsB,WAAW;IAC/B,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;IACjD,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC,2BAA2B,CAAC,CAAC;IAC7E,SAAS,CAAC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IAC7C,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAC/B,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEhC,SAAS,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IAClC,OAAO,CAAC,oBAAoB,CAAC,CAAqB;gBAGhD,QAAQ,EAAE,mBAAmB,EAC7B,SAAS,EAAE,iBAAiB,CAAC,2BAA2B,CAAC,EACzD,iBAAiB,EAAE,MAAM,EACzB,YAAY,CAAC,EAAE,kBAAkB;IAUnC;;OAEG;IACH,QAAQ,KAAK,WAAW,IAAI,MAAM,CAAC;IAEnC;;OAEG;IACH,QAAQ,KAAK,cAAc,IAAI,MAAM,CAAC;IAEtC;;;OAGG;IACH,QAAQ,KAAK,SAAS,IAAI,gBAAgB,CAAC;IAE3C;;OAEG;IACH,QAAQ,CAAC,WAAW,IAAI,OAAO;IAE/B;;OAEG;IACH,QAAQ,CAAC,SAAS,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAElD;;OAEG;IACH,QAAQ,CAAC,SAAS,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAE7D,oFAAoF;IACpF,IAAI,iBAAiB,IAAI,MAAM,CAE9B;IAED;;;OAGG;IACH,SAAS,KAAK,YAAY,IAAI,kBAAkB,CAK/C;IAED,SAAS,KAAK,MAAM,IAAI,iBAAiB,CAExC;IAED;;;OAGG;IACH,SAAS,CAAC,iBAAiB,IAAI,OAAO;IAItC;;OAEG;IACH,KAAK,IAAI,IAAI;IASb;;OAEG;IACH,SAAS,CAAC,2BAA2B,IAAI,IAAI;IAe7C;;OAEG;IACH,SAAS,CAAC,qBAAqB,IAAI,IAAI;IAOvC,oGAAoG;IACpG,OAAO,CAAC,oBAAoB;IAS5B;;;;;OAKG;IACH,SAAS,KAAK,wBAAwB,IAAI,MAAM,GAAG,SAAS,CAE3D;IAED;;;;;;OAMG;IACH,SAAS,CAAC,iBAAiB,IAAI,OAAO;IAUtC;;;;;OAKG;IACH,OAAO,IAAI,IAAI;IAcf;;OAEG;IACH,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,eAAe;IAIpE;;;;;OAKG;cACa,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMxF,qEAAqE;IACrE,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,UAAO,GAAG,OAAO,CAAC,CAAC,CAAC;CAGnF"}
|
|
@@ -7,9 +7,27 @@
|
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.BaseFeature = void 0;
|
|
10
|
+
const capability_detector_1 = require("../device/capability-detector");
|
|
11
|
+
const hap_write_1 = require("../utils/hap-write");
|
|
12
|
+
const errors_1 = require("../utils/errors");
|
|
13
|
+
/** Management point types that host feature switches, in legacy-ownership order. */
|
|
14
|
+
const FEATURE_HOST_TYPES = ['climateControl', 'domesticHotWaterTank'];
|
|
10
15
|
/**
|
|
11
16
|
* Abstract base class for feature modules.
|
|
12
17
|
* Features are optional capabilities that can be enabled/disabled via switches.
|
|
18
|
+
*
|
|
19
|
+
* Switch services are identified by (Service.Switch, subtype), never by display
|
|
20
|
+
* name, and the subtype is namespaced per management point
|
|
21
|
+
* (`<managementPointId>:<serviceSubtype>`), so features of different management
|
|
22
|
+
* points (e.g. the Altherma climateControl and domesticHotWaterTank, which both
|
|
23
|
+
* know a "Powerful mode") can never find or remove each other's switches.
|
|
24
|
+
*
|
|
25
|
+
* Backwards compatibility: accessories cached before namespacing carry switches
|
|
26
|
+
* with the bare `serviceSubtype`. HomeKit identifies a service by its type and
|
|
27
|
+
* subtype, so renaming the subtype would show up as a brand-new switch and break
|
|
28
|
+
* existing automations/scenes. Instead the legacy switch is adopted as-is by the
|
|
29
|
+
* single management point that owns it (see ownsLegacyService), and only new
|
|
30
|
+
* switches get the namespaced subtype.
|
|
13
31
|
*/
|
|
14
32
|
class BaseFeature {
|
|
15
33
|
platform;
|
|
@@ -18,25 +36,38 @@ class BaseFeature {
|
|
|
18
36
|
log;
|
|
19
37
|
name;
|
|
20
38
|
switchService;
|
|
21
|
-
|
|
39
|
+
detectedCapabilities;
|
|
40
|
+
constructor(platform, accessory, managementPointId, capabilities) {
|
|
22
41
|
this.platform = platform;
|
|
23
42
|
this.accessory = accessory;
|
|
24
43
|
this.managementPointId = managementPointId;
|
|
25
44
|
this.log = platform.log;
|
|
26
45
|
this.name = accessory.displayName;
|
|
46
|
+
this.detectedCapabilities = capabilities;
|
|
47
|
+
}
|
|
48
|
+
/** Subtype of switches created by this feature: namespaced per management point. */
|
|
49
|
+
get namespacedSubtype() {
|
|
50
|
+
return `${this.managementPointId}:${this.serviceSubtype}`;
|
|
27
51
|
}
|
|
28
52
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
53
|
+
* Capabilities detected once for this management point (passed in by the
|
|
54
|
+
* FeatureManager; detected lazily when the feature is constructed on its own).
|
|
31
55
|
*/
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (this.configKey in config) {
|
|
36
|
-
return config[this.configKey] === true;
|
|
56
|
+
get capabilities() {
|
|
57
|
+
if (!this.detectedCapabilities) {
|
|
58
|
+
this.detectedCapabilities = new capability_detector_1.DeviceCapabilityDetector(this.device, this.managementPointId).getCapabilities();
|
|
37
59
|
}
|
|
38
|
-
|
|
39
|
-
|
|
60
|
+
return this.detectedCapabilities;
|
|
61
|
+
}
|
|
62
|
+
get device() {
|
|
63
|
+
return this.accessory.context.device;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Check if this feature is enabled in config: the per-feature toggle, with the
|
|
67
|
+
* legacy `showExtraFeatures` fallback for extra features (see ConfigManager).
|
|
68
|
+
*/
|
|
69
|
+
isEnabledInConfig() {
|
|
70
|
+
return this.platform.configManager.isFeatureEnabled(this.configKey);
|
|
40
71
|
}
|
|
41
72
|
/**
|
|
42
73
|
* Set up the feature. Creates or removes the switch service based on support and config.
|
|
@@ -54,29 +85,57 @@ class BaseFeature {
|
|
|
54
85
|
* Create or update the switch service for this feature.
|
|
55
86
|
*/
|
|
56
87
|
createOrUpdateSwitchService() {
|
|
57
|
-
|
|
58
|
-
this.switchService = this.
|
|
59
|
-
this.accessory.addService(this.platform.Service.Switch, this.featureName, this.
|
|
60
|
-
|
|
61
|
-
this.switchService.
|
|
62
|
-
|
|
63
|
-
this.switchService.addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName);
|
|
64
|
-
this.switchService.setCharacteristic(this.platform.Characteristic.ConfiguredName, this.featureName);
|
|
65
|
-
// Set up handlers
|
|
88
|
+
const { Characteristic } = this.platform;
|
|
89
|
+
this.switchService = this.findExistingServices()[0] ||
|
|
90
|
+
this.accessory.addService(this.platform.Service.Switch, this.featureName, this.namespacedSubtype);
|
|
91
|
+
this.switchService.setCharacteristic(Characteristic.Name, this.featureName);
|
|
92
|
+
this.switchService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
93
|
+
this.switchService.setCharacteristic(Characteristic.ConfiguredName, this.featureName);
|
|
66
94
|
this.switchService
|
|
67
|
-
.getCharacteristic(
|
|
95
|
+
.getCharacteristic(Characteristic.On)
|
|
68
96
|
.onGet(this.handleGet.bind(this))
|
|
69
97
|
.onSet(this.handleSet.bind(this));
|
|
70
98
|
}
|
|
71
99
|
/**
|
|
72
|
-
* Remove
|
|
100
|
+
* Remove this feature's switch service(s) if they exist.
|
|
73
101
|
*/
|
|
74
102
|
removeServiceIfExists() {
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
103
|
+
for (const service of this.findExistingServices()) {
|
|
104
|
+
this.accessory.removeService(service);
|
|
105
|
+
}
|
|
106
|
+
this.switchService = undefined;
|
|
107
|
+
}
|
|
108
|
+
/** This feature's switches on the accessory: the namespaced one first, then an owned legacy one. */
|
|
109
|
+
findExistingServices() {
|
|
110
|
+
const { Switch } = this.platform.Service;
|
|
111
|
+
const services = [this.accessory.getServiceById(Switch, this.namespacedSubtype)];
|
|
112
|
+
if (this.ownsLegacyService()) {
|
|
113
|
+
services.push(this.accessory.getServiceById(Switch, this.serviceSubtype));
|
|
79
114
|
}
|
|
115
|
+
return services.filter((service) => service !== undefined);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Data point that decides which management point owns the legacy
|
|
119
|
+
* (un-namespaced) switch. Undefined ⇒ climateControl owns it, as every legacy
|
|
120
|
+
* feature switch was created for climateControl — except the Altherma
|
|
121
|
+
* "Powerful mode", which lives on the domesticHotWaterTank.
|
|
122
|
+
*/
|
|
123
|
+
get legacyOwnershipDataPoint() {
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Whether the legacy un-namespaced switch belongs to this management point.
|
|
128
|
+
* Owner: the first feature-hosting management point (climateControl before
|
|
129
|
+
* domesticHotWaterTank) that supports legacyOwnershipDataPoint; otherwise the
|
|
130
|
+
* climateControl management point. Exactly one management point owns it, so
|
|
131
|
+
* features of different management points never adopt or remove the same switch.
|
|
132
|
+
*/
|
|
133
|
+
ownsLegacyService() {
|
|
134
|
+
const hosts = FEATURE_HOST_TYPES.flatMap(type => (this.device.desc?.managementPoints ?? []).filter(mp => mp.managementPointType === type));
|
|
135
|
+
const dataPoint = this.legacyOwnershipDataPoint;
|
|
136
|
+
const owner = (dataPoint && hosts.find(mp => this.device.getData(mp.embeddedId, dataPoint, undefined).value !== undefined))
|
|
137
|
+
|| hosts[0];
|
|
138
|
+
return (owner?.embeddedId ?? this.managementPointId) === this.managementPointId;
|
|
80
139
|
}
|
|
81
140
|
/**
|
|
82
141
|
* Push current device state to the switch's On characteristic.
|
|
@@ -93,13 +152,13 @@ class BaseFeature {
|
|
|
93
152
|
},
|
|
94
153
|
// handleGet is just a getData read in practice — but guard against custom
|
|
95
154
|
// implementations throwing so one bad feature can't break the refresh loop.
|
|
96
|
-
(err) => this.log.debug(`[${this.name}] ${this.featureName} refresh failed: ${
|
|
155
|
+
(err) => this.log.debug(`[${this.name}] ${this.featureName} refresh failed: ${(0, errors_1.toMessage)(err)}`));
|
|
97
156
|
}
|
|
98
157
|
/**
|
|
99
158
|
* Get device data from the Daikin Cloud.
|
|
100
159
|
*/
|
|
101
160
|
getData(dataPoint, path) {
|
|
102
|
-
return this.
|
|
161
|
+
return this.device.getData(this.managementPointId, dataPoint, path);
|
|
103
162
|
}
|
|
104
163
|
/**
|
|
105
164
|
* Set device data on the Daikin Cloud.
|
|
@@ -108,19 +167,13 @@ class BaseFeature {
|
|
|
108
167
|
* - With path: setData(managementPointId, dataPoint, path, value)
|
|
109
168
|
*/
|
|
110
169
|
async setData(dataPoint, value, path) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
this.platform.forceUpdateDevices();
|
|
119
|
-
}
|
|
120
|
-
catch (e) {
|
|
121
|
-
this.log.warn(`[${this.name}] Failed to set ${dataPoint}: ${e instanceof Error ? e.message : e}`);
|
|
122
|
-
throw new this.platform.api.hap.HapStatusError(-70402 /* this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
|
|
123
|
-
}
|
|
170
|
+
await this.write(dataPoint, () => path
|
|
171
|
+
? this.device.setData(this.managementPointId, dataPoint, path, value)
|
|
172
|
+
: this.device.setData(this.managementPointId, dataPoint, value, undefined));
|
|
173
|
+
}
|
|
174
|
+
/** Run a device write with HAP error handling (see withHapWrite). */
|
|
175
|
+
write(what, op, refresh = true) {
|
|
176
|
+
return (0, hap_write_1.withHapWrite)(this.platform, `[${this.name}] ${what}`, op, { refresh });
|
|
124
177
|
}
|
|
125
178
|
}
|
|
126
179
|
exports.BaseFeature = BaseFeature;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-feature.js","sourceRoot":"","sources":["../../../src/features/base-feature.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;
|
|
1
|
+
{"version":3,"file":"base-feature.js","sourceRoot":"","sources":["../../../src/features/base-feature.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,35 +1,47 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Feature Manager
|
|
3
3
|
*
|
|
4
|
-
* Orchestrates the setup of
|
|
4
|
+
* Orchestrates the setup of the feature modules of one management point.
|
|
5
5
|
* Manages feature lifecycle and provides access to features.
|
|
6
6
|
*/
|
|
7
7
|
import type { PlatformAccessory } from 'homebridge';
|
|
8
8
|
import type { DaikinCloudAccessoryContext, DaikinCloudPlatform } from '../platform';
|
|
9
9
|
import type { BaseFeature } from './base-feature';
|
|
10
|
+
import type { DeviceCapabilities } from '../types';
|
|
10
11
|
/**
|
|
11
|
-
*
|
|
12
|
+
* Feature constructor type
|
|
13
|
+
*/
|
|
14
|
+
export type FeatureConstructor = new (platform: DaikinCloudPlatform, accessory: PlatformAccessory<DaikinCloudAccessoryContext>, managementPointId: string, capabilities?: DeviceCapabilities) => BaseFeature;
|
|
15
|
+
/**
|
|
16
|
+
* Features of a climateControl management point
|
|
17
|
+
*/
|
|
18
|
+
export declare const CLIMATE_CONTROL_FEATURES: readonly FeatureConstructor[];
|
|
19
|
+
/**
|
|
20
|
+
* Features of an Altherma domesticHotWaterTank management point
|
|
21
|
+
*/
|
|
22
|
+
export declare const HOT_WATER_TANK_FEATURES: readonly FeatureConstructor[];
|
|
23
|
+
/**
|
|
24
|
+
* Manages all features for one management point of an accessory
|
|
12
25
|
*/
|
|
13
26
|
export declare class FeatureManager {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
private readonly managementPointId;
|
|
27
|
+
/** Capabilities detected once for the management point; every feature's isSupported reads these. */
|
|
28
|
+
readonly capabilities: DeviceCapabilities;
|
|
17
29
|
private readonly features;
|
|
18
|
-
constructor(platform: DaikinCloudPlatform, accessory: PlatformAccessory<DaikinCloudAccessoryContext>, managementPointId: string);
|
|
30
|
+
constructor(platform: DaikinCloudPlatform, accessory: PlatformAccessory<DaikinCloudAccessoryContext>, managementPointId: string, featureClasses?: readonly FeatureConstructor[]);
|
|
19
31
|
/**
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
32
|
+
* Set up all features. Each feature will create or remove its switch service
|
|
33
|
+
* based on device support and configuration.
|
|
34
|
+
*/
|
|
23
35
|
setupFeatures(): void;
|
|
24
36
|
/**
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
37
|
+
* Push current device state to every feature switch's On characteristic.
|
|
38
|
+
* Called from the services' refreshValues after a poll/WebSocket update so
|
|
39
|
+
* HomeKit reflects mode changes initiated from the Daikin app.
|
|
40
|
+
*/
|
|
29
41
|
refreshAll(): void;
|
|
30
42
|
/**
|
|
31
|
-
|
|
32
|
-
|
|
43
|
+
* Get a specific feature by class type.
|
|
44
|
+
*/
|
|
33
45
|
getFeature<T extends BaseFeature>(featureClass: abstract new (...args: never[]) => T): T | undefined;
|
|
34
46
|
}
|
|
35
47
|
//# sourceMappingURL=feature-manager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-manager.d.ts","sourceRoot":"","sources":["../../../src/features/feature-manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,KAAK,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACpF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"feature-manager.d.ts","sourceRoot":"","sources":["../../../src/features/feature-manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,KAAK,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACpF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAkBnD;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,KAC/B,QAAQ,EAAE,mBAAmB,EAC7B,SAAS,EAAE,iBAAiB,CAAC,2BAA2B,CAAC,EACzD,iBAAiB,EAAE,MAAM,EACzB,YAAY,CAAC,EAAE,kBAAkB,KAC9B,WAAW,CAAC;AAEjB;;GAEG;AACH,eAAO,MAAM,wBAAwB,EAAE,SAAS,kBAAkB,EAYjE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,uBAAuB,EAAE,SAAS,kBAAkB,EAEhE,CAAC;AAEF;;GAEG;AACH,qBAAa,cAAc;IACzB,oGAAoG;IACpG,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAAC;IAC1C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;gBAGvC,QAAQ,EAAE,mBAAmB,EAC7B,SAAS,EAAE,iBAAiB,CAAC,2BAA2B,CAAC,EACzD,iBAAiB,EAAE,MAAM,EACzB,cAAc,GAAE,SAAS,kBAAkB,EAA6B;IAQ1E;;;OAGG;IACH,aAAa,IAAI,IAAI;IAMrB;;;;OAIG;IACH,UAAU,IAAI,IAAI;IAMlB;;OAEG;IACH,UAAU,CAAC,CAAC,SAAS,WAAW,EAC9B,YAAY,EAAE,QAAQ,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,GACjD,CAAC,GAAG,SAAS;CAGjB"}
|
|
@@ -2,17 +2,18 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Feature Manager
|
|
4
4
|
*
|
|
5
|
-
* Orchestrates the setup of
|
|
5
|
+
* Orchestrates the setup of the feature modules of one management point.
|
|
6
6
|
* Manages feature lifecycle and provides access to features.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.FeatureManager = void 0;
|
|
9
|
+
exports.FeatureManager = exports.HOT_WATER_TANK_FEATURES = exports.CLIMATE_CONTROL_FEATURES = void 0;
|
|
10
|
+
const capability_detector_1 = require("../device/capability-detector");
|
|
10
11
|
// Import all features
|
|
11
12
|
const modes_1 = require("./modes");
|
|
12
13
|
/**
|
|
13
|
-
*
|
|
14
|
+
* Features of a climateControl management point
|
|
14
15
|
*/
|
|
15
|
-
|
|
16
|
+
exports.CLIMATE_CONTROL_FEATURES = [
|
|
16
17
|
modes_1.PowerfulModeFeature,
|
|
17
18
|
modes_1.EconoModeFeature,
|
|
18
19
|
modes_1.StreamerModeFeature,
|
|
@@ -26,42 +27,44 @@ const FEATURE_CLASSES = [
|
|
|
26
27
|
modes_1.FirmwareUpdateFeature,
|
|
27
28
|
];
|
|
28
29
|
/**
|
|
29
|
-
*
|
|
30
|
+
* Features of an Altherma domesticHotWaterTank management point
|
|
31
|
+
*/
|
|
32
|
+
exports.HOT_WATER_TANK_FEATURES = [
|
|
33
|
+
modes_1.PowerfulModeFeature,
|
|
34
|
+
];
|
|
35
|
+
/**
|
|
36
|
+
* Manages all features for one management point of an accessory
|
|
30
37
|
*/
|
|
31
38
|
class FeatureManager {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
this.
|
|
38
|
-
this.accessory = accessory;
|
|
39
|
-
this.managementPointId = managementPointId;
|
|
40
|
-
// Create all feature instances
|
|
41
|
-
this.features = FEATURE_CLASSES.map(FeatureClass => new FeatureClass(platform, accessory, managementPointId));
|
|
39
|
+
/** Capabilities detected once for the management point; every feature's isSupported reads these. */
|
|
40
|
+
capabilities;
|
|
41
|
+
features;
|
|
42
|
+
constructor(platform, accessory, managementPointId, featureClasses = exports.CLIMATE_CONTROL_FEATURES) {
|
|
43
|
+
this.capabilities = new capability_detector_1.DeviceCapabilityDetector(accessory.context.device, managementPointId).getCapabilities();
|
|
44
|
+
this.features = featureClasses.map(FeatureClass => new FeatureClass(platform, accessory, managementPointId, this.capabilities));
|
|
42
45
|
}
|
|
43
46
|
/**
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
* Set up all features. Each feature will create or remove its switch service
|
|
48
|
+
* based on device support and configuration.
|
|
49
|
+
*/
|
|
47
50
|
setupFeatures() {
|
|
48
51
|
for (const feature of this.features) {
|
|
49
52
|
feature.setup();
|
|
50
53
|
}
|
|
51
54
|
}
|
|
52
55
|
/**
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
* Push current device state to every feature switch's On characteristic.
|
|
57
|
+
* Called from the services' refreshValues after a poll/WebSocket update so
|
|
58
|
+
* HomeKit reflects mode changes initiated from the Daikin app.
|
|
59
|
+
*/
|
|
57
60
|
refreshAll() {
|
|
58
61
|
for (const feature of this.features) {
|
|
59
62
|
feature.refresh();
|
|
60
63
|
}
|
|
61
64
|
}
|
|
62
65
|
/**
|
|
63
|
-
|
|
64
|
-
|
|
66
|
+
* Get a specific feature by class type.
|
|
67
|
+
*/
|
|
65
68
|
getFeature(featureClass) {
|
|
66
69
|
return this.features.find(f => f instanceof featureClass);
|
|
67
70
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-manager.js","sourceRoot":"","sources":["../../../src/features/feature-manager.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAMH,sBAAsB;AACtB,mCAYiB;
|
|
1
|
+
{"version":3,"file":"feature-manager.js","sourceRoot":"","sources":["../../../src/features/feature-manager.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAMH,uEAAyE;AAEzE,sBAAsB;AACtB,mCAYiB;AAYjB;;GAEG;AACU,QAAA,wBAAwB,GAAkC;IACrE,2BAAmB;IACnB,wBAAgB;IAChB,2BAAmB;IACnB,gCAAwB;IACxB,+BAAuB;IACvB,0BAAkB;IAClB,8BAAsB;IACtB,+BAAuB;IACvB,mCAA2B;IAC3B,0BAAkB;IAClB,6BAAqB;CACtB,CAAC;AAEF;;GAEG;AACU,QAAA,uBAAuB,GAAkC;IACpE,2BAAmB;CACpB,CAAC;AAEF;;GAEG;AACH,MAAa,cAAc;IACzB,oGAAoG;IAC3F,YAAY,CAAqB;IACzB,QAAQ,CAAgB;IAEzC,YACE,QAA6B,EAC7B,SAAyD,EACzD,iBAAyB,EACzB,iBAAgD,gCAAwB;QAExE,IAAI,CAAC,YAAY,GAAG,IAAI,8CAAwB,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,eAAe,EAAE,CAAC;QAChH,IAAI,CAAC,QAAQ,GAAG,cAAc,CAAC,GAAG,CAChC,YAAY,CAAC,EAAE,CAAC,IAAI,YAAY,CAAC,QAAQ,EAAE,SAAS,EAAE,iBAAiB,EAAE,IAAI,CAAC,YAAY,CAAC,CAC5F,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,aAAa;QACX,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,UAAU;QACR,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,UAAU,CACR,YAAkD;QAElD,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,YAAY,YAAY,CAAkB,CAAC;IAC7E,CAAC;CACF;AA9CD,wCA8CC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/features/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/features/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mBAAmB,CAAC;AAClC,cAAc,SAAS,CAAC"}
|
|
@@ -15,6 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./base-feature"), exports);
|
|
18
|
+
__exportStar(require("./on-off-data-point-feature"), exports);
|
|
18
19
|
__exportStar(require("./feature-manager"), exports);
|
|
19
20
|
__exportStar(require("./modes"), exports);
|
|
20
21
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/features/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iDAA+B;AAC/B,oDAAkC;AAClC,0CAAwB"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/features/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iDAA+B;AAC/B,8DAA4C;AAC5C,oDAAkC;AAClC,0CAAwB"}
|
|
@@ -8,20 +8,26 @@
|
|
|
8
8
|
* - ON -> fanSpeed/currentMode = 'auto'
|
|
9
9
|
* - OFF -> fanSpeed/currentMode = 'fixed' (back to manual speed control)
|
|
10
10
|
*
|
|
11
|
+
* Only supported when the device can toggle between 'auto' and 'fixed' —
|
|
12
|
+
* otherwise the switch would have nothing to turn off to.
|
|
13
|
+
*
|
|
11
14
|
* Moving the RotationSpeed slider switches currentMode back to 'fixed'
|
|
12
15
|
* (see ClimateControlService.handleRotationSpeedSet), which turns this switch off
|
|
13
16
|
* on the next refresh. Mutually exclusive with the Indoor silent (quiet) switch:
|
|
14
17
|
* turning one on flips currentMode, so the other reconciles to off on refresh.
|
|
15
18
|
*/
|
|
16
|
-
import
|
|
17
|
-
import {
|
|
18
|
-
export declare class AutoFanModeFeature extends
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
import { OnOffDataPointFeature } from '../on-off-data-point-feature';
|
|
20
|
+
import { DaikinFanSpeedModes } from '../../types';
|
|
21
|
+
export declare class AutoFanModeFeature extends OnOffDataPointFeature {
|
|
22
|
+
protected readonly spec: {
|
|
23
|
+
readonly name: "Auto fan mode";
|
|
24
|
+
readonly subtype: "auto_fan_mode";
|
|
25
|
+
readonly configKey: "showAutoFanMode";
|
|
26
|
+
readonly dataPoint: "fanControl";
|
|
27
|
+
readonly path: (operationMode: string) => string;
|
|
28
|
+
readonly onValue: DaikinFanSpeedModes.AUTO;
|
|
29
|
+
readonly offValue: DaikinFanSpeedModes.FIXED;
|
|
30
|
+
readonly capability: "hasAutoFanMode";
|
|
31
|
+
};
|
|
26
32
|
}
|
|
27
33
|
//# sourceMappingURL=auto-fan-mode.feature.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-fan-mode.feature.d.ts","sourceRoot":"","sources":["../../../../src/features/modes/auto-fan-mode.feature.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"auto-fan-mode.feature.d.ts","sourceRoot":"","sources":["../../../../src/features/modes/auto-fan-mode.feature.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGlD,qBAAa,kBAAmB,SAAQ,qBAAqB;IAC3D,SAAS,CAAC,QAAQ,CAAC,IAAI;;;;;;;;;MASZ;CACZ"}
|