-
Notifications
You must be signed in to change notification settings - Fork 3
feat: add Open-Meteo provider and configurable weather cache #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
058037c
da5e3be
aad05b6
6bf10bd
f1c1305
46dfe15
7fbae87
0b02fd7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,125 @@ | ||||||||||||||||||||||||||||||||||||||||
| using System; | ||||||||||||||||||||||||||||||||||||||||
| using ChillWithYou.EnvSync.Models; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| namespace ChillWithYou.EnvSync.Services | ||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||
| internal static class OpenMeteoWeatherMapper | ||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||
| internal static WeatherInfo Map( | ||||||||||||||||||||||||||||||||||||||||
| int weatherCode, | ||||||||||||||||||||||||||||||||||||||||
| double temperature, | ||||||||||||||||||||||||||||||||||||||||
| double precipitation, | ||||||||||||||||||||||||||||||||||||||||
| double rain, | ||||||||||||||||||||||||||||||||||||||||
| double showers, | ||||||||||||||||||||||||||||||||||||||||
| double snowfall, | ||||||||||||||||||||||||||||||||||||||||
| double cloudCover, | ||||||||||||||||||||||||||||||||||||||||
| DateTime updateTime) | ||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||
| int normalizedCode = ToSeniverseCode(weatherCode, precipitation, rain, showers, snowfall, cloudCover); | ||||||||||||||||||||||||||||||||||||||||
| return new WeatherInfo | ||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||
| Code = normalizedCode, | ||||||||||||||||||||||||||||||||||||||||
| Text = ToWeatherText(weatherCode, normalizedCode), | ||||||||||||||||||||||||||||||||||||||||
| Temperature = (int)Math.Round(temperature), | ||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Math.Round without a MidpointRounding argument defaults to banker's rounding (round-to-even). For example, 2.5°C rounds to 2 and 3.5°C rounds to 4, which can be counterintuitive for weather display. Consider using MidpointRounding.AwayFromZero for temperatures: Math.Round(temperature, MidpointRounding.AwayFromZero). Suggestion:
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
| Condition = ToCondition(normalizedCode), | ||||||||||||||||||||||||||||||||||||||||
| UpdateTime = updateTime | ||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| internal static int ToSeniverseCode( | ||||||||||||||||||||||||||||||||||||||||
| int weatherCode, | ||||||||||||||||||||||||||||||||||||||||
| double precipitation, | ||||||||||||||||||||||||||||||||||||||||
| double rain, | ||||||||||||||||||||||||||||||||||||||||
| double showers, | ||||||||||||||||||||||||||||||||||||||||
| double snowfall, | ||||||||||||||||||||||||||||||||||||||||
| double cloudCover) | ||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||
| if (snowfall > 0d || IsSnow(weatherCode)) | ||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||
| return 21; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| if (IsThunder(weatherCode)) | ||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||
| return 11; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| if (IsHeavyRain(weatherCode) || precipitation >= 2.5d || rain + showers >= 2.5d) | ||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||
| return 14; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| if (IsLightRain(weatherCode) || precipitation > 0d || rain > 0d || showers > 0d) | ||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||
| return 13; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| if (weatherCode == 45 || weatherCode == 48) | ||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||
| return 26; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| // Codes 1-3 (partly cloudy/overcast) or clear sky with high measured cloud cover → Cloudy | ||||||||||||||||||||||||||||||||||||||||
| if ((weatherCode >= 1 && weatherCode <= 3) || cloudCover >= 65d) | ||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||
| return 4; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| return 1; | ||||||||||||||||||||||||||||||||||||||||
|
Tim-Devil marked this conversation as resolved.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When no conditions match, ToSeniverseCode silently returns 1 (Clear). Unrecognized weather codes are effectively hidden, making it harder to detect API changes or mapping gaps during development. Consider logging a warning via ChillEnvPlugin.Log?.LogWarning(...) when an unmapped code is encountered, or alternatively have the caller in WeatherService.ParseOpenMeteoWeatherJson validate the result. Suggestion:
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| private static bool IsLightRain(int weatherCode) | ||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||
| return weatherCode == 51 || | ||||||||||||||||||||||||||||||||||||||||
| weatherCode == 53 || | ||||||||||||||||||||||||||||||||||||||||
| weatherCode == 55 || | ||||||||||||||||||||||||||||||||||||||||
| weatherCode == 56 || | ||||||||||||||||||||||||||||||||||||||||
| weatherCode == 57 || | ||||||||||||||||||||||||||||||||||||||||
| weatherCode == 61 || | ||||||||||||||||||||||||||||||||||||||||
| weatherCode == 63 || | ||||||||||||||||||||||||||||||||||||||||
| weatherCode == 80; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| private static bool IsHeavyRain(int weatherCode) | ||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||
| return weatherCode == 65 || | ||||||||||||||||||||||||||||||||||||||||
| weatherCode == 66 || | ||||||||||||||||||||||||||||||||||||||||
| weatherCode == 67 || | ||||||||||||||||||||||||||||||||||||||||
| weatherCode == 81 || | ||||||||||||||||||||||||||||||||||||||||
| weatherCode == 82; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| private static bool IsSnow(int weatherCode) | ||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||
| return weatherCode == 71 || | ||||||||||||||||||||||||||||||||||||||||
| weatherCode == 73 || | ||||||||||||||||||||||||||||||||||||||||
| weatherCode == 75 || | ||||||||||||||||||||||||||||||||||||||||
| weatherCode == 77 || | ||||||||||||||||||||||||||||||||||||||||
| weatherCode == 85 || | ||||||||||||||||||||||||||||||||||||||||
| weatherCode == 86; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| private static bool IsThunder(int weatherCode) | ||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||
| return weatherCode == 95 || | ||||||||||||||||||||||||||||||||||||||||
| weatherCode == 96 || | ||||||||||||||||||||||||||||||||||||||||
| weatherCode == 99; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| private static WeatherCondition ToCondition(int normalizedCode) | ||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||
| return WeatherService.MapCodeToCondition(normalizedCode); | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
Tim-Devil marked this conversation as resolved.
|
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| private static string ToWeatherText(int weatherCode, int normalizedCode) | ||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||
| if (normalizedCode == 21) return "Snow"; | ||||||||||||||||||||||||||||||||||||||||
| if (normalizedCode == 11) return "ThunderRain"; | ||||||||||||||||||||||||||||||||||||||||
| if (normalizedCode == 14) return "HeavyRain"; | ||||||||||||||||||||||||||||||||||||||||
| if (normalizedCode == 13) return "LightRain"; | ||||||||||||||||||||||||||||||||||||||||
| if (normalizedCode == 26) return "Fog"; | ||||||||||||||||||||||||||||||||||||||||
| if (normalizedCode == 4) return "Cloudy"; | ||||||||||||||||||||||||||||||||||||||||
| return weatherCode == 0 ? "Clear" : "Unknown"; | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+114
to
+122
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ToWeatherText uses the raw weatherCode in its fallback, which can produce "Unknown" when normalizedCode=1 but weatherCode≠0. Meanwhile, ToCondition(1) returns WeatherCondition.Clear via MapCodeToCondition, creating an inconsistency. Add an explicit case for normalizedCode=1 so the text is fully determined by the normalized code, and consider logging a warning for unrecognized weatherCode values. Suggestion:
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.