homebridge-tuya-without-developer-account 1.0.7 → 1.0.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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.8
4
+
5
+ - Added optional HomeKit Adaptive Lighting support for eligible Tuya lights.
6
+ - Added global `options.enableAdaptiveLighting` setting in the Homebridge custom UI.
7
+ - Added per-device `deviceOverrides[].adaptiveLighting.enabled` override support.
8
+ - Adaptive Lighting is enabled only when a light exposes both Brightness and a real ColorTemperature DP. RGB-only lights, brightness-only dimmers, switches, and outlets are skipped automatically.
9
+ - Added safer logging when Adaptive Lighting is disabled or skipped for unsupported lights.
10
+
3
11
  ## 1.0.7
4
12
 
5
13
  - Added Smart Pet Feeder support for `quick_feed`, `manual_feed`, `slow_feed`, `feed_state`, battery, and charging state.
package/README.md CHANGED
@@ -247,6 +247,31 @@ Fahrenheit display examples:
247
247
 
248
248
  HomeKit stores temperature characteristic metadata in Celsius. Do not enter Fahrenheit values in the plugin config.
249
249
 
250
+
251
+ ## Adaptive Lighting
252
+
253
+ Version 1.0.8 adds optional HomeKit Adaptive Lighting support. Enable it in the Homebridge plugin settings with **Enable Adaptive Lighting for eligible CCT/RGBCW lights**.
254
+
255
+ Adaptive Lighting is applied only to Tuya light accessories that expose both:
256
+
257
+ - Brightness
258
+ - A real white color-temperature datapoint, such as `temp_value` or `temp_value_v2`
259
+
260
+ The plugin automatically skips RGB-only lights, brightness-only dimmers such as DP10 dimmer plugs, outlets, switches, and devices without a real color-temperature datapoint. HomeKit automatic mode may send periodic color-temperature updates while Adaptive Lighting is active.
261
+
262
+ Advanced per-device override example:
263
+
264
+ ```json
265
+ {
266
+ "id": "YOUR_LIGHT_DEVICE_ID",
267
+ "adaptiveLighting": {
268
+ "enabled": true
269
+ }
270
+ }
271
+ ```
272
+
273
+ Set `enabled` to `false` to disable Adaptive Lighting for one device even when the global option is enabled.
274
+
250
275
  ## Troubleshooting
251
276
 
252
277
  ### Plugin starts from cache only and logs `Each device override must include an "id"`
@@ -229,3 +229,9 @@ Supported when Tuya exposes `master_mode`. Alarm-triggered state is detected fro
229
229
  ### Aroma Diffuser with Empty Schema
230
230
 
231
231
  If Tuya QR cloud returns an empty schema for the diffuser device, direct device control cannot be mapped. The plugin keeps diffuser Tuya scenes exposed and logs a clearer explanation.
232
+
233
+ ## Adaptive Lighting support
234
+
235
+ Adaptive Lighting is supported for eligible Tuya light accessories that expose both brightness and real white color-temperature datapoints, for example CCT, CW, or RGBCW lights.
236
+
237
+ Not eligible: simple on/off lights, outlets, switches, brightness-only dimmers, DP10 dimmer plugs, and RGB-only lights without a real white-temperature datapoint.
@@ -36,6 +36,12 @@
36
36
  "type": "string"
37
37
  }
38
38
  },
39
+ "enableAdaptiveLighting": {
40
+ "type": "boolean",
41
+ "title": "Enable Adaptive Lighting for eligible lights",
42
+ "description": "Optional. Enables HomeKit Adaptive Lighting only for Tuya lights that expose both brightness and real white color-temperature controls. RGB-only lights and dimmer plugs are skipped.",
43
+ "default": false
44
+ },
39
45
  "deviceOverrides": {
40
46
  "type": "array",
41
47
  "title": "Device Overrides",
@@ -57,8 +63,23 @@
57
63
  "default": false
58
64
  },
59
65
  "adaptiveLighting": {
60
- "type": "boolean",
61
- "title": "Enable Adaptive Lighting",
66
+ "title": "Adaptive Lighting Override",
67
+ "description": "Optional per-device override. Use enabled=true to force-enable for this device, or enabled=false to disable it even when global Adaptive Lighting is enabled.",
68
+ "oneOf": [
69
+ {
70
+ "type": "boolean",
71
+ "title": "Enabled"
72
+ },
73
+ {
74
+ "type": "object",
75
+ "properties": {
76
+ "enabled": {
77
+ "type": "boolean",
78
+ "title": "Enabled"
79
+ }
80
+ }
81
+ }
82
+ ],
62
83
  "default": false
63
84
  },
64
85
  "schema": {
@@ -194,6 +215,7 @@
194
215
  "expanded": false,
195
216
  "items": [
196
217
  "options.homeWhitelist",
218
+ "options.enableAdaptiveLighting",
197
219
  "options.deviceOverrides",
198
220
  "options.debug",
199
221
  "options.debugLevel"
package/dist/platform.js CHANGED
@@ -47,6 +47,7 @@ class TuyaPlatform {
47
47
  // Old Tuya IoT OpenAPI credentials, local LAN mode, username/password login, and hybrid mode are not accepted.
48
48
  this.config.mode = "cloud";
49
49
  this.options.projectType = "3";
50
+ this.options.enableAdaptiveLighting = this.options.enableAdaptiveLighting === true;
50
51
 
51
52
  if (!this.options.userCode || String(this.options.userCode).trim().length === 0) {
52
53
  this.log.error("[Tuya QR] Missing Tuya User Code. Open Homebridge UI → Plugins → Tuya without developer account for Homebridge → Settings, generate/scan the QR code, then save.");
@@ -150,6 +151,16 @@ class TuyaPlatform {
150
151
  delete item.alarm;
151
152
  }
152
153
  }
154
+ if (item.adaptiveLighting !== undefined) {
155
+ if (typeof item.adaptiveLighting === 'boolean') {
156
+ item.adaptiveLighting = { enabled: item.adaptiveLighting };
157
+ } else if (item.adaptiveLighting && typeof item.adaptiveLighting === 'object' && typeof item.adaptiveLighting.enabled === 'boolean') {
158
+ item.adaptiveLighting = { enabled: item.adaptiveLighting.enabled };
159
+ } else {
160
+ this.log.warn('[Tuya QR] Ignoring invalid adaptiveLighting override for id "%s". Use true/false or { enabled: true/false }.', id);
161
+ delete item.adaptiveLighting;
162
+ }
163
+ }
153
164
  seenIds.add(id);
154
165
  validOverrides.push(item);
155
166
  }
@@ -279,7 +290,8 @@ class TuyaPlatform {
279
290
  airConditioner: deviceConfig?.airConditioner ? JSON.stringify(deviceConfig.airConditioner) : undefined,
280
291
  petFeeder: deviceConfig?.petFeeder ? JSON.stringify(deviceConfig.petFeeder) : undefined,
281
292
  alarm: deviceConfig?.alarm ? JSON.stringify(deviceConfig.alarm) : undefined,
282
- adaptiveLighting: deviceConfig?.adaptiveLighting ?? false,
293
+ globalAdaptiveLighting: !!this.options.enableAdaptiveLighting,
294
+ adaptiveLighting: deviceConfig?.adaptiveLighting ? JSON.stringify(deviceConfig.adaptiveLighting) : undefined,
283
295
  };
284
296
  const { changed: configChanged } = this.configHash.hasConfigChanged(device.id, configToHash);
285
297
  device.configChanged = configChanged;
@@ -249,20 +249,53 @@ function configureLight(accessory, service, onSchema, brightSchema, tempSchema,
249
249
  }
250
250
  configureAdaptiveLighting(accessory, service, brightSchema, tempSchema);
251
251
  }
252
- function configureAdaptiveLighting(accessory, service, brightSchema, tempSchema) {
252
+ function getAdaptiveLightingOverride(config) {
253
+ if (!config || config.adaptiveLighting === undefined) {
254
+ return undefined;
255
+ }
256
+ if (typeof config.adaptiveLighting === 'boolean') {
257
+ return config.adaptiveLighting;
258
+ }
259
+ if (config.adaptiveLighting && typeof config.adaptiveLighting === 'object' && typeof config.adaptiveLighting.enabled === 'boolean') {
260
+ return config.adaptiveLighting.enabled;
261
+ }
262
+ return undefined;
263
+ }
264
+ function shouldEnableAdaptiveLighting(accessory) {
253
265
  const config = accessory.platform.getDeviceConfig(accessory.device);
254
- if (!config || config.adaptiveLighting !== true) {
266
+ const override = getAdaptiveLightingOverride(config);
267
+ if (override !== undefined) {
268
+ return override;
269
+ }
270
+ return accessory.platform.options.enableAdaptiveLighting === true;
271
+ }
272
+ function configureAdaptiveLighting(accessory, service, brightSchema, tempSchema) {
273
+ if (!shouldEnableAdaptiveLighting(accessory)) {
255
274
  accessory.log.info('Adaptive Lighting disabled.');
256
275
  return;
257
276
  }
258
- accessory.log.info('Adaptive Lighting enabled.');
259
277
  if (!brightSchema || !tempSchema) {
260
- accessory.log.warn('Adaptive Lighting not supported. Missing brightness or color temperature schema.');
278
+ accessory.log.info('Adaptive Lighting skipped: this light does not expose both brightness and a real color-temperature DP.');
279
+ return;
280
+ }
281
+ if (!service.testCharacteristic(accessory.Characteristic.Brightness) || !service.testCharacteristic(accessory.Characteristic.ColorTemperature)) {
282
+ accessory.log.info('Adaptive Lighting skipped: HomeKit Lightbulb service is missing Brightness or ColorTemperature.');
261
283
  return;
262
284
  }
263
285
  const { AdaptiveLightingController } = accessory.platform.api.hap;
264
- const controller = new AdaptiveLightingController(service);
265
- accessory.accessory.configureController(controller);
266
- accessory.adaptiveLightingController = controller;
286
+ if (!AdaptiveLightingController) {
287
+ accessory.log.warn('Adaptive Lighting skipped: this Homebridge/HAP-NodeJS version does not expose AdaptiveLightingController.');
288
+ return;
289
+ }
290
+ try {
291
+ const controller = new AdaptiveLightingController(service);
292
+ accessory.accessory.configureController(controller);
293
+ accessory.adaptiveLightingController = controller;
294
+ accessory.log.info('Adaptive Lighting enabled for eligible CCT/RGBCW light.');
295
+ }
296
+ catch (error) {
297
+ accessory.log.warn(`Adaptive Lighting setup failed: ${error instanceof Error ? error.message : error}`);
298
+ }
267
299
  }
300
+
268
301
  //# sourceMappingURL=Light.js.map
@@ -114,6 +114,19 @@
114
114
  </div>
115
115
  </div>
116
116
 
117
+
118
+ <div class="tuya-nodev-card">
119
+ <div class="tuya-nodev-title">Adaptive Lighting</div>
120
+ <p class="tuya-nodev-small mb-3">
121
+ Enable HomeKit Adaptive Lighting only for eligible Tuya lights that expose both brightness and real white color-temperature controls. RGB-only lights, dimmer plugs, switches, and outlets are skipped automatically.
122
+ </p>
123
+ <div class="form-check">
124
+ <input id="tuyaNodevAdaptiveLighting" class="form-check-input" type="checkbox">
125
+ <label class="form-check-label" for="tuyaNodevAdaptiveLighting">Enable Adaptive Lighting for eligible CCT/RGBCW lights</label>
126
+ </div>
127
+ <small class="form-text text-muted">HomeKit automatic mode may send color-temperature updates roughly once per minute while Adaptive Lighting is active.</small>
128
+ </div>
129
+
117
130
  <div class="tuya-nodev-card">
118
131
  <div class="tuya-nodev-title">Air Conditioner Temperature Overrides</div>
119
132
  <p class="tuya-nodev-small mb-3">
@@ -213,6 +226,7 @@
213
226
  cfg.options = cfg.options && typeof cfg.options === 'object' ? cfg.options : {};
214
227
  cfg.options.userCode = getUserCode();
215
228
  cfg.options.projectType = '3';
229
+ cfg.options.enableAdaptiveLighting = $('tuyaNodevAdaptiveLighting')?.checked === true;
216
230
  if (!Array.isArray(cfg.options.deviceOverrides)) {
217
231
  cfg.options.deviceOverrides = [];
218
232
  }
@@ -665,6 +679,7 @@
665
679
  ensureConfig();
666
680
  $('tuyaNodevName').value = currentConfig.name || 'Tuya without developer account';
667
681
  $('tuyaNodevUserCode').value = currentConfig.options?.userCode || '';
682
+ $('tuyaNodevAdaptiveLighting').checked = currentConfig.options?.enableAdaptiveLighting === true;
668
683
 
669
684
  if (homebridge.showSchemaForm) homebridge.showSchemaForm();
670
685
  window.homebridge.addEventListener('configChanged', (event) => {
@@ -675,6 +690,7 @@
675
690
  ensureConfig();
676
691
  if (block.name) $('tuyaNodevName').value = block.name;
677
692
  if (block.options?.userCode) $('tuyaNodevUserCode').value = block.options.userCode;
693
+ $('tuyaNodevAdaptiveLighting').checked = block.options?.enableAdaptiveLighting === true;
678
694
  renderAcOverrides();
679
695
  }
680
696
  });
@@ -684,6 +700,10 @@
684
700
  $('tuyaNodevClear').addEventListener('click', clearAuth);
685
701
  $('tuyaNodevSave').addEventListener('click', saveConfig);
686
702
  $('tuyaNodevName').addEventListener('input', syncConfigToUi);
703
+ $('tuyaNodevAdaptiveLighting').addEventListener('change', async () => {
704
+ await syncConfigToUi();
705
+ if (isAuthenticated) enableSaving();
706
+ });
687
707
  $('tuyaNodevUserCode').addEventListener('input', () => {
688
708
  isAuthenticated = false;
689
709
  disableSaving();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "homebridge-tuya-without-developer-account",
3
3
  "displayName": "Tuya without developer account for Homebridge",
4
- "version": "1.0.7",
4
+ "version": "1.0.8",
5
5
  "description": "Homebridge plugin for Tuya and Smart Life devices using QR cloud authentication without a Tuya IoT developer account.",
6
6
  "license": "MIT",
7
7
  "author": "Kosztyk",