homebridge-tuya-without-developer-account 1.0.4 → 1.0.6

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,18 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.6
4
+
5
+ - Fixed a Homebridge UI issue where clicking **Save Configuration** could leave the custom settings page spinner running indefinitely even when QR authentication data had already been saved.
6
+ - Added timeout handling around the custom UI save flow.
7
+ - Added post-save verification of the plugin config so users receive a clear success or recovery message instead of a permanent spinner.
8
+
9
+
10
+ ## 1.0.5
11
+
12
+ - Added support for DP10 / category `tgq` Tuya dimmer plugs that expose `switch_led` + `bright_value_v2`.
13
+ - Fixed dimmer validation so devices using `bright_value_v2` are exposed as HomeKit Lightbulb accessories with On and Brightness instead of being marked unsupported.
14
+ - Fixed dimmer on/off schema matching so `bright_value_v2` no longer incorrectly searches for `switch_v2` / `switch_led_v2`.
15
+
3
16
  ## 1.0.4
4
17
 
5
18
  - Added a Homebridge settings UI helper for air conditioner temperature overrides.
package/README.md CHANGED
@@ -4,6 +4,9 @@
4
4
 
5
5
  # Tuya without developer account for Homebridge
6
6
 
7
+ Current release: **1.0.6**
8
+
9
+
7
10
  A Homebridge platform plugin for Tuya and Smart Life devices that uses **Home Assistant-style Tuya QR Cloud Authentication**.
8
11
 
9
12
  This plugin is designed for users who want to add Tuya / Smart Life devices to HomeKit through Homebridge **without creating a Tuya IoT Developer Platform account** and without entering Tuya cloud project credentials.
@@ -305,3 +308,8 @@ Version 1.0.1 and later persist refreshed Tuya QR tokens back to the Homebridge
305
308
  ```
306
309
 
307
310
  If this still happens after upgrading, open the plugin settings, clear the saved authentication, generate a new QR code, scan it with the Tuya Smart or Smart Life app, save the configuration, and restart Homebridge. Also confirm the Homebridge host clock is synchronized, because Tuya signed requests depend on the current time.
311
+
312
+ ### DP10 Smart Dimmer Plug / `bright_value_v2` dimmers
313
+
314
+ Version **1.0.5** adds support for DP10-style Tuya dimmer plugs that expose `switch_led` and `bright_value_v2`. These are exposed in HomeKit as Lightbulb accessories with On and Brightness. If the accessory was previously shown as **Not Supported**, remove only that cached accessory in Homebridge UI and restart Homebridge after upgrading.
315
+
@@ -204,3 +204,13 @@ Most category code is pinyin abbreviation of Chinese name.
204
204
 
205
205
 
206
206
  For the undocumented product category, you can try override it to the most similar one. See [ADVANCED_OPTIONS.md](./ADVANCED_OPTIONS.md).
207
+
208
+ ### DP10 / Treatlife Smart Dimmer Plug
209
+
210
+ Supported from **v1.0.5**. These devices normally report category `tgq` and expose:
211
+
212
+ - `switch_led` for On/Off
213
+ - `bright_value_v2` for Brightness
214
+
215
+ They are exposed to HomeKit as a Lightbulb with On and Brightness. After upgrading from an older version where the device showed as unsupported, remove the affected cached accessory from Homebridge UI and restart Homebridge.
216
+
@@ -9,7 +9,7 @@ const Name_1 = require("./characteristic/Name");
9
9
  const On_1 = require("./characteristic/On");
10
10
  const SCHEMA_CODE = {
11
11
  ON: ['switch', 'switch_led', 'switch_1', 'switch_led_1'],
12
- BRIGHTNESS: ['bright_value', 'bright_value_1'],
12
+ BRIGHTNESS: ['bright_value', 'bright_value_v2', 'bright_value_1', 'bright_value_2', 'brightness'],
13
13
  };
14
14
  class DimmerAccessory extends BaseAccessory_1.default {
15
15
  requiredSchema() {
@@ -28,10 +28,31 @@ class DimmerAccessory extends BaseAccessory_1.default {
28
28
  const service = this.accessory.getService(_schema.code)
29
29
  || this.accessory.addService(this.Service.Lightbulb, name, _schema.code);
30
30
  (0, Name_1.configureName)(this, service, name);
31
- (0, On_1.configureOn)(this, service, this.getSchema('switch' + suffix, 'switch_led' + suffix));
31
+ const onSchema = this.resolveOnSchemaForBrightness(suffix);
32
+ if (!onSchema) {
33
+ this.log.warn(`No on/off schema found for brightness DP ${_schema.code}. Tried switch/switch_led variants.`);
34
+ }
35
+ (0, On_1.configureOn)(this, service, onSchema);
32
36
  this.configureBrightness(service, suffix);
33
37
  }
34
38
  }
39
+
40
+ resolveOnSchemaForBrightness(suffix) {
41
+ const candidates = [];
42
+ if (suffix) {
43
+ candidates.push('switch' + suffix, 'switch_led' + suffix);
44
+ }
45
+ // bright_value_v2 is a schema generation/version marker, not a separate channel suffix.
46
+ // Devices such as the Treatlife/DP10 Smart dimmer Plug expose:
47
+ // switch_led + bright_value_v2
48
+ // The older logic looked for switch_v2/switch_led_v2 and marked the device unsupported.
49
+ if (suffix === '_v2') {
50
+ candidates.push('switch_led', 'switch');
51
+ }
52
+ candidates.push('switch', 'switch_led', 'switch_1', 'switch_led_1');
53
+ return this.getSchema(...candidates);
54
+ }
55
+
35
56
  configureBrightness(service, suffix) {
36
57
  const schema = this.getSchema('bright_value' + suffix);
37
58
  if (!schema) {
@@ -554,15 +554,92 @@
554
554
  }
555
555
  }
556
556
 
557
+
558
+ function delay(ms) {
559
+ return new Promise((resolve) => setTimeout(resolve, ms));
560
+ }
561
+
562
+ async function withTimeout(promise, timeoutMs, timeoutMessage) {
563
+ let timer;
564
+ try {
565
+ return await Promise.race([
566
+ promise,
567
+ new Promise((_, reject) => {
568
+ timer = setTimeout(() => reject(new Error(timeoutMessage)), timeoutMs);
569
+ }),
570
+ ]);
571
+ } finally {
572
+ if (timer) {
573
+ clearTimeout(timer);
574
+ }
575
+ }
576
+ }
577
+
578
+ async function verifySavedConfig(userCode) {
579
+ const blocks = await withTimeout(
580
+ homebridge.getPluginConfig(),
581
+ 8000,
582
+ 'Configuration save timed out while verifying the saved plugin config.'
583
+ );
584
+ const block = Array.isArray(blocks) && blocks.length > 0 ? blocks[0] : blocks;
585
+ return !!(block && block.platform === PLATFORM && block.options && block.options.userCode === userCode);
586
+ }
587
+
557
588
  async function saveConfig() {
558
589
  if (!isAuthenticated) {
559
590
  setStatus('Scan and approve the QR code before saving.', 'warning');
560
591
  return;
561
592
  }
593
+
594
+ const userCode = getUserCode();
595
+ if (!userCode) {
596
+ setStatus('User Code is required before saving.', 'warning');
597
+ return;
598
+ }
599
+
562
600
  try {
563
601
  homebridge.showSpinner();
564
- await syncConfigToUi();
565
- await homebridge.savePluginConfig();
602
+ $('tuyaNodevSave').disabled = true;
603
+
604
+ await withTimeout(
605
+ syncConfigToUi(),
606
+ 8000,
607
+ 'Timed out while preparing the plugin configuration for saving.'
608
+ );
609
+
610
+ // Some Homebridge UI versions have been observed to save the config but never resolve
611
+ // savePluginConfig(), which leaves the custom UI spinner running forever. Timeout the
612
+ // UI call, then verify the saved config before showing the final result.
613
+ let saveTimedOut = false;
614
+ try {
615
+ await withTimeout(
616
+ homebridge.savePluginConfig(),
617
+ 15000,
618
+ 'Homebridge UI did not finish the save request in time.'
619
+ );
620
+ } catch (e) {
621
+ saveTimedOut = true;
622
+ }
623
+
624
+ let verified = false;
625
+ try {
626
+ await delay(750);
627
+ verified = await verifySavedConfig(userCode);
628
+ } catch (e) {
629
+ verified = false;
630
+ }
631
+
632
+ if (saveTimedOut && !verified) {
633
+ throw new Error('Save did not complete. The QR auth token is saved, but the plugin configuration could not be verified. Close this window, refresh Homebridge UI, and check whether the config was saved.');
634
+ }
635
+
636
+ if (saveTimedOut && verified) {
637
+ const message = 'Configuration appears to be saved, but Homebridge UI did not return a save confirmation. Close this settings window and restart Homebridge.';
638
+ homebridge.toast.success(message, 'Tuya');
639
+ setStatus(message, 'success');
640
+ return;
641
+ }
642
+
566
643
  homebridge.toast.success('Configuration saved. Restart Homebridge to load devices.', 'Tuya');
567
644
  setStatus('Configuration saved. Restart Homebridge to load devices.', 'success');
568
645
  } catch (e) {
@@ -570,6 +647,9 @@
570
647
  homebridge.toast.error(e.message || 'Failed to save configuration.', 'Tuya');
571
648
  } finally {
572
649
  homebridge.hideSpinner();
650
+ if (isAuthenticated) {
651
+ $('tuyaNodevSave').disabled = false;
652
+ }
573
653
  }
574
654
  }
575
655
 
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.4",
4
+ "version": "1.0.6",
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",