Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FR]: Find the next period with low price based on entity or a set period #35

Open
MTrab opened this issue Apr 2, 2022 · 11 comments
Open
Labels
feature request New feature or enhancement

Comments

@MTrab
Copy link
Owner

MTrab commented Apr 2, 2022

Like we have daily min, max and mean it could be a nice feature to be able to set a period of time, either a static period or from an entity (ie. date_time helper), and have the integration return start/end time and total price for that period.

@MTrab MTrab added the feature request New feature or enhancement label Apr 2, 2022
@MTrab MTrab modified the milestone: Release 0.1.5 Apr 2, 2022
@MTrab MTrab changed the title FR: Find the next period with low price based on entity or a set period [FR]: Find the next period with low price based on entity or a set period May 2, 2022
@Bluhme1
Copy link

Bluhme1 commented May 16, 2022

Great idea. I am using a modified template made for Nordpol to find the cheapest 3 consecutive hours (time to charge a car).
It would be much better to have that option as a built-in part of the integration.
Thank you for your work on this
/Lars

@Lyngtoft
Copy link

Lyngtoft commented Aug 8, 2022

Very interested in this as well for a pool pump/heater setup.

Best case would be something like a simple "On/Off" value to be used in Node-Red for turning everything on or off.

Find best timeslot for running 5 hours between times 08:00 and 22:00
Either simply the 5 lowest price hours (doesn't have to be consecutive)
Or the best consecutive timeslot

@Martinnygaard
Copy link

I use the 3 cheapest consecutive hours to heat up my buffertank (Via Geothermal heating).
Would be very usefull if this could take thin into account.

And even if we could input the number of consecutive hours during configuration of the integration. RIght now, I use three hours, but I may change for two.
Other could need 5 hours to their consumption.

@epe71
Copy link

epe71 commented Aug 25, 2022

Just for the fun of it, I have mapped the power usage of my dishwasher hour by hour.
Eco program: 0.666 kWh, 0.030 kWh, 0.348 kWh (= 1'th, 2'th and 3'th hour)
Auto 45-60: 0.619 kWh, 0.428 kWh, 0 kWh
The I calculate the price if it is started at 1 o'clock, 2 o'clock etc. That is 24 * 2 results. Find the lowest price of all the calculations and display the suggested start time, program and total price.
It is a very simple script, will also work for water heater / cars /etc just with another power usage profile

@AndreasHerss
Copy link

Could be interesting to have directly, i guess it would be something much like https://github.com/JBoye/HA-Energy-Price-Calculator ?

@JBoye
Copy link

JBoye commented Oct 23, 2022

Could be interesting to have directly, i guess it would be something much like https://github.com/JBoye/HA-Energy-Price-Calculator ?

I'm really hoping to see something like this. I think it's too complicated for most people to use yaml templates

@MTrab MTrab added the feature planned Marks when a feature is accepted and put on the plan for future development label Jan 9, 2023
@SinnoTech
Copy link

Would be great. It would be nice to be able to setup some entities, that can be named for instance Dishwasher-mode-eco and you set that it requires X hours at X kWh (inputs) and then the entity spits out when to turn on and what it would cost if turned on at that time.

Minstrøm app does something similar but its not in HA. I would love to have a little epaper display next to the dishwasher & washing machine that displays how long delay i should set and what the load will cost!

@MTrab MTrab removed the feature planned Marks when a feature is accepted and put on the plan for future development label Feb 11, 2023
@fars-fede-fire
Copy link

I have created a custom_component (still alpha) that takes history from a sensor like Shelly Plug S and start and end time. Using numpy and Energi Data Service calculates the energy price for each minute and summes it up, and doing this for every possible start time.
It outputs current price, next time it is cheapest to start and delay in whole hours to cheapest start time.

It does not solve the cases where you need to set a dynamic usage time like 'charge battery to x%' and it does not have to be consecutive, but does exactly what @SinnoTech asks for.

https://github.com/fars-fede-fire/price_calc

@jladefoged
Copy link

I found something similar, but for the Nordpool integration:
https://tom.stevens.se/home-assistant-power-saver/

@algopt
Copy link

algopt commented Jan 1, 2024

Great idea. I am using a modified template made for Nordpol to find the cheapest 3 consecutive hours (time to charge a car). It would be much better to have that option as a built-in part of the integration. Thank you for your work on this /Lars

Would you mind sharing? Trying to get this also running for my PHEV

@mortenmathiasen
Copy link

mortenmathiasen commented Jan 21, 2024

Thank you, @MTrab! You have made a great integration to which I wrote a solution to this FR. If you like it, you can put it into your repo.

The solution is a Jinja macro that finds the cheapest period of consecutive hours. The macro receives as input the earliest and latest allowed start time of the requested period. Additionally, the macro receives the period length and a boolean that tells if first or last finding of cheapest period is prioritized as output. The output from the macro is the start time of the founded period:

{% macro CheapestPeriod(earliestDatetime, latestDatetime, durationTimedelta, findLastPeriodBoolean) %}

{# Prepare input parameters #}
{% set earliestDatetime = now() if earliestDatetime is not defined or earliestDatetime is not datetime else earliestDatetime %}
{% set latestDatetime = now()+timedelta(days=7) if latestDatetime is not defined or latestDatetime is not datetime else latestDatetime %}
{% set durationTimedelta = timedelta(hours=1) if durationTimedelta is not defined or durationTimedelta < timedelta(hours=1) else durationTimedelta %}
{% set durationMinutes = durationTimedelta.total_seconds() // 60 | int %}
{% set durationHours = "%.0f"|format((durationMinutes+30) // 60 | round | float) | int %}

{# Retrieve energy prices #}
{% set energyPrice = "sensor.energi_data_service" %}
{% set today = state_attr(energyPrice, 'raw_today') %}
{% set tomorrow = state_attr(energyPrice, 'raw_tomorrow') %}
{% set forecast = state_attr(energyPrice, 'forecast') %}
{% set prices = (today if today else []) + (tomorrow if tomorrow else []) + (forecast if forecast else []) %}

{# Calculate cheapest period #}
{% set result = namespace(priceSum=999999, priceStartTime=None) %}
{% set prices_len = (prices | length) - durationHours | int %}
{% for n in range(prices_len) %}
  {% set priceStartTime = prices[n].hour %}
  {% if earliestDatetime <= priceStartTime and priceStartTime <= latestDatetime %}
    {% set priceSum = namespace(value=0) %}
    {% for i in range(durationHours) %}
      {% set priceSum.value = priceSum.value + prices[n+i].price %}
    {% endfor %}
    {% if priceSum.value<result.priceSum or (findLastPeriodBoolean and priceSum.value<=result.priceSum) %}
      {% set result.priceSum = priceSum.value %}
      {% set result.priceStartTime = priceStartTime %}
    {% endif %}
  {% endif %}
{% endfor %}

{# Output result #}
{{ result.priceStartTime + timedelta(seconds=durationHours*30*60-durationMinutes*30) }}

{% endmacro %}

In general, the macro can be used for automations, sensors, frontend etc.
Here is an example of how it is used to establish a sensor that tells the cheapest 3 consecutive hours witin the next 7 days:

  - sensor:
      - name: "Cheapest 3 hours"
        icon: "mdi:home-lightning-bolt-outline"
        unique_id: "cheapest_3_hours"
        state: >
          {% from 'CheapestPeriod.jinja' import CheapestPeriod %}
          {% set earliestStartTime = now() %}
          {% set latestStartTime = now() + timedelta(days=7) %}
          {% set periodLength = timedelta(minutes=180) %}
          {{ CheapestPeriod(earliestStartTime , latestStartTime , periodLength, false) }}

I use the macro to automatically start my washing machine in the cheapest possible period.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature or enhancement
Projects
None yet
Development

No branches or pull requests