@mp-consulting/homebridge-daikin-cloud 1.3.6 → 1.3.8
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/LICENSE +39 -1
- package/README.md +3 -1
- package/dist/src/accessories/air-conditioning-accessory.d.ts +2 -2
- package/dist/src/accessories/air-conditioning-accessory.d.ts.map +1 -1
- package/dist/src/accessories/air-conditioning-accessory.js.map +1 -1
- package/dist/src/accessories/altherma-accessory.d.ts +2 -2
- package/dist/src/accessories/altherma-accessory.d.ts.map +1 -1
- package/dist/src/accessories/altherma-accessory.js.map +1 -1
- package/dist/src/accessories/base-accessory.d.ts +5 -5
- package/dist/src/accessories/base-accessory.d.ts.map +1 -1
- package/dist/src/accessories/base-accessory.js +7 -4
- package/dist/src/accessories/base-accessory.js.map +1 -1
- package/dist/src/api/daikin-api.d.ts +25 -25
- package/dist/src/api/daikin-api.d.ts.map +1 -1
- package/dist/src/api/daikin-api.js +41 -31
- package/dist/src/api/daikin-api.js.map +1 -1
- package/dist/src/api/daikin-cloud.repository.d.ts.map +1 -1
- package/dist/src/api/daikin-cloud.repository.js.map +1 -1
- package/dist/src/api/daikin-controller.d.ts +41 -42
- package/dist/src/api/daikin-controller.d.ts.map +1 -1
- package/dist/src/api/daikin-controller.js +39 -39
- package/dist/src/api/daikin-controller.js.map +1 -1
- package/dist/src/api/daikin-device.d.ts +33 -31
- package/dist/src/api/daikin-device.d.ts.map +1 -1
- package/dist/src/api/daikin-device.js +40 -29
- package/dist/src/api/daikin-device.js.map +1 -1
- package/dist/src/api/daikin-mobile-oauth.d.ts +16 -16
- package/dist/src/api/daikin-mobile-oauth.d.ts.map +1 -1
- package/dist/src/api/daikin-mobile-oauth.js +32 -22
- package/dist/src/api/daikin-mobile-oauth.js.map +1 -1
- package/dist/src/api/daikin-oauth.d.ts +29 -29
- package/dist/src/api/daikin-oauth.d.ts.map +1 -1
- package/dist/src/api/daikin-oauth.js +45 -35
- package/dist/src/api/daikin-oauth.js.map +1 -1
- package/dist/src/api/daikin-schemas.d.ts +4 -4
- package/dist/src/api/daikin-schemas.js +3 -3
- package/dist/src/api/daikin-schemas.js.map +1 -1
- package/dist/src/api/daikin-types.js.map +1 -1
- package/dist/src/api/daikin-websocket.d.ts +31 -32
- package/dist/src/api/daikin-websocket.d.ts.map +1 -1
- package/dist/src/api/daikin-websocket.js +30 -30
- package/dist/src/api/daikin-websocket.js.map +1 -1
- package/dist/src/api/index.d.ts +1 -1
- package/dist/src/api/index.d.ts.map +1 -1
- package/dist/src/api/index.js +2 -1
- package/dist/src/api/index.js.map +1 -1
- package/dist/src/api/token-storage.d.ts +1 -1
- package/dist/src/api/token-storage.d.ts.map +1 -1
- package/dist/src/api/token-storage.js +20 -11
- package/dist/src/api/token-storage.js.map +1 -1
- package/dist/src/config/config-manager.d.ts +33 -33
- package/dist/src/config/config-manager.d.ts.map +1 -1
- package/dist/src/config/config-manager.js +33 -33
- package/dist/src/config/config-manager.js.map +1 -1
- package/dist/src/constants/api.constants.js.map +1 -1
- package/dist/src/device/accessory-factory.d.ts +10 -10
- package/dist/src/device/accessory-factory.d.ts.map +1 -1
- package/dist/src/device/accessory-factory.js +6 -6
- package/dist/src/device/accessory-factory.js.map +1 -1
- package/dist/src/device/capability-detector.d.ts +8 -8
- package/dist/src/device/capability-detector.d.ts.map +1 -1
- package/dist/src/device/capability-detector.js +6 -6
- package/dist/src/device/capability-detector.js.map +1 -1
- package/dist/src/device/capability-docs.d.ts +1 -1
- package/dist/src/device/capability-docs.d.ts.map +1 -1
- package/dist/src/device/capability-docs.js +1 -2
- package/dist/src/device/capability-docs.js.map +1 -1
- package/dist/src/device/profiles/device-profile.d.ts +1 -1
- package/dist/src/device/profiles/device-profile.d.ts.map +1 -1
- package/dist/src/device/profiles/device-profile.js +4 -4
- package/dist/src/device/profiles/device-profile.js.map +1 -1
- package/dist/src/features/base-feature.d.ts +2 -2
- package/dist/src/features/base-feature.d.ts.map +1 -1
- package/dist/src/features/base-feature.js +2 -3
- package/dist/src/features/base-feature.js.map +1 -1
- package/dist/src/features/feature-manager.d.ts +8 -8
- package/dist/src/features/feature-manager.d.ts.map +1 -1
- package/dist/src/features/feature-manager.js +5 -5
- package/dist/src/features/feature-manager.js.map +1 -1
- package/dist/src/features/modes/dry-operation-mode.feature.d.ts +1 -1
- package/dist/src/features/modes/dry-operation-mode.feature.d.ts.map +1 -1
- package/dist/src/features/modes/dry-operation-mode.feature.js.map +1 -1
- package/dist/src/features/modes/econo-mode.feature.d.ts +1 -1
- package/dist/src/features/modes/econo-mode.feature.d.ts.map +1 -1
- package/dist/src/features/modes/econo-mode.feature.js.map +1 -1
- package/dist/src/features/modes/fan-only-operation-mode.feature.d.ts +1 -1
- 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.map +1 -1
- package/dist/src/features/modes/indoor-silent-mode.feature.d.ts +1 -1
- package/dist/src/features/modes/indoor-silent-mode.feature.d.ts.map +1 -1
- package/dist/src/features/modes/indoor-silent-mode.feature.js.map +1 -1
- package/dist/src/features/modes/outdoor-silent-mode.feature.d.ts +1 -1
- package/dist/src/features/modes/outdoor-silent-mode.feature.d.ts.map +1 -1
- package/dist/src/features/modes/outdoor-silent-mode.feature.js.map +1 -1
- package/dist/src/features/modes/powerful-mode.feature.d.ts +1 -1
- package/dist/src/features/modes/powerful-mode.feature.d.ts.map +1 -1
- package/dist/src/features/modes/powerful-mode.feature.js.map +1 -1
- package/dist/src/features/modes/streamer-mode.feature.d.ts +1 -1
- package/dist/src/features/modes/streamer-mode.feature.d.ts.map +1 -1
- package/dist/src/features/modes/streamer-mode.feature.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/platform.d.ts +6 -5
- package/dist/src/platform.d.ts.map +1 -1
- package/dist/src/platform.js +2 -2
- package/dist/src/platform.js.map +1 -1
- package/dist/src/services/climate-control.service.d.ts +8 -2
- package/dist/src/services/climate-control.service.d.ts.map +1 -1
- package/dist/src/services/climate-control.service.js +53 -59
- package/dist/src/services/climate-control.service.js.map +1 -1
- package/dist/src/services/hot-water-tank.service.d.ts +6 -2
- package/dist/src/services/hot-water-tank.service.d.ts.map +1 -1
- package/dist/src/services/hot-water-tank.service.js +31 -34
- package/dist/src/services/hot-water-tank.service.js.map +1 -1
- package/dist/src/types/daikin-enums.js +12 -12
- package/dist/src/types/daikin-enums.js.map +1 -1
- package/dist/src/types/device-capabilities.d.ts +1 -1
- package/dist/src/types/device-capabilities.d.ts.map +1 -1
- package/dist/src/utils/log-context.d.ts +23 -23
- package/dist/src/utils/log-context.d.ts.map +1 -1
- package/dist/src/utils/log-context.js +28 -28
- package/dist/src/utils/log-context.js.map +1 -1
- package/dist/src/utils/strings.d.ts.map +1 -1
- package/dist/src/utils/strings.js.map +1 -1
- package/dist/src/utils/update-mapper.d.ts +16 -16
- package/dist/src/utils/update-mapper.d.ts.map +1 -1
- package/dist/src/utils/update-mapper.js +14 -14
- package/dist/src/utils/update-mapper.js.map +1 -1
- package/homebridge-ui/public/index.html +24 -24
- package/homebridge-ui/public/lib/kit.css +253 -0
- package/homebridge-ui/public/lib/kit.js +133 -0
- package/homebridge-ui/public/script.js +957 -898
- package/homebridge-ui/public/styles.css +0 -1
- package/homebridge-ui/server.js +739 -695
- package/package.json +30 -25
- package/.claude/settings.json +0 -3
- package/.claude/settings.local.json +0 -24
- package/CHANGELOG.md +0 -114
- package/CLAUDE.md +0 -269
- package/config.md +0 -2
- package/docs/ARCHITECTURE.md +0 -645
- package/docs/IMPLEMENTATION_GUIDE.md +0 -899
- package/docs/IMPROVEMENTS_SUMMARY.md +0 -415
- package/docs/NEXT_STEPS.md +0 -368
- package/docs/Screenshot 2024-07-04 at 18.41.28.png +0 -0
- package/docs/TROUBLESHOOTING.md +0 -475
- package/docs/api-response-for-BRP069A8x.json +0 -520
- package/docs/api-response-for-BRP069C4x-2.json +0 -881
- package/docs/api-response-for-BRP069C4x.json +0 -916
- package/docs/api-response-for-altherma.json +0 -759
- package/docs/api-response-for-altherma2.json +0 -2735
- package/docs/api-response-with-multiple-devices-incl-heatpump.json +0 -2544
- package/docs/cr-insance-altherma-id-0.json +0 -834
- package/docs/mock-air-to-air-dx23.json +0 -759
- package/docs/mock-air-to-air-dx4.json +0 -1134
- package/docs/mock-airpurifier-with-humidifier.json +0 -732
- package/docs/mock-airpurifier.json +0 -450
- package/docs/mock-altherma-air-to-water-lan.json +0 -845
- package/docs/mock-altherma-air-to-water-wlan.json +0 -845
- package/docs/mock-d2cnd-gas-boiler.json +0 -649
- package/docs/setpointmode-vs-controlmode-vs-setpoints-vs-sensorydata.txt +0 -6
- package/images/fan-speed.jpeg +0 -0
- package/images/homekit-controls.jpeg +0 -0
- package/images/homekit-settings.jpeg +0 -0
- package/images/swing-mode.png +0 -0
- package/jest.config.ts +0 -21
- package/test/fixtures/altherma-crSense-2.ts +0 -834
- package/test/fixtures/altherma-fraction.ts +0 -718
- package/test/fixtures/altherma-heat-pump-2.ts +0 -479
- package/test/fixtures/altherma-heat-pump.ts +0 -757
- package/test/fixtures/altherma-miladcerkic-off.ts +0 -524
- package/test/fixtures/altherma-miladcerkic.ts +0 -524
- package/test/fixtures/altherma-v1ckoeln.ts +0 -644
- package/test/fixtures/altherma-with-embedded-id-zero.ts +0 -834
- package/test/fixtures/dx23-airco-2.ts +0 -343
- package/test/fixtures/dx23-airco.ts +0 -518
- package/test/fixtures/dx4-airco.ts +0 -914
- package/test/fixtures/unknown-jan.ts +0 -488
- package/test/fixtures/unknown-kitchen-guests.ts +0 -488
- package/test/hbConfig/.daikin-mobile-tokenset +0 -8
- package/test/hbConfig/.uix-dashboard.json +0 -1
- package/test/hbConfig/.uix-secrets +0 -1
- package/test/hbConfig/accessories/.cachedAccessories.bak +0 -1
- package/test/hbConfig/accessories/cachedAccessories +0 -1
- package/test/hbConfig/accessories/uiAccessoriesLayout.json +0 -1
- package/test/hbConfig/auth.json +0 -10
- package/test/hbConfig/backups/config-backups/config.json.1767953686461 +0 -25
- package/test/hbConfig/backups/config-backups/config.json.1767953695236 +0 -29
- package/test/hbConfig/backups/config-backups/config.json.1767953814763 +0 -29
- package/test/hbConfig/backups/config-backups/config.json.1767953823101 +0 -29
- package/test/hbConfig/backups/config-backups/config.json.1767954822835 +0 -29
- package/test/hbConfig/backups/config-backups/config.json.1767954859218 +0 -29
- package/test/hbConfig/backups/config-backups/config.json.1767960145503 +0 -33
- package/test/hbConfig/backups/config-backups/config.json.1767960168068 +0 -44
- package/test/hbConfig/backups/config-backups/config.json.1767960170333 +0 -46
- package/test/hbConfig/backups/config-backups/config.json.1767960172731 +0 -44
- package/test/hbConfig/backups/config-backups/config.json.1767960179323 +0 -44
- package/test/hbConfig/backups/config-backups/config.json.1767960182114 +0 -44
- package/test/hbConfig/backups/config-backups/config.json.1767960189302 +0 -44
- package/test/hbConfig/backups/config-backups/config.json.1767960195194 +0 -44
- package/test/hbConfig/backups/config-backups/config.json.1767960197301 +0 -44
- package/test/hbConfig/backups/config-backups/config.json.1767960199151 +0 -44
- package/test/hbConfig/backups/config-backups/config.json.1767960199667 +0 -44
- package/test/hbConfig/backups/config-backups/config.json.1767960329839 +0 -44
- package/test/hbConfig/backups/config-backups/config.json.1767960334503 +0 -44
- package/test/hbConfig/backups/config-backups/config.json.1767960336208 +0 -44
- package/test/hbConfig/backups/config-backups/config.json.1767960338537 +0 -44
- package/test/hbConfig/backups/config-backups/config.json.1767963223953 +0 -44
- package/test/hbConfig/backups/config-backups/config.json.1767963241753 +0 -44
- package/test/hbConfig/backups/config-backups/config.json.1767963252785 +0 -44
- package/test/hbConfig/backups/config-backups/config.json.1767963463944 +0 -44
- package/test/hbConfig/backups/config-backups/config.json.1767963834475 +0 -44
- package/test/hbConfig/backups/config-backups/config.json.1767963838474 +0 -44
- package/test/hbConfig/backups/config-backups/config.json.1767963843066 +0 -44
- package/test/hbConfig/backups/config-backups/config.json.1767965217715 +0 -44
- package/test/hbConfig/backups/config-backups/config.json.1767965419624 +0 -25
- package/test/hbConfig/backups/config-backups/config.json.1767965870934 +0 -32
- package/test/hbConfig/backups/config-backups/config.json.1767977675045 +0 -32
- package/test/hbConfig/backups/config-backups/config.json.1767977677222 +0 -33
- package/test/hbConfig/backups/config-backups/config.json.1767977710226 +0 -33
- package/test/hbConfig/backups/config-backups/config.json.1767977741397 +0 -33
- package/test/hbConfig/backups/config-backups/config.json.1767977977093 +0 -35
- package/test/hbConfig/backups/config-backups/config.json.1767977981773 +0 -35
- package/test/hbConfig/backups/config-backups/config.json.1767977986514 +0 -35
- package/test/hbConfig/backups/config-backups/config.json.1767977991174 +0 -35
- package/test/hbConfig/backups/config-backups/config.json.1767979424487 +0 -35
- package/test/hbConfig/backups/config-backups/config.json.1767979424987 +0 -35
- package/test/hbConfig/backups/config-backups/config.json.1767979432646 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767979433150 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767979436933 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767979437438 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767979441676 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767979442180 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767979466735 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767979903636 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767979904135 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767979906606 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767979907108 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767988702341 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767988702837 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767988713159 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767988713664 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767988918139 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767988918639 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767988921120 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767988921624 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767988930307 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767988935070 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767988935574 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767989710262 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767989710760 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767989729668 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767990295225 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767990479921 +0 -47
- package/test/hbConfig/backups/config-backups/config.json.1767990481702 +0 -49
- package/test/hbConfig/backups/instance-backups/homebridge-backup-1E4A432551BA.1768010187391.tar.gz +0 -0
- package/test/hbConfig/backups/instance-backups/homebridge-backup-1E4A432551BA.1768096587387.tar.gz +0 -0
- package/test/hbConfig/backups/instance-backups/homebridge-backup-1E4A432551BA.1768182987404.tar.gz +0 -0
- package/test/hbConfig/config.json +0 -47
- package/test/hbConfig/daikin-cloud-certs/server.crt +0 -22
- package/test/hbConfig/daikin-cloud-certs/server.key +0 -28
- package/test/hbConfig/persist/AccessoryInfo.1E4A432551BA.json +0 -1
- package/test/hbConfig/persist/IdentifierCache.1E4A432551BA.json +0 -1
- package/test/hbConfig/tmp/daikin_request/api.onecta.daikineurope.com_01-09-2026-23-29-52/request_14758 +0 -1
- package/test/hbConfig/tmp/daikin_request/api.onecta.daikineurope.com_01-09-2026-23-29-52/request_14759 +0 -1
- package/test/hbConfig/tmp/daikin_request/api.onecta.daikineurope.com_01-09-2026-23-29-52/request_14760 +0 -1
- package/test/hbConfig/tmp/daikin_request/api.onecta.daikineurope.com_01-09-2026-23-29-52/request_14761 +0 -1
- package/test/hbConfig/tmp/daikin_request/api.onecta.daikineurope.com_01-09-2026-23-29-52/request_14762 +0 -1
- package/test/hbConfig/tmp/daikin_request/api.onecta.daikineurope.com_01-09-2026-23-29-52/request_14764 +0 -1
- package/test/helpers/test-isolation.ts +0 -228
- package/test/integration/air-conditioning.test.ts +0 -396
- package/test/integration/altherma.test.ts +0 -279
- package/test/integration/platform.test.ts +0 -118
- package/test/mobile-tokens.json +0 -8
- package/test/mocks/index.ts +0 -27
- package/test/test-gigya-auth.js +0 -443
- package/test/test-mobile-oauth.js +0 -175
- package/test/test-websocket-mobile.js +0 -123
- package/test/test-websocket.js +0 -116
- package/test/unit/api/__snapshots__/daikinCloud.test.ts.snap +0 -1320
- package/test/unit/api/daikin-api.test.ts +0 -442
- package/test/unit/api/daikin-cloud-repository.test.ts +0 -107
- package/test/unit/api/daikin-oauth.test.ts +0 -214
- package/test/unit/api/daikinCloud.test.ts +0 -12
- package/test/unit/api/token-storage.test.ts +0 -90
- package/test/unit/config/config-manager.test.ts +0 -271
- package/test/unit/device/daikin-device.test.ts +0 -73
- package/test/unit/services/hot-water-tank.service.test.ts +0 -123
- package/test/unit/utils/log-context.test.ts +0 -271
- package/test/unit/utils/update-mapper.test.ts +0 -404
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test Isolation Helpers
|
|
3
|
-
*
|
|
4
|
-
* Provides utilities for better test isolation:
|
|
5
|
-
* - Test context management
|
|
6
|
-
* - Automatic cleanup
|
|
7
|
-
* - Mock factories
|
|
8
|
-
* - Fake timers
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import {Logger, PlatformAccessory, PlatformConfig} from 'homebridge';
|
|
12
|
-
import {DaikinCloudAccessoryContext} from '../../src/platform';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Test context for managing test lifecycle
|
|
16
|
-
*/
|
|
17
|
-
export class TestContext {
|
|
18
|
-
private readonly cleanupCallbacks: Array<() => void | Promise<void>> = [];
|
|
19
|
-
private timersMocked = false;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Register a cleanup callback
|
|
23
|
-
*/
|
|
24
|
-
onCleanup(callback: () => void | Promise<void>): void {
|
|
25
|
-
this.cleanupCallbacks.push(callback);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Use fake timers for this test
|
|
30
|
-
*/
|
|
31
|
-
useFakeTimers(): void {
|
|
32
|
-
if (!this.timersMocked) {
|
|
33
|
-
jest.useFakeTimers();
|
|
34
|
-
this.timersMocked = true;
|
|
35
|
-
this.onCleanup(() => {
|
|
36
|
-
jest.runOnlyPendingTimers();
|
|
37
|
-
jest.useRealTimers();
|
|
38
|
-
this.timersMocked = false;
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Advance timers by time
|
|
45
|
-
*/
|
|
46
|
-
async advanceTimersByTime(ms: number): Promise<void> {
|
|
47
|
-
if (!this.timersMocked) {
|
|
48
|
-
throw new Error('Timers must be mocked first. Call useFakeTimers()');
|
|
49
|
-
}
|
|
50
|
-
jest.advanceTimersByTime(ms);
|
|
51
|
-
await Promise.resolve(); // Flush microtasks
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Run all timers
|
|
56
|
-
*/
|
|
57
|
-
async runAllTimers(): Promise<void> {
|
|
58
|
-
if (!this.timersMocked) {
|
|
59
|
-
throw new Error('Timers must be mocked first. Call useFakeTimers()');
|
|
60
|
-
}
|
|
61
|
-
jest.runAllTimers();
|
|
62
|
-
await Promise.resolve(); // Flush microtasks
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Clean up all resources
|
|
67
|
-
*/
|
|
68
|
-
async cleanup(): Promise<void> {
|
|
69
|
-
for (const callback of this.cleanupCallbacks.reverse()) {
|
|
70
|
-
await callback();
|
|
71
|
-
}
|
|
72
|
-
this.cleanupCallbacks.length = 0;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Create a test context for a test
|
|
78
|
-
*/
|
|
79
|
-
export function createTestContext(): TestContext {
|
|
80
|
-
return new TestContext();
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Create a mock logger
|
|
85
|
-
*/
|
|
86
|
-
export function createMockLogger(): Logger {
|
|
87
|
-
const logger = {
|
|
88
|
-
debug: jest.fn(),
|
|
89
|
-
info: jest.fn(),
|
|
90
|
-
warn: jest.fn(),
|
|
91
|
-
error: jest.fn(),
|
|
92
|
-
log: jest.fn(),
|
|
93
|
-
success: jest.fn(),
|
|
94
|
-
} as unknown as Logger;
|
|
95
|
-
|
|
96
|
-
return logger;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Create a mock platform config
|
|
101
|
-
*/
|
|
102
|
-
export function createMockConfig(overrides: Partial<PlatformConfig> = {}): PlatformConfig {
|
|
103
|
-
return {
|
|
104
|
-
name: 'Test Platform',
|
|
105
|
-
platform: 'DaikinCloud',
|
|
106
|
-
clientId: 'test-client-id',
|
|
107
|
-
clientSecret: 'test-client-secret',
|
|
108
|
-
callbackServerExternalAddress: 'test.example.com',
|
|
109
|
-
callbackServerPort: 8582,
|
|
110
|
-
oidcCallbackServerBindAddr: '0.0.0.0',
|
|
111
|
-
updateIntervalInMinutes: 15,
|
|
112
|
-
forceUpdateDelay: 60000,
|
|
113
|
-
showExtraFeatures: false,
|
|
114
|
-
enableWebSocket: true,
|
|
115
|
-
...overrides,
|
|
116
|
-
} as PlatformConfig;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Create a mock accessory
|
|
121
|
-
*/
|
|
122
|
-
export function createMockAccessory(
|
|
123
|
-
displayName: string,
|
|
124
|
-
context?: Partial<DaikinCloudAccessoryContext>,
|
|
125
|
-
): PlatformAccessory<DaikinCloudAccessoryContext> {
|
|
126
|
-
const mockContext: DaikinCloudAccessoryContext = {
|
|
127
|
-
device: {} as any,
|
|
128
|
-
useHeaterCooler: false,
|
|
129
|
-
...context,
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
const accessory = {
|
|
133
|
-
UUID: `test-uuid-${displayName}`,
|
|
134
|
-
displayName,
|
|
135
|
-
context: mockContext,
|
|
136
|
-
services: [],
|
|
137
|
-
getService: jest.fn(),
|
|
138
|
-
addService: jest.fn(),
|
|
139
|
-
removeService: jest.fn(),
|
|
140
|
-
getServiceById: jest.fn(),
|
|
141
|
-
} as unknown as PlatformAccessory<DaikinCloudAccessoryContext>;
|
|
142
|
-
|
|
143
|
-
return accessory;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Spy on console methods and restore after cleanup
|
|
148
|
-
*/
|
|
149
|
-
export function spyOnConsole(context: TestContext): {
|
|
150
|
-
log: jest.SpyInstance;
|
|
151
|
-
warn: jest.SpyInstance;
|
|
152
|
-
error: jest.SpyInstance;
|
|
153
|
-
} {
|
|
154
|
-
const spies = {
|
|
155
|
-
log: jest.spyOn(console, 'log').mockImplementation(),
|
|
156
|
-
warn: jest.spyOn(console, 'warn').mockImplementation(),
|
|
157
|
-
error: jest.spyOn(console, 'error').mockImplementation(),
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
context.onCleanup(() => {
|
|
161
|
-
spies.log.mockRestore();
|
|
162
|
-
spies.warn.mockRestore();
|
|
163
|
-
spies.error.mockRestore();
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
return spies;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Create isolated test suite with automatic cleanup
|
|
171
|
-
*/
|
|
172
|
-
export function describeIsolated(name: string, fn: (getContext: () => TestContext) => void): void {
|
|
173
|
-
describe(name, () => {
|
|
174
|
-
let context: TestContext;
|
|
175
|
-
|
|
176
|
-
beforeEach(() => {
|
|
177
|
-
context = createTestContext();
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
afterEach(async () => {
|
|
181
|
-
await context.cleanup();
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
fn(() => context);
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Wait for a condition to be true
|
|
190
|
-
*/
|
|
191
|
-
export async function waitFor(
|
|
192
|
-
condition: () => boolean | Promise<boolean>,
|
|
193
|
-
options: { timeout?: number; interval?: number } = {},
|
|
194
|
-
): Promise<void> {
|
|
195
|
-
const timeout = options.timeout ?? 5000;
|
|
196
|
-
const interval = options.interval ?? 50;
|
|
197
|
-
const startTime = Date.now();
|
|
198
|
-
|
|
199
|
-
while (!(await condition())) {
|
|
200
|
-
if (Date.now() - startTime > timeout) {
|
|
201
|
-
throw new Error('waitFor timeout exceeded');
|
|
202
|
-
}
|
|
203
|
-
await new Promise(resolve => setTimeout(resolve, interval));
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Create a deferred promise for testing async flows
|
|
209
|
-
*/
|
|
210
|
-
export function createDeferred<T>(): {
|
|
211
|
-
promise: Promise<T>;
|
|
212
|
-
resolve: (value: T) => void;
|
|
213
|
-
reject: (error: Error) => void;
|
|
214
|
-
} {
|
|
215
|
-
let resolve: (value: T) => void;
|
|
216
|
-
let reject: (error: Error) => void;
|
|
217
|
-
|
|
218
|
-
const promise = new Promise<T>((res, rej) => {
|
|
219
|
-
resolve = res;
|
|
220
|
-
reject = rej;
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
return {
|
|
224
|
-
promise,
|
|
225
|
-
resolve: resolve!,
|
|
226
|
-
reject: reject!,
|
|
227
|
-
};
|
|
228
|
-
}
|
|
@@ -1,396 +0,0 @@
|
|
|
1
|
-
import {PlatformAccessory} from 'homebridge/lib/platformAccessory';
|
|
2
|
-
import {DaikinCloudAccessoryContext, DaikinCloudPlatform} from '../../src/platform';
|
|
3
|
-
import {MockPlatformConfig} from '../mocks';
|
|
4
|
-
import {AirConditioningAccessory} from '../../src/accessories';
|
|
5
|
-
import {DaikinCloudDevice, DaikinCloudController, DaikinApi} from '../../src/api';
|
|
6
|
-
import {unknownJan} from '../fixtures/unknown-jan';
|
|
7
|
-
import {unknownKitchenGuests} from '../fixtures/unknown-kitchen-guests';
|
|
8
|
-
import {dx23Airco} from '../fixtures/dx23-airco';
|
|
9
|
-
import {dx4Airco} from '../fixtures/dx4-airco';
|
|
10
|
-
import {dx23Airco2} from '../fixtures/dx23-airco-2';
|
|
11
|
-
|
|
12
|
-
import {HomebridgeAPI} from 'homebridge/lib/api.js';
|
|
13
|
-
import {Logger} from 'homebridge/lib/logger.js';
|
|
14
|
-
import {
|
|
15
|
-
PowerfulModeFeature,
|
|
16
|
-
EconoModeFeature,
|
|
17
|
-
StreamerModeFeature,
|
|
18
|
-
OutdoorSilentModeFeature,
|
|
19
|
-
IndoorSilentModeFeature,
|
|
20
|
-
DryOperationModeFeature,
|
|
21
|
-
FanOnlyOperationModeFeature,
|
|
22
|
-
} from '../../src/features';
|
|
23
|
-
|
|
24
|
-
// Use fake timers to prevent tests from hanging due to setInterval/setTimeout in platform
|
|
25
|
-
beforeEach(() => {
|
|
26
|
-
jest.useFakeTimers();
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
afterEach(() => {
|
|
30
|
-
jest.clearAllTimers();
|
|
31
|
-
jest.useRealTimers();
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
type DeviceState = {
|
|
35
|
-
activeState: boolean;
|
|
36
|
-
currentTemperature: number;
|
|
37
|
-
targetHeaterCoolerState: string;
|
|
38
|
-
coolingThresholdTemperature: number;
|
|
39
|
-
heatingThresholdTemperature: number;
|
|
40
|
-
rotationSpeed: number;
|
|
41
|
-
swingMode: number;
|
|
42
|
-
powerfulMode: number;
|
|
43
|
-
econoMode: number;
|
|
44
|
-
streamerMode: number;
|
|
45
|
-
outdoorSilentMode: number;
|
|
46
|
-
indoorSilentMode: number;
|
|
47
|
-
dryOperationMode: number;
|
|
48
|
-
fanOnlyOperationMode: number;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
test.each<Array<string | string | any | DeviceState>>([
|
|
52
|
-
[
|
|
53
|
-
'dx4',
|
|
54
|
-
'climateControl',
|
|
55
|
-
dx4Airco,
|
|
56
|
-
{
|
|
57
|
-
activeState: true,
|
|
58
|
-
currentTemperature: 25,
|
|
59
|
-
targetHeaterCoolerState: 1,
|
|
60
|
-
coolingThresholdTemperature: 25,
|
|
61
|
-
heatingThresholdTemperature: 22,
|
|
62
|
-
rotationSpeed: 2,
|
|
63
|
-
swingMode: 0,
|
|
64
|
-
powerfulMode: false,
|
|
65
|
-
econoMode: false,
|
|
66
|
-
streamerMode: false,
|
|
67
|
-
outdoorSilentMode: false,
|
|
68
|
-
indoorSilentMode: false,
|
|
69
|
-
dryOperationMode: false,
|
|
70
|
-
fanOnlyOperationMode: false,
|
|
71
|
-
},
|
|
72
|
-
],
|
|
73
|
-
[
|
|
74
|
-
'dx23',
|
|
75
|
-
'climateControl',
|
|
76
|
-
dx23Airco,
|
|
77
|
-
{
|
|
78
|
-
activeState: false,
|
|
79
|
-
currentTemperature: 27,
|
|
80
|
-
targetHeaterCoolerState: 2,
|
|
81
|
-
coolingThresholdTemperature: 17,
|
|
82
|
-
heatingThresholdTemperature: 17,
|
|
83
|
-
rotationSpeed: 3,
|
|
84
|
-
swingMode: 1,
|
|
85
|
-
powerfulMode: undefined,
|
|
86
|
-
econoMode: undefined,
|
|
87
|
-
streamerMode: undefined,
|
|
88
|
-
outdoorSilentMode: undefined,
|
|
89
|
-
indoorSilentMode: undefined,
|
|
90
|
-
dryOperationMode: false,
|
|
91
|
-
fanOnlyOperationMode: false,
|
|
92
|
-
},
|
|
93
|
-
],
|
|
94
|
-
[
|
|
95
|
-
'dx23-2',
|
|
96
|
-
'climateControl',
|
|
97
|
-
dx23Airco2,
|
|
98
|
-
{
|
|
99
|
-
activeState: true,
|
|
100
|
-
currentTemperature: 19,
|
|
101
|
-
targetHeaterCoolerState: 1,
|
|
102
|
-
coolingThresholdTemperature: 25,
|
|
103
|
-
heatingThresholdTemperature: 13,
|
|
104
|
-
rotationSpeed: 4,
|
|
105
|
-
swingMode: 0,
|
|
106
|
-
powerfulMode: false,
|
|
107
|
-
econoMode: undefined,
|
|
108
|
-
streamerMode: undefined,
|
|
109
|
-
outdoorSilentMode: undefined,
|
|
110
|
-
indoorSilentMode: false,
|
|
111
|
-
dryOperationMode: false,
|
|
112
|
-
fanOnlyOperationMode: false,
|
|
113
|
-
},
|
|
114
|
-
],
|
|
115
|
-
[
|
|
116
|
-
'unknown',
|
|
117
|
-
'climateControl',
|
|
118
|
-
unknownKitchenGuests,
|
|
119
|
-
{
|
|
120
|
-
activeState: false,
|
|
121
|
-
currentTemperature: 30.1,
|
|
122
|
-
targetHeaterCoolerState: 2,
|
|
123
|
-
coolingThresholdTemperature: 23.5,
|
|
124
|
-
heatingThresholdTemperature: undefined,
|
|
125
|
-
rotationSpeed: 1,
|
|
126
|
-
swingMode: 1,
|
|
127
|
-
powerfulMode: undefined,
|
|
128
|
-
econoMode: undefined,
|
|
129
|
-
streamerMode: undefined,
|
|
130
|
-
outdoorSilentMode: undefined,
|
|
131
|
-
indoorSilentMode: undefined,
|
|
132
|
-
dryOperationMode: false,
|
|
133
|
-
fanOnlyOperationMode: false,
|
|
134
|
-
},
|
|
135
|
-
],
|
|
136
|
-
[
|
|
137
|
-
'unknown2',
|
|
138
|
-
'climateControl',
|
|
139
|
-
unknownJan,
|
|
140
|
-
{
|
|
141
|
-
activeState: false,
|
|
142
|
-
currentTemperature: 27,
|
|
143
|
-
targetHeaterCoolerState: 2,
|
|
144
|
-
coolingThresholdTemperature: 26.1,
|
|
145
|
-
heatingThresholdTemperature: undefined,
|
|
146
|
-
rotationSpeed: 1,
|
|
147
|
-
swingMode: 1,
|
|
148
|
-
powerfulMode: undefined,
|
|
149
|
-
econoMode: undefined,
|
|
150
|
-
streamerMode: undefined,
|
|
151
|
-
outdoorSilentMode: undefined,
|
|
152
|
-
indoorSilentMode: undefined,
|
|
153
|
-
dryOperationMode: false,
|
|
154
|
-
fanOnlyOperationMode: false,
|
|
155
|
-
},
|
|
156
|
-
],
|
|
157
|
-
])('Create DaikinCloudAirConditioningAccessory with %s device', async (name: string, climateControlEmbeddedId: string, deviceJson, state: DeviceState) => {
|
|
158
|
-
const mockApi = {
|
|
159
|
-
updateDevice: jest.fn().mockResolvedValue(undefined),
|
|
160
|
-
} as unknown as DaikinApi;
|
|
161
|
-
const device = new DaikinCloudDevice(deviceJson as any, mockApi);
|
|
162
|
-
|
|
163
|
-
jest.spyOn(DaikinCloudController.prototype, 'getCloudDevices').mockImplementation(async () => {
|
|
164
|
-
return [device];
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
const config = new MockPlatformConfig(true);
|
|
168
|
-
const api = new HomebridgeAPI();
|
|
169
|
-
|
|
170
|
-
const uuid = api.hap.uuid.generate(device.getId());
|
|
171
|
-
const accessory = new api.platformAccessory("NAME_FOR_TEST", uuid);
|
|
172
|
-
accessory.context['device'] = device;
|
|
173
|
-
|
|
174
|
-
expect(() => {
|
|
175
|
-
new AirConditioningAccessory(new DaikinCloudPlatform(new Logger(), config, api), accessory as unknown as PlatformAccessory<DaikinCloudAccessoryContext>);
|
|
176
|
-
}).not.toThrow();
|
|
177
|
-
|
|
178
|
-
const homebridgeAccessory = new AirConditioningAccessory(new DaikinCloudPlatform(new Logger(), config, api), accessory as unknown as PlatformAccessory<DaikinCloudAccessoryContext>);
|
|
179
|
-
|
|
180
|
-
if (typeof state.activeState !== 'undefined') {
|
|
181
|
-
expect(await homebridgeAccessory.service.handleActiveStateGet()).toBe(state.activeState);
|
|
182
|
-
await expect(homebridgeAccessory.service.handleActiveStateSet(1)).resolves.not.toThrow();
|
|
183
|
-
await expect(homebridgeAccessory.service.handleActiveStateSet(0)).resolves.not.toThrow();
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
expect(await homebridgeAccessory.service.handleCurrentTemperatureGet()).toBe(state.currentTemperature);
|
|
187
|
-
|
|
188
|
-
if (typeof state.coolingThresholdTemperature !== 'undefined') {
|
|
189
|
-
expect(await homebridgeAccessory.service.handleCoolingThresholdTemperatureGet()).toBe(state.coolingThresholdTemperature);
|
|
190
|
-
await expect(homebridgeAccessory.service.handleCoolingThresholdTemperatureSet(21)).resolves.not.toThrow();
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
if (typeof state.heatingThresholdTemperature !== 'undefined') {
|
|
194
|
-
expect(await homebridgeAccessory.service.handleHeatingThresholdTemperatureGet()).toBe(state.heatingThresholdTemperature);
|
|
195
|
-
await expect(homebridgeAccessory.service.handleHeatingThresholdTemperatureSet(25)).resolves.not.toThrow();
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
if (typeof state.rotationSpeed !== 'undefined') {
|
|
199
|
-
expect(await homebridgeAccessory.service.handleRotationSpeedGet()).toBe(state.rotationSpeed);
|
|
200
|
-
await expect(homebridgeAccessory.service.handleRotationSpeedSet(50)).resolves.not.toThrow();
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
if (typeof state.targetHeaterCoolerState !== 'undefined') {
|
|
204
|
-
expect(await homebridgeAccessory.service.handleTargetHeaterCoolerStateGet()).toBe(state.targetHeaterCoolerState);
|
|
205
|
-
await expect(homebridgeAccessory.service.handleTargetHeaterCoolerStateSet(1)).resolves.not.toThrow();
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
if (typeof state.swingMode !== 'undefined') {
|
|
209
|
-
expect(await homebridgeAccessory.service.handleSwingModeGet()).toBe(state.swingMode);
|
|
210
|
-
await expect(homebridgeAccessory.service.handleSwingModeSet(1)).resolves.not.toThrow();
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
if (typeof state.powerfulMode !== 'undefined') {
|
|
214
|
-
const feature = homebridgeAccessory.service.featureManager.getFeature(PowerfulModeFeature);
|
|
215
|
-
expect(feature).toBeDefined();
|
|
216
|
-
expect(await feature!.handleGet()).toBe(state.powerfulMode);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
if (typeof state.econoMode !== 'undefined') {
|
|
220
|
-
const feature = homebridgeAccessory.service.featureManager.getFeature(EconoModeFeature);
|
|
221
|
-
expect(feature).toBeDefined();
|
|
222
|
-
expect(await feature!.handleGet()).toBe(state.econoMode);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
if (typeof state.streamerMode !== 'undefined') {
|
|
226
|
-
const feature = homebridgeAccessory.service.featureManager.getFeature(StreamerModeFeature);
|
|
227
|
-
expect(feature).toBeDefined();
|
|
228
|
-
expect(await feature!.handleGet()).toBe(state.streamerMode);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
if (typeof state.outdoorSilentMode !== 'undefined') {
|
|
232
|
-
const feature = homebridgeAccessory.service.featureManager.getFeature(OutdoorSilentModeFeature);
|
|
233
|
-
expect(feature).toBeDefined();
|
|
234
|
-
expect(await feature!.handleGet()).toBe(state.outdoorSilentMode);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
if (typeof state.indoorSilentMode !== 'undefined') {
|
|
238
|
-
const feature = homebridgeAccessory.service.featureManager.getFeature(IndoorSilentModeFeature);
|
|
239
|
-
expect(feature).toBeDefined();
|
|
240
|
-
expect(await feature!.handleGet()).toBe(state.indoorSilentMode);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
if (typeof state.dryOperationMode !== 'undefined') {
|
|
244
|
-
const feature = homebridgeAccessory.service.featureManager.getFeature(DryOperationModeFeature);
|
|
245
|
-
expect(feature).toBeDefined();
|
|
246
|
-
expect(await feature!.handleGet()).toBe(state.dryOperationMode);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
if (typeof state.fanOnlyOperationMode !== 'undefined') {
|
|
250
|
-
const feature = homebridgeAccessory.service.featureManager.getFeature(FanOnlyOperationModeFeature);
|
|
251
|
-
expect(feature).toBeDefined();
|
|
252
|
-
expect(await feature!.handleGet()).toBe(state.fanOnlyOperationMode);
|
|
253
|
-
}
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
test.each<Array<string | string | any>>([
|
|
257
|
-
['dx4', 'climateControl', dx4Airco],
|
|
258
|
-
['dx23', 'climateControl', dx23Airco],
|
|
259
|
-
])('Create DaikinCloudAirConditioningAccessory with %s device, showExtraFeatures disabled', async (name, climateControlEmbeddedId, deviceJson) => {
|
|
260
|
-
const mockApi = { updateDevice: jest.fn().mockResolvedValue(undefined) } as unknown as DaikinApi;
|
|
261
|
-
const device = new DaikinCloudDevice(deviceJson as any, mockApi);
|
|
262
|
-
|
|
263
|
-
jest.spyOn(DaikinCloudController.prototype, 'getCloudDevices').mockImplementation(async () => {
|
|
264
|
-
return [device];
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
const config = new MockPlatformConfig(false);
|
|
269
|
-
const api = new HomebridgeAPI();
|
|
270
|
-
|
|
271
|
-
const uuid = api.hap.uuid.generate(device.getId());
|
|
272
|
-
const accessory = new api.platformAccessory("NAME_FOR_TEST", uuid);
|
|
273
|
-
|
|
274
|
-
accessory.addService(api.hap.Service.Switch, 'Powerful mode', 'Powerful_Mode');
|
|
275
|
-
accessory.addService(api.hap.Service.Switch, 'Econo mode', 'Econo_Mode');
|
|
276
|
-
accessory.addService(api.hap.Service.Switch, 'Streamer mode', 'Streamer_Mode');
|
|
277
|
-
accessory.addService(api.hap.Service.Switch, 'Outdoor silent mode', 'Outdoor_Silent_Mode');
|
|
278
|
-
accessory.addService(api.hap.Service.Switch, 'Indoor silent mode', 'Indoor_Silent_Mode');
|
|
279
|
-
accessory.context['device'] = device;
|
|
280
|
-
|
|
281
|
-
const removeServiceSpy = jest.spyOn(accessory, 'removeService').mockImplementation();
|
|
282
|
-
|
|
283
|
-
const homebridgeAccessory = new AirConditioningAccessory(new DaikinCloudPlatform(new Logger(), config, api), accessory as unknown as PlatformAccessory<DaikinCloudAccessoryContext>);
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
expect(removeServiceSpy).toHaveBeenNthCalledWith(1, expect.objectContaining({ displayName: 'Powerful mode', subtype: 'Powerful_Mode' }));
|
|
287
|
-
expect(removeServiceSpy).toHaveBeenNthCalledWith(2, expect.objectContaining({ displayName: 'Econo mode', subtype: 'Econo_Mode' }));
|
|
288
|
-
expect(removeServiceSpy).toHaveBeenNthCalledWith(3, expect.objectContaining({ displayName: 'Streamer mode', subtype: 'Streamer_Mode' }));
|
|
289
|
-
expect(removeServiceSpy).toHaveBeenNthCalledWith(4, expect.objectContaining({ displayName: 'Outdoor silent mode', subtype: 'Outdoor_Silent_Mode' }));
|
|
290
|
-
expect(removeServiceSpy).toHaveBeenNthCalledWith(5, expect.objectContaining({ displayName: 'Indoor silent mode', subtype: 'Indoor_Silent_Mode' }));
|
|
291
|
-
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
test('DaikinCloudAirConditioningAccessory Getters', async () => {
|
|
295
|
-
const mockApi = { updateDevice: jest.fn().mockResolvedValue(undefined) } as unknown as DaikinApi;
|
|
296
|
-
const device = new DaikinCloudDevice(dx4Airco as any, mockApi);
|
|
297
|
-
|
|
298
|
-
jest.spyOn(DaikinCloudController.prototype, 'getCloudDevices').mockImplementation(async () => {
|
|
299
|
-
return [device];
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
const config = new MockPlatformConfig(false);
|
|
303
|
-
const api = new HomebridgeAPI();
|
|
304
|
-
|
|
305
|
-
const uuid = api.hap.uuid.generate(device.getId());
|
|
306
|
-
const accessory = new api.platformAccessory(device.getData('climateControl', 'name', undefined).value as string, uuid);
|
|
307
|
-
accessory.context['device'] = device;
|
|
308
|
-
|
|
309
|
-
const homebridgeAccessory = new AirConditioningAccessory(new DaikinCloudPlatform(new Logger(), config, api), accessory as unknown as PlatformAccessory<DaikinCloudAccessoryContext>);
|
|
310
|
-
|
|
311
|
-
expect(await homebridgeAccessory.service.handleActiveStateGet()).toEqual(true);
|
|
312
|
-
expect(await homebridgeAccessory.service.handleCurrentTemperatureGet()).toEqual(25);
|
|
313
|
-
expect(await homebridgeAccessory.service.handleCoolingThresholdTemperatureGet()).toEqual(25);
|
|
314
|
-
expect(await homebridgeAccessory.service.handleRotationSpeedGet()).toEqual(2);
|
|
315
|
-
expect(await homebridgeAccessory.service.handleHeatingThresholdTemperatureGet()).toEqual(22);
|
|
316
|
-
expect(await homebridgeAccessory.service.handleTargetHeaterCoolerStateGet()).toEqual(1);
|
|
317
|
-
expect(await homebridgeAccessory.service.handleSwingModeGet()).toEqual(0);
|
|
318
|
-
|
|
319
|
-
// Feature-based getters via FeatureManager
|
|
320
|
-
const powerfulFeature = homebridgeAccessory.service.featureManager.getFeature(PowerfulModeFeature);
|
|
321
|
-
expect(await powerfulFeature!.handleGet()).toEqual(false);
|
|
322
|
-
const econoFeature = homebridgeAccessory.service.featureManager.getFeature(EconoModeFeature);
|
|
323
|
-
expect(await econoFeature!.handleGet()).toEqual(false);
|
|
324
|
-
const streamerFeature = homebridgeAccessory.service.featureManager.getFeature(StreamerModeFeature);
|
|
325
|
-
expect(await streamerFeature!.handleGet()).toEqual(false);
|
|
326
|
-
const outdoorSilentFeature = homebridgeAccessory.service.featureManager.getFeature(OutdoorSilentModeFeature);
|
|
327
|
-
expect(await outdoorSilentFeature!.handleGet()).toEqual(false);
|
|
328
|
-
const indoorSilentFeature = homebridgeAccessory.service.featureManager.getFeature(IndoorSilentModeFeature);
|
|
329
|
-
expect(await indoorSilentFeature!.handleGet()).toEqual(false);
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
test('DaikinCloudAirConditioningAccessory Setters', async () => {
|
|
333
|
-
const mockApi = { updateDevice: jest.fn().mockResolvedValue(undefined) } as unknown as DaikinApi;
|
|
334
|
-
const device = new DaikinCloudDevice(dx4Airco as any, mockApi);
|
|
335
|
-
|
|
336
|
-
jest.spyOn(DaikinCloudController.prototype, 'getCloudDevices').mockImplementation(async () => {
|
|
337
|
-
return [device];
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
const setDataSpy = jest.spyOn(DaikinCloudDevice.prototype, 'setData').mockImplementation();
|
|
341
|
-
|
|
342
|
-
const config = new MockPlatformConfig(false);
|
|
343
|
-
const api = new HomebridgeAPI();
|
|
344
|
-
|
|
345
|
-
const uuid = api.hap.uuid.generate(device.getId());
|
|
346
|
-
const accessory = new api.platformAccessory(device.getData('climateControl', 'name', undefined).value as string, uuid);
|
|
347
|
-
// device.updateData = () => jest.fn();
|
|
348
|
-
accessory.context['device'] = device;
|
|
349
|
-
|
|
350
|
-
const homebridgeAccessory = new AirConditioningAccessory(new DaikinCloudPlatform(new Logger(), config, api), accessory as unknown as PlatformAccessory<DaikinCloudAccessoryContext>);
|
|
351
|
-
|
|
352
|
-
await homebridgeAccessory.service.handleActiveStateSet(1);
|
|
353
|
-
expect(setDataSpy).toHaveBeenNthCalledWith(1, 'climateControl', 'onOffMode', 'on', undefined);
|
|
354
|
-
|
|
355
|
-
await homebridgeAccessory.service.handleActiveStateSet(0);
|
|
356
|
-
expect(setDataSpy).toHaveBeenNthCalledWith(2, 'climateControl', 'onOffMode', 'off', undefined);
|
|
357
|
-
|
|
358
|
-
await homebridgeAccessory.service.handleCoolingThresholdTemperatureSet(21);
|
|
359
|
-
expect(setDataSpy).toHaveBeenNthCalledWith(3, 'climateControl', 'temperatureControl', '/operationModes/cooling/setpoints/roomTemperature', 21);
|
|
360
|
-
|
|
361
|
-
await homebridgeAccessory.service.handleRotationSpeedSet(50);
|
|
362
|
-
expect(setDataSpy).toHaveBeenNthCalledWith(4, 'climateControl', 'fanControl', '/operationModes/heating/fanSpeed/currentMode', 'fixed');
|
|
363
|
-
expect(setDataSpy).toHaveBeenNthCalledWith(5, 'climateControl', 'fanControl', '/operationModes/heating/fanSpeed/modes/fixed', 50);
|
|
364
|
-
|
|
365
|
-
await homebridgeAccessory.service.handleHeatingThresholdTemperatureSet(25);
|
|
366
|
-
expect(setDataSpy).toHaveBeenNthCalledWith(6, 'climateControl', 'temperatureControl', '/operationModes/heating/setpoints/roomTemperature', 25);
|
|
367
|
-
|
|
368
|
-
await homebridgeAccessory.service.handleTargetHeaterCoolerStateSet(1);
|
|
369
|
-
expect(setDataSpy).toHaveBeenNthCalledWith(7, 'climateControl', 'operationMode', 'heating', undefined);
|
|
370
|
-
expect(setDataSpy).toHaveBeenNthCalledWith(8, 'climateControl', 'onOffMode', 'on', undefined);
|
|
371
|
-
|
|
372
|
-
await homebridgeAccessory.service.handleSwingModeSet(1);
|
|
373
|
-
expect(setDataSpy).toHaveBeenNthCalledWith(9, 'climateControl', 'fanControl', '/operationModes/heating/fanDirection/horizontal/currentMode', 'swing');
|
|
374
|
-
expect(setDataSpy).toHaveBeenNthCalledWith(10, 'climateControl', 'fanControl', '/operationModes/heating/fanDirection/vertical/currentMode', 'swing');
|
|
375
|
-
|
|
376
|
-
// Feature-based setters via FeatureManager
|
|
377
|
-
const powerfulFeature = homebridgeAccessory.service.featureManager.getFeature(PowerfulModeFeature);
|
|
378
|
-
await powerfulFeature!.handleSet(true);
|
|
379
|
-
expect(setDataSpy).toHaveBeenNthCalledWith(11, 'climateControl', 'powerfulMode', 'on', undefined);
|
|
380
|
-
|
|
381
|
-
const econoFeature = homebridgeAccessory.service.featureManager.getFeature(EconoModeFeature);
|
|
382
|
-
await econoFeature!.handleSet(true);
|
|
383
|
-
expect(setDataSpy).toHaveBeenNthCalledWith(12, 'climateControl', 'econoMode', 'on', undefined);
|
|
384
|
-
|
|
385
|
-
const streamerFeature = homebridgeAccessory.service.featureManager.getFeature(StreamerModeFeature);
|
|
386
|
-
await streamerFeature!.handleSet(true);
|
|
387
|
-
expect(setDataSpy).toHaveBeenNthCalledWith(13, 'climateControl', 'streamerMode', 'on', undefined);
|
|
388
|
-
|
|
389
|
-
const outdoorSilentFeature = homebridgeAccessory.service.featureManager.getFeature(OutdoorSilentModeFeature);
|
|
390
|
-
await outdoorSilentFeature!.handleSet(true);
|
|
391
|
-
expect(setDataSpy).toHaveBeenNthCalledWith(14, 'climateControl', 'outdoorSilentMode', 'on', undefined);
|
|
392
|
-
|
|
393
|
-
const indoorSilentFeature = homebridgeAccessory.service.featureManager.getFeature(IndoorSilentModeFeature);
|
|
394
|
-
await indoorSilentFeature!.handleSet(true);
|
|
395
|
-
expect(setDataSpy).toHaveBeenNthCalledWith(15, 'climateControl', 'fanControl', '/operationModes/heating/fanSpeed/currentMode', 'quiet');
|
|
396
|
-
});
|