@mp-consulting/homebridge-daikin-cloud 1.2.2 → 1.2.3
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/.claude/settings.local.json +2 -1
- package/CHANGELOG.md +6 -0
- package/dist/src/services/climate-control.service.js +2 -2
- package/dist/src/services/climate-control.service.js.map +1 -1
- package/package.json +1 -1
- package/test/hbConfig/accessories/.cachedAccessories.bak +1 -1
- package/test/hbConfig/accessories/cachedAccessories +1 -1
- package/test/integration/air-conditioning.test.ts +10 -0
- package/test/integration/platform.test.ts +39 -21
- package/test/unit/services/hot-water-tank.service.test.ts +13 -3
|
@@ -21,6 +21,16 @@ import {
|
|
|
21
21
|
FanOnlyOperationModeFeature,
|
|
22
22
|
} from '../../src/features';
|
|
23
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
|
+
|
|
24
34
|
type DeviceState = {
|
|
25
35
|
activeState: boolean;
|
|
26
36
|
currentTemperature: number;
|
|
@@ -10,7 +10,14 @@ jest.mock('homebridge');
|
|
|
10
10
|
jest.mock('../../src/accessories/air-conditioning-accessory');
|
|
11
11
|
jest.mock('../../src/accessories/altherma-accessory');
|
|
12
12
|
|
|
13
|
+
// Use fake timers to prevent tests from hanging due to setInterval/setTimeout in platform
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
jest.useFakeTimers();
|
|
16
|
+
});
|
|
17
|
+
|
|
13
18
|
afterEach(() => {
|
|
19
|
+
jest.clearAllTimers();
|
|
20
|
+
jest.useRealTimers();
|
|
14
21
|
jest.resetAllMocks();
|
|
15
22
|
});
|
|
16
23
|
|
|
@@ -30,15 +37,12 @@ test('Initialize platform', async () => {
|
|
|
30
37
|
expect(platform.updateIntervalDelay).toBe(900000);
|
|
31
38
|
});
|
|
32
39
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
jest.spyOn(DaikinCloudController.prototype, 'getCloudDevices').mockResolvedValue([{
|
|
40
|
+
test('DaikinCloudPlatform with new Aircondition accessory', async () => {
|
|
41
|
+
const mockDevice = {
|
|
36
42
|
getId: () => 'MOCK_ID',
|
|
37
|
-
getDescription: () => {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
};
|
|
41
|
-
},
|
|
43
|
+
getDescription: () => ({
|
|
44
|
+
deviceModel: 'Airco',
|
|
45
|
+
}),
|
|
42
46
|
getData: () => 'MOCK_DATE',
|
|
43
47
|
desc: {
|
|
44
48
|
managementPoints: [
|
|
@@ -48,7 +52,15 @@ test.skip('DaikinCloudPlatform with new Aircondition accessory', async () => {
|
|
|
48
52
|
},
|
|
49
53
|
],
|
|
50
54
|
},
|
|
51
|
-
} as unknown as DaikinCloudDevice
|
|
55
|
+
} as unknown as DaikinCloudDevice;
|
|
56
|
+
|
|
57
|
+
// Mock the constructor to set up getCloudDevices on the instance
|
|
58
|
+
(DaikinCloudController as unknown as jest.Mock).mockImplementation(() => ({
|
|
59
|
+
getCloudDevices: jest.fn().mockResolvedValue([mockDevice]),
|
|
60
|
+
isAuthenticated: jest.fn().mockReturnValue(true),
|
|
61
|
+
on: jest.fn(),
|
|
62
|
+
updateAllDeviceData: jest.fn().mockResolvedValue(undefined),
|
|
63
|
+
}));
|
|
52
64
|
|
|
53
65
|
const api = new HomebridgeAPI();
|
|
54
66
|
|
|
@@ -57,22 +69,20 @@ test.skip('DaikinCloudPlatform with new Aircondition accessory', async () => {
|
|
|
57
69
|
new DaikinCloudPlatform(new Logger(), new MockPlatformConfig(true), api);
|
|
58
70
|
api.signalFinished();
|
|
59
71
|
|
|
60
|
-
// Wait for async device discovery to complete
|
|
61
|
-
await
|
|
72
|
+
// Wait for async device discovery to complete using fake timers
|
|
73
|
+
await jest.advanceTimersByTimeAsync(100);
|
|
62
74
|
|
|
63
75
|
expect(AirConditioningAccessory).toHaveBeenCalled();
|
|
64
76
|
expect(AlthermaAccessory).not.toHaveBeenCalled();
|
|
65
77
|
expect(registerPlatformAccessoriesSpy).toHaveBeenCalledWith('@mp-consulting/homebridge-daikin-cloud', 'DaikinCloud', expect.anything());
|
|
66
78
|
});
|
|
67
79
|
|
|
68
|
-
test
|
|
69
|
-
|
|
80
|
+
test('DaikinCloudPlatform with new Altherma accessory', async () => {
|
|
81
|
+
const mockDevice = {
|
|
70
82
|
getId: () => 'MOCK_ID',
|
|
71
|
-
getDescription: () => {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
};
|
|
75
|
-
},
|
|
83
|
+
getDescription: () => ({
|
|
84
|
+
deviceModel: 'Altherma',
|
|
85
|
+
}),
|
|
76
86
|
getData: () => 'MOCK_DATE',
|
|
77
87
|
desc: {
|
|
78
88
|
managementPoints: [
|
|
@@ -82,7 +92,15 @@ test.skip('DaikinCloudPlatform with new Altherma accessory', async () => {
|
|
|
82
92
|
},
|
|
83
93
|
],
|
|
84
94
|
},
|
|
85
|
-
} as unknown as DaikinCloudDevice
|
|
95
|
+
} as unknown as DaikinCloudDevice;
|
|
96
|
+
|
|
97
|
+
// Mock the constructor to set up getCloudDevices on the instance
|
|
98
|
+
(DaikinCloudController as unknown as jest.Mock).mockImplementation(() => ({
|
|
99
|
+
getCloudDevices: jest.fn().mockResolvedValue([mockDevice]),
|
|
100
|
+
isAuthenticated: jest.fn().mockReturnValue(true),
|
|
101
|
+
on: jest.fn(),
|
|
102
|
+
updateAllDeviceData: jest.fn().mockResolvedValue(undefined),
|
|
103
|
+
}));
|
|
86
104
|
|
|
87
105
|
const api = new HomebridgeAPI();
|
|
88
106
|
|
|
@@ -91,8 +109,8 @@ test.skip('DaikinCloudPlatform with new Altherma accessory', async () => {
|
|
|
91
109
|
new DaikinCloudPlatform(new Logger(), new MockPlatformConfig(true), api);
|
|
92
110
|
api.signalFinished();
|
|
93
111
|
|
|
94
|
-
// Wait for async device discovery to complete
|
|
95
|
-
await
|
|
112
|
+
// Wait for async device discovery to complete using fake timers
|
|
113
|
+
await jest.advanceTimersByTimeAsync(100);
|
|
96
114
|
|
|
97
115
|
expect(AlthermaAccessory).toHaveBeenCalled();
|
|
98
116
|
expect(AirConditioningAccessory).not.toHaveBeenCalled();
|
|
@@ -9,13 +9,22 @@ import {althermaHeatPump} from '../../fixtures/altherma-heat-pump';
|
|
|
9
9
|
import {HomebridgeAPI} from 'homebridge/lib/api.js';
|
|
10
10
|
import {Logger} from 'homebridge/lib/logger.js';
|
|
11
11
|
|
|
12
|
-
// TODO: Refactor tests to use new API structure (managementPoints is now an array, not a dictionary)
|
|
13
12
|
// Helper to get management point data from the device
|
|
14
13
|
const getManagementPoint = (device: DaikinCloudDevice, embeddedId: string): any => {
|
|
15
14
|
return (device as any).rawData.managementPoints.find((mp: any) => mp.embeddedId === embeddedId);
|
|
16
15
|
};
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
// Use fake timers to prevent tests from hanging due to setInterval/setTimeout in platform
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
jest.useFakeTimers();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
afterEach(() => {
|
|
23
|
+
jest.clearAllTimers();
|
|
24
|
+
jest.useRealTimers();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe('HotWaterTankService', () => {
|
|
19
28
|
let accessory: PlatformAccessory<DaikinCloudAccessoryContext>;
|
|
20
29
|
let service: HotWaterTankService;
|
|
21
30
|
|
|
@@ -24,7 +33,8 @@ describe.skip('HotWaterTankService', () => {
|
|
|
24
33
|
beforeEach(() => {
|
|
25
34
|
const mockApi = {} as DaikinApi;
|
|
26
35
|
accessory = new PlatformAccessory<DaikinCloudAccessoryContext>('ACCESSORY_NAME', uuid.generate('ACCESSORY_UUID'));
|
|
27
|
-
|
|
36
|
+
// Use a deep copy of the fixture to isolate test mutations
|
|
37
|
+
accessory.context['device'] = new DaikinCloudDevice(JSON.parse(JSON.stringify(althermaHeatPump)) as any, mockApi);
|
|
28
38
|
accessory.context.device.getLastUpdated = jest.fn().mockReturnValue(new Date(1987, 0, 19, 0, 0, 0, 0));
|
|
29
39
|
|
|
30
40
|
const platform = new DaikinCloudPlatform(new Logger(), new MockPlatformConfig(true), new HomebridgeAPI());
|