Xcalibur.Weather.Services 1.0.3

There is a newer version of this package available.
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
                    
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="Xcalibur.Weather.Services" Version="1.0.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Xcalibur.Weather.Services" Version="1.0.3" />
                    
Directory.Packages.props
<PackageReference Include="Xcalibur.Weather.Services" />
                    
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 Xcalibur.Weather.Services --version 1.0.3
                    
#r "nuget: Xcalibur.Weather.Services, 1.0.3"
                    
#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 Xcalibur.Weather.Services@1.0.3
                    
#: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=Xcalibur.Weather.Services&version=1.0.3
                    
Install as a Cake Addin
#tool nuget:?package=Xcalibur.Weather.Services&version=1.0.3
                    
Install as a Cake Tool

Xcalibur.Weather.Services

.NET 10 NuGet License

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 SunriseSunsetService for sunrise and sunset data
  • Added OpenStreetMapService for Nominatim geocoding
  • Added GooglePollenService for daily pollen forecast data

๐Ÿ“‹ Table of Contents

โœจ 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-Agent support 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

IpGeolocation.io

Google Pollen API

  • Base URL: https://pollen.googleapis.com/v1/forecast:lookup
  • API Key: Required
  • Documentation: Google Pollen API Docs

SunriseSunset.io

OpenStreetMap Nominatim

  • Base URL: https://nominatim.openstreetmap.org/search
  • API Key: Not required
  • Requirement: A descriptive User-Agent header 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 operations
  • GeocodioServiceTests: Tests for geocoding functionality and API key validation
  • IpGeoServiceTests: Tests for astronomical data retrieval
  • GooglePollenServiceTests: Tests for pollen forecast retrieval, API key validation, and request URL generation
  • SunriseSunsetServiceTests: Tests for sunrise and sunset data retrieval
  • OpenStreetMapServiceTests: 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

  1. Reuse HttpClient: Create a single HttpClient instance and reuse it across service instances
  2. Use Dependency Injection: Register services in your DI container for better testability
  3. Handle Nulls: All service methods return nullable types; always check for null responses
  4. Monitor Logs: Enable debug logging to troubleshoot API issues
  5. Respect Provider Policies: Be mindful of rate limits and usage policies for Geocodio, IpGeo, Google Pollen, SunriseSunset.io, and OpenStreetMap Nominatim
  6. Secure API Keys: Store API keys in secure configuration (Azure Key Vault, user secrets, etc.)
  7. 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


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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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.

Version Downloads Last Updated
1.0.5 105 5/19/2026
1.0.3 122 5/1/2026
1.0.2 116 4/30/2026
1.0.1 104 4/29/2026
1.0.0 193 3/6/2026

Added services for Google Pollen API.