Skip to content

Conversation

@lackas
Copy link
Contributor

@lackas lackas commented Jan 22, 2026

Summary

Add comprehensive heat pump monitoring methods, primarily for Vitocal 300-G but applicable to other models exposing these API features.

New features:

  • COP (Coefficient of Performance): heating, DHW, total, cooling, green
  • Compressor: power, modulation, load class fallback for statistics.load path
  • Refrigerant circuit: hot gas/suction gas pressure & temperature, liquid gas temperature
  • Heating rod: runtime by level, power consumption summary (DHW & heating)
  • Configuration: buffer temp max, damping factor, heater approvals
  • Primary circuit pump rotation
  • Circuit target temperature
  • New CoolingCircuit class with type and reverse active status

Closes #677

Review guide

Total: ~290 lines of library code, ~280 lines of tests

Lines Type What to review
~35 Logic Load class fallback in Compressor (lines 547-585) - tries statistics then statistics.load
~15 New class CoolingCircuit class (lines 529-543)
~240 Boilerplate Standard getters following existing pattern: @handleNotSupported decorator + single-line property access

The boilerplate getters all follow the exact same pattern as existing methods like getSeasonalPerformanceFactorHeating(). You can skim these quickly - they're just exposing new API properties.

Notes

Test plan

  • 61 tests in test_Vitocal300G.py covering all new methods
  • 16 tests in test_Vitocal250A.py for heating rod power consumption summary
  • Updated ignore list in test_TestForMissingProperties.py
  • All 563 tests pass
  • Ruff passes

@lackas
Copy link
Contributor Author

lackas commented Jan 22, 2026

Thanks for flagging this! Same issue as in #688 - my device exposes both heating.buffer.* and heating.bufferCylinder.* paths with identical values, so I added a fallback without realizing heating.buffer.* is deprecated.

Removed the fallback and reverted to using only bufferCylinder in bd628a1.

Copy link
Member

@CFenner CFenner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please separate the PR into dedicated PRs for:

  • heating rod
  • cooling circuit
  • heating circuit
  • COP
  • compressors
  • etc

Also consider adding the testate in a dedicated PR upfront.

Sorry, this is to much to review.

lackas added a commit to lackas/PyViCare that referenced this pull request Jan 31, 2026
- Remove test data (split to PR openviess#697)
- Rename getTemperature -> getTargetTemperature per review
- Rename getTemperatureUnit -> getTargetTemperatureUnit per review
@lackas lackas marked this pull request as draft January 31, 2026 19:27
@lackas
Copy link
Contributor Author

lackas commented Jan 31, 2026

Thanks for the feedback @CFenner!

Changes made:

Converted to draft until #697 is merged (tests depend on that data).


Review guide for the remaining ~365 lines of code changes:

The changes are grouped into repetitive boilerplate patterns. Here's a quick overview:

Group Methods Pattern
COP metrics 5 getCoefficientOfPerformance*() - simple getters from heating.cop.*
Heating rod summary 14 getHeatingRodPowerConsumptionSummary*() - getters from heating.heatingRod.power.consumption.summary.*
Heating rod runtime 3 getHeatingRodRuntimeLevel*() - getters from heating.heatingRod.runtime
Refrigerant sensors 10 get*Pressure(), get*Temperature() - getters from heating.sensors.*
ECU runtime 2 getMainECURuntime*()
Configuration 7 getConfiguration*() - getters from heating.configuration.*
Primary circuit pump 2 getPrimaryCircuitPumpRotation*()
Circuit target temp 2 getTargetTemperature*() on HeatingCircuit

Non-boilerplate changes:

  1. Compressor load class fallback (getHoursLoadClass1-5): Some devices expose load class stats under statistics.load instead of statistics. Added fallback to try both paths.

  2. Compressor power/modulation (4 methods): New getters for getPower(), getModulation() on Compressor class.

  3. CoolingCircuit class (new): Detection logic for available cooling circuits + getType(), getReverseActive() methods.


I'm happy to split this further if you prefer. That said, my concern is that splitting into many small PRs might actually increase the review burden, and these features only provide full Vitocal 300G support when merged together. But I appreciate your time reviewing this and am glad to support your efforts however works best for you.

@lackas
Copy link
Contributor Author

lackas commented Jan 31, 2026

Note to self: Once #697 is merged, we can remove heating.configuration.dhwHeater from the ignore list in test_TestForMissingProperties.py since this PR implements getConfigurationDHWHeaterApproved() for that property.

lackas added a commit to lackas/PyViCare that referenced this pull request Feb 1, 2026
Minimal changes to make existing tests pass with new Vitocal300G_CU401B.json:
- Update expected values (compressor hours, starts, temperatures)
- Use circuit 1 instead of 0 (device configuration difference)
- Skip load class tests (need statistics.load fallback from PR openviess#689)
- Remove outdated Vitocal300G.json (from 2021)

Comprehensive tests for new features (COP, cooling circuits, heating rod,
refrigerant sensors, etc.) will be added with PR openviess#689.
CFenner added a commit that referenced this pull request Feb 2, 2026
* test: add Vitocal 300G CU401B response data

Adds API response dump for Vitocal 300G with CU401B controller.
This test data will be used by upcoming feature PRs.

* test: add heating.configuration.dhwHeater to ignore list

This property is exposed by Vitocal 300G but not yet implemented.

* Update test setup to use new response file

* Update existing Vitocal 300G tests for fresh data

Minimal changes to make existing tests pass with new Vitocal300G_CU401B.json:
- Update expected values (compressor hours, starts, temperatures)
- Use circuit 1 instead of 0 (device configuration difference)
- Skip load class tests (need statistics.load fallback from PR #689)
- Remove outdated Vitocal300G.json (from 2021)

Comprehensive tests for new features (COP, cooling circuits, heating rod,
refrigerant sensors, etc.) will be added with PR #689.

* fix: use correct circuit list index in Vitocal300G tests

The device only has circuit "1" enabled, so getAvailableCircuits()
returns ["1"]. The library creates circuits[0] for this single circuit,
not circuits[1]. Fix index and clarify comment.

* fix: correct expected modes in Vitocal300G test

Available modes are read from API constraints and vary by device
configuration. This device reports 3 modes: dhw, dhwAndHeating, standby.

---------

Co-authored-by: Christopher Fenner <9592452+CFenner@users.noreply.github.com>
… heating rod stats

Add comprehensive heat pump monitoring for Vitocal 300-G and similar devices:

HeatPump class:
- COP methods: getCoefficientOfPerformance{Heating,DHW,Total,Cooling,Green}
- Compressor: getPower, getModulation (with units)
- Refrigerant sensors: getHotGas/SuctionGas pressure and temperature, getLiquidGasTemperature
- Runtime: getMainECURuntime, getHeatingRodRuntimeLevel{One,Two}
- Configuration: buffer temp max, damping factor, heater approvals
- Heating rod power consumption summary (DHW and heating)

HeatingDevice class:
- Primary circuit pump: getPrimaryCircuitPumpRotation (with unit)

Compressor class:
- Load class methods now support fallback to statistics.load path
- Sensor methods: getInlet/Outlet/Overheat temperature, getInletPressure

New CoolingCircuit class:
- getType, getReverseActive

Closes openviess#677
@lackas lackas force-pushed the feature/heatingrod-power-consumption-summary branch from ce02406 to 037276e Compare February 2, 2026 13:11
@lackas lackas changed the title feat(heat pump): add heating rod power consumption summary methods feat(heat pump): add COP, compressor sensors, refrigerant circuit and heating rod stats Feb 2, 2026
@lackas lackas marked this pull request as ready for review February 2, 2026 13:16
@lackas
Copy link
Contributor Author

lackas commented Feb 3, 2026

While exploring the issue tracker, I noticed this PR addresses several open issues:

That's quite a few birds with one stone! 🪨🐦

No pressure of course - just thought it might be helpful to know the coverage. Happy to adjust anything if needed.

@lackas lackas requested a review from CFenner February 3, 2026 14:55
@lackas
Copy link
Contributor Author

lackas commented Feb 10, 2026

Hi @CFenner,

Just checking in on this PR. Is there anything I can do to help move it forward?

Regarding the split — I hope the review guide in the description helps: 240 of 290 lines are boilerplate getters, leaving only the load class fallback (~35 lines) and CoolingCircuit (~15 lines) as non-trivial code. I'm happy to split if you still prefer, though the individual PRs would only be fully useful once all are merged.

I've been running these features as a custom HA component for over a week now, everything works reliably.

This PR addresses several open issues:

Older issues asked for similar features too: #265, #16. There's also a downstream HA Core PR (home-assistant/core#161422) building on this.

Let me know how you'd like to proceed!

@CFenner
Copy link
Member

CFenner commented Feb 10, 2026

I simply do not have enough time, sorry, but I really appreciate your work, thanks!

I'm fine with the target temp and circulation pump flow addition. In think the cooling circuit could be a or of its own. For some of the other changes, they might be deprecated already (buffer, cop), have to look again.

- Remove getCoefficientOfPerformanceGreen (heating.cop.green is
  deprecated, replaced by heating.cop.photovoltaic)
- Move heating.cop.green to deprecated properties list
- Remove CoolingCircuit class (will be in separate PR)
@lackas
Copy link
Contributor Author

lackas commented Feb 10, 2026

Thanks for taking the time to review this, @CFenner — I really appreciate the guidance, especially given your limited time. It helps a lot!

I now understand why splitting things up makes sense. The cooling circuit is a distinct feature area, so I've moved it into its own PR: #706.

Other changes based on your feedback:

  • Removed getCoefficientOfPerformanceGreenheating.cop.green is deprecated by the API (removalDate: 2025-12-31, replaced by heating.cop.photovoltaic). Moved it to the deprecated properties list.
  • Verified all remaining features against the API's deprecated field in recent device dumps — the other 4 COP endpoints (heating, dhw, cooling, total) are not deprecated.

The buffer paths were already cleaned up in an earlier commit. This PR no longer adds any code targeting deprecated API endpoints.

@CFenner
Copy link
Member

CFenner commented Feb 10, 2026

Thanks, I think I should have added a test case to avoid that deprecated and removed datapoint ts are added again 😀

There is already an SFP for heating she and total, do you see any for cooling in sour device? Would you mind adding that to be consistent?

@lackas
Copy link
Contributor Author

lackas commented Feb 10, 2026

Thanks! The deprecation database PR (#707) should help with that going forward.

Regarding COP for cooling — it's already included in this PR: getCoefficientOfPerformanceCooling() at line 304 of PyViCareHeatPump.py, with a test case at line 25 of test_Vitocal300G.py. My device reports a value of 0 for it (no cooling season yet).

Or did you mean something else by "SFP"?

@CFenner
Copy link
Member

CFenner commented Feb 11, 2026

Yes I meant SFP.

@lackas
Copy link
Contributor Author

lackas commented Feb 11, 2026

Checked our test data — no device has heating.spf.cooling. Our Vitocal 300G (VitoConnect, v1 API) only exposes heating.cop.*, no SPF at all. The devices with SPF (250A, 222S) are on the newer v2 API and only have heating.spf.{dhw,heating,total} — no cooling variant.

Happy to add getSeasonalPerformanceFactorCooling() if someone provides device data with it, but we can't test without real data.


# Heating rod power consumption summary for DHW:
@handleNotSupported
def getHeatingRodPowerConsumptionSummaryDHWUnit(self) -> str:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HeatingRod is a device component of its own, so using this like this looks a bit odd:

heatingRod1 = ..
heatingRod.GetHeatingRodPowerConsumption()

I would recommend to remove the heatingRod prefix.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, no it's not, sorry. So next question, would it not make sense to have this as a component like we have for compressors and so on?

@CFenner CFenner marked this pull request as draft February 12, 2026 08:21
Extract all getHeatingRod* methods from HeatPump into a dedicated
HeatingRod class, consistent with Compressor/Condensor/Inverter.
Access via device.heatingRod.getStarts() etc.
@lackas
Copy link
Contributor Author

lackas commented Feb 12, 2026

You're right, made it a component class now — HeatingRod, consistent with Compressor/Condensor/Inverter. Access via device.heatingRod.getStarts(), device.heatingRod.getPowerConsumptionSummaryDHWCurrentDay(), etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Power Consumtion of Vitocal 250

2 participants