PhilPJL / ImpSoft.OctopusEnergy

A .Net and .Net Core client for Octopus Energy's tariff and energy consumption API.
MIT License
10 stars 4 forks source link

Call to GetElectricityUnitRatesAsync takes over a minute to return #13

Closed NibblyPig closed 3 years ago

NibblyPig commented 3 years ago

Bit odd, as a call to GetElectricityConsumptionAsync for the past 24 hours returns instantly.

Using a client initialised with my API key (and after a call to GetElectricityConsumptionAsync) I do this:

var productCode = "AGILE-18-02-21";

var tariff = "E-1R-AGILE-18-02-21-L";

Stopwatch sw = Stopwatch.StartNew();
var data = await client.GetElectricityUnitRatesAsync(productCode, tariff);
var timeTaken = sw.Elapsed.TotalSeconds;

The value of timeTaken is around 90 seconds.

Doing this:

curl -u "[myKey]" "https://api.octopus.energy/v1/products/AGILE-18-02-21/electricity-tariffs/E-1R-AGILE-18-02-21-L/standard-unit-rates/" returns instantly.

Any idea why there's such a huge delay?

PhilPJL commented 3 years ago

Hey, someone is using my API :)

When you use "curl -u" you're only retrieving a single page of results at a time. The api is retrieving all available pages within a specified date range, which right now with the default values is 74000 unit rates. In order to limit the results, you need to set the from/to interval for which you require results. Internally the code is

return await GetCollectionAsync<Charge>(ComposeGetElectricityUnitRatesUri(productCode, tariffCode, rate, from, to));

With the default values this will try to get all available standard unit rates.

The code below requests all standard rates from 1st March to now and returns 1100 unit rates in 0.28 seconds. Whereas with default values the api returns 74000 unit rates in 3.6 seconds (for me anyway).

var from = new DateTimeOffset(2021, 03, 01, 0, 0, 0, TimeSpan.Zero);
var data = await api.GetElectricityUnitRatesAsync(productCode, tariff, ElectricityUnitRate.Standard, from);
data.Count().Dump();
var timeTaken = sw.Elapsed.TotalSeconds;            
timeTaken.Dump();
NibblyPig commented 3 years ago

I see, are you using their .NET wrapper? I couldn't find any documentation on that or get it to work, which is where I stumbled upon yours and tried that. In the end though I just did a direct call to their REST api myself. Without any parameters it returns the count of total records but only the latest 100 results:

public async Task<GetUnitRatesResponse> GetElectricityUnitRates(string productCode, string tariff)
{
    var url = $"https://api.octopus.energy/v1/products/{productCode}/electricity-tariffs/{tariff}/standard-unit-rates/";

    var response = await _octopusHttpClient.GetAsync(url);

    var resultdata = await response.Content?.ReadAsStringAsync();

    if (!response.IsSuccessStatusCode)
    {
        throw new Exception($"Error calling API. Http code: {response.StatusCode} Error: {resultdata}");
    }

    return JsonConvert.DeserializeObject<GetUnitRatesResponse>(resultdata);
}

Perhaps there are more parameters that can be sent, I just copied that from the API key page in my account where it gives a couple of examples of how to call it.

Cheers though that would explain it.

PhilPJL commented 3 years ago

What do you mean 'their .NET wrapper'? I haven't seen that. This is all my code.

If you have LinqPad try

async Task Main()
{
    try
    {
        using (var client = new HttpClient())
        {
            var api = new OctopusEnergyClient(client);

            var productCode = "AGILE-18-02-21";
            var tariff = "E-1R-AGILE-18-02-21-L";

            Stopwatch sw = Stopwatch.StartNew();

            var from = new DateTimeOffset(2021, 03, 01, 0, 0, 0, TimeSpan.Zero);
            var data = await api.GetElectricityUnitRatesAsync(productCode, tariff, ElectricityUnitRate.Standard, null);
            data.Count().Dump();
            var timeTaken = sw.Elapsed.TotalSeconds;            
            timeTaken.Dump();
        }
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.Message);

        // TODO: convert exception?
        throw;
    }
}
NibblyPig commented 3 years ago

Ah, cool.

They have this: https://www.nuget.org/packages/Octopus.Client/ which I wasn't sure if you were using under the hood.

PhilPJL commented 3 years ago

@NibblyPig That's Octopus.Client for OctopusDeploy, nothing to do with Octopus Energy.

I assume you know there's a Nuget package for my stuff as well? https://www.nuget.org/packages/ImpSoft.OctopusEnergy.Api/