Octopus Energy - Gas Tracker Tariff Dynamic Pricing sensors - SOLVED


So I recently moved over to Octopus Energy’s gas tracker tariff. The price for your gas is set at 00:00 each day based on wholesale pricing with a price cap for consumer protection, and it’s a flat rate for the whole day. Setting this correctly lets more accurately model my gas consumption costs using the stock Home Assistant Energy tooling.

The API for the day pricing on electricity is extensively documented, both by Octopus and third party authors. The Gas Tracker however required that I research on the Octopus Intelligent forum, and even then it took some final integration on my part.

I’m not going to claim this is the most elegant approach. I’ve broken my calculations into separate sensors where I felt something might have reuse value/I want to track it independently. There is probably a single sensor solution for this with the correct value template, but I can stand the extra two template sensors.

It consists of three parts —

  1. Day number Template Sensor - sourced from here: [Create sensor to show only today's day "number" (i.e. 2017-09-05, my sensor would output the "05")]
- platform: template
        value_template: '{{now().strftime("%-d")}}'

I need this as the Octopus API for the returns JSON I can address as an array. Said array is base index 0 and contains only Tracker values for this month, be they calculated yet or not, in date order. If you’re interested, future values are pre-populated with last year’s data (we think).

  1. Octopus API REST sensor - Todays Tracker price
    I hit the Octopus web API which returns Tracker data for my tariff. Finding your tariff code (in my example: G-1R-SILVER-22-07-22-H) is a challenge. The last letter is your DNO region code which you can lookup (I’ll provide links) and the tariff name was provided to me on one of my sign up emails or in my Octopus account dashboard. I’ll update this thread with ideas on that if you need them.
  - platform: rest
    resource: https://octopus.energy/api/v1/tracker/G-1R-SILVER-22-07-22-H/daily/current/0/0
    method: GET
    name: octopus_uncapped_gas_tracker_cost_by_API
    value_template: "{{((value_json.periods[((states('sensor.today_number') | float | round(0)-1))].unit_rate)/100) | round (4) }}"
    unit_of_measurement: 'GBP/kWh'
    scan_interval: 3600
    force_update: true
    icon: hass:currency-gbp

This sensor returns the UNCAPPED rate for the day. It’s set to update pretty infrequently, as the way I’d expect someone to use this is to force an entity update using NodeRed at 00:05.
[Manually refresh rest sensor?]
[How to translate this to NodeRED?]

You’ll note I perform the minus 1 operation on the day number here, after converting it into a simple integer, as I may not always want to reference the day number as an array index. There’s also a divide by 100 function on the API return as it provides the units in pence and HASS elements expect it in GBP. The rounding is just for my own sanity.

  1. Capped rate Template Sensor
    This one is essentially a clone sensor, copying the value in sensor (2) unless it’s greater than 16 pence, in which case it flattens it down to that value. You may be on the 22p capped tracker if you joined later than me, or the 10p capped tariff. Guess what you have to change? :smiley:
#Octopus Tracker unit rate sensor
- platform: template
        unique_id: sensor.octopus_gas_tracker_unit_rate_with_cap
        friendly_name: "Octopus Tracker Unit Rate"
        unit_of_measurement: 'GBP/kWh'
        icon_template: hass:currency-gbp
        value_template: >
          {% if (states('sensor.octopus_uncapped_gas_tracker_cost_by_API') | float) < 0.16 %}
          {% else %}
          {% endif %}

I’m probably going to change the cap number and tariff code to be input helpers in Home Assistant, so I don’t have to dig into the code next year assuming the API operates the same way, but for the purposes of someone getting value out of this tutorial, I’ll keep it without those elements.

I hope this is of some use to someone. I’ll post a follow-up on getting your Gas Tracker product code and region code. Good primer lives in terms of general approach lives here: [Guy Lipman - Energy]

P.S. I’m not sure if this entire endeavour is made irrelevant by the Octopus Energy HASS integration BUT if you want something lighter weight or to explore first principles? I’m going to go upset myself now by way of installing suspected successor.

Ah-hah! It’s not redundant! It’s not! The Octopus Energy integration has no idea how to handle the Gas Tracker tariff yet. I mean, it probably will at some point, but for now, there’s always my musings above.

Okay. So the Gas Tracker tariffs are not listed/explorable by way of the API, so this block from Guy’s research seems relevant to assist you finding your tracker tariff path by way of ‘working it out’

Each tariff belongs to a product. There are multiple tariffs for each product, mostly distinguished by the region, whether it is a single or dual register (economy 7 is an example of dual register) and whether it electricity or gas. To identify the product code for a particular tariff, you can usually take off the first few letters of the tariff (E-1R-, E-2R- or G-1R) which indicate if it is electricity single register, electricity dual register (eg economy7) or gas single register, and the letter at the end (eg -A) which indicates the region code. So, for example, E-1R-VAR-19-04-12-N is one of the tariffs for product VAR-19-04-12.


I’ve just switched to a gas tracker so added this into my dashboard.
I had to tweak it slightly as HA now requires a default value for float, so added (0) after each float & works fine.

I obviously changed the region code to my area & also duplicated the code to grab the standing charge too.

I use the data to give me a live total cost for the day which calculates my live gas & electricity useage plus standing charges, then adjusts depending on my total export that has been sold back to the grid.

Thanks! I’ll apply your update.

Something else I’ve noticed is that the API doesn’t always cleanly. Could be something local (DNS on my network or whatever) but I think what I want to do is, in the event that 0 is returned by the wholesale sensor, make the applied rate sensor whatever my cap value is.

That or retain yesterdays number using this sort of code.
[Sensor: If "not available" occurs keep the previous value - #4 by Troon]

I’m thinking I’d rather air on the side of overcosting and go with the cap though.

Okay. This was easily done with floats. And by leaving the RESTful sensor ‘dirty’ in terms of it’s float, it returns unknown, which tells me when the API is not working, and I’m assuming a value on the billable rate sensor.

(note: code has been ported to use a helper input number, hence any discrepancy)

#Octopus Tracker unit rate sensor
        unique_id: sensor.octopus_gas_tracker_unit_rate_with_cap
        friendly_name: "Octopus Tracker Unit Rate"
        unit_of_measurement: 'GBP/kWh'
        icon_template: hass:currency-gbp
        value_template: >
          {% if (states('sensor.octopus_uncapped_gas_tracker_cost_by_API') | float(states('input_number.octopus_gas_tracker_capped_price')|float(0))) < (states('input_number.octopus_gas_tracker_capped_price') | float(0)) %}
          {% else %}
          {% endif %}

Okay - Now I have the code for tomorrow’s forecast/contracted Gas Wholesale rates.

Octopus publish this to their API at 18:00. With some mild steer from the developer of the iOS app Home-Aid, I managed to pull the below code together:

  - platform: rest
    resource_template: https://api.octopus.energy/v1/products/SILVER-22-07-22/gas-tariffs/G-1R-SILVER-22-07-22-H/standard-unit-rates/?period_from={{(now().timestamp()+ (86400)) | timestamp_custom('%Y-%m-%d')}}
    method: GET
    name: octopus_uncapped_gas_tracker_forecast_by_API
    value_template: "{{(value_json.results[0].value_inc_vat/100) | round (5) }}"
    unit_of_measurement: 'GBP/kWh'
#    scan_interval: 3600
    force_update: true
    icon: hass:currency-gbp

This time I baked my date logic into the sensor itself using timestamp functioning. Now I understand it, I’ll probably take the ‘day number sensor’ out of my wider setup and just refactor my original sensor.

Walking through it, you need to know your product code (in this case SILVER-22-07-22) and your regionalised product code (G-1R-SILVER-22-07-22-H in this case).

This RESTful call is constructed requesting a ‘period_from’ parameter of tomorrow’s date, programatically constructed by taking the ‘now’ timestamp, adding 86400 seconds (a day, basically), and then piping that to a custom formatting function to refactor to the expected format for the API query.

The call returns a single item array if tomorrow’s price is published, populating the sensor with a numeric value. If it’s not published yet, it returns no array, so the sensor calculates out to ‘unknown’.

Hope this helps!

P.S. I’ve made some assumptions that an automation is going to call this as and when, so don’t have a scan interval. Yada, yada, thanks for all the fish.

1 Like

Do you know the api for the new v3 gas tracker, it doesn’t seem to follow any logic I can guess at - product code "“G-1R-SILVER-FLEX-22-11-25-H”

Thanks in advance

I can’t make it work either with the same product

I had the same issue as @IMgoRt - for some reason the deeper queries fail, but I’ve manged to get something that appears to work for the new gas Tracker (at least it gives me a price which is the same as the Octopus app). The ‘_A’ appears to be the area you are in (so analogous to the -H above).

  - platform: rest
    resource: https://api.octopus.energy/v1/products/SILVER-FLEX-22-11-25/
    name: "Octopus Gas Price"
    value_template: "{{ (value_json['single_register_gas_tariffs']['_A']['direct_debit_monthly'].standard_unit_rate_inc_vat/100) | round (5) }}"
    unit_of_measurement: 'GBP/kWh'
    scan_interval: 600

Hey guys,

Apologies for not replying. I’m glad Ian was able to discover another way. Thanks!

It’s maddening as there isn’t consistency across the products, and now it appears there isn’t consistency on different versions of the same product.

I guess I’ve paid less attention as mine has been working consistently since it went in.

I’ll see if they have backported Ian’s calls to my tariff code, just out of academic interst.

Yup. Checked it out. Utterly nonsensical. I can pull todays applicable rate from the top level ‘all regions’ query, but I can’t pull the historical data and the lookahead pricing for this product, even though I call the EXACT URL Octopus publish in their API JSON return they advertise for such work.

I don’t know what to say but ‘blame the 8 legged one’. One for the Octopus Developers forums I think.

I’m getting a little wrapped up trying to get this working, is there a template to follow or do I need to add some of the first 2 templates with Ians ? Thanks !

Hi Mr P,

Not sure if this is news … I’m new to using Octopus API and these forums. Full current month rates (inc breakdown) can be pulled for this tariff from the following resources:

Gas: https://octopus.energy/api/v1/tracker/G-1R-SILVER-FLEX-22-11-25-L/daily/current/0/0/

Electric: https://octopus.energy/api/v1/tracker/E-1R-SILVER-FLEX-22-11-25-L/daily/current/0/0/

(The “L” at the end obviously needs replacing with your region code).

Those url’s pull the entire current months data for gas & electric for the November 22 tracker.

Ian’s template appears to replace <2> on my initial post. Does that help? If it doesn’t, feel free to talk me through what you’ve done so far and I’ll see if I can assist.


That does help - I’ll see if this method can be backported to older tariffs such as mine. If it can, I’ll rebase, republish and consider it authoritative.



Glad to help. I hear Octopus are working on porting the tariff into their normal api but not a priority.

I’ve also been told that currently, aside from standing charges, all tracker rates are the same as they are below the cap, so theoretically one could import prices from an earlier tracker as another temporary measure. This would have the advantage of being nearer to OE’s standard api use.

Ooo, will give this a whirl! Tmrw’s price is the only missing piece

Screenshot 2023-02-17 at 09.59.30

1 Like

Might you be able to share your code for this, please?

Are you live updating electric prices from the API? And usage from your meter? I would love to do this!

Hi All - has there been any progress with the octopus integration and gas tracker? I was hoping my current gas tariff would just update to reflect changes each day. Perhaps not.

1 Like