Xcalibur.Weather.Services
1.0.13
dotnet add package Xcalibur.Weather.Services --version 1.0.13
NuGet\Install-Package Xcalibur.Weather.Services -Version 1.0.13
<PackageReference Include="Xcalibur.Weather.Services" Version="1.0.13" />
<PackageVersion Include="Xcalibur.Weather.Services" Version="1.0.13" />
<PackageReference Include="Xcalibur.Weather.Services" />
paket add Xcalibur.Weather.Services --version 1.0.13
#r "nuget: Xcalibur.Weather.Services, 1.0.13"
#:package Xcalibur.Weather.Services@1.0.13
#addin nuget:?package=Xcalibur.Weather.Services&version=1.0.13
#tool nuget:?package=Xcalibur.Weather.Services&version=1.0.13
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, Atmospore, SunriseSunset.io, and OpenStreetMap for weather forecasting, geocoding, air quality monitoring, pollen insights, multi-source weather alerts, and astronomical data.
Created by: Joshua Arzt | Company: Xcalibur Systems, LLC.
Purpose
Xcalibur.Weather.Services is designed to:
- Provide production-ready HTTP client services for multiple weather, geocoding, astronomy, pollen, and alert APIs
- Enable seamless integration with Open-Meteo, Geocodio, IpGeolocation.io, Atmospore, SunriseSunset.io, OpenStreetMap, and multi-source weather alert providers
- Deliver async/await patterns with cancellation token support for responsive applications
- Offer strongly-typed responses using Xcalibur.Weather.Models
- Support both API-key and no-key service providers for flexible deployment scenarios
- Centralize API communication logic with built-in error handling and logging
Latest Updates
- Package version:
1.0.12 - Models package dependency:
1.0.12 - Target framework: .NET 10.0
- Latest release: Performance improvements and property descriptions for Weather Alerts
- Added
AtmosporeServicefor pollen forecast data from Atmospore API - Added
WeatherAlertServicefor multi-provider weather alerts (Meteoalarm, NWS, GDACS, Environment Canada, BOM Australia, EMSC, DWD) - Services moved to flat namespace structure (
Xcalibur.Weather.Services) - All 44 unit tests passing with comprehensive coverage across all services
๐ Table of Contents
- Purpose
- Latest Updates
- Features
- Technology
- Use Cases
- Installation
- Services
- Usage
- API Endpoints
- Dependencies
- Testing
- API Key Management
- Best Practices
- Advanced Configuration
- Project Structure
- Version History
- License
- Related Projects
- Contributing
โจ Features
- Multiple Weather Providers: Integrated support for Open-Meteo, Geocodio, IpGeolocation.io, Atmospore, SunriseSunset.io, and OpenStreetMap APIs
- Multi-Source Weather Alerts: Aggregated weather alerts from Meteoalarm, NWS, GDACS, Environment Canada, BOM Australia, EMSC, and DWD
- Comprehensive Weather Data: Access current weather, forecasts, air quality, pollen forecasts, weather alerts, 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
๐ง Technology
- Target Framework: .NET 10.0
- Current Package Version: 1.0.12
- Dependencies:
- Microsoft.Extensions.Hosting (v10.0.9) - For logging and dependency injection abstractions
- Xcalibur.Weather.Models (v1.0.12) - Shared models and DTOs
- Features:
- Implicit usings enabled
- Nullable reference types enabled
- Async/await throughout with CancellationToken support
- Native AOT compilation support via source-generated JSON contexts
- Streaming JSON deserialization for efficient memory usage
- Built-in retry logic and error handling
- Comprehensive logging via Microsoft.Extensions.Logging
- NuGet package generation on Release build
๐ก Use Cases
This library is ideal for:
- Weather Applications: Mobile and desktop apps requiring current conditions, forecasts, and air quality data
- Smart Home Systems: IoT devices and home automation requiring weather-based triggers
- Agricultural Solutions: Farm management systems needing weather, pollen, and environmental data
- Travel & Navigation Apps: Applications requiring location-based weather and alerts
- Health & Wellness Apps: Allergy tracking with pollen forecast integration
- Emergency Management: Systems aggregating multi-source weather alerts and disaster notifications
- Environmental Monitoring: Air quality dashboards and pollution tracking systems
- Astronomy Applications: Sunrise/sunset tracking, moon phase, and astronomical event planning
- Geocoding Services: Address validation, coordinate lookup, and location-based features
- Web APIs & Microservices: Backend services needing weather data aggregation from multiple providers
๐ฆ Installation
Install via NuGet Package Manager:
dotnet add package Xcalibur.Weather.Services
Or via Package Manager Console:
Install-Package Xcalibur.Weather.Services
Or add to your project file:
<PackageReference Include="Xcalibur.Weather.Services" Version="1.0.12" />
๐ฆ๏ธ 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
AtmosporeService
The AtmosporeService provides pollen forecast data from the Atmospore API (pollenapi.com) and requires an API key.
Key Features:
- Multi-day pollen forecast lookup by coordinates
- Overall pollen risk assessment
- Detailed species-level pollen data with risk levels
- Display names and values for individual pollen species
- Date-specific or current date forecasts
- API key validation
WeatherAlertService
The WeatherAlertService aggregates weather alerts from multiple international sources without requiring an API key.
Key Features:
- Meteoalarm: European weather alerts by coordinates
- NWS (National Weather Service): US weather alerts by coordinates
- GDACS (Global Disaster Alert and Coordination System): Global disaster alerts
- Environment Canada: Canadian weather warnings by province code
- BOM Australia: Australian weather warnings by state code
- EMSC (European-Mediterranean Seismological Centre): Earthquake alerts by coordinates and radius
- DWD (Deutscher Wetterdienst): German weather warnings
- Combined alerts: Fetch from multiple sources simultaneously
- Automatic User-Agent header management for provider compatibility
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;
using Xcalibur.Weather.Services;
var httpClient = new HttpClient();
var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole());
var openMeteoService = new OpenMeteoService(httpClient, loggerFactory.CreateLogger<OpenMeteoService>());
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 atmosporeService = new AtmosporeService(httpClient, "YOUR_ATMOSPORE_API_KEY", loggerFactory.CreateLogger<AtmosporeService>());
var weatherAlertService = new WeatherAlertService(httpClient, loggerFactory.CreateLogger<WeatherAlertService>());
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 Hourly Weather
var yesterday = DateTime.UtcNow.AddDays(-1);
var historicalWeather = await openMeteoService.GetYesterdayHourlyForecastAsync(
"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");
}
}
Get Yesterday's Daily Weather
var yesterday = DateTime.UtcNow.AddDays(-1);
var historicalDaily = await openMeteoService.GetYesterdayDailyForecastAsync(
"40.7128",
"-74.0060",
yesterday.ToString("yyyy-MM-dd"));
if (historicalDaily?.Daily != null)
{
Console.WriteLine($"Yesterday's daily summary:");
Console.WriteLine($"High: {historicalDaily.Daily.Temperature2mMax?[0]}ยฐC");
Console.WriteLine($"Low: {historicalDaily.Daily.Temperature2mMin?[0]}ยฐC");
Console.WriteLine($"Precipitation: {historicalDaily.Daily.PrecipitationSum?[0]}mm");
}
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}");
}
Atmospore Examples
Setup with API Key
var atmosporeService = new AtmosporeService(
httpClient,
"YOUR_ATMOSPORE_API_KEY",
loggerFactory.CreateLogger<AtmosporeService>());
Test API Key
var isValid = await atmosporeService.TestApiKey();
Console.WriteLine($"API Key is {(isValid ? "valid" : "invalid")}");
Get Pollen Forecast for Today
var pollenForecast = await atmosporeService.GetPollenForecastAsync(
"39.4300996",
"-77.804161",
null, // null = today's date
1); // 1 day forecast
if (pollenForecast?.Data != null && pollenForecast.Data.Count > 0)
{
var daily = pollenForecast.Data[0];
Console.WriteLine($"Date: {daily.Date}");
Console.WriteLine($"Overall Risk: {daily.OverallRisk}");
if (daily.Species != null)
{
foreach (var species in daily.Species)
{
Console.WriteLine($"{species.DisplayName}: {species.RiskLevel} (Value: {species.Value})");
}
}
}
Get Multi-Day Pollen Forecast
var multiDayForecast = await atmosporeService.GetPollenForecastAsync(
"39.4300996",
"-77.804161",
"2026-05-27", // specific date
3); // 3 days
if (multiDayForecast?.Data != null)
{
Console.WriteLine($"Location: {multiDayForecast.Meta?.Location?.Lat}, {multiDayForecast.Meta?.Location?.Lon}");
foreach (var day in multiDayForecast.Data)
{
Console.WriteLine($"\n{day.Date}: Overall Risk = {day.OverallRisk}");
}
}
WeatherAlert Examples
Setup
var weatherAlertService = new WeatherAlertService(
httpClient,
loggerFactory.CreateLogger<WeatherAlertService>());
Get Combined Alerts from All Sources
var combinedAlerts = await weatherAlertService.GetCombinedAlertsAsync(
"40.7128", // latitude
"-74.0060", // longitude
"ON", // province/state code
"NSW", // Australian state code
100); // radius in km for earthquake alerts
if (combinedAlerts != null)
{
if (combinedAlerts.MeteoalarmAlerts != null)
{
Console.WriteLine($"Meteoalarm Alerts: {combinedAlerts.MeteoalarmAlerts.Count}");
}
if (combinedAlerts.NwsAlerts != null)
{
Console.WriteLine($"NWS Alerts: {combinedAlerts.NwsAlerts.Features?.Count ?? 0}");
}
if (combinedAlerts.GdacsAlerts != null)
{
Console.WriteLine($"GDACS Events: {combinedAlerts.GdacsAlerts.Item?.Count ?? 0}");
}
}
Get Meteoalarm Alerts (European)
var meteoalarmAlerts = await weatherAlertService.GetMeteoalarmAlertsAsync(
"48.8566", // Paris latitude
"2.3522"); // Paris longitude
if (meteoalarmAlerts != null)
{
Console.WriteLine($"Found {meteoalarmAlerts.Count} Meteoalarm alerts");
}
Get NWS Alerts (US)
var nwsAlerts = await weatherAlertService.GetNwsAlertsAsync(
"40.7128", // NYC latitude
"-74.0060"); // NYC longitude
if (nwsAlerts?.Features != null)
{
foreach (var feature in nwsAlerts.Features)
{
Console.WriteLine($"Event: {feature.Properties?.Event}");
Console.WriteLine($"Severity: {feature.Properties?.Severity}");
Console.WriteLine($"Description: {feature.Properties?.Description}");
}
}
Get Environment Canada Alerts
var canadaAlerts = await weatherAlertService.GetEnvironmentCanadaAlertsAsync("ON"); // Ontario
if (canadaAlerts?.Channel?.Item != null)
{
foreach (var item in canadaAlerts.Channel.Item)
{
Console.WriteLine($"Title: {item.Title}");
Console.WriteLine($"Category: {item.Category}");
}
}
Get BOM Australia Alerts
var bomAlerts = await weatherAlertService.GetBomAlertsAsync("NSW"); // New South Wales
if (bomAlerts?.Warnings != null)
{
Console.WriteLine($"Found {bomAlerts.Warnings.Count} BOM warnings");
}
Get Earthquake Alerts (EMSC)
var earthquakeAlerts = await weatherAlertService.GetEmscAlertsAsync(
"35.6762", // Tokyo latitude
"139.6503", // Tokyo longitude
500); // 500 km radius
if (earthquakeAlerts?.Features != null)
{
foreach (var earthquake in earthquakeAlerts.Features)
{
Console.WriteLine($"Magnitude: {earthquake.Properties?.Mag}");
Console.WriteLine($"Location: {earthquake.Properties?.Flynn_region}");
Console.WriteLine($"Time: {earthquake.Properties?.Time}");
}
}
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
Atmospore API
- Base URL:
https://pollenapi.com/v1/pollen - API Key: Required (via
x-api-keyheader) - Sign Up: Atmospore
- Documentation: Atmospore API Docs
Weather Alert Sources
- Meteoalarm:
https://api.meteoalarm.org/v1/alerts(European weather alerts) - NWS:
https://api.weather.gov/alerts/active(US National Weather Service) - GDACS:
https://www.gdacs.org/gdacsapi/api/events/geteventlist/MAP(Global disasters) - Environment Canada:
https://weather.gc.ca/rss/warning/(Canadian warnings) - BOM:
http://www.bom.gov.au/fwo/(Australian Bureau of Meteorology) - EMSC:
https://www.seismicportal.eu/fdsnws/event/1/query(European earthquake alerts) - DWD:
https://www.dwd.de/DWD/warnungen/warnapp/json/warnings.json(German weather service) - API Key: Not required
- Note: NWS requires a User-Agent header (automatically added by the service)
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.9): For hosting, logging, and dependency injection abstractions
- Xcalibur.Weather.Models (v1.0.12): 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
All tests use:
- xUnit as the testing framework
- FluentAssertions for readable assertions
- DelegatingHandlerStub from
Xcalibur.Weather.Models.Testingfor HTTP mocking - NullLogger for lightweight test logging
Test Statistics
- Total Tests: 44
- Status: โ All passing
- Coverage: Comprehensive unit tests for all services
Current Test Coverage
OpenMeteoServiceTests (7 tests)
- Current weather deserialization and validation
- Air quality data retrieval
- Hourly and daily forecast operations
- Historical weather data (yesterday)
- Error handling for non-success HTTP responses
- Invalid JSON response handling
GeocodioServiceTests (5 tests)
- API key validation (valid, invalid, forbidden)
- Address-to-coordinate geocoding
- Error handling for bad requests
- Invalid JSON response handling
IpGeoServiceTests (5 tests)
- API key validation (valid, unauthorized)
- Astronomical data retrieval (sun/moon)
- Error handling for non-success responses
- Invalid JSON response handling
AtmosporeServiceTests (9 tests)
- API key validation (OK, unauthorized, forbidden)
- Pollen forecast data deserialization
- URL generation with explicit and null dates
- API key header verification
- Request parameter validation
- Error handling for bad requests
- Invalid JSON response handling
WeatherAlertServiceTests (10 tests)
- Multi-provider alert aggregation
- Individual provider alert retrieval (Meteoalarm, NWS, GDACS, Environment Canada, BOM, EMSC, DWD)
- User-Agent header management
- Error handling for all alert sources
- Combined alert fetching from multiple sources
SunriseSunsetServiceTests (3 tests)
- Sunrise and sunset data deserialization
- Error handling for non-success responses
- Invalid JSON response handling
OpenStreetMapServiceTests (5 tests)
- Location search and geocoding
- User-Agent header management (default, preservation)
- Error handling for bad requests
- Invalid JSON response handling
๐๏ธ Project Structure
Xcalibur.Weather.Services/
โโโ AtmosporeService.cs
โโโ GeocodioService.cs
โโโ IpGeoService.cs
โโโ OpenMeteoService.cs
โโโ OpenStreetMapService.cs
โโโ SunriseSunsetService.cs
โโโ WeatherAlertService.cs
โโโ Xcalibur.Weather.Services.csproj
Xcalibur.Weather.Services.Tests/
โโโ AtmosporeServiceTests.cs
โโโ GeocodioServiceTests.cs
โโโ IpGeoServiceTests.cs
โโโ OpenMeteoServiceTests.cs
โโโ OpenStreetMapServiceTests.cs
โโโ SunriseSunsetServiceTests.cs
โโโ WeatherAlertServiceTests.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, Atmospore, 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 and NWS require a meaningful
User-Agent; services set defaults if one is not already present - Aggregate Alerts Efficiently: Use
GetCombinedAlertsAsyncto fetch from multiple weather alert sources in parallel
๐ 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 "Atmospore:ApiKey" "YOUR_API_KEY"
appsettings.json
{
"Geocodio": {
"ApiKey": "YOUR_GEOCODIO_API_KEY"
},
"IpGeo": {
"ApiKey": "YOUR_IPGEO_API_KEY"
},
"Atmospore": {
"ApiKey": "YOUR_ATMOSPORE_API_KEY"
}
}
Environment Variables
set GEOCODIO_API_KEY=your_key_here
set IPGEO_API_KEY=your_key_here
set ATMOSPORE_API_KEY=your_key_here
๐ Version History
v1.0.12 (Current)
- Performance improvements and property descriptions for Weather Alerts
- Enhanced documentation and XML comments
- Updated dependencies to latest stable versions
v1.0.10
- Additional property descriptions and documentation improvements
- Bug fixes and stability enhancements
v1.0.9
- Minor bug fixes and refinements
- Improved error handling across services
v1.0.8
- Internal improvements and updates
- Dependency version updates
v1.0.7
- Added multi-source weather alert aggregation support
- Introduced
GetCombinedAlertsAsyncfor unified alert handling - Enhanced alert service provider coverage
v1.0.6
- Major Refactoring: Services moved to flat namespace structure (
Xcalibur.Weather.Services) - Added AtmosporeService: Pollen forecast data from Atmospore API (replaced Google Pollen)
- Added WeatherAlertService: Multi-provider weather alerts
- Meteoalarm (European severe weather)
- NWS (US National Weather Service)
- GDACS (Global disasters)
- Environment Canada (Canadian alerts)
- BOM (Australian Bureau of Meteorology)
- EMSC (European earthquake data)
- DWD (German Weather Service)
- Updated to use Xcalibur.Weather.Models v1.0.6 with refactored structure
v1.0.5
- Added support for Google Weather Alerts API
- Introduced weather alert retrieval capabilities
- Updated model dependencies
v1.0.4
- Added pollen forecast support (Google Pollen API)
- Enhanced geocoding functionality
- Improved error handling
v1.0.3
- Added SunriseSunsetService for astronomy data
- Added OpenStreetMapService for geocoding
- Expanded API provider coverage
v1.0.2
- Improved logging and error handling
- Performance optimizations
- Documentation updates
v1.0.1
- Initial bug fixes
- Improved API key validation
v1.0.0
- Initial release
- OpenMeteoService for weather and air quality
- GeocodioService for geocoding
- IpGeoService for astronomy data
- Comprehensive async/await support
- Built-in logging and error handling
๐ 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.
๐ฅ Contributing
Contributions are welcome! Please feel free to submit issues or pull requests to improve the library.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
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, IpGeolocation.io, and Atmospore services. Open-Meteo, SunriseSunset.io, OpenStreetMap Nominatim, and all Weather Alert sources (Meteoalarm, NWS, GDACS, Environment Canada, BOM, EMSC, DWD) 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.9)
- Xcalibur.Weather.Models (>= 1.0.13)
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.
Weather code value retired for multi-language compatibility.