Xcalibur.Weather.Services
1.0.3
See the version list below for details.
dotnet add package Xcalibur.Weather.Services --version 1.0.3
NuGet\Install-Package Xcalibur.Weather.Services -Version 1.0.3
<PackageReference Include="Xcalibur.Weather.Services" Version="1.0.3" />
<PackageVersion Include="Xcalibur.Weather.Services" Version="1.0.3" />
<PackageReference Include="Xcalibur.Weather.Services" />
paket add Xcalibur.Weather.Services --version 1.0.3
#r "nuget: Xcalibur.Weather.Services, 1.0.3"
#:package Xcalibur.Weather.Services@1.0.3
#addin nuget:?package=Xcalibur.Weather.Services&version=1.0.3
#tool nuget:?package=Xcalibur.Weather.Services&version=1.0.3
Xcalibur.Weather.Services
A comprehensive .NET library providing HTTP client services for weather-related APIs. Seamless integration with multiple weather data providers including Open-Meteo, Geocodio, IpGeolocation.io, Google Pollen, SunriseSunset.io, and OpenStreetMap for weather forecasting, geocoding, air quality monitoring, pollen insights, and astronomical data.
Created by: Joshua Arzt | Company: Xcalibur Systems, LLC.
Latest Updates
- Package version:
1.0.2 - Models package dependency:
1.0.3 - Added
SunriseSunsetServicefor sunrise and sunset data - Added
OpenStreetMapServicefor Nominatim geocoding - Added
GooglePollenServicefor daily pollen forecast data
๐ Table of Contents
- Features
- Installation
- Services
- Usage
- API Endpoints
- Dependencies
- Testing
- API Key Management
- Best Practices
- Advanced Configuration
- Project Structure
- License
- Related Projects
โจ Features
- Multiple Weather Providers: Integrated support for Open-Meteo, Geocodio, IpGeolocation.io, Google Pollen, SunriseSunset.io, and OpenStreetMap APIs
- Comprehensive Weather Data: Access current weather, forecasts, air quality, pollen forecasts, geocoding, and astronomical data
- Modern .NET 10: Built with the latest .NET features and best practices
- Async/Await: Full asynchronous API support with cancellation tokens
- Logging Support: Built-in logging using Microsoft.Extensions.Logging
- AOT-Ready: Source-generated JSON contexts for Native AOT compilation support
- Error Handling: Robust error handling with detailed logging
- Streaming Deserialization: Efficient memory usage with streaming JSON deserialization
- Type-Safe: Strongly-typed responses using Xcalibur.Weather.Models
- Flexible Provider Coverage: Includes both API key and no-key providers for geocoding, pollen, and astronomy data
๐ฆ Installation
Install via NuGet Package Manager:
dotnet add package Xcalibur.Weather.Services
Or via Package Manager Console:
Install-Package Xcalibur.Weather.Services
๐ฆ๏ธ Services
OpenMeteoService
The OpenMeteoService provides access to Open-Meteo weather APIs, offering comprehensive weather data without requiring an API key.
Key Features:
- Current weather conditions
- Current air quality index (AQI)
- 48-hour hourly forecasts
- Multi-day daily forecasts
- Historical weather data (yesterday)
Supported Data Points:
- Temperature (current, apparent, min/max)
- Humidity and dew point
- Precipitation (rain, showers, snowfall)
- Wind (speed, direction, gusts)
- Atmospheric pressure
- Cloud cover and visibility
- Weather codes
- Air quality metrics (PM2.5, PM10, CO, NO2, SO2, O3, etc.)
- Pollen levels (alder, birch, grass, mugwort, olive, ragweed)
- UV index
- Sunrise/sunset and daylight duration
GeocodioService
The GeocodioService provides geocoding capabilities to convert addresses into geographic coordinates.
Key Features:
- Forward geocoding (address to coordinates)
- Country-specific searches
- API key validation
- Detailed location results with accuracy information
IpGeoService
The IpGeoService provides astronomical data for specific geographic locations.
Key Features:
- Sunrise and sunset times
- Moonrise and moonset times
- Moon phase information
- API key validation
GooglePollenService
The GooglePollenService provides daily pollen forecast data from the Google Pollen API and requires an API key.
Key Features:
- Daily pollen forecast lookup by coordinates
- Pollen type insights for grass, tree, and weed categories
- Plant-specific pollen details and descriptions
- Health recommendations
- API key validation
SunriseSunsetService
The SunriseSunsetService provides sunrise and sunset data from SunriseSunset.io without requiring an API key.
Key Features:
- Sunrise and sunset times
- Solar noon and day length data
- No API key required
- Lightweight astronomy lookups by coordinates
OpenStreetMapService
The OpenStreetMapService provides geocoding through OpenStreetMap Nominatim.
Key Features:
- Forward geocoding (address to coordinates)
- Address details in results
- Country-filtered searches
- No API key required
- Built-in default
User-Agentsupport for Nominatim requests
๐ Usage
Basic Setup
using Microsoft.Extensions.Logging.Abstractions;
using Xcalibur.Weather.Services.WeatherProvider.OpenMeteo;
using Xcalibur.Weather.Services.WeatherProvider.Geocodio;
using Xcalibur.Weather.Services.WeatherProvider.IpGeo;
using Xcalibur.Weather.Services.WeatherProvider.GooglePollen;
using Xcalibur.Weather.Services.WeatherProvider.SunriseSunset;
using Xcalibur.Weather.Services.WeatherProvider.OpenStreetMap;
var httpClient = new HttpClient();
var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole());
var logger = loggerFactory.CreateLogger<OpenMeteoService>();
var openMeteoService = new OpenMeteoService(httpClient, logger);
var geocodioService = new GeocodioService(httpClient, "YOUR_GEOCODIO_API_KEY", loggerFactory.CreateLogger<GeocodioService>());
var ipGeoService = new IpGeoService(httpClient, "YOUR_IPGEO_API_KEY", loggerFactory.CreateLogger<IpGeoService>());
var googlePollenService = new GooglePollenService(httpClient, "YOUR_GOOGLE_POLLEN_API_KEY", loggerFactory.CreateLogger<GooglePollenService>());
var sunriseSunsetService = new SunriseSunsetService(httpClient, loggerFactory.CreateLogger<SunriseSunsetService>());
var openStreetMapService = new OpenStreetMapService(httpClient, loggerFactory.CreateLogger<OpenStreetMapService>());
OpenMeteo Examples
Get Current Weather
var currentWeather = await openMeteoService.GetCurrentWeatherAsync("40.7128", "-74.0060");
if (currentWeather?.Current != null)
{
Console.WriteLine($"Temperature: {currentWeather.Current.Temperature}ยฐC");
Console.WriteLine($"Humidity: {currentWeather.Current.RelativeHumidity}%");
Console.WriteLine($"Wind Speed: {currentWeather.Current.WindSpeed} km/h");
}
Get Current Air Quality
var airQuality = await openMeteoService.GetCurrentAirQualityAsync("40.7128", "-74.0060");
if (airQuality?.Current != null)
{
Console.WriteLine($"US AQI: {airQuality.Current.UsAqi}");
Console.WriteLine($"PM2.5: {airQuality.Current.Pm2_5}");
Console.WriteLine($"PM10: {airQuality.Current.Pm10}");
}
Get Hourly Forecast
var hourlyForecast = await openMeteoService.GetHourlyForecastAsync("40.7128", "-74.0060");
if (hourlyForecast?.Hourly != null)
{
for (int i = 0; i < hourlyForecast.Hourly.Time.Length; i++)
{
Console.WriteLine($"{hourlyForecast.Hourly.Time[i]}: {hourlyForecast.Hourly.Temperature2m[i]}ยฐC");
}
}
Get Daily Forecast
// Get 7-day forecast
var dailyForecast = await openMeteoService.GetDailyForecastAsync("40.7128", "-74.0060", 7);
if (dailyForecast?.Daily != null)
{
for (int i = 0; i < dailyForecast.Daily.Time.Length; i++)
{
Console.WriteLine($"{dailyForecast.Daily.Time[i]}:");
Console.WriteLine($" High: {dailyForecast.Daily.Temperature2mMax[i]}ยฐC");
Console.WriteLine($" Low: {dailyForecast.Daily.Temperature2mMin[i]}ยฐC");
Console.WriteLine($" Precipitation: {dailyForecast.Daily.PrecipitationSum[i]}mm");
}
}
Get Yesterday's Weather
var yesterday = DateTime.UtcNow.AddDays(-1);
var historicalWeather = await openMeteoService.GetYesterdayForecastAsync(
"40.7128",
"-74.0060",
yesterday.ToString("yyyy-MM-dd"));
if (historicalWeather?.Hourly != null)
{
Console.WriteLine($"Yesterday's temperatures:");
for (int i = 0; i < historicalWeather.Hourly.Time.Length; i++)
{
Console.WriteLine($"{historicalWeather.Hourly.Time[i]}: {historicalWeather.Hourly.Temperature2m[i]}ยฐC");
}
}
Geocodio Examples
Setup with API Key
var geocodioService = new GeocodioService(
httpClient,
"YOUR_GEOCODIO_API_KEY",
loggerFactory.CreateLogger<GeocodioService>());
Test API Key
var isValid = await geocodioService.TestApiKey();
Console.WriteLine($"API Key is {(isValid ? "valid" : "invalid")}");
Geocode an Address
var locations = await geocodioService.GetLocationsAsync(
"1600 Pennsylvania Avenue NW, Washington, DC",
"US");
if (locations?.Results != null)
{
foreach (var result in locations.Results)
{
Console.WriteLine($"Location: {result.FormattedAddress}");
Console.WriteLine($"Coordinates: {result.Location.Latitude}, {result.Location.Longitude}");
Console.WriteLine($"Accuracy: {result.Accuracy}");
}
}
IpGeo Examples
Setup with API Key
var ipGeoService = new IpGeoService(
httpClient,
"YOUR_IPGEO_API_KEY",
loggerFactory.CreateLogger<IpGeoService>());
Test API Key
var isValid = await ipGeoService.TestApiKey();
Console.WriteLine($"API Key is {(isValid ? "valid" : "invalid")}");
Get Astronomical Data
var sunMoonData = await ipGeoService.GetSunMoonDataAsync("40.7128", "-74.0060");
if (sunMoonData != null)
{
Console.WriteLine($"Sunrise: {sunMoonData.Astronomy?.Sunrise}");
Console.WriteLine($"Sunset: {sunMoonData.Astronomy?.Sunset}");
Console.WriteLine($"Moonrise: {sunMoonData.Astronomy?.Moonrise}");
Console.WriteLine($"Moonset: {sunMoonData.Astronomy?.Moonset}");
Console.WriteLine($"Moon Phase: {sunMoonData.Astronomy?.MoonPhase}");
}
GooglePollen Examples
Setup with API Key
var googlePollenService = new GooglePollenService(
httpClient,
"YOUR_GOOGLE_POLLEN_API_KEY",
loggerFactory.CreateLogger<GooglePollenService>());
Test API Key
var isValid = await googlePollenService.TestApiKey();
Console.WriteLine($"API Key is {(isValid ? "valid" : "invalid")}");
Get Pollen Forecast
var pollenForecast = await googlePollenService.GetPollenForecastAsync("39.4300996", "-77.804161");
if (pollenForecast?.DailyInfo != null && pollenForecast.DailyInfo.Count > 0)
{
var daily = pollenForecast.DailyInfo[0];
Console.WriteLine($"Region: {pollenForecast.RegionCode}");
if (daily.PollenTypeInfo != null)
{
foreach (var pollenType in daily.PollenTypeInfo)
{
Console.WriteLine($"{pollenType.DisplayName}: {pollenType.IndexInfo?.Category} ({pollenType.IndexInfo?.Value})");
}
}
}
SunriseSunset Examples
Setup
var sunriseSunsetService = new SunriseSunsetService(
httpClient,
loggerFactory.CreateLogger<SunriseSunsetService>());
Get Sunrise and Sunset Data
var astronomy = await sunriseSunsetService.GetSunriseSunsetAsync("40.7128", "-74.0060");
if (astronomy?.Results != null)
{
Console.WriteLine($"Sunrise: {astronomy.Results.Sunrise}");
Console.WriteLine($"Sunset: {astronomy.Results.Sunset}");
Console.WriteLine($"Day Length: {astronomy.Results.DayLength}");
Console.WriteLine($"Solar Noon: {astronomy.Results.SolarNoon}");
}
OpenStreetMap Examples
Setup
var openStreetMapService = new OpenStreetMapService(
httpClient,
loggerFactory.CreateLogger<OpenStreetMapService>());
Search for Locations
var locations = await openStreetMapService.GetLocationsAsync(
"1600 Pennsylvania Avenue NW, Washington, DC",
"us");
if (locations != null)
{
foreach (var location in locations)
{
Console.WriteLine($"Display Name: {location.DisplayName}");
Console.WriteLine($"Coordinates: {location.Lat}, {location.Lon}");
}
}
๐ API Endpoints
Open-Meteo
- Current Weather:
https://api.open-meteo.com/v1/forecast - Air Quality:
https://air-quality-api.open-meteo.com/v1/air-quality - Historical:
https://archive-api.open-meteo.com/v1/archive - API Key: Not required (free and open)
- Documentation: Open-Meteo API Docs
Geocodio
- Base URL:
https://api.geocod.io/v1.9/geocode - API Key: Required
- Sign Up: Geocodio
- Documentation: Geocodio API Docs
IpGeolocation.io
- Base URL:
https://api.ipgeolocation.io/v2/astronomy - API Key: Required
- Sign Up: IpGeolocation.io
- Documentation: IpGeo API Docs
Google Pollen API
- Base URL:
https://pollen.googleapis.com/v1/forecast:lookup - API Key: Required
- Documentation: Google Pollen API Docs
SunriseSunset.io
- Base URL:
https://api.sunrisesunset.io/json - API Key: Not required
- Documentation: SunriseSunset.io Docs
OpenStreetMap Nominatim
- Base URL:
https://nominatim.openstreetmap.org/search - API Key: Not required
- Requirement: A descriptive
User-Agentheader is required - Documentation: Nominatim Search API
๐ Dependencies
- .NET 10.0: Target framework
- Microsoft.Extensions.Hosting (v10.0.7): For hosting, logging, and dependency injection abstractions
- Xcalibur.Weather.Models (v1.0.3): Shared models and DTOs for weather data
๐งช Testing
The project includes comprehensive unit tests in the Xcalibur.Weather.Services.Tests project.
Running Tests
dotnet test
Current Test Coverage
OpenMeteoServiceTests: Tests for Open-Meteo API operationsGeocodioServiceTests: Tests for geocoding functionality and API key validationIpGeoServiceTests: Tests for astronomical data retrievalGooglePollenServiceTests: Tests for pollen forecast retrieval, API key validation, and request URL generationSunriseSunsetServiceTests: Tests for sunrise and sunset data retrievalOpenStreetMapServiceTests: Tests for geocoding and Nominatim request behavior
๐๏ธ Project Structure
Xcalibur.Weather.Services/
โโโ WeatherProvider/
โ โโโ OpenMeteo/
โ โ โโโ OpenMeteoService.cs
โ โโโ Geocodio/
โ โ โโโ GeocodioService.cs
โ โโโ IpGeo/
โ โ โโโ IpGeoService.cs
โ โโโ GooglePollen/
โ โ โโโ GooglePollenService.cs
โ โโโ SunriseSunset/
โ โ โโโ SunriseSunsetService.cs
โ โโโ OpenStreetMap/
โ โโโ OpenStreetMapService.cs
โโโ Xcalibur.Weather.Services.csproj
โ
Xcalibur.Weather.Services.Tests/
โโโ WeatherProvider/
โ โโโ OpenMeteoServiceTests.cs
โ โโโ GeocodioServiceTests.cs
โ โโโ IpGeoServiceTests.cs
โ โโโ GooglePollenServiceTests.cs
โ โโโ SunriseSunsetServiceTests.cs
โ โโโ OpenStreetMapServiceTests.cs
โโโ Xcalibur.Weather.Services.Tests.csproj
๐ง Advanced Configuration
Custom HttpClient Configuration
var httpClient = new HttpClient
{
Timeout = TimeSpan.FromSeconds(30)
};
httpClient.DefaultRequestHeaders.Add("User-Agent", "YourApp/1.0");
var service = new OpenMeteoService(httpClient, logger);
Cancellation Token Support
All async methods support cancellation tokens for graceful shutdown:
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
try
{
var weather = await openMeteoService.GetCurrentWeatherAsync(
"40.7128",
"-74.0060",
cts.Token);
}
catch (OperationCanceledException)
{
Console.WriteLine("Request was cancelled");
}
๐ Best Practices
- Reuse HttpClient: Create a single
HttpClientinstance and reuse it across service instances - Use Dependency Injection: Register services in your DI container for better testability
- Handle Nulls: All service methods return nullable types; always check for null responses
- Monitor Logs: Enable debug logging to troubleshoot API issues
- Respect Provider Policies: Be mindful of rate limits and usage policies for Geocodio, IpGeo, Google Pollen, SunriseSunset.io, and OpenStreetMap Nominatim
- Secure API Keys: Store API keys in secure configuration (Azure Key Vault, user secrets, etc.)
- Set a User-Agent When Needed: OpenStreetMap Nominatim requires a meaningful
User-Agent; the service sets a default if one is not already present
๐ API Key Management
User Secrets (Development)
dotnet user-secrets init
dotnet user-secrets set "Geocodio:ApiKey" "YOUR_API_KEY"
dotnet user-secrets set "IpGeo:ApiKey" "YOUR_API_KEY"
dotnet user-secrets set "GooglePollen:ApiKey" "YOUR_API_KEY"
appsettings.json
{
"Geocodio": {
"ApiKey": "YOUR_GEOCODIO_API_KEY"
},
"IpGeo": {
"ApiKey": "YOUR_IPGEO_API_KEY"
},
"GooglePollen": {
"ApiKey": "YOUR_GOOGLE_POLLEN_API_KEY"
}
}
Environment Variables
set GEOCODIO_API_KEY=your_key_here
set IPGEO_API_KEY=your_key_here
set GOOGLEPOLLEN_API_KEY=your_key_here
๐ License
This project is licensed under the Apache License 2.0. See the LICENSE-2.0.txt file for details.
Copyright ยฉ 2006 - 2026, Xcalibur Systems, LLC - All Rights Reserved
๐ Related Projects
- Xcalibur.Weather.Models - Core weather data models and DTOs (GitHub)
- Xcalibur.Weather.Helpers - Utility functions and conversion helpers (GitHub)
Part of the Xcalibur Weather ecosystem for comprehensive weather data integration.
Author
Joshua Arzt
Xcalibur Systems, LLC
Note: This library requires API keys for Geocodio and IpGeolocation.io services. Open-Meteo, SunriseSunset.io, and OpenStreetMap Nominatim do not require API keys.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.0
- Microsoft.Extensions.Hosting (>= 10.0.7)
- Xcalibur.Weather.Models (>= 1.0.3)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Xcalibur.Weather.Services:
| Package | Downloads |
|---|---|
|
Xcalibur.Weather.Helpers
A comprehensive .NET helper library providing utility functions for weather-related operations. Includes conversion helpers for temperature, wind speed, length, and pressure, along with specialized helpers for Open-Meteo, Geocodio, and IpGeolocation.io weather data processing and transformation. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Added services for Google Pollen API.