homebridge-denon-tv 5.4.1 → 5.4.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
@@ -12,6 +12,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
12
12
  - after update to 4.7.x buttons, sensors, volume display type need to be configure again using config UI
13
13
  - after update to 3.15.x need remove the accessory frome Home app and add it again
14
14
 
15
+ ## [5.4.2] - (02.06.2025)
16
+
17
+ ## Changes
18
+
19
+ - fix HAP-NodeJS WARNING: The accessory has an invalid 'Name' characteristic 'configuredName'
20
+ - Please use only alphanumeric, space, and apostrophe characters
21
+ - Ensure it starts and ends with an alphabetic or numeric character, and avoid emojis
22
+
15
23
  ## [5.4.1] - (03.02.2025)
16
24
 
17
25
  ## Changes
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "Denon TV",
3
3
  "name": "homebridge-denon-tv",
4
- "version": "5.4.1",
4
+ "version": "5.4.2",
5
5
  "description": "Homebridge plugin to control Denon/Marantz AV Receivers.",
6
6
  "license": "MIT",
7
7
  "author": "grzegorz914",
package/src/mainzone.js CHANGED
@@ -133,6 +133,22 @@ class MainZone extends EventEmitter {
133
133
  };
134
134
  }
135
135
 
136
+ async sanitizeString(str) {
137
+ // Replace dots, colons, and semicolons inside words with a space
138
+ str = str.replace(/(\w)[.:;]+(\w)/g, '$1 $2');
139
+
140
+ // Remove remaining dots, colons, semicolons, plus, and minus anywhere in the string
141
+ str = str.replace(/[.:;+\-]/g, '');
142
+
143
+ // Replace all other invalid characters (anything not A-Z, a-z, 0-9, space, or apostrophe) with a space
144
+ str = str.replace(/[^A-Za-z0-9 ']/g, ' ');
145
+
146
+ // Trim leading and trailing spaces
147
+ str = str.trim();
148
+
149
+ return str;
150
+ }
151
+
136
152
  async setOverExternalIntegration(integration, key, value) {
137
153
  try {
138
154
  let set = false
@@ -598,8 +614,11 @@ class MainZone extends EventEmitter {
598
614
  const inputReference = input.reference;
599
615
 
600
616
  //get input name
601
- const savedInputsName = this.savedInputsNames[inputReference] ?? false;
602
- input.name = savedInputsName ? savedInputsName : input.name;
617
+ const name = input.name ?? `Input ${inputIdentifier}`;
618
+
619
+ //get input name
620
+ const savedInputsNames = this.savedInputsNames[inputReference] ?? false;
621
+ input.name = savedInputsNames ? savedInputsNames.substring(0, 64) : name.substring(0, 64);
603
622
 
604
623
  //get type
605
624
  const inputSourceType = 0;
@@ -614,17 +633,18 @@ class MainZone extends EventEmitter {
614
633
  input.identifier = inputIdentifier;
615
634
 
616
635
  //input service
617
- const inputService = accessory.addService(Service.InputSource, input.name, `Input ${inputIdentifier}`);
636
+ const sanitizedName = await this.sanitizeString(input.name);
637
+ const inputService = accessory.addService(Service.InputSource, sanitizedName, `Input ${inputIdentifier}`);
618
638
  inputService
619
639
  .setCharacteristic(Characteristic.Identifier, inputIdentifier)
620
- .setCharacteristic(Characteristic.Name, input.name)
640
+ .setCharacteristic(Characteristic.Name, sanitizedName)
621
641
  .setCharacteristic(Characteristic.IsConfigured, isConfigured)
622
642
  .setCharacteristic(Characteristic.InputSourceType, inputSourceType)
623
643
  .setCharacteristic(Characteristic.CurrentVisibilityState, input.visibility)
624
644
 
625
645
  inputService.getCharacteristic(Characteristic.ConfiguredName)
626
646
  .onGet(async () => {
627
- return input.name;
647
+ return sanitizedName;
628
648
  })
629
649
  .onSet(async (value) => {
630
650
  try {
@@ -863,7 +883,7 @@ class MainZone extends EventEmitter {
863
883
  };
864
884
 
865
885
  //sort inputs list
866
- const sortInputsDisplayOrder = this.televisionService ? await this.displayOrder() : false;
886
+ await this.displayOrder();
867
887
 
868
888
  return accessory;
869
889
  } catch (error) {
@@ -91,6 +91,22 @@ class MainZone extends EventEmitter {
91
91
  };
92
92
  }
93
93
 
94
+ async sanitizeString(str) {
95
+ // Replace dots, colons, and semicolons inside words with a space
96
+ str = str.replace(/(\w)[.:;]+(\w)/g, '$1 $2');
97
+
98
+ // Remove remaining dots, colons, semicolons, plus, and minus anywhere in the string
99
+ str = str.replace(/[.:;+\-]/g, '');
100
+
101
+ // Replace all other invalid characters (anything not A-Z, a-z, 0-9, space, or apostrophe) with a space
102
+ str = str.replace(/[^A-Za-z0-9 ']/g, ' ');
103
+
104
+ // Trim leading and trailing spaces
105
+ str = str.trim();
106
+
107
+ return str;
108
+ }
109
+
94
110
  async displayOrder() {
95
111
  try {
96
112
  switch (this.inputsDisplayOrder) {
@@ -278,8 +294,11 @@ class MainZone extends EventEmitter {
278
294
  const inputReference = input.reference;
279
295
 
280
296
  //get input name
281
- const savedInputsName = this.savedInputsNames[inputReference] ?? false;
282
- input.name = savedInputsName ? savedInputsName : input.name;
297
+ const name = input.name ?? `Input ${inputIdentifier}`;
298
+
299
+ //get input name
300
+ const savedInputsNames = this.savedInputsNames[inputReference] ?? false;
301
+ input.name = savedInputsNames ? savedInputsNames.substring(0, 64) : name.substring(0, 64);
283
302
 
284
303
  //get type
285
304
  const inputSourceType = 0;
@@ -294,17 +313,18 @@ class MainZone extends EventEmitter {
294
313
  input.identifier = inputIdentifier;
295
314
 
296
315
  //input service
297
- const inputService = accessory.addService(Service.InputSource, input.name, `Input ${inputIdentifier}`);
316
+ const sanitizedName = await this.sanitizeString(input.name);
317
+ const inputService = accessory.addService(Service.InputSource, sanitizedName, `Input ${inputIdentifier}`);
298
318
  inputService
299
319
  .setCharacteristic(Characteristic.Identifier, inputIdentifier)
300
- .setCharacteristic(Characteristic.Name, input.name)
320
+ .setCharacteristic(Characteristic.Name, sanitizedName)
301
321
  .setCharacteristic(Characteristic.IsConfigured, isConfigured)
302
322
  .setCharacteristic(Characteristic.InputSourceType, inputSourceType)
303
323
  .setCharacteristic(Characteristic.CurrentVisibilityState, input.visibility)
304
324
 
305
325
  inputService.getCharacteristic(Characteristic.ConfiguredName)
306
326
  .onGet(async () => {
307
- return input.name;
327
+ return sanitizedName;
308
328
  })
309
329
  .onSet(async (value) => {
310
330
  try {
@@ -394,7 +414,7 @@ class MainZone extends EventEmitter {
394
414
  }
395
415
 
396
416
  //sort inputs list
397
- const sortInputsDisplayOrder = this.televisionService ? await this.displayOrder() : false;
417
+ await this.displayOrder();
398
418
 
399
419
  return accessory;
400
420
  } catch (error) {
package/src/surround.js CHANGED
@@ -92,6 +92,22 @@ class Surround extends EventEmitter {
92
92
  };
93
93
  }
94
94
 
95
+ async sanitizeString(str) {
96
+ // Replace dots, colons, and semicolons inside words with a space
97
+ str = str.replace(/(\w)[.:;]+(\w)/g, '$1 $2');
98
+
99
+ // Remove remaining dots, colons, semicolons, plus, and minus anywhere in the string
100
+ str = str.replace(/[.:;+\-]/g, '');
101
+
102
+ // Replace all other invalid characters (anything not A-Z, a-z, 0-9, space, or apostrophe) with a space
103
+ str = str.replace(/[^A-Za-z0-9 ']/g, ' ');
104
+
105
+ // Trim leading and trailing spaces
106
+ str = str.trim();
107
+
108
+ return str;
109
+ }
110
+
95
111
  async prepareDataForAccessory() {
96
112
  try {
97
113
  //read inputs file
@@ -285,8 +301,11 @@ class Surround extends EventEmitter {
285
301
  const inputReference = input.reference;
286
302
 
287
303
  //get input name
288
- const savedInputsName = this.savedInputsNames[inputReference] ?? false;
289
- input.name = savedInputsName ? savedInputsName : input.name;
304
+ const name = input.name ?? `Input ${inputIdentifier}`;
305
+
306
+ //get input name
307
+ const savedInputsNames = this.savedInputsNames[inputReference] ?? false;
308
+ input.name = savedInputsNames ? savedInputsNames.substring(0, 64) : name.substring(0, 64);
290
309
 
291
310
  //get type
292
311
  const inputSourceType = 0;
@@ -301,17 +320,18 @@ class Surround extends EventEmitter {
301
320
  input.identifier = inputIdentifier;
302
321
 
303
322
  //input service
304
- const inputService = accessory.addService(Service.InputSource, input.name, `Surround ${inputIdentifier}`);
323
+ const sanitizedName = await this.sanitizeString(input.name);
324
+ const inputService = accessory.addService(Service.InputSource, sanitizedName, `Surround ${inputIdentifier}`);
305
325
  inputService
306
326
  .setCharacteristic(Characteristic.Identifier, inputIdentifier)
307
- .setCharacteristic(Characteristic.Name, input.name)
327
+ .setCharacteristic(Characteristic.Name, sanitizedName)
308
328
  .setCharacteristic(Characteristic.IsConfigured, isConfigured)
309
329
  .setCharacteristic(Characteristic.InputSourceType, inputSourceType)
310
330
  .setCharacteristic(Characteristic.CurrentVisibilityState, input.visibility)
311
331
 
312
332
  inputService.getCharacteristic(Characteristic.ConfiguredName)
313
333
  .onGet(async () => {
314
- return input.name;
334
+ return sanitizedName;
315
335
  })
316
336
  .onSet(async (value) => {
317
337
  try {
@@ -401,7 +421,7 @@ class Surround extends EventEmitter {
401
421
  }
402
422
 
403
423
  //sort inputs list
404
- const sortInputsDisplayOrder = this.televisionService ? await this.displayOrder() : false;
424
+ await this.displayOrder();
405
425
 
406
426
  return accessory;
407
427
  } catch (error) {
package/src/zone2.js CHANGED
@@ -137,6 +137,22 @@ class Zone2 extends EventEmitter {
137
137
  };
138
138
  }
139
139
 
140
+ async sanitizeString(str) {
141
+ // Replace dots, colons, and semicolons inside words with a space
142
+ str = str.replace(/(\w)[.:;]+(\w)/g, '$1 $2');
143
+
144
+ // Remove remaining dots, colons, semicolons, plus, and minus anywhere in the string
145
+ str = str.replace(/[.:;+\-]/g, '');
146
+
147
+ // Replace all other invalid characters (anything not A-Z, a-z, 0-9, space, or apostrophe) with a space
148
+ str = str.replace(/[^A-Za-z0-9 ']/g, ' ');
149
+
150
+ // Trim leading and trailing spaces
151
+ str = str.trim();
152
+
153
+ return str;
154
+ }
155
+
140
156
  async setOverExternalIntegration(integration, key, value) {
141
157
  try {
142
158
  let set = false
@@ -521,8 +537,11 @@ class Zone2 extends EventEmitter {
521
537
  const inputReference = input.reference;
522
538
 
523
539
  //get input name
524
- const savedInputsName = this.savedInputsNames[inputReference] ?? false;
525
- input.name = savedInputsName ? savedInputsName : input.name;;
540
+ const name = input.name ?? `Input ${inputIdentifier}`;
541
+
542
+ //get input name
543
+ const savedInputsNames = this.savedInputsNames[inputReference] ?? false;
544
+ input.name = savedInputsNames ? savedInputsNames.substring(0, 64) : name.substring(0, 64);
526
545
 
527
546
  //get type
528
547
  const inputSourceType = 0;
@@ -537,17 +556,18 @@ class Zone2 extends EventEmitter {
537
556
  input.identifier = inputIdentifier;
538
557
 
539
558
  //input service
540
- const inputService = accessory.addService(Service.InputSource, input.name, `Input ${inputIdentifier}`);
559
+ const sanitizedName = await this.sanitizeString(input.name);
560
+ const inputService = accessory.addService(Service.InputSource, sanitizedName, `Input ${inputIdentifier}`);
541
561
  inputService
542
562
  .setCharacteristic(Characteristic.Identifier, inputIdentifier)
543
- .setCharacteristic(Characteristic.Name, input.name)
563
+ .setCharacteristic(Characteristic.Name, sanitizedName)
544
564
  .setCharacteristic(Characteristic.IsConfigured, isConfigured)
545
565
  .setCharacteristic(Characteristic.InputSourceType, inputSourceType)
546
566
  .setCharacteristic(Characteristic.CurrentVisibilityState, input.visibility)
547
567
 
548
568
  inputService.getCharacteristic(Characteristic.ConfiguredName)
549
569
  .onGet(async () => {
550
- return input.name;
570
+ return sanitizedName;
551
571
  })
552
572
  .onSet(async (value) => {
553
573
  try {
@@ -779,7 +799,7 @@ class Zone2 extends EventEmitter {
779
799
  };
780
800
 
781
801
  //sort inputs list
782
- const sortInputsDisplayOrder = this.televisionService ? await this.displayOrder() : false;
802
+ await this.displayOrder();
783
803
 
784
804
  return accessory;
785
805
  } catch (error) {
package/src/zone3.js CHANGED
@@ -137,6 +137,22 @@ class Zone3 extends EventEmitter {
137
137
  };
138
138
  }
139
139
 
140
+ async sanitizeString(str) {
141
+ // Replace dots, colons, and semicolons inside words with a space
142
+ str = str.replace(/(\w)[.:;]+(\w)/g, '$1 $2');
143
+
144
+ // Remove remaining dots, colons, semicolons, plus, and minus anywhere in the string
145
+ str = str.replace(/[.:;+\-]/g, '');
146
+
147
+ // Replace all other invalid characters (anything not A-Z, a-z, 0-9, space, or apostrophe) with a space
148
+ str = str.replace(/[^A-Za-z0-9 ']/g, ' ');
149
+
150
+ // Trim leading and trailing spaces
151
+ str = str.trim();
152
+
153
+ return str;
154
+ }
155
+
140
156
  async setOverExternalIntegration(integration, key, value) {
141
157
  try {
142
158
  let set = false
@@ -521,8 +537,11 @@ class Zone3 extends EventEmitter {
521
537
  const inputReference = input.reference;
522
538
 
523
539
  //get input name
524
- const savedInputsName = this.savedInputsNames[inputReference] ?? false;
525
- input.name = savedInputsName ? savedInputsName : input.name;;
540
+ const name = input.name ?? `Input ${inputIdentifier}`;
541
+
542
+ //get input name
543
+ const savedInputsNames = this.savedInputsNames[inputReference] ?? false;
544
+ input.name = savedInputsNames ? savedInputsNames.substring(0, 64) : name.substring(0, 64);
526
545
 
527
546
  //get type
528
547
  const inputSourceType = 0;
@@ -537,17 +556,18 @@ class Zone3 extends EventEmitter {
537
556
  input.identifier = inputIdentifier;
538
557
 
539
558
  //input service
540
- const inputService = accessory.addService(Service.InputSource, input.name, `Input ${inputIdentifier}`);
559
+ const sanitizedName = await this.sanitizeString(input.name);
560
+ const inputService = accessory.addService(Service.InputSource, sanitizedName, `Input ${inputIdentifier}`);
541
561
  inputService
542
562
  .setCharacteristic(Characteristic.Identifier, inputIdentifier)
543
- .setCharacteristic(Characteristic.Name, input.name)
563
+ .setCharacteristic(Characteristic.Name, sanitizedName)
544
564
  .setCharacteristic(Characteristic.IsConfigured, isConfigured)
545
565
  .setCharacteristic(Characteristic.InputSourceType, inputSourceType)
546
566
  .setCharacteristic(Characteristic.CurrentVisibilityState, input.visibility)
547
567
 
548
568
  inputService.getCharacteristic(Characteristic.ConfiguredName)
549
569
  .onGet(async () => {
550
- return input.name;
570
+ return sanitizedName;
551
571
  })
552
572
  .onSet(async (value) => {
553
573
  try {
@@ -778,7 +798,7 @@ class Zone3 extends EventEmitter {
778
798
  };
779
799
 
780
800
  //sort inputs list
781
- const sortInputsDisplayOrder = this.televisionService ? await this.displayOrder() : false;
801
+ await this.displayOrder();
782
802
 
783
803
  return accessory;
784
804
  } catch (error) {