EnergiDataService.Client 0.1.2

dotnet add package EnergiDataService.Client --version 0.1.2
                    
NuGet\Install-Package EnergiDataService.Client -Version 0.1.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="EnergiDataService.Client" Version="0.1.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="EnergiDataService.Client" Version="0.1.2" />
                    
Directory.Packages.props
<PackageReference Include="EnergiDataService.Client" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add EnergiDataService.Client --version 0.1.2
                    
#r "nuget: EnergiDataService.Client, 0.1.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package EnergiDataService.Client@0.1.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=EnergiDataService.Client&version=0.1.2
                    
Install as a Cake Addin
#tool nuget:?package=EnergiDataService.Client&version=0.1.2
                    
Install as a Cake Tool

EnergiDataService.Client

A .NET client library for consuming day-ahead energy prices from the Danish Energi Data Service API.

NuGet Build Status

Features

  • Simple API: Clean and intuitive methods for retrieving day-ahead prices
  • Flexible: Support for single or multiple price areas (DK1, DK2, etc.)
  • Async/Await: Full async support with cancellation tokens
  • Dependency Injection: Built-in support for Microsoft.Extensions.DependencyInjection
  • Comprehensive: Strongly typed models with full XML documentation
  • Tested: Comprehensive unit tests and integration tests

Installation

Install the package via NuGet Package Manager:

dotnet add package EnergiDataService.Client

Or via Package Manager Console:

Install-Package EnergiDataService.Client

Quick Start

Basic Usage

using EnergiDataService.Client;

// Create an HTTP client and the service client
using var httpClient = new HttpClient();
var client = new EnergiDataServiceClient(httpClient);

// Get day-ahead prices for DK1 area
var prices = await client.GetDayAheadPricesAsync("DK1", limit: 24);

Console.WriteLine($"Found {prices.Total} price records");
foreach (var record in prices.Records)
{
    Console.WriteLine($"{record.TimeDk:yyyy-MM-dd HH:mm}: {record.DayAheadPriceDkk:F2} DKK/MWh");
}

Multiple Price Areas

// Get prices for both DK1 and DK2
var prices = await client.GetDayAheadPricesAsync(new[] { "DK1", "DK2" }, limit: 50);

var dk1Prices = prices.Records.Where(r => r.PriceArea == "DK1").ToList();
var dk2Prices = prices.Records.Where(r => r.PriceArea == "DK2").ToList();

With Dependency Injection

First, register the service in your DI container:

using EnergiDataService.Client.Extensions;

// In Program.cs or Startup.cs
services.AddEnergiDataServiceClient();

// Or with custom HTTP client configuration
services.AddEnergiDataServiceClient(client =>
{
    client.Timeout = TimeSpan.FromSeconds(30);
});

Then inject and use the client:

public class EnergyService
{
    private readonly EnergiDataServiceClient _client;

    public EnergyService(EnergiDataServiceClient client)
    {
        _client = client;
    }

    public async Task<decimal> GetCurrentPriceAsync()
    {
        var result = await _client.GetDayAheadPricesAsync("DK1", limit: 1);
        return result.Records.First().DayAheadPriceDkk;
    }
}

API Reference

EnergiDataServiceClient Methods

GetDayAheadPricesAsync(string priceArea, int limit = 100, CancellationToken cancellationToken = default)

Gets day-ahead prices for a single price area.

Parameters:

  • priceArea: Price area code (e.g., "DK1", "DK2")
  • limit: Maximum number of records to retrieve (default: 100)
  • cancellationToken: Cancellation token

Returns: Task<DayAheadPriceResponse>

GetDayAheadPricesAsync(IEnumerable<string> priceAreas, int limit = 100, CancellationToken cancellationToken = default)

Gets day-ahead prices for multiple price areas.

Parameters:

  • priceAreas: Collection of price area codes
  • limit: Maximum number of records to retrieve (default: 100)
  • cancellationToken: Cancellation token

Returns: Task<DayAheadPriceResponse>

Data Models

DayAheadPriceResponse

Represents the complete response from the API:

public class DayAheadPriceResponse
{
    public int Total { get; set; }                                    // Total number of available records
    public string Filters { get; set; }                              // Applied filters as JSON string
    public int Limit { get; set; }                                   // Limit applied to the query
    public string Dataset { get; set; }                              // Dataset name ("DayAheadPrices")
    public IReadOnlyList<DayAheadPriceRecord> Records { get; set; }  // Collection of price records
}
DayAheadPriceRecord

Represents a single day-ahead price record:

public class DayAheadPriceRecord
{
    public DateTime TimeUtc { get; set; }           // UTC timestamp
    public DateTime TimeDk { get; set; }            // Danish local timestamp
    public string PriceArea { get; set; }           // Price area (e.g., "DK1", "DK2")
    public decimal DayAheadPriceEur { get; set; }   // Price in EUR per MWh
    public decimal DayAheadPriceDkk { get; set; }   // Price in DKK per MWh
}

Price Areas

The Danish electricity market is divided into different price areas:

  • DK1: Western Denmark (Jutland and Funen)
  • DK2: Eastern Denmark (Zealand, Lolland, Falster, and Bornholm)

You can also use price areas from other Nordic countries if available in the API.

Error Handling

The client throws the following exceptions:

  • ArgumentNullException: When required parameters are null
  • ArgumentException: When price areas list is empty or invalid
  • HttpRequestException: When HTTP requests fail
  • InvalidOperationException: When response cannot be deserialized
try
{
    var prices = await client.GetDayAheadPricesAsync("DK1");
    // Process prices...
}
catch (HttpRequestException ex)
{
    Console.WriteLine($"HTTP error: {ex.Message}");
}
catch (ArgumentException ex)
{
    Console.WriteLine($"Invalid argument: {ex.Message}");
}

Configuration

HTTP Client Configuration

When using dependency injection, you can configure the underlying HTTP client:

services.AddEnergiDataServiceClient(client =>
{
    client.Timeout = TimeSpan.FromMinutes(1);
    client.DefaultRequestHeaders.Add("User-Agent", "MyApp/1.0");
});

Retry Policies

For production use, consider adding retry policies using libraries like Polly:

services.AddHttpClient<EnergiDataServiceClient>()
    .AddPolicyHandler(Policy.TimeoutAsync<HttpResponseMessage>(30))
    .AddPolicyHandler(Policy
        .Handle<HttpRequestException>()
        .WaitAndRetryAsync(3, retryAttempt =>
            TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))));

Examples

Get Today's Hourly Prices

var today = DateTime.Today;
var prices = await client.GetDayAheadPricesAsync("DK1", limit: 100);

var todaysPrices = prices.Records
    .Where(r => r.TimeDk.Date == today)
    .OrderBy(r => r.TimeDk)
    .ToList();

foreach (var price in todaysPrices)
{
    Console.WriteLine($"{price.TimeDk:HH:mm}: {price.DayAheadPriceDkk:F2} øre/kWh");
}

Find Peak and Off-Peak Hours

var prices = await client.GetDayAheadPricesAsync("DK1", limit: 24);

var sortedPrices = prices.Records
    .OrderBy(r => r.DayAheadPriceDkk)
    .ToList();

var cheapestHour = sortedPrices.First();
var expensiveHour = sortedPrices.Last();

Console.WriteLine($"Cheapest: {cheapestHour.TimeDk:HH:mm} - {cheapestHour.DayAheadPriceDkk:F2} DKK/MWh");
Console.WriteLine($"Most expensive: {expensiveHour.TimeDk:HH:mm} - {expensiveHour.DayAheadPriceDkk:F2} DKK/MWh");

Compare Price Areas

var prices = await client.GetDayAheadPricesAsync(new[] { "DK1", "DK2" }, limit: 50);

var dk1Average = prices.Records
    .Where(r => r.PriceArea == "DK1")
    .Average(r => r.DayAheadPriceDkk);

var dk2Average = prices.Records
    .Where(r => r.PriceArea == "DK2")
    .Average(r => r.DayAheadPriceDkk);

Console.WriteLine($"DK1 average: {dk1Average:F2} DKK/MWh");
Console.WriteLine($"DK2 average: {dk2Average:F2} DKK/MWh");

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

Building from Source

git clone https://github.com/christianhelle/edsclient.git
cd edsclient
dotnet build
dotnet test

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.2 39 9/26/2025
0.1.0 38 9/26/2025