blueprint:
  name: EDF Energy - Manual Smart Charging Refresh
  description: Handle the refresh of Smart Charging dispatches automatically, while refreshing when an external car sensor is plugged in. When automatic, will use normal backoff methods in event of failure.
  domain: automation
  author: BottlecapDave (amended for EDF Energy by Steve Kirtley)

  input:
    intelligent_dispatches_data_last_retrieved_sensor:
      name: Smart Charging dispatches data last retrieved
      description: "The sensor that determines when Smart Charging dispatches data was last retrieved (e.g. sensor.edf_energy_{{DEVICE_ID}}_intelligent_dispatches_data_last_retrieved)."
      selector:
        entity:
          filter:
            domain: sensor
            integration: edf_energy

    intelligent_dispatches_sensor:
      name: Smart Charging dispatches
      description: "The sensor that determines if Smart Charging dispatches is active (e.g. binary_sensor.edf_energy_{{DEVICE_ID}}_intelligent_dispatching)"
      selector:
        entity:
          filter:
            domain: binary_sensor
            integration: edf_energy

    car_plugged_in_sensor:
      name: Car plugged in sensor (external)
      description: "The external sensor that determines if the car has been plugged in (e.g. binary_sensor.car_is_plugged_in). This sensor is provided by an integration outside of the EDF Energy integration."
      selector:
        entity:
          filter:
            domain:
            - binary_sensor
            - sensor
            - input_boolean

    car_plugged_in_sensor_state:
      name: Car plugged in sensor expected state
      description: "The expected state of the external sensor that determines if the car has been plugged in (e.g. 'on')."
      selector:
        text:
          multiple: true

    actions:
      name: Actions
      description: Additional actions to run after refresh
      default: []
      selector:
        action: {}

variables:
  intelligent_dispatches_data_last_retrieved_sensor: !input intelligent_dispatches_data_last_retrieved_sensor
  intelligent_dispatches_sensor: !input intelligent_dispatches_sensor
  car_plugged_in_sensor: !input car_plugged_in_sensor
  millisecond_jitter: >
    {{ range(1, 1000) | random }}

mode: single
triggers:
  - trigger: state
    id: car_plugged_in
    entity_id: !input car_plugged_in_sensor
    to: !input car_plugged_in_sensor_state
  - trigger: state
    id: car_unplugged
    entity_id: !input car_plugged_in_sensor
    from: !input car_plugged_in_sensor_state
    not_to: !input car_plugged_in_sensor_state
  - trigger: time_pattern
    id: periodic_check
    minutes: "/1"
conditions:
  - condition: or
    conditions:
    - condition: and
      conditions:
      - condition: state
        entity_id: !input car_plugged_in_sensor
        state: !input car_plugged_in_sensor_state
      # Make sure that our dispatches are either due to be updated or our automation was triggered due to the vehicle being plugged in
      - condition: or
        conditions:
        - condition: template
          value_template: >
            {{ trigger.id == "car_plugged_in" }}
        - condition: template
          value_template: >
            {% set next_refresh = state_attr(intelligent_dispatches_data_last_retrieved_sensor, 'next_refresh') %}
            {{ next_refresh == None or next_refresh | as_datetime | as_local < now() }}
    - condition: template
      value_template: >
        {{ trigger.id == "car_unplugged" }}
actions:
  # Wait 30 seconds to give EDF Energy a chance to update the dispatches if caused by car state change
  - if:
    - condition: template
      value_template: >
        {{ trigger.id != "periodic_check" }}
    then:
    - delay: 00:00:30
  # Wait until we are under the request limit
  - wait_template: >-
      {% set requests_current_hour = state_attr(intelligent_dispatches_data_last_retrieved_sensor, 'requests_current_hour') %}
      {% set maximum_requests_per_hour = state_attr(intelligent_dispatches_data_last_retrieved_sensor, 'maximum_requests_per_hour') %}
      {% set request_limits_last_reset = state_attr(intelligent_dispatches_data_last_retrieved_sensor, 'request_limits_last_reset') %}
      {{ requests_current_hour == None or
        (requests_current_hour | int < maximum_requests_per_hour | int) or
        request_limits_last_reset + timedelta(hours=1) < now()
      }}
    continue_on_timeout: true
  # Add a bit of jitter so the API isn't hit at once
  - delay:
      milliseconds: >
         {{ millisecond_jitter }}
  - action: edf_energy.refresh_intelligent_dispatches
    target:
      entity_id: !input intelligent_dispatches_sensor
  - choose: []
    default: !input actions
