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

Cheapest hours in the past #17

Open
happosade opened this issue Nov 8, 2024 · 1 comment
Open

Cheapest hours in the past #17

happosade opened this issue Nov 8, 2024 · 1 comment

Comments

@happosade
Copy link

happosade commented Nov 8, 2024

I seem to get the cheapest hours put on the wrong day (1.1.1970).
It also seems like our math between the me and the automation varies a bit. I don't know if it just default time in UTC (TZ: Europe/Helsinki) and it's completely confused, or what might be the case.

Expected behavior: Calendar event added for tomorrow (2024-11-09) between time 01:00 - 04:00 (localtime)
Result: Calendar event created for 1970-01-01 from 02:00 - 05:00

Additional information:

Output of this step of the trace is:

Executed: November 8, 2024 at 17:28:25
Result:

params:
  domain: calendar
  service: create_event
  service_data:
    start_date_time: '1970-01-01T02:00:00+02:00'
    end_date_time: '1970-01-01T05:00:00+02:00'
    summary: Cheapest hours energy
    entity_id:
      - calendar.electricity
  target:
    entity_id:
      - calendar.electricity
running_script: false

The script as a whole is from repo:

# Package to create and handle cheapest hours from nord pool integration!
# This is the SINGLE entry version.
# For more details check out the blog post at https://www.creatingsmarthome.com/?p=1620

template:
  -  sensor:
      # The actual cheapest hour sensor. If multiple entries are required, copy and set unique_id and configure attributes.
      - name: "Cheapest hours energy"
        unique_id: cheapest_hours_energy
        device_class: timestamp
        state: >
          {%- set sensor = (this.attributes.get('sensor', 'sensor.nordpool_kwh_fi_eur_3_10_01') | string) -%}
          {%- set numberOfSequentialHours = (this.attributes.get('number_of_sequential_hours',1) | int) -%}
          {%- set lastHour = (this.attributes.get('last_hour',23) | int) -%}
          {%- set firstHour = (this.attributes.get('first_hour', 0) | int) -%}
          {%- set startingToday = (this.attributes.get('starting_today', false) | bool) -%}
          {%- if state_attr(sensor, 'tomorrow_valid') == true -%}
            {%- set arr = state_attr(sensor, 'today') + state_attr(sensor, 'tomorrow') -%}
            {%- set ns = namespace(counter=0, list=[], cheapestHour=today_at("00:00"), cheapestPrice=999.00) -%}
            {%- if startingToday == true -%}
              {%- set ns.starting = firstHour -%}
            {%- else -%}
              {%- set ns.starting = firstHour + 24 -%}
            {%- endif -%}
              {%- set ns.ending = lastHour + 24 + 1 -%}
            {%- for i in range(ns.starting + numberOfSequentialHours, ns.ending+1) -%}
              {%- set ns.counter = 0.0 -%}
              {%- for j in range(i-numberOfSequentialHours, i) -%}
                {%- set ns.counter = ns.counter + arr[j] -%}
              {%- endfor -%}
              {%- set ns.list = ns.list + [ns.counter] -%}
              {%- if ns.counter < ns.cheapestPrice -%}
                {%- set ns.cheapestPrice = ns.counter -%}
                {%- set ns.cheapestHour = today_at("00:00") + timedelta( hours = (i - numberOfSequentialHours)) -%}
              {%- endif -%}
            {%- endfor -%}
            {{ ns.cheapestHour }}
            {%- set ns.cheapestPrice = ns.cheapestPrice / numberOfSequentialHours -%}
          {%- endif -%}
        attributes:
          # CHANGE-ME: Set your personal configurations in here
          number_of_sequential_hours: 3 # Amount of sequantial cheapest hours in search
          first_hour: 18 # Search starting hour
          last_hour: 23 # Search ending hour
          starting_today: true # Is the first_hour today (true / false). If false, first_hour needs to be before last_hour.
          sensor: nordpool_kwh_fi_eur_3_10_0255 # Nord pool sensor id. Check it ouf from your integrations page!
          fail_safe_starting: '00:00' # If nordpool fetch fails, starting time to make the calendar entry


automation:
  # Automation to trigger when calendar event hits the cheapest hour mark
  # start/stop automation
  - id: 'cheapest_hours_calendar_entry'
    alias: 'Cheapest hours: Calendar trigger'
    description: ''
    trigger:
    - platform: calendar
      event: start
      entity_id: calendar.electricity
    - platform: calendar
      event: end
      entity_id: calendar.electricity
    condition:
    - condition: template
      value_template: >
        {%- set sensorId = 'sensor.cheapest_hours_energy' -%}
        {{ (state_attr(sensorId, 'friendly_name') | string) == trigger.calendar_event.summary }}
    action:
    - if:
      - condition: template
        value_template: '{{ trigger.event == ''start'' }}'
      then:
      # CHANGE-ME: Actions to do when cheapest hours starts
      - service: light.turn_on
        entity_id: light.office_work
      else:
      # CHANGE-ME: Actions to do when cheapest hours ends
      - service: light.turn_off
        entity_id: light.office_work
    mode: single

  # -- GLOBAL CONFIGURATIONS BELOW, NO NEED TO CHANGE UNLESS CREATING MULTIPLE SEQUENCES --
  # Create calendar event
  - id: 'cheapest_hours_set_sequence'
    alias: 'Cheapest hours: Set next cheapest sequence'
    description: 'Checks tomorrow energy prices every hour and create calendar entry when available AND events not yet created'
    trigger:
    - platform: time_pattern
      hours: /1
    condition:
    - condition: template
      # from which sensor we should try the tomorrow price validation
      value_template: >
        {%- set sensorId = 'sensor.cheapest_hours_energy' -%}
        {{ state_attr((state_attr(sensorId, 'sensor') | string), 'tomorrow_valid') == true }}
    - condition: state
      entity_id: input_boolean.cheapest_hours_set
      state: 'off'
    action:
    - service: input_boolean.turn_on
      data: {}
      target:
        entity_id: input_boolean.cheapest_hours_set
    # Event creation
    - service: calendar.create_event
      data:
        start_date_time: >
          {%- set sensorId = 'sensor.cheapest_hours_energy' -%}
          {{ as_timestamp(states(sensorId), 0) | timestamp_local }}
        end_date_time: >
          {%- set sensorId = 'sensor.cheapest_hours_energy' -%}
          {{ (as_timestamp(states(sensorId), 0) + (3600 * state_attr(sensorId, 'number_of_sequential_hours') | float)) | timestamp_local }}
        summary: >
          {%- set sensorId = 'sensor.cheapest_hours_energy' -%}
          {{ state_attr(sensorId, 'friendly_name') | string }}
      target:
        entity_id: calendar.electricity
    # If multiple cheapest hours sequences are required, copy 'calendar.create_event' block from aboce and change the 'sensorId' variabes values to match corresponding new cheapest hours templated sensor
    mode: single

  # Failsafe
  - id: 'cheapest_hours_failsafe'
    alias: 'Cheapest hours: Failsafe'
    description: 'Failsafe: Set cheapest hours from fail_safe value to amount of hours'
    trigger:
    - platform: time
      at: '23:15'
    condition:
    - condition: state
      entity_id: input_boolean.cheapest_hours_set
      state: 'off'
    action:
    - service: input_boolean.turn_on
      data: {}
      target:
        entity_id: input_boolean.cheapest_hours_set
    # Failsafe action
    - service: calendar.create_event
      data:
        start_date_time: >
          {%- set sensorId = 'sensor.cheapest_hours_energy' -%}
          {{ as_timestamp(today_at(state_attr(sensorId, 'fail_safe_starting')) + timedelta( hours = 24 ), 0) | timestamp_local }}
        end_date_time: >
          {%- set sensorId = 'sensor.cheapest_hours_energy' -%}
          {{ (as_timestamp(today_at(state_attr(sensorId, 'fail_safe_starting')) + timedelta( hours = 24 ), 0) + (3600 * state_attr(sensorId, 'number_of_sequential_hours') | float)) | timestamp_local }}
        summary: >
          {%- set sensorId = 'sensor.cheapest_hours_energy' -%}
          {{ state_attr(sensorId, 'friendly_name') | string }}
      target:
        entity_id: calendar.electricity
    # If multiple cheapest hours sequences are required, make a copy of 'calendar.create_event' block above and set the 'sensorId' values to match the new one
    mode: single

  # input_boolean reset
  - id: 'cheapest_hours_clear_set_flag'
    alias: 'Cheapest hours: Reset the set helper for the next day'
    description: 'Clears cheapes hours helper boolean when the day changes.'
    trigger:
    - platform: time
      at: '01:15:00'
    condition: []
    action:
    - service: input_boolean.turn_off
      data: {}
      target:
        entity_id: input_boolean.cheapest_hours_set
    mode: single

# We need a helper to know if the calendar mark(s) has already been set!
input_boolean:
  cheapest_hours_set:
    name: Cheapest hours set for the next day
    icon: mdi:clock

The nordpool sensor has currently this value:

state_class: total
average: 1.419875
off_peak_1: 1.35925
off_peak_2: 0.39575
peak: 1.8016666666666667
min: 0.314
max: 3.906
mean: 0.8025
unit: kWh
currency: EUR
country: Finland
region: FI
low_price: true
price_percent_to_average: 0.6486486486486487
today:
  - 2.787
  - 2.198
  - 0.803
  - 0.498
  - 0.489
  - 0.491
  - 0.63
  - 2.978
  - 3.769
  - 3.906
  - 3.677
  - 2.073
  - 2.008
  - 1.551
  - 0.802
  - 0.717
  - 0.861
  - 0.921
  - 0.596
  - 0.739
  - 0.483
  - 0.41
  - 0.376
  - 0.314
tomorrow:
  - 0.241
  - 0.004
  - 0
  - 0.001
  - 0.079
  - 0.19
  - 0.323
  - 0.526
  - 0.784
  - 1.163
  - 2.323
  - 4.526
  - 3.824
  - 5.045
  - 5.979
  - 6.767
  - 9.844
  - 11.496
  - 12.088
  - 12.102
  - 12.263
  - 11.57
  - 11.107
  - 10.04
tomorrow_valid: true
raw_today:
  - start: "2024-11-08T00:00:00+02:00"
    end: "2024-11-08T01:00:00+02:00"
    value: 2.787
  - start: "2024-11-08T01:00:00+02:00"
    end: "2024-11-08T02:00:00+02:00"
    value: 2.198
  - start: "2024-11-08T02:00:00+02:00"
    end: "2024-11-08T03:00:00+02:00"
    value: 0.803
  - start: "2024-11-08T03:00:00+02:00"
    end: "2024-11-08T04:00:00+02:00"
    value: 0.498
  - start: "2024-11-08T04:00:00+02:00"
    end: "2024-11-08T05:00:00+02:00"
    value: 0.489
  - start: "2024-11-08T05:00:00+02:00"
    end: "2024-11-08T06:00:00+02:00"
    value: 0.491
  - start: "2024-11-08T06:00:00+02:00"
    end: "2024-11-08T07:00:00+02:00"
    value: 0.63
  - start: "2024-11-08T07:00:00+02:00"
    end: "2024-11-08T08:00:00+02:00"
    value: 2.978
  - start: "2024-11-08T08:00:00+02:00"
    end: "2024-11-08T09:00:00+02:00"
    value: 3.769
  - start: "2024-11-08T09:00:00+02:00"
    end: "2024-11-08T10:00:00+02:00"
    value: 3.906
  - start: "2024-11-08T10:00:00+02:00"
    end: "2024-11-08T11:00:00+02:00"
    value: 3.677
  - start: "2024-11-08T11:00:00+02:00"
    end: "2024-11-08T12:00:00+02:00"
    value: 2.073
  - start: "2024-11-08T12:00:00+02:00"
    end: "2024-11-08T13:00:00+02:00"
    value: 2.008
  - start: "2024-11-08T13:00:00+02:00"
    end: "2024-11-08T14:00:00+02:00"
    value: 1.551
  - start: "2024-11-08T14:00:00+02:00"
    end: "2024-11-08T15:00:00+02:00"
    value: 0.802
  - start: "2024-11-08T15:00:00+02:00"
    end: "2024-11-08T16:00:00+02:00"
    value: 0.717
  - start: "2024-11-08T16:00:00+02:00"
    end: "2024-11-08T17:00:00+02:00"
    value: 0.861
  - start: "2024-11-08T17:00:00+02:00"
    end: "2024-11-08T18:00:00+02:00"
    value: 0.921
  - start: "2024-11-08T18:00:00+02:00"
    end: "2024-11-08T19:00:00+02:00"
    value: 0.596
  - start: "2024-11-08T19:00:00+02:00"
    end: "2024-11-08T20:00:00+02:00"
    value: 0.739
  - start: "2024-11-08T20:00:00+02:00"
    end: "2024-11-08T21:00:00+02:00"
    value: 0.483
  - start: "2024-11-08T21:00:00+02:00"
    end: "2024-11-08T22:00:00+02:00"
    value: 0.41
  - start: "2024-11-08T22:00:00+02:00"
    end: "2024-11-08T23:00:00+02:00"
    value: 0.376
  - start: "2024-11-08T23:00:00+02:00"
    end: "2024-11-09T00:00:00+02:00"
    value: 0.314
raw_tomorrow:
  - start: "2024-11-09T00:00:00+02:00"
    end: "2024-11-09T01:00:00+02:00"
    value: 0.241
  - start: "2024-11-09T01:00:00+02:00"
    end: "2024-11-09T02:00:00+02:00"
    value: 0.004
  - start: "2024-11-09T02:00:00+02:00"
    end: "2024-11-09T03:00:00+02:00"
    value: 0
  - start: "2024-11-09T03:00:00+02:00"
    end: "2024-11-09T04:00:00+02:00"
    value: 0.001
  - start: "2024-11-09T04:00:00+02:00"
    end: "2024-11-09T05:00:00+02:00"
    value: 0.079
  - start: "2024-11-09T05:00:00+02:00"
    end: "2024-11-09T06:00:00+02:00"
    value: 0.19
  - start: "2024-11-09T06:00:00+02:00"
    end: "2024-11-09T07:00:00+02:00"
    value: 0.323
  - start: "2024-11-09T07:00:00+02:00"
    end: "2024-11-09T08:00:00+02:00"
    value: 0.526
  - start: "2024-11-09T08:00:00+02:00"
    end: "2024-11-09T09:00:00+02:00"
    value: 0.784
  - start: "2024-11-09T09:00:00+02:00"
    end: "2024-11-09T10:00:00+02:00"
    value: 1.163
  - start: "2024-11-09T10:00:00+02:00"
    end: "2024-11-09T11:00:00+02:00"
    value: 2.323
  - start: "2024-11-09T11:00:00+02:00"
    end: "2024-11-09T12:00:00+02:00"
    value: 4.526
  - start: "2024-11-09T12:00:00+02:00"
    end: "2024-11-09T13:00:00+02:00"
    value: 3.824
  - start: "2024-11-09T13:00:00+02:00"
    end: "2024-11-09T14:00:00+02:00"
    value: 5.045
  - start: "2024-11-09T14:00:00+02:00"
    end: "2024-11-09T15:00:00+02:00"
    value: 5.979
  - start: "2024-11-09T15:00:00+02:00"
    end: "2024-11-09T16:00:00+02:00"
    value: 6.767
  - start: "2024-11-09T16:00:00+02:00"
    end: "2024-11-09T17:00:00+02:00"
    value: 9.844
  - start: "2024-11-09T17:00:00+02:00"
    end: "2024-11-09T18:00:00+02:00"
    value: 11.496
  - start: "2024-11-09T18:00:00+02:00"
    end: "2024-11-09T19:00:00+02:00"
    value: 12.088
  - start: "2024-11-09T19:00:00+02:00"
    end: "2024-11-09T20:00:00+02:00"
    value: 12.102
  - start: "2024-11-09T20:00:00+02:00"
    end: "2024-11-09T21:00:00+02:00"
    value: 12.263
  - start: "2024-11-09T21:00:00+02:00"
    end: "2024-11-09T22:00:00+02:00"
    value: 11.57
  - start: "2024-11-09T22:00:00+02:00"
    end: "2024-11-09T23:00:00+02:00"
    value: 11.107
  - start: "2024-11-09T23:00:00+02:00"
    end: "2024-11-10T00:00:00+02:00"
    value: 10.04
current_price: 0.921
additional_costs_current_hour: 0
price_in_cents: true
unit_of_measurement: c/kWh
device_class: monetary
icon: mdi:flash
friendly_name: nordpool_kwh_fi_eur_3_10_0255

Current version:

Home Assistant

Core 2024.10.4
Frontend 20241002.4

I think this broke few weeks ago and it has been just fallback that I've been given.

TTV 189 for reference.
image

@kotope
Copy link
Owner

kotope commented Nov 9, 2024

Sounds really odd issue here..

Anyhow, I've created a new (easier) approach for the cheapest hours so I don't really maintain this one that much anymore.
You might want to check out the new integration at https://github.com/kotope/aio_energy_management

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

No branches or pull requests

2 participants