homebridge-tuya-without-developer-account 1.0.1 → 1.0.2

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,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.2
4
+
5
+ - Fixed startup abort when Homebridge UI saves an empty or incomplete `deviceOverrides` row. Invalid override rows without `id` are now skipped with a warning instead of stopping QR cloud startup.
6
+ - Duplicate device override IDs are now ignored safely, keeping the first valid entry.
7
+ - Invalid or duplicate schema override entries are now skipped with warnings instead of blocking Homebridge startup.
8
+
3
9
  ## 1.0.1
4
10
 
5
11
  - Fixes repeated `code=-9999999, msg=sign invalid` errors caused by incomplete token expiry handling and non-persistent token refreshes.
package/README.md CHANGED
@@ -192,6 +192,11 @@ Use `
192
192
 
193
193
  ## Troubleshooting
194
194
 
195
+ ### Plugin starts from cache only and logs `Each device override must include an "id"`
196
+
197
+ Version 1.0.2 and newer no longer abort startup for empty override rows created by the Homebridge UI. Invalid override entries are skipped with a warning. If you still see old warnings, remove empty rows from the Device Overrides section in the plugin settings and restart Homebridge.
198
+
199
+
195
200
  ### The QR code does not appear
196
201
 
197
202
  Make sure you opened the settings for this plugin, not another Tuya plugin. The plugin name should be:
package/dist/platform.js CHANGED
@@ -68,24 +68,45 @@ class TuyaPlatform {
68
68
  if (!this.options.deviceOverrides) {
69
69
  return true;
70
70
  }
71
- const idMap = new Map();
71
+ if (!Array.isArray(this.options.deviceOverrides)) {
72
+ this.log.warn('[Tuya QR] Ignoring invalid deviceOverrides value because it is not an array.');
73
+ this.options.deviceOverrides = [];
74
+ return true;
75
+ }
76
+
77
+ const validOverrides = [];
78
+ const seenIds = new Set();
79
+ let skippedMissingId = 0;
80
+ let skippedDuplicateId = 0;
81
+
72
82
  for (const item of this.options.deviceOverrides) {
73
- if (!item || !item.id) {
74
- this.log.error('[Tuya QR] Each device override must include an "id".');
75
- return false;
83
+ if (!item || typeof item !== 'object') {
84
+ skippedMissingId++;
85
+ continue;
76
86
  }
77
- if (idMap.has(item.id)) {
78
- idMap.get(item.id).push(item);
79
- } else {
80
- idMap.set(item.id, [item]);
87
+ const id = String(item.id || '').trim();
88
+ if (!id) {
89
+ skippedMissingId++;
90
+ continue;
81
91
  }
82
- }
83
- for (const items of idMap.values()) {
84
- if (items.length > 1) {
85
- this.log.error('[Tuya QR] "deviceOverrides" conflict, "id" must be unique: %o.', items);
86
- return false;
92
+ if (seenIds.has(id)) {
93
+ skippedDuplicateId++;
94
+ this.log.warn('[Tuya QR] Ignoring duplicate device override for id "%s". Keeping the first one.', id);
95
+ continue;
87
96
  }
97
+ item.id = id;
98
+ seenIds.add(id);
99
+ validOverrides.push(item);
100
+ }
101
+
102
+ if (skippedMissingId > 0) {
103
+ this.log.warn('[Tuya QR] Ignored %d invalid device override(s) without an "id". QR cloud startup will continue.', skippedMissingId);
104
+ }
105
+ if (skippedDuplicateId > 0) {
106
+ this.log.warn('[Tuya QR] Ignored %d duplicate device override(s). QR cloud startup will continue.', skippedDuplicateId);
88
107
  }
108
+
109
+ this.options.deviceOverrides = validOverrides;
89
110
  return true;
90
111
  }
91
112
 
@@ -97,20 +118,43 @@ class TuyaPlatform {
97
118
  if (!deviceOverride.schema) {
98
119
  continue;
99
120
  }
100
- const idMap = new Map();
121
+ if (!Array.isArray(deviceOverride.schema)) {
122
+ this.log.warn('[Tuya QR] Ignoring invalid schema override for device id "%s" because schema is not an array.', deviceOverride.id);
123
+ deviceOverride.schema = undefined;
124
+ continue;
125
+ }
126
+ const validSchema = [];
127
+ const seenCodes = new Set();
128
+ let skippedMissingCode = 0;
129
+ let skippedDuplicateCode = 0;
130
+
101
131
  for (const item of deviceOverride.schema) {
102
- if (idMap.has(item.code)) {
103
- idMap.get(item.code).push(item);
104
- } else {
105
- idMap.set(item.code, [item]);
132
+ if (!item || typeof item !== 'object') {
133
+ skippedMissingCode++;
134
+ continue;
106
135
  }
107
- }
108
- for (const items of idMap.values()) {
109
- if (items.length > 1) {
110
- this.log.error('[Tuya QR] "schema" conflict, "code" must be unique: %o.', items);
111
- return false;
136
+ const code = String(item.code || '').trim();
137
+ if (!code) {
138
+ skippedMissingCode++;
139
+ continue;
140
+ }
141
+ if (seenCodes.has(code)) {
142
+ skippedDuplicateCode++;
143
+ this.log.warn('[Tuya QR] Ignoring duplicate schema override code "%s" for device id "%s". Keeping the first one.', code, deviceOverride.id);
144
+ continue;
112
145
  }
146
+ item.code = code;
147
+ seenCodes.add(code);
148
+ validSchema.push(item);
149
+ }
150
+
151
+ if (skippedMissingCode > 0) {
152
+ this.log.warn('[Tuya QR] Ignored %d invalid schema override(s) without a "code" for device id "%s".', skippedMissingCode, deviceOverride.id);
153
+ }
154
+ if (skippedDuplicateCode > 0) {
155
+ this.log.warn('[Tuya QR] Ignored %d duplicate schema override(s) for device id "%s".', skippedDuplicateCode, deviceOverride.id);
113
156
  }
157
+ deviceOverride.schema = validSchema;
114
158
  }
115
159
  return true;
116
160
  }
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.1",
4
+ "version": "1.0.2",
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",