homebridge-denon-tv 6.2.4 → 6.2.5

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
@@ -21,6 +21,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
21
21
  - For plugin < v6.1.0 use Homebridge UI <= v5.5.0
22
22
  - For plugin >= v6.1.0 use Homebridge UI >= v5.13.0
23
23
 
24
+ ## [6.2.5] - (24.09.2026)
25
+
26
+ ### Changes
27
+
28
+ - fix: with 85 inputs (the HomeKit limit) the input list from the receiver no longer updated existing inputs, the limit skipped every input instead of only new ones, so names of existing inputs were never refreshed. The limit now applies to new inputs only
29
+
24
30
  ## [6.2.4] - (24.09.2026)
25
31
 
26
32
  ### Changes
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "Denon TV",
3
3
  "name": "homebridge-denon-tv",
4
- "version": "6.2.4",
4
+ "version": "6.2.5",
5
5
  "description": "Homebridge plugin to control Denon/Marantz AV Receivers.",
6
6
  "license": "MIT",
7
7
  "author": "grzegorz914",
@@ -20,12 +20,14 @@ class HaDiscovery {
20
20
  this.configTopic = `${mqtt.haPrefix}/media_player/${this.objectId}/config`;
21
21
  this.stateTopic = `${mqtt.config.prefix}/HA State`;
22
22
  this.commandTopic = `${mqtt.config.prefix}/Set`;
23
+ this.imageTopic = config.image ? `${mqtt.config.prefix}/HA Image` : null;
23
24
 
24
25
  this.sources = [];
25
26
  this.soundModes = [];
26
27
  this.state = {};
27
28
  this.lastConfig = '';
28
29
  this.lastState = '';
30
+ this.lastImageKey = undefined;
29
31
  }
30
32
 
31
33
  // Publish (or republish when changed) the retained discovery message
@@ -45,6 +47,7 @@ class HaDiscovery {
45
47
  state_topic: this.stateTopic,
46
48
  command_topic: this.commandTopic,
47
49
  availability_topic: this.mqtt.availabilityTopic,
50
+ ...(this.imageTopic ? { image_topic: this.imageTopic } : {}),
48
51
  device,
49
52
  commands: this.commands,
50
53
  sources: this.sources,
@@ -58,6 +61,28 @@ class HaDiscovery {
58
61
  return true;
59
62
  }
60
63
 
64
+ // Publish the image of the current source (app icon, channel picon) once per source.
65
+ // key identifies the image, fetchImage returns a Buffer or null, null clears the image
66
+ async updateImage(key, fetchImage) {
67
+ if (!this.imageTopic || key === this.lastImageKey) return false;
68
+ this.lastImageKey = key;
69
+
70
+ let image = null;
71
+ try {
72
+ image = key ? await fetchImage() : null;
73
+ } catch {
74
+ // Network or device error, allow a retry on the next state update
75
+ image = null;
76
+ if (key === this.lastImageKey) this.lastImageKey = undefined;
77
+ return false;
78
+ }
79
+
80
+ // The source changed again while fetching, a newer call publishes its own image
81
+ if (key !== this.lastImageKey) return false;
82
+ await this.mqtt.publishRetained(this.imageTopic, image ?? '');
83
+ return true;
84
+ }
85
+
61
86
  // Merge a partial state and publish it retained when something changed
62
87
  async updateState(partial) {
63
88
  for (const [key, value] of Object.entries(partial)) {
package/src/mainzone.js CHANGED
@@ -227,8 +227,6 @@ class MainZone extends EventEmitter {
227
227
  let updated = false;
228
228
 
229
229
  for (const input of inputs) {
230
- if (this.inputsServices.length >= 85 && !remove) continue;
231
-
232
230
  const inputReference = input.reference;
233
231
  const savedName = this.savedInputsNames[inputReference] ?? input.name;
234
232
  const sanitizedName = await this.functions.sanitizeString(savedName);
@@ -259,6 +257,9 @@ class MainZone extends EventEmitter {
259
257
  updated = true;
260
258
  }
261
259
  } else {
260
+ // HomeKit allows at most 85 inputs, the limit applies to new inputs only, existing ones are still updated
261
+ if (this.inputsServices.length >= 85) continue;
262
+
262
263
  const identifier = this.inputsServices.length + 1;
263
264
  inputService = this.accessory.addService(Service.InputSource, sanitizedName, `Input ${inputReference}`);
264
265
  inputService.identifier = identifier;
package/src/mqtt.js CHANGED
@@ -110,7 +110,7 @@ class Mqtt extends EventEmitter {
110
110
  if (this.config.logWarn) this.emit('warn', `MQTT Publish error: ${error.message}`);
111
111
  return reject(error);
112
112
  }
113
- if (this.config.logDebug) this.emit('debug', `MQTT Publish retained Topic: ${fullTopic}, Payload: ${payload}`);
113
+ if (this.config.logDebug) this.emit('debug', `MQTT Publish retained Topic: ${fullTopic}, Payload: ${typeof payload === 'string' ? payload : `${payload.length} bytes`}`);
114
114
  resolve();
115
115
  });
116
116
  });
@@ -107,8 +107,6 @@ class PassThroughInputs extends EventEmitter {
107
107
  let updated = false;
108
108
 
109
109
  for (const input of inputs) {
110
- if (this.inputsServices.length >= 85 && !remove) continue;
111
-
112
110
  const inputReference = input.reference;
113
111
  const savedName = this.savedInputsNames[inputReference] ?? input.name;
114
112
  const sanitizedName = await this.functions.sanitizeString(savedName);
@@ -139,6 +137,9 @@ class PassThroughInputs extends EventEmitter {
139
137
  updated = true;
140
138
  }
141
139
  } else {
140
+ // HomeKit allows at most 85 inputs, the limit applies to new inputs only, existing ones are still updated
141
+ if (this.inputsServices.length >= 85) continue;
142
+
142
143
  const identifier = this.inputsServices.length + 1;
143
144
  inputService = this.accessory.addService(Service.InputSource, sanitizedName, `Input ${inputReference}`);
144
145
  inputService.identifier = identifier;
package/src/surrounds.js CHANGED
@@ -118,8 +118,6 @@ class Surrounds extends EventEmitter {
118
118
  let updated = false;
119
119
 
120
120
  for (const input of inputs) {
121
- if (this.inputsServices.length >= 85 && !remove) continue;
122
-
123
121
  const inputReference = input.reference;
124
122
  const savedName = this.savedInputsNames[inputReference] ?? input.name;
125
123
  const sanitizedName = await this.functions.sanitizeString(savedName);
@@ -150,6 +148,9 @@ class Surrounds extends EventEmitter {
150
148
  updated = true;
151
149
  }
152
150
  } else {
151
+ // HomeKit allows at most 85 inputs, the limit applies to new inputs only, existing ones are still updated
152
+ if (this.inputsServices.length >= 85) continue;
153
+
153
154
  const identifier = this.inputsServices.length + 1;
154
155
  inputService = this.accessory.addService(Service.InputSource, sanitizedName, `Input ${inputReference}`);
155
156
  inputService.identifier = identifier;
package/src/zone2.js CHANGED
@@ -225,8 +225,6 @@ class Zone2 extends EventEmitter {
225
225
  let updated = false;
226
226
 
227
227
  for (const input of inputs) {
228
- if (this.inputsServices.length >= 85 && !remove) continue;
229
-
230
228
  const inputReference = input.reference;
231
229
  const savedName = this.savedInputsNames[inputReference] ?? input.name;
232
230
  const sanitizedName = await this.functions.sanitizeString(savedName);
@@ -257,6 +255,9 @@ class Zone2 extends EventEmitter {
257
255
  updated = true;
258
256
  }
259
257
  } else {
258
+ // HomeKit allows at most 85 inputs, the limit applies to new inputs only, existing ones are still updated
259
+ if (this.inputsServices.length >= 85) continue;
260
+
260
261
  const identifier = this.inputsServices.length + 1;
261
262
  inputService = this.accessory.addService(Service.InputSource, sanitizedName, `Input ${inputReference}`);
262
263
  inputService.identifier = identifier;
package/src/zone3.js CHANGED
@@ -225,8 +225,6 @@ class Zone3 extends EventEmitter {
225
225
  let updated = false;
226
226
 
227
227
  for (const input of inputs) {
228
- if (this.inputsServices.length >= 85 && !remove) continue;
229
-
230
228
  const inputReference = input.reference;
231
229
  const savedName = this.savedInputsNames[inputReference] ?? input.name;
232
230
  const sanitizedName = await this.functions.sanitizeString(savedName);
@@ -257,6 +255,9 @@ class Zone3 extends EventEmitter {
257
255
  updated = true;
258
256
  }
259
257
  } else {
258
+ // HomeKit allows at most 85 inputs, the limit applies to new inputs only, existing ones are still updated
259
+ if (this.inputsServices.length >= 85) continue;
260
+
260
261
  const identifier = this.inputsServices.length + 1;
261
262
  inputService = this.accessory.addService(Service.InputSource, sanitizedName, `Input ${inputReference}`);
262
263
  inputService.identifier = identifier;