EnergiDataService.Client
0.1.2
dotnet add package EnergiDataService.Client --version 0.1.2
NuGet\Install-Package EnergiDataService.Client -Version 0.1.2
<PackageReference Include="EnergiDataService.Client" Version="0.1.2" />
<PackageVersion Include="EnergiDataService.Client" Version="0.1.2" />
<PackageReference Include="EnergiDataService.Client" />
paket add EnergiDataService.Client --version 0.1.2
#r "nuget: EnergiDataService.Client, 0.1.2"
#:package EnergiDataService.Client@0.1.2
#addin nuget:?package=EnergiDataService.Client&version=0.1.2
#tool nuget:?package=EnergiDataService.Client&version=0.1.2
EnergiDataService.Client
A .NET client library for consuming day-ahead energy prices from the Danish Energi Data Service API.
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 codeslimit
: 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 nullArgumentException
: When price areas list is empty or invalidHttpRequestException
: When HTTP requests failInvalidOperationException
: 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
- Data provided by Energi Data Service (Energinet)
- Built with .NET 8 and modern C# features
Related Links
Product | Versions 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. |
-
.NETStandard 2.0
- Microsoft.Extensions.Http (>= 9.0.9)
- System.Text.Json (>= 9.0.9)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.