Innovenergy_trunk/csharp/App/Backend/Services/NetworkProviderService.cs

79 lines
2.3 KiB
C#

using Flurl.Http;
using Newtonsoft.Json.Linq;
namespace InnovEnergy.App.Backend.Services;
/// <summary>
/// Fetches and caches the list of Swiss electricity network providers (Netzbetreiber)
/// from the ELCOM/LINDAS SPARQL endpoint. Refreshes every 24 hours.
/// </summary>
public static class NetworkProviderService
{
private static IReadOnlyList<string> _providers = Array.Empty<string>();
private static Timer? _refreshTimer;
private const string SparqlEndpoint = "https://ld.admin.ch/query";
private const string SparqlQuery = @"
PREFIX schema: <http://schema.org/>
SELECT DISTINCT ?name
FROM <https://lindas.admin.ch/elcom/electricityprice>
WHERE {
?operator a schema:Organization ;
schema:name ?name .
}
ORDER BY ?name";
public static void Initialize()
{
// Fire-and-forget initial load
Task.Run(RefreshAsync);
// Refresh every 24 hours
_refreshTimer = new Timer(
_ => Task.Run(RefreshAsync),
null,
TimeSpan.FromHours(24),
TimeSpan.FromHours(24)
);
Console.WriteLine("[NetworkProviderService] initialised.");
}
public static IReadOnlyList<string> GetProviders() => _providers;
private static async Task RefreshAsync()
{
try
{
var response = await SparqlEndpoint
.WithHeader("Accept", "application/sparql-results+json")
.PostUrlEncodedAsync(new { query = SparqlQuery });
var json = await response.GetStringAsync();
var parsed = JObject.Parse(json);
var names = parsed["results"]?["bindings"]?
.Select(b => b["name"]?["value"]?.ToString())
.Where(n => !string.IsNullOrWhiteSpace(n))
.Distinct()
.OrderBy(n => n)
.ToList();
if (names is { Count: > 0 })
{
_providers = names!;
Console.WriteLine($"[NetworkProviderService] Loaded {names.Count} providers from ELCOM.");
}
else
{
Console.Error.WriteLine("[NetworkProviderService] SPARQL query returned no results.");
}
}
catch (Exception ex)
{
Console.Error.WriteLine($"[NetworkProviderService] Failed to fetch providers: {ex.Message}");
}
}
}