Skip to content

Comments

Add .env support, hot water correction, README, and bug fixes#2

Open
Appesteijn wants to merge 40 commits intoRickvdt:mainfrom
Appesteijn:main
Open

Add .env support, hot water correction, README, and bug fixes#2
Appesteijn wants to merge 40 commits intoRickvdt:mainfrom
Appesteijn:main

Conversation

@Appesteijn
Copy link

Summary

  • .env support — Moved HA_URL and TOKEN to .env file using python-dotenv, added .env.example
  • Hot water correction — Gas-only users get automatic DHW baseline subtraction based on warm-day gas usage (>HOT_WATER_OUTSIDE_TEMP_THRESHOLD), with DHW summary in output
  • Heat loss analysis — Combined heat loss analysis for both heat pump and gas data, with balance point temperature calculation and gas vs heat pump comparison
  • README — Added Dutch README with usage guide for heat pump, gas-only, and transitioning users, including JupyterLab HA add-on instructions
  • Bug fixes — Fixed locals() vs globals() for inter-cell variables, deprecated pandas resample('H'), timezone mismatch in joins, stale data from failed fetches
  • Housekeeping — Added .gitignore, moved older notebook versions to archive/

Test plan

  • Run Cell 1 (install deps) — verify python-dotenv is included
  • Run Cell 2 (heat pump data) — verify it reads HA_URL/TOKEN from .env
  • Run Cell 2B (gas data) — verify hot water correction output and DHW summary
  • Run Cell 2B with invalid entity — verify downstream cells don't show stale gas data
  • Run all analysis cells — verify no locals() or timezone errors
  • Run heat loss analysis cell — verify heat loss coefficient and balance point for both data sources

🤖 Generated with Claude Code

Appesteijn and others added 30 commits February 13, 2026 20:35
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add README.md with usage guide for heat pump, gas, and transitioning users
- Move HA_URL and TOKEN to .env file (python-dotenv)
- Add hot water correction for gas-only users based on warm-day baseline
- Fix locals() vs globals() checks for inter-cell variable access
- Fix deprecated pandas resample('H') to resample('h')
- Fix timezone mismatch in gas data join
- Initialize df_gas_daily as empty to prevent stale data in downstream cells

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Convert Jupyter notebook analysis into a full HA integration with config flow,
sensors, services, and an apexcharts-card dashboard. Move original notebook
and files to archive.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
attr_fn was set to None instead of a lambda returning None,
causing a TypeError when HA called extra_state_attributes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Rename component from "Quatt Stooklijn Analyse" to "Quatt Warmteanalyse"
  across all user-visible locations (manifest, HACS, sensors, config flow,
  dashboard, README). Internal identifiers (domain, module paths) unchanged.
- Fix pandas FutureWarning in quatt.py by dropping all-NA columns before
  DataFrame concatenation.
- Add 94 unit/integration tests covering heat loss regression, stooklijn
  curve fitting, gas processing, sensor value/attr functions, config flow
  validation, and coordinator logic.
- Add .gitignore entries for __pycache__ and .pytest_cache.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The gas analysis period typically predates the heat pump installation,
so outdoor temperature from Quatt hourly data was always empty (no
overlapping dates). Now fetches temperature directly from the HA
recorder for the gas date range using the configured temp_entities.
Falls back to heat pump data if recorder fetch finds nothing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Change the last_analysis sensor to display the date in yyyy-mm-dd format
instead of using the timestamp device class which shows a localized
human-readable format.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Extend heat_at_temps to include interpolated COP values per temperature
- Add new columns to dashboard table: COP and electricity consumption
- Calculate accurate electricity usage based on temperature-specific COP
- Update tests for new heat_at_temps structure

This provides more accurate electricity consumption estimates by using
interpolated COP values for each temperature instead of a single average,
giving users better insight into heat pump efficiency across different
temperatures.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Major performance and accuracy improvements:

CACHING SYSTEM:
- Add persistent cache for Quatt insights data to minimize API calls
- Implement 30-day initial fetch limit to prevent API abuse for new users
- Cache grows organically (1 day per run) to full history over time
- 99.6% reduction in API calls after initial run (251 calls → 1 call)
- Cache stored in .storage/quatt_stooklijn_insights_cache

KNEE DETECTION IMPROVEMENTS:
- Use all available Quatt hourly data (grows from 30 to 250+ days)
- Smart filtering removes defrost cycles and partial operation hours
- Fallback to recorder data if Quatt unavailable
- 3x to 25x more data than previous 10-day recorder method
- Progressive accuracy as cache grows

CHANGES:
- Add custom_components/quatt_stooklijn/cache.py (new cache helper)
- Update quatt.py with caching and 30-day limit
- Update stooklijn.py with improved knee detection
- Extensive README documentation on caching and performance
- Add comprehensive documentation files

BENEFITS:
- New users: Safe 30 API calls first run, grows automatically
- Existing users: Instant analyses with 1 API call per run
- Better accuracy: More historical data for knee detection
- No configuration needed: Works transparently

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
After a restart, dashboards showed empty graphs because analysis
data is in-memory only. Now automatically triggers analysis after
EVENT_HOMEASSISTANT_STARTED, using cached data for fast completion.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instead of fetching all historical data from the Quatt API (which was
limited to 30 days on first run anyway), now uses HA recorder long-term
statistics for the full configured period. The Quatt API is only used
for the last 30 days of hourly detail data (for knee detection).

This gives months of daily data immediately without any API calls,
and the API data overwrites recorder data for recent days where it's
more accurate.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
With recorder statistics now providing months of data including summer,
the COP average and stooklijn regression were skewed by days with no
heating demand. Now filters on totalHeatPerHour >= 200W and COP > 0
to only include meaningful heating days.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The recorder's heatpump_total_quatt_cop sensor averages over 24h
including off-periods (COP=0), giving artificially low values on
warm days when the pump runs fewer hours. Now calculates COP as
totalHpHeat/totalHpElectric which matches the Quatt API behavior
and gives the correct operational COP.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously, cached hourly data older than 30 days was ignored.
Now checks cache for the full configured period before fetching
from the API, giving more data points for knee detection.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The recorder DataFrame used int64 (0) for totalBoilerGas while
the API data contains floats, causing a pandas dtype warning
on df_daily.update().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Scatter data for both stooklijn and heat loss charts included
summer days with 0W heating, causing the x-axis to extend to
~29°C. Now uses the same heating_data filter as the regression.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrites the "How it works" and "Performance & Caching" sections
to document the recorder + API + cache hybrid approach, adds
auto-startup info, and updates troubleshooting with COP tips.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
All trend/stooklijn lines were drawn from -10°C to 25°C regardless
of actual data. Now they stop at max(scatter_data temps) + 1°C,
so lines don't extend far beyond the data points.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Lines with shallow slopes (like Quatt estimated) extended far
beyond the relevant range because y > 0 was the only limit.
Now each line stops at min(-intercept/slope + 1, 20)°C, which
is where heat demand reaches zero.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
graph_span reduced from 35h to 30h so x-axis stops at 20°C,
matching the data range. Beyond 20°C there is no heating demand.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Quatt API returns hourly averages, which makes the 2500W power
filter unreliable (partial operation hours pass the filter). This
resulted in an artificially shallow slope (-133 W/°C vs expected -318).

Now uses HA recorder state_changes (minute-level granularity) for the
stooklijn slope estimation, matching the original notebook approach.
Quatt hourly data is still used for knee detection where it works well.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Appesteijn and others added 5 commits February 17, 2026 22:25
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
More data points give a more reliable stooklijn estimation, especially
if recent days had mild weather. This is a local database query only
(no Quatt API calls).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Documents the 4-source hybrid approach: recorder statistics, recorder
state changes (minute-level), Quatt API, and cache. Explains why
minute-level data is used for stooklijn estimation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The dashboard trendlines were recalculating slope/intercept from scatter
point averages, which is inaccurate and caused the line to go horizontal
at the right end. Now uses the actual regression slope and intercept
from the sensor attributes.

Also exposes slope, intercept, and balance_point on both heat loss
sensors (HP and gas) for use in the dashboard.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Appesteijn and others added 5 commits February 19, 2026 21:43
- Add Dutch, German, and French translations
- Fix codeowners to @Appesteijn

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add hassfest, HACS validation, and pytest workflows
- Fix conftest.py stubs for recorder.statistics and helpers.storage
- All 94 tests pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Vervang curve_fit door exhaustieve grid search (-4 tot +4°C, stap 0.25°C)
  om lokale minima te vermijden; deterministisch en debugbaar
- Voeg fysieke beperkingen toe aan grid search:
  warme kant moet negatieve helling hebben, koude kant substantieel vlakker
- Stel recorder minuutdata in als primaire bron voor knikdetectie
  (geen defrost-verdunning van uurgemiddelden → nauwkeuriger, stabiel op 1.75°C)
- Quatt uurdata blijft als fallback bij onvoldoende koude-weer recorder-data
- Herschrijf KNEE_DETECTION_IMPROVEMENTS.md met validatieresultaten en
  onderbouwing van databron-keuze

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
scipy wordt niet meer gebruikt na vervanging van curve_fit door grid search.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

1 participant