Updated Sensor YAML for 2024/25: Adding National Grid’s DFS Dates to Home Assistant

National Grid have brought back the DFS scheme back again for the winter of 2024-25, albeit this time with significant reductions in the terms of financial compensation for those participating. Once again there appears to have been a few changes to the data in the API, so the below YAML has been updated to reflect those changes. National Grid have a habit of tweaking things mid-season so whilst the code has worked for me in testing, it may unexpectedly break.

Home Assistant Sensor YAML

I strongly suggest using a package to keep the sensor YAML together rather than cluttering up your configuration file. The code below should be placed in file called national_grid_dfs–202425.yaml located in the directory /homeassistant/packages/National Grid DFS 2024-25/. You can of course pull the relevant code out of the below example and directly insert it in your configuration file.

This following package will create two sensors, one for the start date and time, and one for end date and time for the latest event. This loops through the data checking for the latest event, and then keeps looking to find the start time of the first session, and the end time of the last session in that event. This example is set for Octopus Energy, see the original post Adding National Grid’s DFS Dates to Home Assistant for information on how to change this to another supplier.

national_grid_dfs_202425:
## National Grid Demand Flexibility Service
    sensor:

        # All Events - OctopusEnergyLimited Accepted
        
        # Start Time and Date
      - platform: rest
        resource: "https://api.nationalgrideso.com/api/3/action/datastore_search_sql?sql=SELECT%20COUNT(*)%20OVER%20()%20AS%20_count,%20*%20FROM%20%22cc36fff5-5f6f-4fde-8932-c935d982ecd8%22%20WHERE%20%22Status%22%20=%20'Accepted'%20AND%20%22Registered%20DFS%20Participant%22%20=%20'OctopusEnergyLimited'%20ORDER%20BY%20%22_id%22%20ASC%20LIMIT%20100"
        scan_interval: 900
        name: National Grid ESO Latest DFS Event Start 24-25
        unique_id: 2425_national_grid_eso_latest_event_dfs_start
        value_template: >-
            {% set d = value_json['result']['records'][0]['Delivery Date'] %}
            {% if '/' in d %}
                        {% set ns=namespace(start_time = strptime(d+' '+value_json['result']['records'][0]['From'],'%d/%m/%Y %H:%M')) %}
                        {% for record in value_json['result']['records'] %}
                          {% if record['Delivery Date'] == d -%}
                            {% if strptime(d+' '+record['From'],'%d/%m/%Y %H:%M') <= ns.start_time -%}
                              {% set ns.start_time = strptime(d+' '+record['From'],'%d/%m/%Y %H:%M') %}
                            {%- endif %}
                          {%- endif %}
                        {% endfor %}
            {% else %}
                        {% set ns=namespace(start_time = strptime(d+' '+value_json['result']['records'][0]['From'],'%Y-%m-%d %H:%M:%S')) %}
                        {% for record in value_json['result']['records'] %}
                          {% if record['Delivery Date'] == d -%}
                            {% if strptime(d+' '+record['From'],'%Y-%m-%d %H:%M:%S') <= ns.start_time -%}
                              {% set ns.start_time = strptime(d+' '+record['From'],'%Y-%m-%d %H:%M:%S') %}
                            {%- endif %}
                          {%- endif %}
                        {% endfor %}
            {% endif %}         
            {{ns.start_time}}

        # End Time and Date
      - platform: rest
        resource: "https://api.nationalgrideso.com/api/3/action/datastore_search_sql?sql=SELECT%20COUNT(*)%20OVER%20()%20AS%20_count,%20*%20FROM%20%22cc36fff5-5f6f-4fde-8932-c935d982ecd8%22%20WHERE%20%22Status%22%20=%20'Accepted'%20AND%20%22Registered%20DFS%20Participant%22%20=%20'OctopusEnergyLimited'%20ORDER%20BY%20%22_id%22%20ASC%20LIMIT%20100"
        scan_interval: 900
        name: National Grid ESO Latest DFS Event End 24-25
        unique_id: 2425_national_grid_eso_latest_event_dfs_end
        value_template: >-
            {% set d = value_json['result']['records'][0]['Delivery Date'] %}
            {% if '/' in d %}
                        {% set ns=namespace(end_time = strptime(d+' '+value_json['result']['records'][0]['To'],'%d/%m/%Y %H:%M')) %}
                        {% for record in value_json['result']['records'] %}
                          {% if record['Delivery Date'] == d -%}
                            {% if strptime(d+' '+record['To'],'%d/%m/%Y %H:%M') >= ns.end_time -%}
                              {% set ns.end_time = strptime(d+' '+record['To'],'%d/%m/%Y %H:%M') %}
                            {%- endif %}
                          {%- endif %}
                        {% endfor %}
            {% else %}
                        {% set ns=namespace(end_time = strptime(d+' '+value_json['result']['records'][0]['To'],'%Y-%m-%d %H:%M:%S')) %}
                        {% for record in value_json['result']['records'] %}
                          {% if record['Delivery Date'] == d -%}
                            {% if strptime(d+' '+record['To'],'%Y-%m-%d %H:%M:%S') >= ns.end_time -%}
                              {% set ns.end_time = strptime(d+' '+record['To'],'%Y-%m-%d %H:%M:%S') %}
                            {%- endif %}
                          {%- endif %}
                        {% endfor %}
            {% endif %}         
            {{ns.end_time}}

        # Event Price kWh
      - platform: rest
        resource: "https://api.nationalgrideso.com/api/3/action/datastore_search_sql?sql=SELECT%20COUNT(*)%20OVER%20()%20AS%20_count,%20*%20FROM%20%22cc36fff5-5f6f-4fde-8932-c935d982ecd8%22%20WHERE%20%22Status%22%20=%20'Accepted'%20AND%20%22Registered%20DFS%20Participant%22%20=%20'OctopusEnergyLimited'%20ORDER%20BY%20%22_id%22%20ASC%20LIMIT%20100"
        scan_interval: 900
        name: National Grid ESO Latest DFS Event Price per kWh 24-25
        unique_id: 2425_national_grid_eso_latest_event_dfs_price_kWh
        value_template: >-
            {% set d = value_json['result']['records'][0]['Delivery Date'] %}
            {% if '/' in d %}
                        {% set ns=namespace(start_time = strptime(d+' '+value_json['result']['records'][0]['From'],'%d/%m/%Y %H:%M')) %}
                        {% for record in value_json['result']['records'] %}
                          {% if record['Delivery Date'] == d -%}
                            {% if strptime(d+' '+record['From'],'%d/%m/%Y %H:%M') <= ns.start_time -%}
                              {% set ns.start_time = strptime(d+' '+record['From'],'%d/%m/%Y %H:%M') %}
                              {% set ns.price_kWh = record['Utilisation Price GBP per MWh'] | float %}
                            {%- endif %}
                          {%- endif %}
                        {% endfor %}
            {% else %}
                        {% set ns=namespace(start_time = strptime(d+' '+value_json['result']['records'][0]['From'],'%Y-%m-%d %H:%M:%S')) %}
                        {% for record in value_json['result']['records'] %}
                          {% if record['Delivery Date'] == d -%}
                            {% if strptime(d+' '+record['From'],'%Y-%m-%d %H:%M:%S') <= ns.start_time -%}
                              {% set ns.start_time = strptime(d+' '+record['From'],'%Y-%m-%d %H:%M:%S') %}
                              {% set ns.price_kWh = record['Utilisation Price GBP per MWh'] | float %}
                            {%- endif %}
                          {%- endif %}
                        {% endfor %}
            {% endif %}   
            
            {{"£%.2f"|format(ns.price_kWh /1000 |float) }}    
            
        
        # Event Type
      - platform: rest
        resource: "https://api.nationalgrideso.com/api/3/action/datastore_search_sql?sql=SELECT%20COUNT(*)%20OVER%20()%20AS%20_count,%20*%20FROM%20%22cc36fff5-5f6f-4fde-8932-c935d982ecd8%22%20WHERE%20%22Status%22%20=%20'Accepted'%20AND%20%22Registered%20DFS%20Participant%22%20=%20'OctopusEnergyLimited'%20ORDER%20BY%20%22_id%22%20ASC%20LIMIT%20100"
        scan_interval: 900
        name: National Grid ESO Latest DFS Event Type 24-25
        unique_id: 2425_national_grid_eso_latest_event_dfs_type
        value_template: >-
            {% set d = value_json['result']['records'][0]['Delivery Date'] %}
            {% if '/' in d %}
                        {% set ns=namespace(start_time = strptime(d+' '+value_json['result']['records'][0]['From'],'%d/%m/%Y %H:%M')) %}
                        {% for record in value_json['result']['records'] %}
                          {% if record['Delivery Date'] == d -%}
                            {% if strptime(d+' '+record['From'],'%d/%m/%Y %H:%M') <= ns.start_time -%}
                              {% set ns.start_time = strptime(d+' '+record['From'],'%d/%m/%Y %H:%M') %}
                              {% set ns.event_type = record['Service Requirement Type'] %}
                            {%- endif %}
                          {%- endif %}
                        {% endfor %}
            {% else %}
                        {% set ns=namespace(start_time = strptime(d+' '+value_json['result']['records'][0]['From'],'%Y-%m-%d %H:%M:%S')) %}
                        {% for record in value_json['result']['records'] %}
                          {% if record['Delivery Date'] == d -%}
                            {% if strptime(d+' '+record['From'],'%Y-%m-%d %H:%M:%S') <= ns.start_time -%}
                              {% set ns.start_time = strptime(d+' '+record['From'],'%Y-%m-%d %H:%M:%S') %}
                              {% set ns.event_type = record['Service Requirement Type'] %}
                            {%- endif %}
                          {%- endif %}
                        {% endfor %}
            {% endif %}   
            
            {{ns.event_type}}	

Using the Sensors

Now that you’ve got the data, its possible to create automations in Home Assistant to turn off any unnecessary devices at the start time of the event, and turn them back on at the end. To do this, I created 2 date-time helpers which trigger such an automation. To update the date-time helper you need to create an automation that runs on a regular basis, or is triggered by the refreshing of the sensors. You can use similar to the below in the action section of an automation. Repeat this for each of the helpers and their corresponding sensors.

      - service: input_datetime.set_datetime
        data:
          datetime: >-
            {{
            strptime(states('sensor.2425_national_grid_eso_latest_event_dfs_start'),
            '%Y-%m-%d %H:%M:%S') }}
        target:
          entity_id: input_datetime.dfs_event_start

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *