homebridge-viessmann-vicare 2.0.21 → 2.0.23

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/README.md CHANGED
@@ -853,6 +853,14 @@ For issues and questions:
853
853
  - 🔧 `scheduleStateRefresh()` replaced by `scheduleCommandConfirmation()` in all three accessories.
854
854
  - 🔧 Applied uniformly to `dhw-accessory`, `boiler-accessory`, and `heating-circuit-accessory`.
855
855
 
856
+ ### [2.0.23] - 2026-03-09
857
+ **Fixed**
858
+ - 🐛 **Wrong active temperature program shown in HomeKit**: the plugin was guessing the active program by comparing temperatures instead of reading `heating.circuits.0.operating.programs.active` from the API. This caused HomeKit to show "Ridotto" as active even when the API reported "normal". Fixed by reading the authoritative `operating.programs.active.value` directly and only falling back to the previous value if the API returns an unknown program name.
859
+
860
+ ### [2.0.22]
861
+ **Fixed**
862
+ - 🐛 **ExtendedHeating/Holiday/HolidayAtHome show wrong state on boot**: `onGet` alone is not sufficient — HAP uses the cached accessory value until `updateCharacteristic` is called explicitly. Added `updateCharacteristic` push for all three quick selection services immediately after creation, so the correct state is visible in HomeKit right after Homebridge restarts. Also logs `ExtendedHeating initial state: ON/OFF` for easier debugging.
863
+
856
864
  ### [2.0.21] - 2026-03-05
857
865
  **Fixed**
858
866
  - 🐛 **ExtendedHeating wrong initial state on boot**: at startup the plugin was reading `comfortProgram.properties?.active?.value` to determine if Extended Heating was active, but on this device the alternative method `forcedLastFromSchedule` is used. The initial state now checks both `comfortProgram.active` and `forcedLastFromSchedule.active`, so `Risc Extra` shows the correct ON/OFF state immediately after Homebridge restart.
@@ -1 +1 @@
1
- {"version":3,"file":"heating-circuit-accessory.d.ts","sourceRoot":"","sources":["../../src/accessories/heating-circuit-accessory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"heating-circuit-accessory.d.ts","sourceRoot":"","sources":["../../src/accessories/heating-circuit-accessory.ts"],"names":[],"mappings":"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"}
@@ -212,6 +212,7 @@ class ViessmannHeatingCircuitAccessory {
212
212
  const comfortActive = comfortProgram.properties?.active?.value || false;
213
213
  const forcedActive = forcedProgram?.properties?.active?.value || false;
214
214
  this.states.ExtendedHeatingActive = comfortActive || forcedActive;
215
+ this.platform.log.info(`U0001F50D ExtendedHeating debug — comfortActive: ${comfortActive}, forcedActive: ${forcedActive}, forcedProps: ${JSON.stringify(forcedProgram?.properties)}, comfortProps: ${JSON.stringify(comfortProgram?.properties)}`);
215
216
  const activateExecutable = hasActivate?.isExecutable || false;
216
217
  const deactivateExecutable = hasDeactivate?.isExecutable || false;
217
218
  const setTempExecutable = hasSetTemperature?.isExecutable || false;
@@ -437,6 +438,18 @@ class ViessmannHeatingCircuitAccessory {
437
438
  .onGet(() => this.states.ExtendedHeatingActive)
438
439
  .onSet(this.setExtendedHeatingMode.bind(this));
439
440
  }
441
+ // 🛠️ Push initial state to HomeKit — onGet alone is not enough because HAP uses
442
+ // the cached accessory value until an explicit updateCharacteristic is called.
443
+ if (this.holidayService) {
444
+ this.holidayService.updateCharacteristic(this.platform.Characteristic.On, this.states.HolidayActive);
445
+ }
446
+ if (this.holidayAtHomeService) {
447
+ this.holidayAtHomeService.updateCharacteristic(this.platform.Characteristic.On, this.states.HolidayAtHomeActive);
448
+ }
449
+ if (this.extendedHeatingService) {
450
+ this.extendedHeatingService.updateCharacteristic(this.platform.Characteristic.On, this.states.ExtendedHeatingActive);
451
+ this.platform.log.info(`ExtendedHeating initial state: ${this.states.ExtendedHeatingActive ? 'ON' : 'OFF'}`);
452
+ }
440
453
  this.platform.log.info(`✅ HC${this.circuitNumber} quick selection services setup completed for selections: [${this.availableQuickSelections.join(', ')}] with subtype version: ${subtypeVersion}`);
441
454
  }
442
455
  removeAllTemperatureProgramServices() {
@@ -1245,27 +1258,29 @@ class ViessmannHeatingCircuitAccessory {
1245
1258
  this.heaterCoolerService.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, this.states.CurrentTemperature);
1246
1259
  }
1247
1260
  }
1248
- // Update temperature programs and detect which one is currently active
1261
+ // Update temperature programs
1249
1262
  const programTypes = ['comfort', 'normal', 'reduced'];
1250
- let activeProgram = 'normal'; // Default fallback
1251
1263
  for (const programType of programTypes) {
1252
1264
  const programFeature = features.find(f => f.feature === `${circuitPrefix}.operating.programs.${programType}`);
1253
1265
  if (programFeature?.properties?.temperature?.value !== undefined) {
1254
1266
  const newTemp = programFeature.properties.temperature.value;
1255
1267
  const oldTemp = this.programTemperatures[programType];
1256
- // Update stored temperature for this program
1257
1268
  if (newTemp !== oldTemp) {
1258
1269
  this.programTemperatures[programType] = newTemp;
1259
1270
  anyTemperatureChanged = true;
1260
1271
  this.platform.log.debug(`Program ${programType} temperature updated: ${oldTemp}°C → ${newTemp}°C`);
1261
1272
  }
1262
- // Determine which program is currently active based on the HeatingThresholdTemperature
1263
- // The active program is likely the one whose temperature matches the current target
1264
- if (Math.abs(newTemp - this.states.HeatingThresholdTemperature) < 0.5) {
1265
- activeProgram = programType;
1266
- }
1267
1273
  }
1268
1274
  }
1275
+ // Read active program directly from API (operating.programs.active) — authoritative source
1276
+ const activeProgramFeature = features.find(f => f.feature === `${circuitPrefix}.operating.programs.active`);
1277
+ let activeProgram = activeProgramFeature?.properties?.value?.value || this.currentProgram;
1278
+ // Normalize: API can return 'forcedLastFromSchedule' or other values not in our set
1279
+ if (!['comfort', 'normal', 'reduced'].includes(activeProgram)) {
1280
+ this.platform.log.debug(`HC${this.circuitNumber} active program "${activeProgram}" not in known set — keeping ${this.currentProgram}`);
1281
+ activeProgram = this.currentProgram;
1282
+ }
1283
+ this.platform.log.debug(`HC${this.circuitNumber} active program from API: ${activeProgram.toUpperCase()}`);
1269
1284
  // Update current program if it changed
1270
1285
  if (Date.now() < this.pendingProgramUntil) {
1271
1286
  if (activeProgram !== this.pendingPreviousProgram && activeProgram !== this.pendingExpectedProgram) {
@@ -9,7 +9,7 @@ export declare const PLUGIN_NAME = "homebridge-viessmann-vicare";
9
9
  /**
10
10
  * Plugin version for User-Agent and logging
11
11
  */
12
- export declare const PLUGIN_VERSION = "2.0.21";
12
+ export declare const PLUGIN_VERSION = "2.0.23";
13
13
  /**
14
14
  * Default configuration values
15
15
  */
package/dist/settings.js CHANGED
@@ -12,7 +12,7 @@ exports.PLUGIN_NAME = 'homebridge-viessmann-vicare';
12
12
  /**
13
13
  * Plugin version for User-Agent and logging
14
14
  */
15
- exports.PLUGIN_VERSION = '2.0.21';
15
+ exports.PLUGIN_VERSION = '2.0.23';
16
16
  /**
17
17
  * Default configuration values
18
18
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "homebridge-viessmann-vicare",
3
- "version": "2.0.21",
3
+ "version": "2.0.23",
4
4
  "description": "Complete Homebridge plugin for Viessmann ViCare heating systems with full control capabilities, advanced rate limiting protection, and intelligent cache management",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {