homebridge-tuya-plus 3.1.2 → 3.2.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.
@@ -3,7 +3,7 @@ name: Bug report
3
3
  about: Create a report to help us improve
4
4
  title: ''
5
5
  labels: bug
6
- assignees: iRayanKhan
6
+ assignees: adrianjagielak
7
7
 
8
8
  ---
9
9
 
package/Readme.MD CHANGED
@@ -8,7 +8,6 @@
8
8
  # homebridge-tuya-plus
9
9
 
10
10
  [![npm](https://img.shields.io/npm/v/homebridge-tuya-plus.svg)](https://www.npmjs.com/package/homebridge-tuya-plus)
11
- [![npm](https://img.shields.io/npm/dt/homebridge-tuya-plus.svg)](https://www.npmjs.com/package/homebridge-tuya-plus)
12
11
 
13
12
 
14
13
  </span>
@@ -29,22 +28,22 @@ A community-maintained Homebridge plugin for controlling Tuya devices locally ov
29
28
  ## Supported Device Types
30
29
  > Click the number next to your device to find the possible DataPoint "DP" values, then add as needed to your config.
31
30
 
32
- * Air Conditioner<sup>[1](https://github.com/iRayanKhan/homebridge-tuya/wiki/Supported-Device-Types#air-conditioners)</sup>
31
+ * Air Conditioner<sup>[1](https://github.com/adrianjagielak/homebridge-tuya-plus/blob/main/wiki/Supported-Device-Types.md#air-conditioners)</sup>
33
32
  * Air Purifiers<sup>[2]()</sup>
34
- * Convectors<sup>[3](https://github.com/iRayanKhan/homebridge-tuya/wiki/Supported-Device-Types#heat-convectors)</sup>
35
- * Dehumidifers<sup>[4](https://github.com/iRayanKhan/homebridge-tuya/wiki/Supported-Device-Types)</sup>
36
- * Dimmers<sup>[5](https://github.com/iRayanKhan/homebridge-tuya/wiki/Supported-Device-Types#simple-dimmers)</sup>
37
- * Fan<sup>[6](https://github.com/iRayanKhan/homebridge-tuya/wiki/Supported-Device-Types)</sup>
38
- * Fan v2<sup>[7](https://github.com/iRayanKhan/homebridge-tuya/wiki/Supported-Device-Types)</sup>
39
- * Garages<sup>[8](https://github.com/iRayanKhan/homebridge-tuya/wiki/Supported-Device-Types#garage-doors)</sup>
40
- * Heaters<sup>[9](https://github.com/iRayanKhan/homebridge-tuya/wiki/Supported-Device-Types)</sup>
33
+ * Convectors<sup>[3](https://github.com/adrianjagielak/homebridge-tuya-plus/blob/main/wiki/Supported-Device-Types.md#heat-convectors)</sup>
34
+ * Dehumidifers<sup>[4](https://github.com/adrianjagielak/homebridge-tuya-plus/blob/main/wiki/Supported-Device-Types.md)</sup>
35
+ * Dimmers<sup>[5](https://github.com/adrianjagielak/homebridge-tuya-plus/blob/main/wiki/Supported-Device-Types.md#simple-dimmers)</sup>
36
+ * Fan<sup>[6](https://github.com/adrianjagielak/homebridge-tuya-plus/blob/main/wiki/Supported-Device-Types.md)</sup>
37
+ * Fan v2<sup>[7](https://github.com/adrianjagielak/homebridge-tuya-plus/blob/main/wiki/Supported-Device-Types.md)</sup>
38
+ * Garages<sup>[8](https://github.com/adrianjagielak/homebridge-tuya-plus/blob/main/wiki/Supported-Device-Types.md#garage-doors)</sup>
39
+ * Heaters<sup>[9](https://github.com/adrianjagielak/homebridge-tuya-plus/blob/main/wiki/Supported-Device-Types.md)</sup>
41
40
  * Lights
42
- * On/Off<sup>[10](https://github.com/iRayanKhan/homebridge-tuya/wiki/Supported-Device-Types)</sup>
43
- * Brightness<sup>[11](https://github.com/iRayanKhan/homebridge-tuya/wiki/Supported-Device-Types#tunable-white-light-bulbs)</sup>
44
- * Color<sup>[12](https://github.com/iRayanKhan/homebridge-tuya/wiki/Supported-Device-Types#white-and-color-light-bulbs)</sup> (Hue, Saturation, Adaptive Lighting)
45
- * Oil Diffusers<sup>[13](https://github.com/iRayanKhan/homebridge-tuya/wiki/Supported-Device-Types)</sup>
46
- * Outlets<sup>[14](https://github.com/iRayanKhan/homebridge-tuya/wiki/Supported-Device-Types#outlets)</sup>
47
- * Switches<sup>[15](https://github.com/iRayanKhan/homebridge-tuya/wiki/Supported-Device-Types)</sup>
41
+ * On/Off<sup>[10](https://github.com/adrianjagielak/homebridge-tuya-plus/blob/main/wiki/Supported-Device-Types.md)</sup>
42
+ * Brightness<sup>[11](https://github.com/adrianjagielak/homebridge-tuya-plus/blob/main/wiki/Supported-Device-Types.md#tunable-white-light-bulbs)</sup>
43
+ * Color<sup>[12](https://github.com/adrianjagielak/homebridge-tuya-plus/blob/main/wiki/Supported-Device-Types.md#white-and-color-light-bulbs)</sup> (Hue, Saturation, Adaptive Lighting)
44
+ * Oil Diffusers<sup>[13](https://github.com/adrianjagielak/homebridge-tuya-plus/blob/main/wiki/Supported-Device-Types.md)</sup>
45
+ * Outlets<sup>[14](https://github.com/adrianjagielak/homebridge-tuya-plus/blob/main/wiki/Supported-Device-Types.md#outlets)</sup>
46
+ * Switches<sup>[15](https://github.com/adrianjagielak/homebridge-tuya-plus/blob/main/wiki/Supported-Device-Types.md)</sup>
48
47
 
49
48
  Note: Motion, and other sensor types don't behave well with responce requests, so they will not be added.
50
49
 
package/bin/cli-find.js CHANGED
@@ -200,7 +200,7 @@ proxy.listen({port: program.port, sslCaDir: ROOT}, err => {
200
200
 
201
201
  QRCode.toString(`http://${address}:${port}/cert`, {type: 'terminal'}, function(err, url) {
202
202
  console.log(url);
203
- console.log('\nFollow the instructions on https://github.com/AMoo-Miki/homebridge-tuya-lan/wiki/Setup-Instructions');
203
+ console.log('\nFollow the instructions on https://github.com/adrianjagielak/homebridge-tuya-plus/blob/main/wiki/Get-Local-Keys-for-Your-Devices.md');
204
204
  console.log(`Proxy IP: ${address}`);
205
205
  console.log(`Proxy Port: ${port}\n\n`);
206
206
  })
package/config-example.MD CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
 
8
8
  ## Configurations
9
- The configuration parameters to enable your devices would need to be added to `platforms` section of the Homebridge configuration file. Examples of device configs can be found on the [Supported Device Types](https://github.com/iRayanKhan/homebridge-tuya/wiki/Supported-Device-Types) page. Check out the [Common Problems](https://github.com/iRayanKhan/homebridge-tuya/wiki/Common-Problems) page for solutions or raise an issue if you face problems.
9
+ The configuration parameters to enable your devices would need to be added to `platforms` section of the Homebridge configuration file. Examples of device configs can be found on the [Supported Device Types](https://github.com/adrianjagielak/homebridge-tuya-plus/blob/main/wiki/Supported-Device-Types.md) page. Check out the [Common Problems](https://github.com/adrianjagielak/homebridge-tuya-plus/blob/main/wiki/Common-Problems.md) page for solutions or raise an issue if you face problems.
10
10
  ```json5
11
11
  {
12
12
  ...
@@ -15,6 +15,7 @@ The configuration parameters to enable your devices would need to be added to `p
15
15
  /* The block you need to enable this plugin */
16
16
  {
17
17
  "platform": "TuyaLan",
18
+ "discoverTimeout": 60000,
18
19
  "devices": [
19
20
  /* The block you need for each device */
20
21
  {
@@ -33,11 +34,14 @@ The configuration parameters to enable your devices would need to be added to `p
33
34
  ...
34
35
  }
35
36
  ```
36
- #### Parameters
37
+ #### Device parameters
37
38
  * `name` (required) is anything you'd like to use to identify this device. You can always change the name from within the Home app.
38
- * `type` (required) is a case-insensitive identifier that lets the plugin know how to handle your device. Find your device `type` on the [Supported Device Type List](https://github.com/iRayanKhan/homebridge-tuya/wiki/Supported-Device-Types) page.
39
+ * `type` (required) is a case-insensitive identifier that lets the plugin know how to handle your device. Find your device `type` on the [Supported Device Type List](https://github.com/adrianjagielak/homebridge-tuya-plus/blob/main/wiki/Supported-Device-Types.md) page.
39
40
  * `manufacturer` and `model` are anything you like; the purpose of them is to help you identify the device.
40
41
  * `id` (required) and `key` (required) are parameters for your device. If you don't have them, follow the steps found on the [Setup Instructions](https://github.com/iRayanKgan/homebridge-tuya/wiki/Setup-Instructions) page.
41
- * `ip` needs to be added **_only_** if you face discovery issues. See [Common Problems](https://github.com/iRayanKhan/homebridge-tuya/wiki/Common-Problems) for more details.
42
+ * `ip` needs to be added **_only_** if you face discovery issues. See [Common Problems](https://github.com/adrianjagielak/homebridge-tuya-plus/blob/main/wiki/Common-Problems.md) for more details.
42
43
 
43
44
  > To find out which `id` belongs to which device, open the Tuya Smart app and check the `Device Information` by tapping the configuration icon of your devices; it is almost always a tiny icon on the top-right.
45
+
46
+ #### Other parameters
47
+ * `discoverTimeout` (optional) is the time period (millisecond) the plugin should spend for device auto-discovery. If unspecified, the default value is 60000.
@@ -2,11 +2,19 @@
2
2
  "pluginAlias": "TuyaLan",
3
3
  "pluginType": "platform",
4
4
  "singular": true,
5
- "headerDisplay": "<p align='center'><img height='60px' src='https://user-images.githubusercontent.com/3979615/78354049-dc7ff780-75f6-11ea-8026-2f8bf81d8331.png'></p>\n\nBefore using the Tuya plugin you need to discover your devices by following [these instructions](https://github.com/AMoo-Miki/homebridge-tuya-lan/wiki/Setup-Instructions).\n\n",
5
+ "headerDisplay": "<p align='center'><img height='60px' src='https://user-images.githubusercontent.com/3979615/78354049-dc7ff780-75f6-11ea-8026-2f8bf81d8331.png'></p>\n\nBefore using the Tuya plugin you need to discover your devices by following [these instructions](https://github.com/adrianjagielak/homebridge-tuya-plus/blob/main/wiki/Get-Local-Keys-for-Your-Devices.md).\n\n",
6
6
  "footerDisplay": "",
7
7
  "schema": {
8
8
  "type": "object",
9
9
  "properties": {
10
+ "discoverTimeout": {
11
+ "title": "Device IP auto-discovery timeout",
12
+ "type": "integer",
13
+ "minimum": 0,
14
+ "placeholder": "Timeout (millisecond) for device IP address discovery",
15
+ "default": 60000,
16
+ "required": false
17
+ },
10
18
  "devices": {
11
19
  "type": "array",
12
20
  "orderable": false,
@@ -133,7 +141,7 @@
133
141
  "id": {
134
142
  "type": "string",
135
143
  "title": "Tuya ID",
136
- "description": "If you don't have the Tuya ID or Key, follow the steps found on the <a href='https://github.com/AMoo-Miki/homebridge-tuya-lan/wiki/Setup-Instructions' target='_blank'>Setup Instructions</a> page.",
144
+ "description": "If you don't have the Tuya ID or Key, follow the steps found on the <a href='https://github.com/adrianjagielak/homebridge-tuya-plus/blob/main/wiki/Get-Local-Keys-for-Your-Devices.md' target='_blank'>Setup Instructions</a> page.",
137
145
  "required": true,
138
146
  "condition": {
139
147
  "functionBody": "return model.devices && model.devices[arrayIndices].type !== 'null';"
@@ -475,9 +483,9 @@
475
483
  "functionBody": "return model.devices && model.devices[arrayIndices] && ['SimpleHeater'].includes(model.devices[arrayIndices].type);"
476
484
  }
477
485
  },
478
- "targetTemperatureDivisor": {
486
+ "temperatureOffset": {
479
487
  "type": "integer",
480
- "placeholder": "1",
488
+ "placeholder": "0",
481
489
  "condition": {
482
490
  "functionBody": "return model.devices && model.devices[arrayIndices] && ['SimpleHeater'].includes(model.devices[arrayIndices].type);"
483
491
  }
package/index.js CHANGED
@@ -26,6 +26,7 @@ const DoorbellAccessory = require('./lib/DoorbellAccessory');
26
26
 
27
27
  const PLUGIN_NAME = 'homebridge-tuya';
28
28
  const PLATFORM_NAME = 'TuyaLan';
29
+ const DEFAULT_DISCOVER_TIMEOUT = 60000;
29
30
 
30
31
  const CLASS_DEF = {
31
32
  outlet: OutletAccessory,
@@ -154,7 +155,7 @@ class TuyaLan {
154
155
  this.log.warn('Failed to discover %s (%s) in time but will keep looking.', devices[deviceId].name, deviceId);
155
156
  }
156
157
  });
157
- }, 60000);
158
+ }, this.config.discoverTimeout ?? DEFAULT_DISCOVER_TIMEOUT);
158
159
  }
159
160
 
160
161
  registerPlatformAccessories(platformAccessories) {
@@ -55,7 +55,7 @@ class AirConditionerAccessory extends BaseAccessory {
55
55
  const {Service, Characteristic} = this.hap;
56
56
  const service = this.accessory.getService(Service.HeaterCooler);
57
57
  this._checkServiceName(service, this.device.context.name);
58
-
58
+
59
59
  this.dpActive = this._getCustomDP(this.device.context.dpActive) || '1';
60
60
  this.dpThreshold = this._getCustomDP(this.device.context.dpThreshold) || '2';
61
61
  this.dpCurrentTemperature = this._getCustomDP(this.device.context.dpCurrentTemperature) || '3';
@@ -64,7 +64,7 @@ class AirConditionerAccessory extends BaseAccessory {
64
64
  this.dpChildLock = this._getCustomDP(this.device.context.dpChildLock) || '6';
65
65
  this.dpTempUnits = this._getCustomDP(this.device.context.dpTempUnits) || '19';
66
66
  this.dpSwingMode = this._getCustomDP(this.device.context.dpSwingMode) || '104';
67
-
67
+
68
68
  const characteristicActive = service.getCharacteristic(Characteristic.Active)
69
69
  .updateValue(this._getActive(this.dpActive))
70
70
  .on('get', this.getActive.bind(this))
@@ -89,8 +89,8 @@ class AirConditionerAccessory extends BaseAccessory {
89
89
  .on('set', this.setTargetHeaterCoolerState.bind(this));
90
90
 
91
91
  const characteristicCurrentTemperature = service.getCharacteristic(Characteristic.CurrentTemperature)
92
- .updateValue(dps[this.dpSwingMode])
93
- .on('get', this.getState.bind(this, this.dpSwingMode));
92
+ .updateValue(dps[this.dpCurrentTemperature])
93
+ .on('get', this.getState.bind(this, this.dpCurrentTemperature));
94
94
 
95
95
  let characteristicSwingMode;
96
96
  if (!this.device.context.noSwing) {
@@ -154,18 +154,16 @@ class BaseAccessory {
154
154
  const min = this.device.context.minWhiteColor || 140;
155
155
  const max = this.device.context.maxWhiteColor || 400;
156
156
  const scale = this.device.context.scaleWhiteColor || 255;
157
- const adjustedValue = (value - 71) * (max - min) / (600 - 71) + 153;
158
- const convertedValue = Math.round((scale * min / (max - min)) * ((max / adjustedValue) - 1));
159
- return Math.min(scale, Math.max(0, convertedValue));
157
+ const result = Math.round(Math.max(Math.min(scale-(scale-1)/(max-min)*(value-min),scale),1));
158
+ return result;
160
159
  }
161
160
 
162
161
  convertColorTemperatureFromTuyaToHomeKit(value) {
163
162
  const min = this.device.context.minWhiteColor || 140;
164
163
  const max = this.device.context.maxWhiteColor || 400;
165
164
  const scale = this.device.context.scaleWhiteColor || 255;
166
- const unadjustedValue = max / ((value * (max - min) / (scale * min)) + 1);
167
- const convertedValue = Math.round((unadjustedValue - 153) * (600 - 71) / (max - min) + 71);
168
- return Math.min(600, Math.max(71, convertedValue));
165
+ const result = Math.round(Math.max(Math.min((scale-value)/((scale-1)/(max-min))+min,max),min));
166
+ return Math.min(600, Math.max(71, result));
169
167
  }
170
168
 
171
169
  convertColorFromHomeKitToTuya(value, dpValue) {
@@ -58,10 +58,10 @@ class RGBTWLightAccessory extends BaseAccessory {
58
58
 
59
59
  const characteristicColorTemperature = service.getCharacteristic(Characteristic.ColorTemperature)
60
60
  .setProps({
61
- minValue: 0,
62
- maxValue: 600
61
+ minValue: this.device.context.minWhiteColor,
62
+ maxValue: this.device.context.maxWhiteColor
63
63
  })
64
- .updateValue(dps[this.dpMode] === this.cmdWhite ? this.convertColorTemperatureFromTuyaToHomeKit(dps[this.dpColorTemperature]) : 0)
64
+ .updateValue(dps[this.dpMode] === this.cmdWhite ? this.convertColorTemperatureFromTuyaToHomeKit(dps[this.dpColorTemperature]) : this.device.context.minWhiteColor)
65
65
  .on('get', this.getColorTemperature.bind(this))
66
66
  .on('set', this.setColorTemperature.bind(this));
67
67
 
@@ -126,12 +126,12 @@ class RGBTWLightAccessory extends BaseAccessory {
126
126
  if (oldColor.b !== newColor.b) characteristicBrightness.updateValue(newColor.b);
127
127
  if (oldColor.h !== newColor.h) characteristicHue.updateValue(newColor.h);
128
128
 
129
- if (oldColor.s !== newColor.s) characteristicSaturation.updateValue(newColor.h);
129
+ if (oldColor.s !== newColor.s) characteristicSaturation.updateValue(newColor.s);
130
130
 
131
- if (characteristicColorTemperature.value !== 0) characteristicColorTemperature.updateValue(0);
131
+ if (characteristicColorTemperature.value !== this.device.context.minWhiteColor) characteristicColorTemperature.updateValue(this.device.context.minWhiteColor);
132
132
 
133
133
  } else if (changes[this.dpMode]) {
134
- if (characteristicColorTemperature.value !== 0) characteristicColorTemperature.updateValue(0);
134
+ if (characteristicColorTemperature.value !== this.device.context.minWhiteColor) characteristicColorTemperature.updateValue(this.device.context.minWhiteColor);
135
135
  }
136
136
  }
137
137
  });
@@ -148,7 +148,7 @@ class RGBTWLightAccessory extends BaseAccessory {
148
148
  }
149
149
 
150
150
  getColorTemperature(callback) {
151
- if (this.device.state[this.dpMode] !== this.cmdWhite) return callback(null, 0);
151
+ if (this.device.state[this.dpMode] !== this.cmdWhite) return callback(null, this.device.context.minWhiteColor);
152
152
  callback(null, this.convertColorTemperatureFromTuyaToHomeKit(this.device.state[this.dpColorTemperature]));
153
153
  }
154
154
 
@@ -160,12 +160,20 @@ class RGBTWLightAccessory extends BaseAccessory {
160
160
  this.characteristicHue.updateValue(newColor.h);
161
161
  this.characteristicSaturation.updateValue(newColor.s);
162
162
 
163
- this.setMultiState({[this.dpMode]: this.cmdWhite, [this.dpColorTemperature]: this.convertColorTemperatureFromHomeKitToTuya(value)}, callback);
163
+ if (this.device.state[this.dpMode] !== this.cmdWhite) {
164
+ this.setMultiState({[this.dpMode]: this.cmdWhite, [this.dpColorTemperature]: this.convertColorTemperatureFromHomeKitToTuya(value), [this.dpBrightness]: this.convertBrightnessFromHomeKitToTuya(this.convertColorFromTuyaToHomeKit(this.device.state[this.dpColor]).b)}, callback);
165
+ } else {
166
+ this.setMultiState({[this.dpMode]: this.cmdWhite, [this.dpColorTemperature]: this.convertColorTemperatureFromHomeKitToTuya(value)}, callback);
167
+ }
164
168
  }
165
169
 
166
170
  getHue(callback) {
167
- if (this.device.state[this.dpMode] === this.cmdWhite) return callback(null, 0);
168
- callback(null, this.convertColorFromTuyaToHomeKit(this.device.state[this.dpColor]).h);
171
+ if (this.device.state[this.dpMode] === this.cmdWhite) {
172
+ const prepareHue = this.convertHomeKitColorTemperatureToHomeKitColor(this.convertColorTemperatureFromTuyaToHomeKit(this.device.state[this.dpColorTemperature]));
173
+ callback(null, prepareHue.h);
174
+ } else {
175
+ callback(null, this.convertColorFromTuyaToHomeKit(this.device.state[this.dpColor]).h);
176
+ }
169
177
  }
170
178
 
171
179
  setHue(value, callback) {
@@ -173,8 +181,12 @@ class RGBTWLightAccessory extends BaseAccessory {
173
181
  }
174
182
 
175
183
  getSaturation(callback) {
176
- if (this.device.state[this.dpMode] === this.cmdWhite) return callback(null, 0);
177
- callback(null, this.convertColorFromTuyaToHomeKit(this.device.state[this.dpColor]).s);
184
+ if (this.device.state[this.dpMode] === this.cmdWhite) {
185
+ const prepareSaturation = this.convertHomeKitColorTemperatureToHomeKitColor(this.convertColorTemperatureFromTuyaToHomeKit(this.device.state[this.dpColorTemperature]));
186
+ callback(null, prepareSaturation.s);
187
+ } else {
188
+ callback(null, this.convertColorFromTuyaToHomeKit(this.device.state[this.dpColor]).s);
189
+ }
178
190
  }
179
191
 
180
192
  setSaturation(value, callback) {
@@ -208,10 +220,13 @@ class RGBTWLightAccessory extends BaseAccessory {
208
220
  } catch (ex) {}
209
221
  next();
210
222
  }, () => {
211
- this.characteristicColorTemperature.updateValue(0);
223
+ this.characteristicColorTemperature.updateValue(this.device.context.minWhiteColor);
212
224
  });
213
225
  };
214
226
 
227
+ if (this.device.state[this.dpMode] !== this.cmdColor)
228
+ this._pendingHueSaturation.props.b = this.convertBrightnessFromTuyaToHomeKit(this.device.state[this.dpBrightness]);
229
+
215
230
  const isSham = this._pendingHueSaturation.props.h === 0 && this._pendingHueSaturation.props.s === 0;
216
231
  const newValue = this.convertColorFromHomeKitToTuya(this._pendingHueSaturation.props);
217
232
  this._pendingHueSaturation = null;
@@ -7,6 +7,7 @@ class SimpleHeaterAccessory extends BaseAccessory {
7
7
 
8
8
  constructor(...props) {
9
9
  super(...props);
10
+ this.currentHeaterCoolerState = 0;
10
11
  }
11
12
 
12
13
  _registerPlatformAccessory() {
@@ -27,14 +28,14 @@ class SimpleHeaterAccessory extends BaseAccessory {
27
28
  this.dpCurrentTemperature = this._getCustomDP(this.device.context.dpCurrentTemperature) || '3';
28
29
  this.temperatureDivisor = parseInt(this.device.context.temperatureDivisor) || 1;
29
30
  this.thresholdTemperatureDivisor = parseInt(this.device.context.thresholdTemperatureDivisor) || 1;
30
- this.targetTemperatureDivisor = parseInt(this.device.context.targetTemperatureDivisor) || 1;
31
+ this.temperatureOffset = parseInt(this.device.context.temperatureOffset) || 0;
31
32
 
32
33
  const characteristicActive = service.getCharacteristic(Characteristic.Active)
33
34
  .updateValue(this._getActive(dps[this.dpActive]))
34
35
  .on('get', this.getActive.bind(this))
35
36
  .on('set', this.setActive.bind(this));
36
37
 
37
- service.getCharacteristic(Characteristic.CurrentHeaterCoolerState)
38
+ const characteristicCurrentHeaterCoolerState = service.getCharacteristic(Characteristic.CurrentHeaterCoolerState)
38
39
  .updateValue(this._getCurrentHeaterCoolerState(dps))
39
40
  .on('get', this.getCurrentHeaterCoolerState.bind(this));
40
41
 
@@ -75,11 +76,12 @@ class SimpleHeaterAccessory extends BaseAccessory {
75
76
 
76
77
  if (changes.hasOwnProperty(this.dpDesiredTemperature)) {
77
78
  if (characteristicHeatingThresholdTemperature.value !== changes[this.dpDesiredTemperature])
78
- characteristicHeatingThresholdTemperature.updateValue(changes[this.dpDesiredTemperature * this.targetTemperatureDivisor]);
79
+ characteristicHeatingThresholdTemperature.updateValue(this._getDividedState(changes[this.dpDesiredTemperature], this.thresholdTemperatureDivisor));
79
80
  }
80
81
 
81
82
  if (changes.hasOwnProperty(this.dpCurrentTemperature) && characteristicCurrentTemperature.value !== changes[this.dpCurrentTemperature]) characteristicCurrentTemperature.updateValue(this._getDividedState(changes[this.dpCurrentTemperature], this.temperatureDivisor));
82
83
 
84
+ characteristicCurrentHeaterCoolerState.updateValue(this._getCurrentHeaterCoolerState(state));
83
85
  this.log.info('SimpleHeater changed: ' + JSON.stringify(state));
84
86
  });
85
87
  }
@@ -113,16 +115,22 @@ class SimpleHeaterAccessory extends BaseAccessory {
113
115
  }
114
116
 
115
117
  getCurrentHeaterCoolerState(callback) {
116
- this.getState([this.dpActive], (err, dps) => {
117
- if (err) return callback(err);
118
-
119
- callback(null, this._getCurrentHeaterCoolerState(dps));
120
- });
118
+ callback(null, this.currentHeaterCoolerState);
121
119
  }
122
120
 
123
121
  _getCurrentHeaterCoolerState(dps) {
124
122
  const {Characteristic} = this.hap;
125
- return dps[this.dpActive] ? Characteristic.CurrentHeaterCoolerState.HEATING : Characteristic.CurrentHeaterCoolerState.INACTIVE;
123
+ if (dps[this.dpActive]) {
124
+ if (dps[this.dpCurrentTemperature] < dps[this.dpDesiredTemperature]) {
125
+ this.currentHeaterCoolerState = Characteristic.CurrentHeaterCoolerState.HEATING;
126
+ }
127
+ if (dps[this.dpCurrentTemperature] > dps[this.dpDesiredTemperature]) {
128
+ this.currentHeaterCoolerState = Characteristic.CurrentHeaterCoolerState.IDLE;
129
+ }
130
+ } else {
131
+ this.currentHeaterCoolerState = Characteristic.CurrentHeaterCoolerState.INACTIVE;
132
+ };
133
+ return this.currentHeaterCoolerState;
126
134
  }
127
135
 
128
136
  getTargetHeaterCoolerState(callback) {
@@ -139,7 +147,7 @@ class SimpleHeaterAccessory extends BaseAccessory {
139
147
  }
140
148
 
141
149
  setTargetThresholdTemperature(value, callback) {
142
- this.setState(this.dpDesiredTemperature, value * this.thresholdTemperatureDivisor, err => {
150
+ this.setState(this.dpDesiredTemperature, (value - this.temperatureOffset) * this.thresholdTemperatureDivisor, err => {
143
151
  if (err) return callback(err);
144
152
 
145
153
  if (this.characteristicHeatingThresholdTemperature) {
@@ -149,6 +157,10 @@ class SimpleHeaterAccessory extends BaseAccessory {
149
157
  callback();
150
158
  });
151
159
  }
160
+
161
+ _getDividedState(dp, divisor) {
162
+ return ((parseFloat(dp) / divisor) + this.temperatureOffset) || 0;
163
+ }
152
164
  }
153
165
 
154
166
  module.exports = SimpleHeaterAccessory;
@@ -1,6 +1,9 @@
1
1
  const BaseAccessory = require('./BaseAccessory');
2
2
  const async = require('async');
3
3
 
4
+ const DEFAULT_MIN_WHITE_COLOR = 0;
5
+ const DEFAULT_MAX_WHITE_COLOR = 600;
6
+
4
7
  class TWLightAccessory extends BaseAccessory {
5
8
  static getCategory(Categories) {
6
9
  return Categories.LIGHTBULB;
@@ -39,8 +42,8 @@ class TWLightAccessory extends BaseAccessory {
39
42
 
40
43
  const characteristicColorTemperature = service.getCharacteristic(Characteristic.ColorTemperature)
41
44
  .setProps({
42
- minValue: 0,
43
- maxValue: 600
45
+ minValue: this.device.context.minWhiteColor ?? DEFAULT_MIN_WHITE_COLOR,
46
+ maxValue: this.device.context.maxWhiteColor ?? DEFAULT_MAX_WHITE_COLOR
44
47
  })
45
48
  .updateValue(this.convertColorTemperatureFromTuyaToHomeKit(dps[this.dpColorTemperature]))
46
49
  .on('get', this.getColorTemperature.bind(this))
@@ -88,4 +91,4 @@ class TWLightAccessory extends BaseAccessory {
88
91
  }
89
92
  }
90
93
 
91
- module.exports = TWLightAccessory;
94
+ module.exports = TWLightAccessory;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "homebridge-tuya-plus",
3
- "version": "3.1.2",
3
+ "version": "3.2.0",
4
4
  "description": "A community-maintained Homebridge plugin for controlling Tuya devices locally over LAN. Includes new features, fixes, and updated device support.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -0,0 +1,20 @@
1
+ # Common Problems
2
+ > Find answers to previously answered questions, if this guide doesn't help you, please file a new issue.
3
+
4
+
5
+ ## Error getting keys with HOOBS/Config-Ui-X
6
+
7
+ HOOBS and Config-Ui-X both utilise port 8080. If you are not using port 8080, your network may have a device hosting something on that port. To fix this issue, change the discovery port. [First appeared](https://github.com/iRayanKhan/homebridge-tuya-platform/issues/4).
8
+
9
+ ## Device only partially works.
10
+
11
+ Your device may have different data points/commands than the plugin is defaulted to handle. To fix this issue, you currently have to manually edit the device type file for your specific device. Version 2.0 (Not in Beta yet), will allow you to fix this issue via the config.json file. [First appeared](https://github.com/iRayanKhan/homebridge-tuya-platform/issues/11)
12
+
13
+ ## Can't get device keys.
14
+
15
+ Tuya has updated their SDK to prevent the MITM method used to extract deviceID and keys. A guide is being compiled to fix this issue. Alternatively a website is being updated to add support for the old Tuya apps, to keep this method going. [First appeared](https://github.com/iRayanKhan/homebridge-tuya-platform/issues/13)
16
+
17
+ ## How to install the beta?
18
+
19
+ Currently there is no beta release that you can use via NPM. You can visit the RC branch, and git clone it from there. If you do not know how to Git Clone, a guide is being compiled. A new beta will be published soon, and this page will be constantly updated to reflect a new beta update, with instructions. [First appeared](No-ref-yet.com/)
20
+
@@ -0,0 +1,3 @@
1
+ ## Device Mapping
2
+
3
+ Your device may have different command to interact with this. This (W.I.P) guide will provide a detailed example for each device of all optional parameters per device, and an example of an implementation. To get your devices details, please refer to the schema of your device.
@@ -0,0 +1,77 @@
1
+ To get the local keys for your devices, you'll need an account on Tuya's IoT site. Don't be overwhelmed, there's a lot on that site but it's pretty easy to get what you need out of it. The free trial will give you enough access to the Tuya API to get the information you need, on up to 50 devices.
2
+
3
+ ## 1 - Tuya Smart App
4
+ As a prerequisite, add all of your devices to the Tuya Smart app ([iOS](https://apps.apple.com/au/app/tuya-smart/id1034649547) / [Android](https://play.google.com/store/apps/details?id=com.tuya.smart&hl=en_AU&gl=US&pli=1))
5
+
6
+ ## 2 - Sign up for an IoT account
7
+ Go to https://iot.tuya.com and click Sign Up
8
+
9
+ ![signup](https://user-images.githubusercontent.com/82495132/120384295-d2c95100-c2da-11eb-930d-75eaad628f4f.png)
10
+
11
+ * Fill in your information
12
+ * Make up a company name if you need to
13
+
14
+ ![signup-info](https://user-images.githubusercontent.com/82495132/120384453-099f6700-c2db-11eb-8cbc-20f3bc5bb17f.png)
15
+
16
+ * Check Agree to Terms
17
+ * Click Agree
18
+ * You'll be emailed a code, enter it
19
+
20
+ ## 3 - Sign in at iot.tuya.com
21
+
22
+ ## 4 - Create a cloud project
23
+ * Click through the intro
24
+ * On the sidebar click cloud, then projects
25
+ * Click Free Trial under TRIAL EDITION
26
+
27
+ ![freetrial](https://user-images.githubusercontent.com/82495132/120384723-60a53c00-c2db-11eb-8f79-f2a2f38dbc8a.png)
28
+
29
+ * Click Buy now in the new tab
30
+
31
+ ![buynow](https://user-images.githubusercontent.com/82495132/120384754-69960d80-c2db-11eb-802c-7067dff3274a.png)
32
+
33
+ * Close the Tuya Value Added Service tab/popup
34
+ * In the Tuya IoT Platform tab, click Subscribed to be taken back to Cloud -> Projects
35
+ * Click create
36
+
37
+ ![create](https://user-images.githubusercontent.com/82495132/120384789-7a468380-c2db-11eb-9770-8bdd41d65a3a.png)
38
+
39
+ * Make sure you pick smart home PAAS and the correct region, this affects whether you will be able to access your devices in the following steps. Click create
40
+
41
+ ![createproject](https://user-images.githubusercontent.com/82495132/120386067-04431c00-c2dd-11eb-93ff-27371397e1e2.png)
42
+
43
+ * Click Authorize for the recommended APIs
44
+
45
+ ![authorize](https://user-images.githubusercontent.com/82495132/120384846-87637280-c2db-11eb-8a3c-b2fd256f68d5.png)
46
+
47
+ ## 5 - Link devices registered in Tuya app to the IoT site
48
+ * From your project, click the link devices tab, then Link devices by App Account, then Add App Account
49
+
50
+ ![addappaccount](https://user-images.githubusercontent.com/82495132/120385095-d7dad000-c2db-11eb-9e4c-595af4502154.png)
51
+
52
+ * In the Tuya Smart app, click me at the bottom, then the scan button, then scan your QR code
53
+
54
+ ![scan2](https://user-images.githubusercontent.com/82495132/120385375-2f793b80-c2dc-11eb-9343-c579fc288962.png)
55
+
56
+ * Confirm the sign in
57
+
58
+ ## 6 - Get the keys for your devices
59
+ * Go to the device list tab
60
+ * Copy the device ID for your device
61
+
62
+ ![devices](https://user-images.githubusercontent.com/484912/204113199-a7ffd1c6-7f22-4295-a3a1-948ba15643b2.png)
63
+
64
+ * In the sidebar, hover over "Cloud" and click on "API Explorer"
65
+
66
+ ![apiexplorer](https://user-images.githubusercontent.com/484912/204113419-3d106164-eff8-4ff3-a4f5-c7f2a025de96.png)
67
+
68
+ * In the sidebar, search for "get device information" endpoint and click on the highlighted option. (It should be under "General Devices management" section. Note: there is also another endpoint called "Get _the_ device information" which will not work.)
69
+
70
+ * In the "device_id" text field, paste in the device ID you copied and click "Submit Request"
71
+
72
+ * In the "Response" section, there should be a property called `local_key` which is your local key.
73
+
74
+ ![localkey](https://user-images.githubusercontent.com/484912/204113337-81ebe3c3-5f3a-4854-a069-aa929bfb145d.png)
75
+
76
+ ## 7 - Video Tutorial
77
+ * [YouTube](https://youtu.be/FpY-xsY-pZ8)
package/wiki/Setup.md ADDED
@@ -0,0 +1,6 @@
1
+ To get your device's ID/Key, please watch [this](https://www.youtube.com/watch?v=oq0JL_wicKg
2
+ ) video.
3
+
4
+
5
+
6
+ Once you are done, add your devices info into your config. The other Wiki pages may help.