Skip to content

Commit

Permalink
Change types and add converters for values
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszzborek committed Jun 2, 2024
1 parent ae01338 commit 62aa640
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1405,12 +1405,35 @@ public async Task GetWeatherForecastAsync()
.And.Property(nameof(WeatherForecast.ValidStats)).Not.Default
.And.Property(nameof(WeatherForecast.AffectsSession)).Not.Default
.And.Property(nameof(WeatherForecast.CloudCover)).Not.Default
.And.Property(nameof(WeatherForecast.RelHumidity)).Not.Default
.And.Property(nameof(WeatherForecast.RelativeHumidity)).Not.Default
.And.Property(nameof(WeatherForecast.WindSpeed)).Not.Default
.And.Property(nameof(WeatherForecast.AllowPrecipitation)).Not.Null
.And.Property(nameof(WeatherForecast.PrecipitationAmount)).Not.Null
.And.Property(nameof(WeatherForecast.Timestamp)).Not.Null);

var forecast = response.First();
Assert.Multiple(() =>
{
Assert.That(forecast.TimeOffset, Is.EqualTo(TimeSpan.FromMinutes(-385)));
Assert.That(forecast.RawAirTemp, Is.EqualTo(7.72m));
Assert.That(forecast.PrecipitationChance, Is.EqualTo(100m));
Assert.That(forecast.Index, Is.EqualTo(0));
Assert.That(forecast.IsSunUp, Is.EqualTo(true));
Assert.That(forecast.Pressure, Is.EqualTo(967.1m));
Assert.That(forecast.WindDir, Is.EqualTo(239));
Assert.That(forecast.WindDirection, Is.EqualTo(WindDirection.SouthWest));
Assert.That(forecast.AirTemp, Is.EqualTo(18.63m));
Assert.That(forecast.ValidStats, Is.EqualTo(true));
Assert.That(forecast.AffectsSession, Is.EqualTo(false));
Assert.That(forecast.CloudCover, Is.EqualTo(76.6m));
Assert.That(forecast.RelativeHumidity, Is.EqualTo(99.99m));
Assert.That(forecast.WindSpeed, Is.EqualTo(6.07m));
Assert.That(forecast.AllowPrecipitation, Is.EqualTo(true));
Assert.That(forecast.PrecipitationAmount, Is.EqualTo(42));
Assert.That(forecast.Timestamp, Is.EqualTo(new DateTime(2024, 04, 13, 12, 0, 0, DateTimeKind.Utc)));
});


}

protected override void Dispose(bool disposing)
Expand Down
33 changes: 33 additions & 0 deletions src/Aydsko.iRacingData/Converters/OneDecimalPointValueConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Text.Json;

namespace Aydsko.iRacingData.Converters;

/// <summary>
/// Convert the cloud cover value from the API to a decimal.
/// </summary>
public class OneDecimalPointValueConverter : JsonConverter<decimal>
{
public override decimal Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TryGetInt32(out var intValue))
{
return intValue / 10m;
}

return default;
}

public override void Write(Utf8JsonWriter writer, decimal value, JsonSerializerOptions options)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif

writer.WriteNumberValue(value * 10);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Text.Json;

namespace Aydsko.iRacingData.Converters;

/// <summary>
/// Convert the temperature value from the API to a decimal.
/// </summary>
public class TwoDecimalPointsValueConverter : JsonConverter<decimal>
{
public override decimal Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TryGetInt32(out var intValue))
{
return intValue / 100m;
}

return default;
}

public override void Write(Utf8JsonWriter writer, decimal value, JsonSerializerOptions options)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif

writer.WriteNumberValue(value * 100);
}
}
97 changes: 74 additions & 23 deletions src/Aydsko.iRacingData/Series/WeatherForecast.cs
Original file line number Diff line number Diff line change
@@ -1,59 +1,110 @@
using Aydsko.iRacingData.Constants;
using Aydsko.iRacingData.Converters;

namespace Aydsko.iRacingData.Series;

public class WeatherForecast
{
[JsonPropertyName("time_offset")]
public int TimeOffset { get; set; }

[JsonPropertyName("raw_air_temp")]
public int RawAirTemp { get; set; }

[JsonPropertyName("precip_chance")]
public int PrecipitationChance { get; set; }

/// <summary>
/// Offset from race start time
/// </summary>
[JsonPropertyName("time_offset"), JsonConverter(typeof(UtcOffsetToTimeSpanConverter))]
public TimeSpan TimeOffset { get; set; }

[JsonPropertyName("raw_air_temp"), JsonConverter(typeof(TwoDecimalPointsValueConverter))]
public decimal RawAirTemp { get; set; }

/// <summary>
/// Precipitation chance in percentage
/// </summary>
[JsonPropertyName("precip_chance"), JsonConverter(typeof(TwoDecimalPointsValueConverter))]
public decimal PrecipitationChance { get; set; }

/// <summary>
/// Index of the forecast
/// </summary>
[JsonPropertyName("index")]
public int Index { get; set; }

/// <summary>
/// Is the sun up
/// </summary>
[JsonPropertyName("is_sun_up")]
public bool IsSunUp { get; set; }

[JsonPropertyName("pressure")]
public int Pressure { get; set; }
/// <summary>
/// Pressure in hPa
/// </summary>
[JsonPropertyName("pressure"), JsonConverter(typeof(OneDecimalPointValueConverter))]
public decimal Pressure { get; set; }

/// <summary>
/// Wind direction in degrees
/// </summary>
[JsonPropertyName("wind_dir")]
public int WindDir { get; set; }

/// <summary>
/// Rounded wind direction
/// </summary>
[JsonIgnore]
public WindDirection WindDirection => (WindDirection)WindDir;
public WindDirection WindDirection => ConvertDegreeToDirection(WindDir);

[JsonPropertyName("air_temp")]
public int AirTemp { get; set; }
/// <summary>
/// Air temperature
/// </summary>
[JsonPropertyName("air_temp"), JsonConverter(typeof(TwoDecimalPointsValueConverter))]
public decimal AirTemp { get; set; }

[JsonPropertyName("valid_stats")]
public bool ValidStats { get; set; }

/// <summary>
/// Is the session affected by the weather
/// </summary>
[JsonPropertyName("affects_session")]
public bool AffectsSession { get; set; }

[JsonPropertyName("cloud_cover")]
public int CloudCover { get; set; }

[JsonPropertyName("rel_humidity")]
public int RelHumidity { get; set; }

[JsonPropertyName("wind_speed")]
public int WindSpeed { get; set; }

/// <summary>
/// Cloud cover in percentage
/// </summary>
[JsonPropertyName("cloud_cover"), JsonConverter(typeof(OneDecimalPointValueConverter))]
public decimal CloudCover { get; set; }

/// <summary>
/// Relative humidity in percentage
/// </summary>
[JsonPropertyName("rel_humidity"), JsonConverter(typeof(TwoDecimalPointsValueConverter))]
public decimal RelativeHumidity { get; set; }

/// <summary>
/// Wind speed (in meters per second)
/// </summary>
[JsonPropertyName("wind_speed"), JsonConverter(typeof(TwoDecimalPointsValueConverter))]
public decimal WindSpeed { get; set; }

/// <summary>
/// Is precipitation allowed
/// </summary>
[JsonPropertyName("allow_precip")]
public bool AllowPrecipitation { get; set; }

/// <summary>
/// Precipitation amount in millimeters
/// </summary>
[JsonPropertyName("precip_amount")]
public decimal PrecipitationAmount { get; set; }

/// <summary>
/// Date and time of the forecast
/// </summary>
[JsonPropertyName("timestamp")]
public DateTime Timestamp { get; set; }

private static WindDirection ConvertDegreeToDirection(int degree)
{
return (WindDirection)(int)Math.Round(((double)degree % 360) / 45);
}
}

[JsonSerializable(typeof(List<WeatherForecast>)), JsonSourceGenerationOptions(WriteIndented = true)]
Expand Down

0 comments on commit 62aa640

Please sign in to comment.