@homebridge-plugins/homebridge-tuya 2.3.0 → 2.4.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -27,9 +27,13 @@ const SCHEMA_CODE = {
27
27
  CURRENT_HUMIDITY: ['humidity_current'],
28
28
  TARGET_HUMIDITY: ['humidity_set'],
29
29
  };
30
- const AC_MODES = ['auto', 'cold', 'hot'];
31
- const DEHUMIDIFIER_MODE = 'wet';
32
- const FAN_MODE = 'wind';
30
+ // Mode values
31
+ const AC_HEAT_MODES = ['hot', 'heat'];
32
+ const AC_COOL_MODES = ['cold', 'cool'];
33
+ const AC_MODES = ['auto', ...AC_HEAT_MODES, ...AC_COOL_MODES];
34
+ // Added support for dyr, which is included because some devices return a misspelled code value.
35
+ const DEHUMIDIFIER_MODE = ['wet', 'dry', 'dyr'];
36
+ const FAN_MODE = ['wind', 'fan'];
33
37
  class AirConditionerAccessory extends BaseAccessory_1.default {
34
38
  requiredSchema() {
35
39
  return [SCHEMA_CODE.ACTIVE, SCHEMA_CODE.MODE, SCHEMA_CODE.WORK_STATE, SCHEMA_CODE.CURRENT_TEMP];
@@ -86,7 +90,8 @@ class AirConditionerAccessory extends BaseAccessory_1.default {
86
90
  const activeSchema = this.getSchema(...SCHEMA_CODE.ACTIVE);
87
91
  const modeSchema = this.getSchema(...SCHEMA_CODE.MODE);
88
92
  const property = modeSchema.property;
89
- if (!property.range.includes(DEHUMIDIFIER_MODE)) {
93
+ const dehumidifierCode = property.range.find(code => DEHUMIDIFIER_MODE.includes(code.toLowerCase()));
94
+ if (!dehumidifierCode) {
90
95
  return;
91
96
  }
92
97
  const service = this.dehumidifierService();
@@ -96,7 +101,7 @@ class AirConditionerAccessory extends BaseAccessory_1.default {
96
101
  .onGet(() => {
97
102
  const activeStatus = this.getStatus(activeSchema.code);
98
103
  const modeStatus = this.getStatus(modeSchema.code);
99
- return (activeStatus.value === true && modeStatus.value === DEHUMIDIFIER_MODE) ? ACTIVE : INACTIVE;
104
+ return (activeStatus.value === true && modeStatus.value === dehumidifierCode) ? ACTIVE : INACTIVE;
100
105
  })
101
106
  .onSet(async (value) => {
102
107
  await this.sendCommands([{
@@ -104,7 +109,7 @@ class AirConditionerAccessory extends BaseAccessory_1.default {
104
109
  value: (value === ACTIVE) ? true : false,
105
110
  }, {
106
111
  code: modeSchema.code,
107
- value: DEHUMIDIFIER_MODE,
112
+ value: dehumidifierCode,
108
113
  }], true);
109
114
  });
110
115
  const { DEHUMIDIFYING } = this.Characteristic.CurrentHumidifierDehumidifierState;
@@ -129,7 +134,8 @@ class AirConditionerAccessory extends BaseAccessory_1.default {
129
134
  const activeSchema = this.getSchema(...SCHEMA_CODE.ACTIVE);
130
135
  const modeSchema = this.getSchema(...SCHEMA_CODE.MODE);
131
136
  const property = modeSchema.property;
132
- if (!property.range.includes(FAN_MODE)) {
137
+ const fanCode = property.range.find(code => FAN_MODE.includes(code.toLowerCase()));
138
+ if (!fanCode) {
133
139
  return;
134
140
  }
135
141
  const service = this.fanService();
@@ -139,7 +145,7 @@ class AirConditionerAccessory extends BaseAccessory_1.default {
139
145
  .onGet(() => {
140
146
  const activeStatus = this.getStatus(activeSchema.code);
141
147
  const modeStatus = this.getStatus(modeSchema.code);
142
- return (activeStatus.value === true && modeStatus.value === FAN_MODE) ? ACTIVE : INACTIVE;
148
+ return (activeStatus.value === true && modeStatus.value === fanCode) ? ACTIVE : INACTIVE;
143
149
  })
144
150
  .onSet(async (value) => {
145
151
  await this.sendCommands([{
@@ -147,7 +153,7 @@ class AirConditionerAccessory extends BaseAccessory_1.default {
147
153
  value: (value === ACTIVE) ? true : false,
148
154
  }, {
149
155
  code: modeSchema.code,
150
- value: FAN_MODE,
156
+ value: fanCode,
151
157
  }], true);
152
158
  });
153
159
  // Optional Characteristics
@@ -198,10 +204,10 @@ class AirConditionerAccessory extends BaseAccessory_1.default {
198
204
  if (property.range.includes('auto')) {
199
205
  validValues.push(AUTO);
200
206
  }
201
- if (property.range.includes('hot')) {
207
+ if (property.range.some(mode => AC_HEAT_MODES.includes(mode.toLowerCase()))) {
202
208
  validValues.push(HEAT);
203
209
  }
204
- if (property.range.includes('cold')) {
210
+ if (property.range.some(mode => AC_COOL_MODES.includes(mode.toLowerCase()))) {
205
211
  validValues.push(COOL);
206
212
  }
207
213
  if (validValues.length === 0) {
@@ -211,10 +217,10 @@ class AirConditionerAccessory extends BaseAccessory_1.default {
211
217
  this.mainService().getCharacteristic(this.Characteristic.TargetHeaterCoolerState)
212
218
  .onGet(() => {
213
219
  const status = this.getStatus(schema.code);
214
- if (status.value === 'hot') {
220
+ if (AC_HEAT_MODES.includes(String(status.value).toLowerCase())) {
215
221
  return HEAT;
216
222
  }
217
- else if (status.value === 'cold') {
223
+ else if (AC_COOL_MODES.includes(String(status.value).toLowerCase())) {
218
224
  return COOL;
219
225
  }
220
226
  return validValues.includes(AUTO) ? AUTO : validValues[0];
@@ -222,10 +228,10 @@ class AirConditionerAccessory extends BaseAccessory_1.default {
222
228
  .onSet(async (value) => {
223
229
  let mode;
224
230
  if (value === HEAT) {
225
- mode = 'hot';
231
+ mode = property.range.find(m => AC_HEAT_MODES.includes(m.toLowerCase())) || AC_HEAT_MODES[0];
226
232
  }
227
233
  else if (value === COOL) {
228
- mode = 'cold';
234
+ mode = property.range.find(m => AC_COOL_MODES.includes(m.toLowerCase())) || AC_COOL_MODES[0];
229
235
  }
230
236
  else {
231
237
  mode = 'auto';
@@ -1 +1 @@
1
- {"version":3,"file":"AirConditionerAccessory.js","sourceRoot":"","sources":["../../src/accessory/AirConditionerAccessory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AirConditionerAccessory.js","sourceRoot":"","sources":["../../src/accessory/AirConditionerAccessory.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@homebridge-plugins/homebridge-tuya",
3
3
  "displayName": "Homebridge Tuya",
4
- "version": "2.3.0",
4
+ "version": "2.4.0-beta.0",
5
5
  "description": "Forked from 0x5e/homebridge-tuya-platform, with a focus on fixing bugs and adding new device support.",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -0,0 +1,729 @@
1
+ import { describe, expect, test, beforeEach, jest } from '@jest/globals';
2
+ import AirConditionerAccessory from '../../src/accessory/AirConditionerAccessory';
3
+ import TuyaDevice, { TuyaDeviceSchema, TuyaDeviceStatus, TuyaDeviceSchemaMode, TuyaDeviceSchemaType } from '../../src/device/TuyaDevice';
4
+
5
+ // Mock data
6
+ const mockSchema = (code: string, type: string, mode: string, property: any): TuyaDeviceSchema => ({
7
+ code,
8
+ mode: mode as TuyaDeviceSchemaMode,
9
+ type: type as TuyaDeviceSchemaType,
10
+ property,
11
+ });
12
+
13
+ const mockStatus = (code: string, value: string | number | boolean): TuyaDeviceStatus => ({
14
+ code,
15
+ value,
16
+ });
17
+
18
+ // Create mock device with AC capabilities
19
+ const createMockDevice = (overrides?: Partial<TuyaDevice>): TuyaDevice => {
20
+ const device = new TuyaDevice({
21
+ id: 'test-device-001',
22
+ uuid: 'uuid-001',
23
+ name: 'Test Air Conditioner',
24
+ online: true,
25
+ owner_id: 'home-001',
26
+ product_id: 'ac-product-001',
27
+ product_name: 'Smart Air Conditioner',
28
+ model: 'AC-2024',
29
+ icon: 'ac.png',
30
+ category: 'ac',
31
+ schema: [
32
+ mockSchema('switch', 'Boolean', 'rw', {}),
33
+ mockSchema('mode', 'Enum', 'rw', { range: ['auto', 'cold', 'hot', 'wet', 'wind'] }),
34
+ mockSchema('work_status', 'Enum', 'ro', { range: ['heating', 'cooling', 'idle'] }),
35
+ mockSchema('temp_current', 'Integer', 'ro', { min: 0, max: 100, scale: 0, step: 1, unit: '°C' }),
36
+ mockSchema('temp_set', 'Integer', 'rw', { min: 16, max: 30, scale: 0, step: 1, unit: '°C' }),
37
+ mockSchema('fan_speed_enum', 'Enum', 'rw', { range: ['auto', 'low', 'middle', 'high'] }),
38
+ mockSchema('lock', 'Boolean', 'rw', {}),
39
+ mockSchema('humidity_current', 'Integer', 'ro', { min: 0, max: 100, scale: 0, step: 1, unit: '%' }),
40
+ mockSchema('humidity_set', 'Integer', 'rw', { min: 30, max: 80, scale: 0, step: 1, unit: '%' }),
41
+ mockSchema('temp_unit_convert', 'Enum', 'rw', { range: ['C', 'F'] }),
42
+ ],
43
+ status: [
44
+ mockStatus('switch', true),
45
+ mockStatus('mode', 'cold'),
46
+ mockStatus('work_status', 'cooling'),
47
+ mockStatus('temp_current', 24),
48
+ mockStatus('temp_set', 22),
49
+ mockStatus('fan_speed_enum', 'auto'),
50
+ mockStatus('lock', false),
51
+ mockStatus('humidity_current', 60),
52
+ mockStatus('humidity_set', 60),
53
+ mockStatus('temp_unit_convert', 'C'),
54
+ ],
55
+ sub: false,
56
+ ...overrides,
57
+ });
58
+ return device;
59
+ };
60
+
61
+ // Create mock platform
62
+ const createMockPlatform = (): any => {
63
+ // Mock the HAP objects needed by the accessory
64
+ const MockService = {
65
+ HeaterCooler: 'HeaterCooler',
66
+ HumidifierDehumidifier: 'HumidifierDehumidifier',
67
+ Fanv2: 'Fanv2',
68
+ AccessoryInformation: 'AccessoryInformation',
69
+ Battery: 'Battery',
70
+ };
71
+
72
+ const MockCharacteristic = {
73
+ Active: { ACTIVE: 1, INACTIVE: 0 },
74
+ CurrentHeaterCoolerState: { INACTIVE: 0, HEATING: 1, COOLING: 2 },
75
+ TargetHeaterCoolerState: { AUTO: 0, HEAT: 1, COOL: 2 },
76
+ CurrentHumidifierDehumidifierState: { DEHUMIDIFYING: 2 },
77
+ TargetHumidifierDehumidifierState: { DEHUMIDIFIER: 2 },
78
+ CurrentRelativeHumidity: 'CurrentRelativeHumidity',
79
+ RelativeHumidityDehumidifierThreshold: 'RelativeHumidityDehumidifierThreshold',
80
+ CurrentTemperature: 'CurrentTemperature',
81
+ CoolingThresholdTemperature: 'CoolingThresholdTemperature',
82
+ HeatingThresholdTemperature: 'HeatingThresholdTemperature',
83
+ RotationSpeed: 'RotationSpeed',
84
+ LockPhysicalControls: 'LockPhysicalControls',
85
+ Manufacturer: 'Manufacturer',
86
+ Model: 'Model',
87
+ Name: 'Name',
88
+ ConfiguredName: 'ConfiguredName',
89
+ SerialNumber: 'SerialNumber',
90
+ StatusLowBattery: { BATTERY_LEVEL_NORMAL: 0, BATTERY_LEVEL_LOW: 1 },
91
+ BatteryLevel: 'BatteryLevel',
92
+ ChargingState: { NOT_CHARGING: 0, CHARGING: 1 },
93
+ StatusActive: 'StatusActive',
94
+ ProgrammableSwitchEvent: { UUID: 'ProgrammableSwitchEvent' },
95
+ TemperatureDisplayUnits: { CELSIUS: 0, FAHRENHEIT: 1 },
96
+ };
97
+
98
+ return {
99
+ api: {
100
+ hap: {
101
+ Service: MockService,
102
+ Characteristic: MockCharacteristic,
103
+ HapStatusError: class HapStatusError extends Error {
104
+ constructor(public status: number) {
105
+ super();
106
+ }
107
+ },
108
+ HAPStatus: {
109
+ SERVICE_COMMUNICATION_FAILURE: 72,
110
+ },
111
+ },
112
+ },
113
+ deviceManager: {
114
+ getDevice: jest.fn(),
115
+ sendCommands: jest.fn(),
116
+ },
117
+ options: {
118
+ debug: false,
119
+ debugLevel: '',
120
+ },
121
+ getDeviceSchemaConfig: jest.fn(() => undefined),
122
+ };
123
+ };
124
+
125
+ // Create mock accessory
126
+ const createMockAccessory = (): any => ({
127
+ context: { deviceID: 'test-device-001' },
128
+ displayName: 'Test Air Conditioner',
129
+ services: [],
130
+ getService: jest.fn(),
131
+ addService: jest.fn(),
132
+ });
133
+
134
+ const createMockCharacteristic = () => {
135
+ const characteristic: any = {
136
+ getHandler: undefined as any,
137
+ setHandler: undefined as any,
138
+ onGet: jest.fn().mockImplementation(function (fn: any) {
139
+ characteristic.getHandler = fn;
140
+ return characteristic;
141
+ }),
142
+ onSet: jest.fn().mockImplementation(function (fn: any) {
143
+ characteristic.setHandler = fn;
144
+ return characteristic;
145
+ }),
146
+ updateValue: jest.fn().mockReturnThis(),
147
+ setProps: jest.fn().mockReturnThis(),
148
+ };
149
+ return characteristic;
150
+ };
151
+
152
+ const createMockService = () => {
153
+ const characteristics = new Map<string, any>();
154
+ const getCharacteristic = jest.fn((key: any) => {
155
+ const keyName = typeof key === 'string' ? key : JSON.stringify(key);
156
+ if (!characteristics.has(keyName)) {
157
+ characteristics.set(keyName, createMockCharacteristic());
158
+ }
159
+ return characteristics.get(keyName);
160
+ });
161
+ return {
162
+ getCharacteristic,
163
+ setCharacteristic: jest.fn().mockReturnThis(),
164
+ addOptionalCharacteristic: jest.fn(),
165
+ testCharacteristic: jest.fn(() => false),
166
+ characteristics,
167
+ };
168
+ };
169
+
170
+ describe('AirConditionerAccessory', () => {
171
+ let platform: any;
172
+ let accessory: any;
173
+ let device: TuyaDevice;
174
+ let airConditionerAccessory: AirConditionerAccessory;
175
+
176
+ beforeEach(() => {
177
+ platform = createMockPlatform();
178
+ accessory = createMockAccessory();
179
+ device = createMockDevice();
180
+
181
+ platform.deviceManager.getDevice.mockReturnValue(device);
182
+
183
+ // Setup mock services and characteristics
184
+ const mockHeaterCoolerService = {
185
+ getCharacteristic: jest.fn(),
186
+ setCharacteristic: jest.fn().mockReturnThis(),
187
+ addOptionalCharacteristic: jest.fn(),
188
+ testCharacteristic: jest.fn(() => false),
189
+ };
190
+
191
+ const mockHumidifierService = {
192
+ getCharacteristic: jest.fn(),
193
+ setCharacteristic: jest.fn().mockReturnThis(),
194
+ addOptionalCharacteristic: jest.fn(),
195
+ testCharacteristic: jest.fn(() => false),
196
+ };
197
+
198
+ const mockFanService = {
199
+ getCharacteristic: jest.fn(),
200
+ setCharacteristic: jest.fn().mockReturnThis(),
201
+ addOptionalCharacteristic: jest.fn(),
202
+ testCharacteristic: jest.fn(() => false),
203
+ };
204
+
205
+ const mockAccessoryInformationService = {
206
+ setCharacteristic: jest.fn().mockReturnThis(),
207
+ getCharacteristic: jest.fn(),
208
+ };
209
+
210
+ const mockBatteryService = {
211
+ getCharacteristic: jest.fn(),
212
+ setCharacteristic: jest.fn().mockReturnThis(),
213
+ };
214
+
215
+ // Create a service map for easier mocking
216
+ const serviceMap: any = {
217
+ 'HeaterCooler': mockHeaterCoolerService,
218
+ 'HumidifierDehumidifier': mockHumidifierService,
219
+ 'Fanv2': mockFanService,
220
+ 'AccessoryInformation': mockAccessoryInformationService,
221
+ 'Battery': mockBatteryService,
222
+ };
223
+
224
+ // Both getService and addService should return the same mock services
225
+ accessory.getService.mockImplementation((serviceType: any) => {
226
+ const serviceName = typeof serviceType === 'string' ? serviceType : serviceType?.UUID;
227
+ return serviceMap[serviceName] || mockAccessoryInformationService; // Default to AccessoryInformation
228
+ });
229
+
230
+ accessory.addService.mockImplementation((serviceType: any, ...args: any[]) => {
231
+ const serviceName = typeof serviceType === 'string' ? serviceType : serviceType?.UUID;
232
+ return serviceMap[serviceName] || mockAccessoryInformationService; // Default to AccessoryInformation
233
+ });
234
+
235
+ // Mock characteristic getters
236
+ const mockCharacteristic = {
237
+ onGet: jest.fn().mockReturnThis(),
238
+ onSet: jest.fn().mockReturnThis(),
239
+ updateValue: jest.fn().mockReturnThis(),
240
+ setProps: jest.fn().mockReturnThis(),
241
+ };
242
+
243
+ mockHeaterCoolerService.getCharacteristic.mockReturnValue(mockCharacteristic);
244
+ mockHumidifierService.getCharacteristic.mockReturnValue(mockCharacteristic);
245
+ mockFanService.getCharacteristic.mockReturnValue(mockCharacteristic);
246
+ mockAccessoryInformationService.getCharacteristic.mockReturnValue(mockCharacteristic);
247
+ mockBatteryService.getCharacteristic.mockReturnValue(mockCharacteristic);
248
+
249
+ // Store the service map for testing
250
+ (accessory as any).serviceMap = serviceMap;
251
+
252
+ airConditionerAccessory = new AirConditionerAccessory(platform, accessory);
253
+ });
254
+
255
+ describe('requiredSchema', () => {
256
+ test('should return required schema codes for AC', () => {
257
+ const required = airConditionerAccessory.requiredSchema();
258
+ expect(required).toBeDefined();
259
+ expect(Array.isArray(required)).toBe(true);
260
+ expect(required.length).toBeGreaterThan(0);
261
+ });
262
+
263
+ test('should include switch, mode, work_status, and temp_current', () => {
264
+ const required = airConditionerAccessory.requiredSchema();
265
+ expect(required).toContainEqual(['switch']);
266
+ expect(required).toContainEqual(['mode']);
267
+ });
268
+ });
269
+
270
+ describe('configureServices', () => {
271
+ test('should configure all three services (AC, Dehumidifier, Fan)', () => {
272
+ // Reset the mock to track new calls during configureServices
273
+ jest.clearAllMocks();
274
+
275
+ airConditionerAccessory.configureServices();
276
+
277
+ // Check that services are being configured (getService/addService will be called)
278
+ expect(accessory.getService).toHaveBeenCalled();
279
+ });
280
+
281
+ test('should configure main HeaterCooler service', () => {
282
+ airConditionerAccessory.configureServices();
283
+
284
+ const mainService = accessory.getService('HeaterCooler');
285
+ expect(mainService).toBeDefined();
286
+ });
287
+ });
288
+
289
+ describe('configureAirConditioner', () => {
290
+ test('should setup Active characteristic handlers', () => {
291
+ const mockService = {
292
+ getCharacteristic: jest.fn(),
293
+ setCharacteristic: jest.fn(),
294
+ };
295
+
296
+ jest.spyOn(airConditionerAccessory, 'mainService').mockReturnValue(mockService as any);
297
+
298
+ const mockCharacteristic = {
299
+ onGet: jest.fn().mockReturnThis(),
300
+ onSet: jest.fn().mockReturnThis(),
301
+ updateValue: jest.fn().mockReturnThis(),
302
+ setProps: jest.fn().mockReturnThis(),
303
+ };
304
+
305
+ mockService.getCharacteristic.mockReturnValue(mockCharacteristic);
306
+
307
+ airConditionerAccessory.configureAirConditioner();
308
+
309
+ expect(mockService.getCharacteristic).toHaveBeenCalled();
310
+ });
311
+
312
+ test('should handle Active get returns ACTIVE when device is on and in AC mode', async () => {
313
+ device.status = [
314
+ mockStatus('switch', true),
315
+ mockStatus('mode', 'cold'),
316
+ mockStatus('work_status', 'cooling'),
317
+ mockStatus('temp_current', 24),
318
+ mockStatus('temp_set', 22),
319
+ mockStatus('fan_speed_enum', 'auto'),
320
+ mockStatus('lock', false),
321
+ mockStatus('humidity_current', 60),
322
+ mockStatus('humidity_set', 60),
323
+ mockStatus('temp_unit_convert', 'C'),
324
+ ];
325
+
326
+ const activeStatus = airConditionerAccessory.getStatus('switch');
327
+ const modeStatus = airConditionerAccessory.getStatus('mode');
328
+
329
+ expect(activeStatus?.value).toBe(true);
330
+ expect(modeStatus?.value).toBe('cold');
331
+ });
332
+
333
+ test('should handle Active get returns INACTIVE when device is off', () => {
334
+ device.status[0] = mockStatus('switch', false); // Turn off
335
+
336
+ const activeStatus = airConditionerAccessory.getStatus('switch');
337
+ expect(activeStatus?.value).toBe(false);
338
+ });
339
+ });
340
+
341
+ describe('configureDehumidifier', () => {
342
+ test('should configure dehumidifier service when mode includes wet', () => {
343
+ const mockService = {
344
+ getCharacteristic: jest.fn(),
345
+ setCharacteristic: jest.fn(),
346
+ };
347
+
348
+ jest.spyOn(airConditionerAccessory, 'dehumidifierService').mockReturnValue(mockService as any);
349
+
350
+ const mockCharacteristic = {
351
+ onGet: jest.fn().mockReturnThis(),
352
+ onSet: jest.fn().mockReturnThis(),
353
+ updateValue: jest.fn().mockReturnThis(),
354
+ setProps: jest.fn().mockReturnThis(),
355
+ };
356
+
357
+ mockService.getCharacteristic.mockReturnValue(mockCharacteristic);
358
+
359
+ airConditionerAccessory.configureDehumidifier();
360
+
361
+ expect(mockService.getCharacteristic).toHaveBeenCalled();
362
+ });
363
+
364
+ test('should not configure dehumidifier when mode does not include wet', () => {
365
+ const deviceWithoutWet = createMockDevice({
366
+ schema: [
367
+ mockSchema('switch', 'Boolean', 'rw', {}),
368
+ mockSchema('mode', 'Enum', 'rw', { range: ['auto', 'cold', 'hot'] }),
369
+ ],
370
+ });
371
+ platform.deviceManager.getDevice.mockReturnValue(deviceWithoutWet);
372
+
373
+ const ac = new AirConditionerAccessory(platform, accessory);
374
+ const mockService = {
375
+ getCharacteristic: jest.fn(),
376
+ setCharacteristic: jest.fn(),
377
+ };
378
+
379
+ jest.spyOn(ac, 'dehumidifierService').mockReturnValue(mockService as any);
380
+
381
+ ac.configureDehumidifier();
382
+
383
+ // Should not configure if wet mode is not available
384
+ expect(mockService.getCharacteristic).not.toHaveBeenCalled();
385
+ });
386
+ });
387
+
388
+ describe('configureFan', () => {
389
+ test('should configure fan service when mode includes wind', () => {
390
+ const mockService = {
391
+ getCharacteristic: jest.fn(),
392
+ setCharacteristic: jest.fn(),
393
+ };
394
+
395
+ jest.spyOn(airConditionerAccessory, 'fanService').mockReturnValue(mockService as any);
396
+
397
+ const mockCharacteristic = {
398
+ onGet: jest.fn().mockReturnThis(),
399
+ onSet: jest.fn().mockReturnThis(),
400
+ updateValue: jest.fn().mockReturnThis(),
401
+ setProps: jest.fn().mockReturnThis(),
402
+ };
403
+
404
+ mockService.getCharacteristic.mockReturnValue(mockCharacteristic);
405
+
406
+ airConditionerAccessory.configureFan();
407
+
408
+ expect(mockService.getCharacteristic).toHaveBeenCalled();
409
+ });
410
+
411
+ test('should not configure fan when mode does not include wind', () => {
412
+ const deviceWithoutWind = createMockDevice({
413
+ schema: [
414
+ mockSchema('switch', 'Boolean', 'rw', {}),
415
+ mockSchema('mode', 'Enum', 'rw', { range: ['auto', 'cold', 'hot'] }),
416
+ ],
417
+ });
418
+ platform.deviceManager.getDevice.mockReturnValue(deviceWithoutWind);
419
+
420
+ const ac = new AirConditionerAccessory(platform, accessory);
421
+ const mockService = {
422
+ getCharacteristic: jest.fn(),
423
+ setCharacteristic: jest.fn(),
424
+ };
425
+
426
+ jest.spyOn(ac, 'fanService').mockReturnValue(mockService as any);
427
+
428
+ ac.configureFan();
429
+
430
+ // Should not configure if wind mode is not available
431
+ expect(mockService.getCharacteristic).not.toHaveBeenCalled();
432
+ });
433
+ });
434
+
435
+ describe('Characteristic handlers', () => {
436
+ test('HeaterCooler Active onGet/onSet should reflect AC active state and send commands', async () => {
437
+ const service = createMockService();
438
+ jest.spyOn(airConditionerAccessory, 'mainService').mockReturnValue(service as any);
439
+
440
+ airConditionerAccessory.configureAirConditioner();
441
+
442
+ const activeChar = service.characteristics.get(JSON.stringify(platform.api.hap.Characteristic.Active));
443
+ expect(activeChar).toBeDefined();
444
+ expect(activeChar.getHandler).toBeDefined();
445
+ expect(activeChar.setHandler).toBeDefined();
446
+
447
+ const activeValue = activeChar.getHandler();
448
+ expect(activeValue).toBe(platform.api.hap.Characteristic.Active.ACTIVE);
449
+
450
+ jest.useFakeTimers();
451
+ activeChar.setHandler(platform.api.hap.Characteristic.Active.ACTIVE);
452
+ jest.runAllTimers();
453
+ jest.useRealTimers();
454
+
455
+ expect(platform.deviceManager.sendCommands).toHaveBeenCalledWith('test-device-001', [{ code: 'switch', value: true }]);
456
+ expect(airConditionerAccessory.getStatus('switch')?.value).toBe(true);
457
+ });
458
+
459
+ test('TargetHeaterCoolerState onGet/onSet should map mode values correctly', async () => {
460
+ const service = createMockService();
461
+ jest.spyOn(airConditionerAccessory, 'mainService').mockReturnValue(service as any);
462
+
463
+ airConditionerAccessory.configureAirConditioner();
464
+
465
+ const targetChar = service.characteristics.get(JSON.stringify(platform.api.hap.Characteristic.TargetHeaterCoolerState));
466
+ expect(targetChar).toBeDefined();
467
+ expect(targetChar.getHandler).toBeDefined();
468
+ expect(targetChar.setHandler).toBeDefined();
469
+
470
+ device.status = device.status.map(status => status.code === 'mode' ? mockStatus('mode', 'hot') : status);
471
+ const targetValue = targetChar.getHandler();
472
+ expect(targetValue).toBe(platform.api.hap.Characteristic.TargetHeaterCoolerState.HEAT);
473
+
474
+ jest.useFakeTimers();
475
+ targetChar.setHandler(platform.api.hap.Characteristic.TargetHeaterCoolerState.COOL);
476
+ jest.runAllTimers();
477
+ jest.useRealTimers();
478
+
479
+ expect(platform.deviceManager.sendCommands).toHaveBeenCalledWith('test-device-001', [{ code: 'mode', value: 'cold' }]);
480
+ expect(airConditionerAccessory.getStatus('mode')?.value).toBe('cold');
481
+ });
482
+
483
+ test('CoolingThresholdTemperature onGet/onSet should respect auto mode limits', async () => {
484
+ const service = createMockService();
485
+ jest.spyOn(airConditionerAccessory, 'mainService').mockReturnValue(service as any);
486
+ airConditionerAccessory.configureAirConditioner();
487
+
488
+ const temperatureKey = platform.api.hap.Characteristic.CoolingThresholdTemperature;
489
+ const coolingChar = service.getCharacteristic(temperatureKey);
490
+ expect(coolingChar).toBeDefined();
491
+ expect(coolingChar.getHandler).toBeDefined();
492
+ expect(coolingChar.setHandler).toBeDefined();
493
+
494
+ device.status = device.status.map(status => status.code === 'mode' ? mockStatus('mode', 'auto') : status);
495
+ const getValue = coolingChar.getHandler();
496
+ expect(getValue).toBe(16);
497
+
498
+ jest.useFakeTimers();
499
+ coolingChar.setHandler(18);
500
+ jest.runAllTimers();
501
+ jest.useRealTimers();
502
+
503
+ expect(service.getCharacteristic(temperatureKey).updateValue).toHaveBeenCalledWith(16);
504
+ expect(airConditionerAccessory.getStatus('temp_set')?.value).toBe(22);
505
+ });
506
+
507
+ test('HeatingThresholdTemperature onGet/onSet should respect auto mode limits', async () => {
508
+ const service = createMockService();
509
+ jest.spyOn(airConditionerAccessory, 'mainService').mockReturnValue(service as any);
510
+ airConditionerAccessory.configureAirConditioner();
511
+
512
+ const temperatureKey = platform.api.hap.Characteristic.HeatingThresholdTemperature;
513
+ const heatingChar = service.getCharacteristic(temperatureKey);
514
+ expect(heatingChar).toBeDefined();
515
+ expect(heatingChar.getHandler).toBeDefined();
516
+ expect(heatingChar.setHandler).toBeDefined();
517
+
518
+ device.status = device.status.map(status => status.code === 'mode' ? mockStatus('mode', 'auto') : status);
519
+ const getValue = heatingChar.getHandler();
520
+ expect(getValue).toBe(30);
521
+
522
+ jest.useFakeTimers();
523
+ heatingChar.setHandler(25);
524
+ jest.runAllTimers();
525
+ jest.useRealTimers();
526
+
527
+ expect(service.getCharacteristic(temperatureKey).updateValue).toHaveBeenCalledWith(30);
528
+ expect(airConditionerAccessory.getStatus('temp_set')?.value).toBe(22);
529
+ });
530
+
531
+ test('CurrentHeaterCoolerState onGet should return correct operating state', () => {
532
+ const service = createMockService();
533
+ jest.spyOn(airConditionerAccessory, 'mainService').mockReturnValue(service as any);
534
+ airConditionerAccessory.configureAirConditioner();
535
+
536
+ const currentStateChar = service.characteristics.get(JSON.stringify(platform.api.hap.Characteristic.CurrentHeaterCoolerState));
537
+ expect(currentStateChar).toBeDefined();
538
+
539
+ device.status = device.status.map(status => status.code === 'work_status' ? mockStatus('work_status', 'heating') : status);
540
+ expect(currentStateChar.getHandler()).toBe(platform.api.hap.Characteristic.CurrentHeaterCoolerState.HEATING);
541
+
542
+ device.status = device.status.map(status => status.code === 'work_status' ? mockStatus('work_status', 'idle') : status);
543
+ expect(currentStateChar.getHandler()).toBe(platform.api.hap.Characteristic.CurrentHeaterCoolerState.INACTIVE);
544
+ });
545
+
546
+ test('Dehumidifier Active onGet/onSet should send wet mode commands', async () => {
547
+ const service = createMockService();
548
+ jest.spyOn(airConditionerAccessory, 'dehumidifierService').mockReturnValue(service as any);
549
+ airConditionerAccessory.configureDehumidifier();
550
+
551
+ const activeChar = service.characteristics.get(JSON.stringify(platform.api.hap.Characteristic.Active));
552
+ expect(activeChar).toBeDefined();
553
+ expect(activeChar.getHandler).toBeDefined();
554
+ expect(activeChar.setHandler).toBeDefined();
555
+
556
+ device.status = device.status.map(status => status.code === 'mode' ? mockStatus('mode', 'wet') : status);
557
+ const activeValue = activeChar.getHandler();
558
+ expect(activeValue).toBe(platform.api.hap.Characteristic.Active.ACTIVE);
559
+
560
+ jest.useFakeTimers();
561
+ activeChar.setHandler(platform.api.hap.Characteristic.Active.INACTIVE);
562
+ jest.runAllTimers();
563
+ jest.useRealTimers();
564
+
565
+ expect(platform.deviceManager.sendCommands).toHaveBeenCalledWith('test-device-001', [
566
+ { code: 'switch', value: false },
567
+ { code: 'mode', value: 'wet' },
568
+ ]);
569
+ expect(airConditionerAccessory.getStatus('switch')?.value).toBe(false);
570
+ });
571
+
572
+ test('Fan Active onGet/onSet should send wind mode commands', async () => {
573
+ const service = createMockService();
574
+ jest.spyOn(airConditionerAccessory, 'fanService').mockReturnValue(service as any);
575
+ airConditionerAccessory.configureFan();
576
+
577
+ const activeChar = service.characteristics.get(JSON.stringify(platform.api.hap.Characteristic.Active));
578
+ expect(activeChar).toBeDefined();
579
+ expect(activeChar.getHandler).toBeDefined();
580
+ expect(activeChar.setHandler).toBeDefined();
581
+
582
+ device.status = device.status.map(status => status.code === 'mode' ? mockStatus('mode', 'wind') : status);
583
+ const activeValue = activeChar.getHandler();
584
+ expect(activeValue).toBe(platform.api.hap.Characteristic.Active.ACTIVE);
585
+
586
+ jest.useFakeTimers();
587
+ activeChar.setHandler(platform.api.hap.Characteristic.Active.ACTIVE);
588
+ jest.runAllTimers();
589
+ jest.useRealTimers();
590
+
591
+ expect(platform.deviceManager.sendCommands).toHaveBeenCalledWith('test-device-001', [
592
+ { code: 'switch', value: true },
593
+ { code: 'mode', value: 'wind' },
594
+ ]);
595
+ expect(airConditionerAccessory.getStatus('switch')?.value).toBe(true);
596
+ });
597
+ });
598
+
599
+ describe('getSchema', () => {
600
+ test('should return schema for valid code', () => {
601
+ const schema = airConditionerAccessory.getSchema('switch');
602
+ expect(schema).toBeDefined();
603
+ expect(schema?.code).toBe('switch');
604
+ });
605
+
606
+ test('should return schema for alternative code names', () => {
607
+ // SCHEMA_CODE.FAN_SPEED_ENUM should map to 'fan_speed_enum'
608
+ const schema = airConditionerAccessory.getSchema('windspeed', 'fan_speed_enum');
609
+ expect(schema).toBeDefined();
610
+ expect(device.schema.some((s) => s.code === 'fan_speed_enum')).toBeTruthy();
611
+ expect(schema?.code).toBe('fan_speed_enum');
612
+ });
613
+
614
+ test('should return undefined for non-existent code', () => {
615
+ const schema = airConditionerAccessory.getSchema('non_existent_code');
616
+ expect(schema).toBeUndefined();
617
+ });
618
+
619
+ test('should be case-insensitive', () => {
620
+ const schema1 = airConditionerAccessory.getSchema('SWITCH');
621
+ const schema2 = airConditionerAccessory.getSchema('switch');
622
+ expect(schema1?.code).toBe(schema2?.code);
623
+ });
624
+ });
625
+
626
+ describe('getStatus', () => {
627
+ test('should return status for valid code', () => {
628
+ const status = airConditionerAccessory.getStatus('switch');
629
+ expect(status).toBeDefined();
630
+ expect(status?.code).toBe('switch');
631
+ expect(status?.value).toBe(true);
632
+ });
633
+
634
+ test('should return status for temperature', () => {
635
+ const status = airConditionerAccessory.getStatus('temp_current');
636
+ expect(status?.value).toBe(24);
637
+ });
638
+
639
+ test('should return undefined for non-existent code', () => {
640
+ const status = airConditionerAccessory.getStatus('non_existent');
641
+ expect(status).toBeUndefined();
642
+ });
643
+ });
644
+
645
+ describe('service methods', () => {
646
+ test('mainService should return HeaterCooler service', () => {
647
+ const service = airConditionerAccessory.mainService();
648
+ expect(service).toBeDefined();
649
+ });
650
+
651
+ test('dehumidifierService should return HumidifierDehumidifier service', () => {
652
+ const service = airConditionerAccessory.dehumidifierService();
653
+ expect(service).toBeDefined();
654
+ });
655
+
656
+ test('fanService should return Fanv2 service', () => {
657
+ const service = airConditionerAccessory.fanService();
658
+ expect(service).toBeDefined();
659
+ });
660
+ });
661
+
662
+ describe('device offline handling', () => {
663
+ test('should update characteristic when device status changes', () => {
664
+ device.status[0] = mockStatus('switch', false);
665
+
666
+ const status = airConditionerAccessory.getStatus('switch');
667
+ expect(status?.value).toBe(false);
668
+ });
669
+
670
+ test('should handle multiple mode values correctly', () => {
671
+ const modeSchema = airConditionerAccessory.getSchema('mode');
672
+ expect(modeSchema).toBeDefined();
673
+ const property = modeSchema?.property as any;
674
+ expect(property.range).toContain('auto');
675
+ expect(property.range).toContain('cold');
676
+ expect(property.range).toContain('hot');
677
+ });
678
+ });
679
+
680
+ describe('temperature configuration', () => {
681
+ test('should have correct temperature range', () => {
682
+ const schema = airConditionerAccessory.getSchema('temp_set');
683
+ expect(schema).toBeDefined();
684
+ const property = schema?.property as any;
685
+ expect(property.min).toBe(16);
686
+ expect(property.max).toBe(30);
687
+ });
688
+
689
+ test('should have correct humidity range', () => {
690
+ const schema = airConditionerAccessory.getSchema('humidity_set');
691
+ expect(schema).toBeDefined();
692
+ const property = schema?.property as any;
693
+ expect(property.min).toBe(30);
694
+ expect(property.max).toBe(80);
695
+ });
696
+ });
697
+
698
+ describe('mode switching', () => {
699
+ test('should support cold mode', () => {
700
+ device.status[1] = mockStatus('mode', 'cold');
701
+ const status = airConditionerAccessory.getStatus('mode');
702
+ expect(status?.value).toBe('cold');
703
+ });
704
+
705
+ test('should support hot mode', () => {
706
+ device.status[1] = mockStatus('mode', 'hot');
707
+ const status = airConditionerAccessory.getStatus('mode');
708
+ expect(status?.value).toBe('hot');
709
+ });
710
+
711
+ test('should support auto mode', () => {
712
+ device.status[1] = mockStatus('mode', 'auto');
713
+ const status = airConditionerAccessory.getStatus('mode');
714
+ expect(status?.value).toBe('auto');
715
+ });
716
+
717
+ test('should support wet (dehumidifier) mode', () => {
718
+ device.status[1] = mockStatus('mode', 'wet');
719
+ const status = airConditionerAccessory.getStatus('mode');
720
+ expect(status?.value).toBe('wet');
721
+ });
722
+
723
+ test('should support wind (fan) mode', () => {
724
+ device.status[1] = mockStatus('mode', 'wind');
725
+ const status = airConditionerAccessory.getStatus('mode');
726
+ expect(status?.value).toBe('wind');
727
+ });
728
+ });
729
+ });