@homebridge-plugins/homebridge-tuya 2.7.2-beta.0 → 2.7.2-beta.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.
@@ -4,8 +4,23 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const BaseAccessory_1 = __importDefault(require("./BaseAccessory"));
7
+ const CurrentRelativeHumidity_1 = require("./characteristic/CurrentRelativeHumidity");
8
+ const CurrentTemperature_1 = require("./characteristic/CurrentTemperature");
9
+ // Standard (indoor / main unit) DPs of the qxj instruction set.
10
+ const SCHEMA_CODE = {
11
+ CURRENT_TEMP: ['temp_current', 'va_temperature'],
12
+ CURRENT_HUMIDITY: ['humidity_value', 'va_humidity'],
13
+ };
7
14
  class TemperatureHumiditySensorAccessory extends BaseAccessory_1.default {
8
15
  configureServices() {
16
+ const tempSchema = this.getSchema(...SCHEMA_CODE.CURRENT_TEMP);
17
+ if (tempSchema) {
18
+ (0, CurrentTemperature_1.configureCurrentTemperature)(this, this.getMainService(this.Service.TemperatureSensor), tempSchema);
19
+ }
20
+ const humiditySchema = this.getSchema(...SCHEMA_CODE.CURRENT_HUMIDITY);
21
+ if (humiditySchema) {
22
+ (0, CurrentRelativeHumidity_1.configureCurrentRelativeHumidity)(this, this.getMainService(this.Service.HumiditySensor), humiditySchema);
23
+ }
9
24
  const { temperatureSchemas, humiditySchemas } = this.getDynamicSchemaCodes();
10
25
  temperatureSchemas.forEach((schema, index) => {
11
26
  const serviceName = `Temperature Sensor ${index + 1}`;
@@ -40,6 +55,11 @@ class TemperatureHumiditySensorAccessory extends BaseAccessory_1.default {
40
55
  });
41
56
  });
42
57
  }
58
+ // The service without subtype; getService(type) could return one of the per-channel services instead.
59
+ getMainService(type) {
60
+ return this.accessory.services.find(service => service.UUID === type.UUID && !service.subtype)
61
+ || this.accessory.addService(type);
62
+ }
43
63
  getDynamicSchemaCodes() {
44
64
  const temperatureSchemas = [];
45
65
  const humiditySchemas = [];
@@ -1 +1 @@
1
- {"version":3,"file":"WeatherStationAccessory.js","sourceRoot":"","sources":["../../src/accessory/WeatherStationAccessory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"WeatherStationAccessory.js","sourceRoot":"","sources":["../../src/accessory/WeatherStationAccessory.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.7.2-beta.0",
4
+ "version": "2.7.2-beta.1",
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,186 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { describe, expect, test, beforeEach, jest } from '@jest/globals';
3
+
4
+ import WeatherStationAccessory from '../../src/accessory/WeatherStationAccessory';
5
+ import TuyaDevice, { TuyaDeviceSchemaMode, TuyaDeviceSchemaType } from '../../src/device/TuyaDevice';
6
+ import { initLogger } from '../../src/util/Logger';
7
+
8
+ const integerSchema = (code: string, unit: string, min: number, max: number, scale: number) => ({
9
+ code,
10
+ mode: TuyaDeviceSchemaMode.READ_ONLY,
11
+ type: TuyaDeviceSchemaType.Integer,
12
+ property: { unit, min, max, scale, step: 1 },
13
+ });
14
+
15
+ // Schema of a Tuya "LED temperature and humidity alarm clock" (category `qxj`), standard DPs only.
16
+ const CLOCK_SCHEMA = [
17
+ integerSchema('temp_current', '℃', -100, 600, 1),
18
+ integerSchema('humidity_value', '%', 0, 100, 0),
19
+ { code: 'volume', mode: TuyaDeviceSchemaMode.READ_WRITE, type: TuyaDeviceSchemaType.Enum, property: { range: ['mute', 'low'] } },
20
+ ];
21
+ const CLOCK_STATUS = [
22
+ { code: 'temp_current', value: 304 },
23
+ { code: 'humidity_value', value: 64 },
24
+ { code: 'volume', value: 'low' },
25
+ ];
26
+
27
+ // Multi-channel weather station: per-channel outdoor sensor DPs.
28
+ const CHANNEL_SCHEMA = [
29
+ integerSchema('ch1_ToutCh', '℃', -400, 800, 1),
30
+ integerSchema('ch1_HoutCh', '%', 0, 100, 0),
31
+ ];
32
+ const CHANNEL_STATUS = [
33
+ { code: 'ch1_ToutCh', value: 125 },
34
+ { code: 'ch1_HoutCh', value: 88 },
35
+ ];
36
+
37
+ describe('WeatherStationAccessory', () => {
38
+
39
+ let services: any[];
40
+ let mockAccessory: any;
41
+ let mockPlatform: any;
42
+ let device: TuyaDevice;
43
+
44
+ const Service = {
45
+ TemperatureSensor: { UUID: 'TemperatureSensor' },
46
+ HumiditySensor: { UUID: 'HumiditySensor' },
47
+ AccessoryInformation: { UUID: 'AccessoryInformation' },
48
+ Battery: { UUID: 'Battery' },
49
+ };
50
+
51
+ const makeService = (type: any, subtype?: string) => {
52
+ const characteristics = new Map<any, any>();
53
+ return {
54
+ UUID: type.UUID,
55
+ displayName: `${type.UUID}`,
56
+ subtype,
57
+ characteristics: [] as any[],
58
+ getCharacteristic: jest.fn(function(this: any, characteristicType: any) {
59
+ let characteristic = characteristics.get(characteristicType);
60
+ if (!characteristic) {
61
+ characteristic = {
62
+ type: characteristicType,
63
+ value: null,
64
+ getHandler: undefined,
65
+ onGet: jest.fn((handler: any) => (characteristic.getHandler = handler, characteristic)),
66
+ onSet: jest.fn(() => characteristic),
67
+ setProps: jest.fn(() => characteristic),
68
+ updateValue: jest.fn((value: any) => (characteristic.value = value, characteristic)),
69
+ };
70
+ characteristics.set(characteristicType, characteristic);
71
+ this.characteristics.push(characteristic);
72
+ }
73
+ return characteristic;
74
+ }),
75
+ setCharacteristic: jest.fn(function(this: any) {
76
+ return this;
77
+ }),
78
+ addOptionalCharacteristic: jest.fn(),
79
+ testCharacteristic: jest.fn(() => true),
80
+ };
81
+ };
82
+
83
+ const createDevice = (schema: any[], status: any[]) => new TuyaDevice({
84
+ id: 'qxj-device-id',
85
+ uuid: 'qxj-uuid',
86
+ name: 'Clock',
87
+ online: true,
88
+ owner_id: 'owner-1',
89
+ product_id: 'qxj-product',
90
+ product_name: 'LED temperature and humidity alarm clock',
91
+ category: 'qxj',
92
+ sub: false,
93
+ schema,
94
+ status,
95
+ } as any);
96
+
97
+ beforeEach(() => {
98
+ services = [];
99
+
100
+ const hap = {
101
+ Service,
102
+ Characteristic: {
103
+ CurrentTemperature: 'CurrentTemperature',
104
+ CurrentRelativeHumidity: 'CurrentRelativeHumidity',
105
+ StatusActive: 'StatusActive',
106
+ Manufacturer: 'Manufacturer',
107
+ Model: 'Model',
108
+ Name: 'Name',
109
+ ConfiguredName: 'ConfiguredName',
110
+ SerialNumber: 'SerialNumber',
111
+ ProgrammableSwitchEvent: { UUID: 'ProgrammableSwitchEvent' },
112
+ },
113
+ };
114
+
115
+ const noop = () => undefined;
116
+ mockPlatform = {
117
+ api: { hap },
118
+ options: { debug: false },
119
+ deviceManager: { getDevice: jest.fn(() => device), sendCommands: jest.fn() },
120
+ getDeviceConfig: jest.fn(() => undefined),
121
+ getDeviceSchemaConfig: jest.fn(() => undefined),
122
+ log: { info: noop, warn: noop, error: noop, debug: noop },
123
+ };
124
+ initLogger(mockPlatform.log);
125
+
126
+ mockAccessory = {
127
+ UUID: 'qxj-uuid',
128
+ displayName: 'Clock',
129
+ context: { deviceID: 'qxj-device-id' },
130
+ services,
131
+ getService: jest.fn((type: any) => services.find(s => s.UUID === type.UUID)),
132
+ getServiceById: jest.fn((type: any, subtype: string) => services.find(s => s.UUID === type.UUID && s.subtype === subtype)),
133
+ addService: jest.fn((type: any, _name?: string, subtype?: string) => {
134
+ const service = makeService(type, subtype);
135
+ services.push(service);
136
+ return service;
137
+ }),
138
+ removeService: jest.fn(),
139
+ };
140
+ });
141
+
142
+ const setup = (schema: any[], status: any[]) => {
143
+ device = createDevice(schema, status);
144
+ const accessory = new WeatherStationAccessory(mockPlatform as any, mockAccessory as any);
145
+ accessory.configureServices();
146
+ return accessory;
147
+ };
148
+
149
+ const find = (type: string, subtype?: string) => services.filter(s => s.UUID === type && s.subtype === subtype);
150
+ const read = (type: string, subtype: string | undefined, characteristicType: string) =>
151
+ find(type, subtype)[0]?.getCharacteristic(characteristicType).getHandler();
152
+
153
+ test('standard temp_current / humidity_value are exposed (clock with no channel DPs)', () => {
154
+ setup(CLOCK_SCHEMA, CLOCK_STATUS.map(s => ({ ...s })));
155
+
156
+ expect(find('TemperatureSensor')).toHaveLength(1);
157
+ expect(find('HumiditySensor')).toHaveLength(1);
158
+ expect(read('TemperatureSensor', undefined, 'CurrentTemperature')).toBe(30.4);
159
+ expect(read('HumiditySensor', undefined, 'CurrentRelativeHumidity')).toBe(64);
160
+ });
161
+
162
+ test('multi-channel station without standard DPs is unchanged', () => {
163
+ setup(CHANNEL_SCHEMA, CHANNEL_STATUS.map(s => ({ ...s })));
164
+
165
+ expect(find('TemperatureSensor')).toHaveLength(0);
166
+ expect(find('HumiditySensor')).toHaveLength(0);
167
+ expect(read('TemperatureSensor', 'temperature_sensor_1', 'CurrentTemperature')).toBe(12.5);
168
+ expect(read('HumiditySensor', 'humidity_sensor_1', 'CurrentRelativeHumidity')).toBe(88);
169
+ });
170
+
171
+ test('main unit and channels get separate services, also with cached channel services', () => {
172
+ // Restored from cache: channel services already exist before the main-unit ones.
173
+ services.push(makeService(Service.TemperatureSensor, 'temperature_sensor_1'));
174
+ services.push(makeService(Service.HumiditySensor, 'humidity_sensor_1'));
175
+
176
+ setup([...CLOCK_SCHEMA, ...CHANNEL_SCHEMA], [...CLOCK_STATUS, ...CHANNEL_STATUS].map(s => ({ ...s })));
177
+
178
+ expect(services.filter(s => s.UUID === 'TemperatureSensor')).toHaveLength(2);
179
+ expect(services.filter(s => s.UUID === 'HumiditySensor')).toHaveLength(2);
180
+ expect(read('TemperatureSensor', undefined, 'CurrentTemperature')).toBe(30.4);
181
+ expect(read('HumiditySensor', undefined, 'CurrentRelativeHumidity')).toBe(64);
182
+ expect(read('TemperatureSensor', 'temperature_sensor_1', 'CurrentTemperature')).toBe(12.5);
183
+ expect(read('HumiditySensor', 'humidity_sensor_1', 'CurrentRelativeHumidity')).toBe(88);
184
+ });
185
+
186
+ });