Octopus Energy Agile Tariff

Agile rate dates are in UTC thus when converting to BST we are getting two slots (23:00 - 23:30 and 23:30 - 00:00) from the previous day. This is why in my last attempt I’m actually taking 00:00 of current day in local time and convert it to UTC with timestamp_custom('%Y-%m-%dT%H:%M:%SZ', False):

{% set from = as_timestamp(as_timestamp(now()) | timestamp_custom('%Y-%m-%d') + 'T00:00:00') %}
{% set to = from + 24 * 60 * 60 %}
{% set format = '%Y-%m-%dT%H:%M:%SZ' %}
https://api.octopus.energy/v1/products/AGILE-18-02-21/electricity-tariffs/E-1R-AGILE-18-02-21-{{ region }}/standard-unit-rates/?period_from={{ from | timestamp_custom('%Y-%m-%dT%H:%M:%SZ', False) }}&period_to={{ to | timestamp_custom('%Y-%m-%dT%H:%M:%SZ', False) }}

I think it should be OK this time. My latest package is here:

Is the calorific value fixed at 39.1? I have not has my first bill yet but I do remember that OVO used 40.2 or something like that.

No, it varies because, naturally, it varies. You will be billed an average value over the time of the bill IIRC.

Thanks, I do know it varies but I thought that companies use a fixed average value they establish for themselves. I do remember SMETS1 used to report values in kWh.

You’ll have to wait for your first bill I guess.
Mine says this near the bottom …

Your energy usage is calculated from your gasconsumption using a standard industry formula:
Units Consumed (Cubic Metres)× Volume Correction (for temperature & pressure)× Calorific Value (energy in each m3 of gas)÷ 3.6 (convert from joules)≈ Usage (in kWh)
For you:118.8 × 1.02264 × 39.1† ÷ 3.6 = 1319.5† Average calorific value shown to one decimal place.
1 Like

Thanks! BTW, I’ve also added another sensor which shows forthcoming rates and will update code on GitHub at some point. My dashboard is close to what I wanted it to look like :slight_smile:

UPDATE: Added estimated cost and savings compared to fixed tariff.

6 Likes

Probably a discussion for another place but although the HUD/IHD will show in kWh, I suggest the meter itself can only measure the volume passing through and that is what is reported to DCC.

1 Like

Absolutely love it, would you mind sharing your dashboard json code?

It is not as straightforward I’m afraid :slight_smile: as I’m generating tiles on the fly, but you can get the general idea:

 {
         title: 'Octopus',
         bg: 'images/bg2.png',
         icon: 'mdi-flash',
         tileSize: 180,
         groups: [
            {
               title: 'Electricity rates',
               width: 4,
               height: 2.2,
               items: [
                  $$(TILES.AGILE_CURRENT_RATE, [0, 0]),
                  $$(TILES.AGILE_NEXT_RATE, [1, 0]),
                  $$(TILES.AGILE_MIN_UPCOMING_RATE, [2, 0]),
                  $$(TILES.AGILE_AVG_RATE_TODAY, [3, 0]),
               ].concat([1, 2, 3, 4].map(function (col, i) {
                  var rows = 12;
                  var entity = 'sensor.agile_upcoming_rates';
                  var getItem = function(ctx, index) {
                     return ctx.states[entity].attributes.results[index];
                  }

                  return $$(TILE_CONFIGS.AGILE_RATES_LIST, {
                     id: entity,
                     position:[i, 1.08],
                     list: Array(rows).fill(null).map(function(row, j) {
                        return {
                            icon: function() {
                                 var rate = getItem(this, j + rows * i).value_inc_vat;
                                 if(rate) return rate < 13 ? 'mdi-arrow-down-box' : (rate < 18 ? 'mdi-checkbox-blank' : 'mdi-arrow-up-box');
                            },
                            title: function() {
                               var item = getItem(this, j + rows * i);
                               if(item) return formatTime(item.valid_from) + ' - ' + formatTime(item.valid_to);
                            },
                            value: function() {
                               var rate = getItem(this, j + rows * i).value_inc_vat;
                               if(rate) return parseFloat(rate).toFixed(2) + 'p';
                            }
                        }
                    })
                  });
               }))
            }
   AGILE_RATES_LIST: {
      type: TYPES.TEXT_LIST,
      width: 1,
      height: 1.55,
      state: false,
      title: '',
      classes: ['-agile-rates']
   },

This is how I’ve integrated Octopus API (didn’t want to use custom component):

1 Like

How are you generating tiles on the fly? Are you using a custom component for that?

I’ve found your GitHub page :slight_smile:

Just the power of JavaScript :slight_smile:

1 Like

A bit out of my league :stuck_out_tongue:

I can always help :slight_smile:

Are you using TileBoard to produce the table?

Yes, I am.

It looks awesome, I wish I had more time to play with it :smiley:

I’ve added the code to config.js and I have the sensors from your GitHub, I’m just not sure where this goes

   AGILE_RATES_LIST: {
      type: TYPES.TEXT_LIST,
      width: 1,
      height: 1.55,
      state: false,
      title: '',
      classes: ['-agile-rates']
   },

Got this error
image

I guess Im missing the tiles…

Yeah, you can’t blindly copy-paste it, there are a lot of things I’m using from other files. I’m only posted it to show a general idea.

Think I have worked out the BST.

I have just removed the Z from the end of the times

{{ ts_now |timestamp_custom (’%Y-%m-%dT%H:%M:%SZ’) }}&period_to=
{{ (ts_now + 246060) |timestamp_custom (’%Y-%m-%dT%H:%M:%SZ’) }}

Does anyone know how to resolve these errors , as far as I can tell there is a problem reading a json file - but the only json I know of in this context is the octopusagile,json file but if I delete that the problem just reappears a a hort while later. In any case the problem does not appear to happen every half hour when I expect that that particular file is read.

2021-04-20 10:00:01 ERROR (SyncWorker_2) [custom_components.octopusagile] Expecting value: line 1 column 1 (char 0)

2021-04-20 10:00:25 ERROR (SyncWorker_5) [custom_components.octopusagile] Expecting value: line 1 column 1 (char 0)

2021-04-20 11:30:16 ERROR (SyncWorker_0) [custom_components.octopusagile] Expecting value: line 1 column 1 (char 0)

2021-04-20 12:00:00 ERROR (MainThread) [homeassistant.helpers.entity] Update for sensor.octopus_agile_previous_rate fails

Traceback (most recent call last):

File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 292, in async_update_ha_state

await self.async_device_update()

File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 490, in async_device_update

raise exc

File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run

result = self.fn(*self.args, **self.kwargs)

File "/config/custom_components/octopusagile/sensor.py", line 85, in update

rate = round(self.myrates.get_previous_rate(), 2)

File "/config/custom_components/octopusagile/OctopusAgile/Agile.py", line 302, in get_previous_rate

date_rates = self.get_rates(prev_time, rounded_time)["date_rates"]

File "/config/custom_components/octopusagile/OctopusAgile/Agile.py", line 219, in get_rates

results = self.get_raw_rates(date_from, date_to)

File "/config/custom_components/octopusagile/OctopusAgile/Agile.py", line 210, in get_raw_rates

results = self.get_raw_rates_json(date_from, date_to)["results"]

File "/config/custom_components/octopusagile/OctopusAgile/Agile.py", line 195, in get_raw_rates_json

results = r.json()

File "/usr/local/lib/python3.8/site-packages/requests/models.py", line 900, in json

return complexjson.loads(self.text, **kwargs)

File "/usr/local/lib/python3.8/site-packages/simplejson/__init__.py", line 525, in loads

return _default_decoder.decode(s)

File "/usr/local/lib/python3.8/site-packages/simplejson/decoder.py", line 370, in decode

obj, end = self.raw_decode(s)

File "/usr/local/lib/python3.8/site-packages/simplejson/decoder.py", line 400, in raw_decode

return self.scan_once(s, idx=_w(s, idx).end())

simplejson.errors.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

2021-04-20 12:00:00 ERROR (MainThread) [homeassistant.helpers.entity] Update for sensor.octopus_agile_min_rate fails

Traceback (most recent call last):

File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 292, in async_update_ha_state

await self.async_device_update()

File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 490, in async_device_update

raise exc

File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run

result = self.fn(*self.args, **self.kwargs)

File "/config/custom_components/octopusagile/sensor.py", line 277, in update

new_rates = self.myrates.get_new_rates()["date_rates"]

File "/config/custom_components/octopusagile/OctopusAgile/Agile.py", line 216, in get_new_rates

return self.get_rates(date_from)

File "/config/custom_components/octopusagile/OctopusAgile/Agile.py", line 219, in get_rates

results = self.get_raw_rates(date_from, date_to)

File "/config/custom_components/octopusagile/OctopusAgile/Agile.py", line 210, in get_raw_rates

results = self.get_raw_rates_json(date_from, date_to)["results"]

File "/config/custom_components/octopusagile/OctopusAgile/Agile.py", line 195, in get_raw_rates_json

results = r.json()

File "/usr/local/lib/python3.8/site-packages/requests/models.py", line 900, in json

return complexjson.loads(self.text, **kwargs)

File "/usr/local/lib/python3.8/site-packages/simplejson/__init__.py", line 525, in loads

return _default_decoder.decode(s)

File "/usr/local/lib/python3.8/site-packages/simplejson/decoder.py", line 370, in decode

obj, end = self.raw_decode(s)

File "/usr/local/lib/python3.8/site-packages/simplejson/decoder.py", line 400, in raw_decode

return self.scan_once(s, idx=_w(s, idx).end())

simplejson.errors.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

2021-04-20 12:00:00 ERROR (SyncWorker_8) [custom_components.octopusagile] Expecting value: line 1 column 1 (char 0)

2021-04-20 15:00:00 ERROR (SyncWorker_2) [custom_components.octopusagile] Expecting value: line 1 column 1 (char 0)

2021-04-20 15:30:13 ERROR (SyncWorker_1) [custom_components.octopusagile] Expecting value: line 1 column 1 (char 0)

2021-04-20 16:10:49 ERROR (MainThread) [homeassistant.helpers.script.websocket_api_script] websocket_api script: Error executing script. Unexpected error for call_service at pos 1: Expecting value: line 1 column 1 (char 0)

You’ve got me wondering… in the last few days, I’ve started seeing issues where by the ‘start_in:’ attribute does not update. I use ‘start_in: x’ to trigger notifications and devices. If a manually run the half hour service, then it seems to update.

I’m wondering if this might be related, I need to enable some additional logging…