Skip to content

Add entity-based dynamic cost pricing (usecase: tempo) - #159

Merged
bokub merged 3 commits into
bokub:masterfrom
vinzd:feature/entity-based-cost-pricing
Jan 7, 2026
Merged

Add entity-based dynamic cost pricing (usecase: tempo)#159
bokub merged 3 commits into
bokub:masterfrom
vinzd:feature/entity-based-cost-pricing

Conversation

@vinzd

@vinzd vinzd commented Nov 19, 2025

Copy link
Copy Markdown
Contributor

Extended the cost calculator to support dynamic pricing from Home Assistant entities in addition to static prices. Prices are fetched from entity history and matched by timestamp, with automatic unit conversion (c€/kWh, EUR/MWh, etc).

Key changes:

  • Added entity_id field to CostConfig (alternative to static price)
  • Implemented getEntityHistory() to fetch price data via WebSocket API
  • Added automatic price unit conversion (cents, EUR/MWh → €/kWh)
  • Supports time-based filters (after/before/weekday/dates) for both modes
  • Comprehensive test coverage (21 tests passing)

Extended the cost calculator to support dynamic pricing from Home Assistant
entities in addition to static prices. Prices are fetched from entity history
and matched by timestamp, with automatic unit conversion (c€/kWh, EUR/MWh, etc).

Key changes:
- Added entity_id field to CostConfig (alternative to static price)
- Implemented getEntityHistory() to fetch price data via WebSocket API
- Added automatic price unit conversion (cents, EUR/MWh → €/kWh)
- Supports time-based filters (after/before/weekday/dates) for both modes
- Comprehensive test coverage (21 tests passing)
@codecov

codecov Bot commented Nov 19, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 46.50206% with 130 lines in your changes missing coverage. Please review.
✅ Project coverage is 41.55%. Comparing base (6344dea) to head (91a2f54).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
src/ha.ts 0.00% 66 Missing ⚠️
src/index.ts 0.00% 47 Missing ⚠️
src/cost.ts 87.35% 11 Missing ⚠️
src/config.ts 86.04% 6 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #159      +/-   ##
==========================================
+ Coverage   39.57%   41.55%   +1.98%     
==========================================
  Files           8        8              
  Lines         791     1013     +222     
  Branches       85      118      +33     
==========================================
+ Hits          313      421     +108     
- Misses        475      589     +114     
  Partials        3        3              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@vinzd

vinzd commented Dec 16, 2025

Copy link
Copy Markdown
Contributor Author

@bokub je me permets un rappel pour cette PR, merci !

@bokub

bokub commented Dec 16, 2025

Copy link
Copy Markdown
Owner

@vinzd Oula oui merci tu as bien fait !

@bokub

bokub commented Dec 17, 2025

Copy link
Copy Markdown
Owner

Il y a un truc que je n'arrive pas trop à comprendre:

Quand le lis la documentation et dans le parsing de la configuration, j'ai l'impression que tu autorises de mettre à la fois un price et un entity_id ? Si oui, que se passe-t-il ?

Au début je m'attendais à ce que le prix statique soit un fallback, mais en fait pas du tout, le entity_id est prioritaire et annule complètement l'effet du price, donc pourquoi autoriser de renseigner les deux ?

      if (matchingCostConfig.entity_id && entityHistory) {
        price = findPriceFromEntityHistory(point, matchingCostConfig.entity_id, entityHistory);
        if (price === null) {
          continue;
        }

Pourrais-tu choisir soit l'une soit l'autre des deux approches ?

  • Approche 1: entity_id est prioritaire, price sert de fallback si il est renseigné
  • Approche 2: il faut choisir entre entity_id et price, on ne peut pas renseigner les deux

@vinzd

vinzd commented Dec 24, 2025

Copy link
Copy Markdown
Contributor Author

En effet, ça prête à confusion. J’ai modifié pour n’accepter que l’un ou l’autre, ça devrait être plus clair

@ekinox3600

Copy link
Copy Markdown

Bonjour,tres interressé par cette PR !

@bokub bokub left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Hello @vinzd !

Désolé pour les délais, je suis enfin rentré de vacances et j'ai pu prendre un peu de temps pour tester ta PR. Tout a l'air de bien fonctionner, c'est OK pour moi!

Je n'ai pas les droits en édition, peux-tu régler ces 3 derniers détails, ensuite on pourra merger et je ferai une release

Merci et bonne soirée !

Comment thread .DS_Store Outdated
Comment thread .github/.DS_Store Outdated
Comment thread config.yaml Outdated
@vinzd

vinzd commented Jan 6, 2026

Copy link
Copy Markdown
Contributor Author

Bonsoir Boris, merci d’avoir pris le temps de regarder ! J’ai annulé les changements mentionnés 👍🏻

@bokub
bokub merged commit f85f692 into bokub:master Jan 7, 2026
6 of 7 checks passed
@bokub

bokub commented Jan 7, 2026

Copy link
Copy Markdown
Owner

Merci @vinzd ! C'est mergé et publié sous le numéro de version 1.7.0

En faisant des tests je me suis posé une question:

Pourquoi empêcher l'utilisation de filtres horaires dans une tarification dynamique ?

On pourrait très bien avoir une entité input_number.prix_hp pour les heures pleines et une autre entité input_number.prix_hc pour les heures creuses, avec la possibilité de modifier ces entités au fur à mesure que la tarification du fournisseur évolue, non ?

Y a-t-il un blocage technique que je n'ai pas saisi ? J'ai l'impression que ça rend la doc (et le code) compliqués pour rien, mais encore une fois j'ai peut-être loupé un truc

Merci encore

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.

3 participants