Skip to content

Commit 95cba90

Browse files
authored
Upgrade Flurl to v4.0.2 (#171)
**Summary:** This pull request upgrades the Flurl library used in the project and includes necessary adjustments to ensure compatibility with the new version. Because Flurl v4 move to `System.text.Json` we need to change here the serializer.
1 parent 0faec4d commit 95cba90

67 files changed

Lines changed: 415 additions & 429 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.idea/.idea.Netatmo/.idea/vcs.xml

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Netatmo/AirClient.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace Netatmo;
77
public class AirClient(string baseUrl, ICredentialManager credentialManager) : IAirClient
88
{
99
public Task<DataResponse<GetHomeCoachsData>> GetHomeCoachsData(string deviceId = null) =>
10-
baseUrl.ConfigureRequest(Configuration.ConfigureRequest)
10+
baseUrl.WithSettings(Configuration.ConfigureRequest)
1111
.AppendPathSegment("/api/gethomecoachsdata")
1212
.WithOAuthBearerToken(credentialManager.AccessToken)
1313
.PostJsonAsync(new GetHomeCoachsDataRequest { DeviceId = deviceId })

src/Netatmo/Configuration.cs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
1+
using System.Text.Json;
2+
using System.Text.Json.Serialization;
13
using Flurl.Http.Configuration;
24
using Netatmo.Converters;
3-
using Newtonsoft.Json;
45

56
namespace Netatmo;
67

78
public static class Configuration
89
{
9-
public static JsonSerializerSettings JsonSerializer() =>
10-
new() { NullValueHandling = NullValueHandling.Ignore, Converters = [new TimestampToInstantConverter(), new StringToDateTimeZoneConverter()] };
10+
public static JsonSerializerOptions JsonSerializerOptions =>
11+
new() { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, Converters = { new TimestampToInstantConverter(), new StringToDateTimeZoneConverter() } };
1112

1213
public static void ConfigureRequest(FlurlHttpSettings settings)
1314
{
14-
var jsonSettings = JsonSerializer();
15-
16-
//jsonSettings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
17-
settings.JsonSerializer = new NewtonsoftJsonSerializer(jsonSettings);
15+
// something like maybe miss : jsonSettings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
16+
settings.JsonSerializer = new DefaultJsonSerializer(JsonSerializerOptions);
1817
}
1918
}
Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,13 @@
1-
using Flurl.Util;
2-
using Newtonsoft.Json;
1+
using System.Text.Json;
2+
using System.Text.Json.Serialization;
33
using NodaTime;
44

55
namespace Netatmo.Converters;
66

77
public class StringToDateTimeZoneConverter : JsonConverter<DateTimeZone>
88
{
9-
public override void WriteJson(JsonWriter writer, DateTimeZone value, JsonSerializer serializer)
10-
{
11-
writer.WriteValue(value?.ToInvariantString());
12-
}
9+
public override DateTimeZone Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
10+
DateTimeZoneProviders.Tzdb.GetZoneOrNull(reader.GetString()!);
1311

14-
public override DateTimeZone ReadJson(JsonReader reader, Type objectType, DateTimeZone existingValue, bool hasExistingValue, JsonSerializer serializer)
15-
{
16-
if (reader.Value == null)
17-
{
18-
return null;
19-
}
20-
21-
return DateTimeZoneProviders.Tzdb[reader.Value.ToString()];
22-
}
12+
public override void Write(Utf8JsonWriter writer, DateTimeZone value, JsonSerializerOptions options) => writer.WriteStringValue(value?.Id);
2313
}
Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,12 @@
1-
using Newtonsoft.Json;
1+
using System.Text.Json;
2+
using System.Text.Json.Serialization;
23
using NodaTime;
34

45
namespace Netatmo.Converters;
56

6-
public class TimestampToInstantConverter : JsonConverter<Instant?>
7+
public class TimestampToInstantConverter : JsonConverter<Instant>
78
{
8-
public override void WriteJson(JsonWriter writer, Instant? value, JsonSerializer serializer)
9-
{
10-
if (value.HasValue)
11-
{
12-
writer.WriteValue(value.Value.ToUnixTimeSeconds().ToString());
13-
}
14-
}
9+
public override Instant Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => Instant.FromUnixTimeSeconds(reader.GetInt64());
1510

16-
public override Instant? ReadJson(JsonReader reader, Type objectType, Instant? existingValue, bool hasExistingValue, JsonSerializer serializer)
17-
{
18-
if (reader.Value == null)
19-
{
20-
return null;
21-
}
22-
23-
var value = long.Parse(reader.Value.ToString());
24-
25-
return Instant.FromUnixTimeSeconds(value);
26-
}
11+
public override void Write(Utf8JsonWriter writer, Instant value, JsonSerializerOptions options) => writer.WriteNumberValue(value.ToUnixTimeSeconds());
2712
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System.Text.Json;
2+
using System.Text.Json.Serialization;
3+
4+
namespace Netatmo.Converters;
5+
6+
public class ZoneIdConverter : JsonConverter<string>
7+
{
8+
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
9+
reader.TokenType switch
10+
{
11+
JsonTokenType.String => reader.GetString(),
12+
JsonTokenType.Number => reader.GetInt32().ToString(),
13+
_ => throw new JsonException("Zone.Id must be a string or an integer.")
14+
};
15+
16+
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) => writer.WriteNumberValue(int.Parse(value));
17+
}

src/Netatmo/EnergyClient.cs

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,28 @@ namespace Netatmo;
99
public class EnergyClient(string baseUrl, ICredentialManager credentialManager) : IEnergyClient
1010
{
1111
public Task<DataResponse<GetHomesDataBody>> GetHomesData(string homeId = null, string gatewayTypes = null) =>
12-
baseUrl.ConfigureRequest(Configuration.ConfigureRequest)
12+
baseUrl.WithSettings(Configuration.ConfigureRequest)
1313
.AppendPathSegment("/api/homesdata")
1414
.WithOAuthBearerToken(credentialManager.AccessToken)
1515
.PostJsonAsync(new GetHomesDataRequest { HomeId = homeId, GatewayTypes = gatewayTypes })
1616
.ReceiveJson<DataResponse<GetHomesDataBody>>();
1717

1818
public async Task<DataResponse<GetHomeStatusBody>> GetHomeStatus(string homeId, string[] deviceTypes = null) =>
19-
await baseUrl.ConfigureRequest(Configuration.ConfigureRequest)
19+
await baseUrl.WithSettings(Configuration.ConfigureRequest)
2020
.AppendPathSegment("/api/homestatus")
2121
.WithOAuthBearerToken(credentialManager.AccessToken)
2222
.PostJsonAsync(new GetHomeStatusRequest { HomeId = homeId, DeviceTypes = deviceTypes })
2323
.ReceiveJson<DataResponse<GetHomeStatusBody>>();
2424

2525
public async Task<DataResponse> SetThermMode(string homeId, string mode, Instant? endTime = null) =>
26-
await baseUrl.ConfigureRequest(Configuration.ConfigureRequest)
26+
await baseUrl.WithSettings(Configuration.ConfigureRequest)
2727
.AppendPathSegment("/api/setthermmode")
2828
.WithOAuthBearerToken(credentialManager.AccessToken)
2929
.PostJsonAsync(new SetThermModeRequest { HomeId = homeId, Mode = mode, EndTime = endTime })
3030
.ReceiveJson<DataResponse>();
3131

3232
public async Task<DataResponse> SetRoomThermPoint(string homeId, string roomId, string mode, double? temp = null, Instant? endTime = null) =>
33-
await baseUrl.ConfigureRequest(Configuration.ConfigureRequest)
33+
await baseUrl.WithSettings(Configuration.ConfigureRequest)
3434
.AppendPathSegment("/api/setroomthermpoint")
3535
.WithOAuthBearerToken(credentialManager.AccessToken)
3636
.PostJsonAsync(
@@ -49,55 +49,55 @@ public async Task<DataResponse<T[]>> GetRoomMeasure<T>(GetRoomMeasureParameters
4949
{
5050
ValidateGetRoomMeasureParameters<T>(parameters);
5151

52-
return await baseUrl.ConfigureRequest(Configuration.ConfigureRequest)
52+
return await baseUrl.WithSettings(Configuration.ConfigureRequest)
5353
.AppendPathSegment("/api/getroommeasure")
5454
.WithOAuthBearerToken(credentialManager.AccessToken)
55-
.PostJsonAsync(
56-
new GetRoomMeasureRequest
55+
.SetQueryParams(
56+
new
5757
{
58-
HomeId = parameters.HomeId,
59-
RoomId = parameters.RoomId,
60-
Scale = parameters.Scale.Value,
61-
Type = parameters.Type.Value,
62-
BeginAt = parameters.BeginAt,
63-
EndAt = parameters.EndAt,
64-
Limit = parameters.Limit,
65-
Optimize = parameters.Optimize,
66-
RealTime = parameters.RealTime
58+
home_id = parameters.HomeId,
59+
room_id = parameters.RoomId,
60+
scale = parameters.Scale.Value,
61+
type = parameters.Type.Value,
62+
date_begin = parameters.BeginAt?.ToUnixTimeSeconds(),
63+
date_end = parameters.EndAt?.ToUnixTimeSeconds(),
64+
limit = parameters.Limit,
65+
optimize = parameters.Optimize,
66+
real_time = parameters.RealTime
6767
})
68-
.ReceiveJson<DataResponse<T[]>>();
68+
.GetJsonAsync<DataResponse<T[]>>();
6969
}
7070

7171
public async Task<DataResponse> SwitchHomeSchedule(string homeId, string scheduleId) =>
72-
await baseUrl.ConfigureRequest(Configuration.ConfigureRequest)
72+
await baseUrl.WithSettings(Configuration.ConfigureRequest)
7373
.AppendPathSegment("/api/switchhomeschedule")
7474
.WithOAuthBearerToken(credentialManager.AccessToken)
7575
.PostJsonAsync(new SwitchHomeScheduleRequest { HomeId = homeId, ScheduleId = scheduleId })
7676
.ReceiveJson<DataResponse>();
7777

7878
public async Task<DataResponse> RenameHomeSchedule(string homeId, string scheduleId, string name) =>
79-
await baseUrl.ConfigureRequest(Configuration.ConfigureRequest)
79+
await baseUrl.WithSettings(Configuration.ConfigureRequest)
8080
.AppendPathSegment("/api/renamehomeschedule")
8181
.WithOAuthBearerToken(credentialManager.AccessToken)
8282
.PostJsonAsync(new RenameHomeScheduleRequest { HomeId = homeId, ScheduleId = scheduleId, Name = name })
8383
.ReceiveJson<DataResponse>();
8484

8585
public async Task<DataResponse> DeleteHomeSchedule(string homeId, string scheduleId) =>
86-
await baseUrl.ConfigureRequest(Configuration.ConfigureRequest)
86+
await baseUrl.WithSettings(Configuration.ConfigureRequest)
8787
.AppendPathSegment("/api/deletehomeschedule")
8888
.WithOAuthBearerToken(credentialManager.AccessToken)
8989
.PostJsonAsync(new DeleteHomeScheduleRequest { HomeId = homeId, ScheduleId = scheduleId })
9090
.ReceiveJson<DataResponse>();
9191

9292
public async Task<DataResponse> SyncHomeSchedule(SyncHomeScheduleRequest requestParameters) =>
93-
await baseUrl.ConfigureRequest(Configuration.ConfigureRequest)
93+
await baseUrl.WithSettings(Configuration.ConfigureRequest)
9494
.AppendPathSegment("/api/synchomeschedule")
9595
.WithOAuthBearerToken(credentialManager.AccessToken)
9696
.PostJsonAsync(requestParameters)
9797
.ReceiveJson<DataResponse>();
9898

9999
public async Task<CreateHomeScheduleResponse> CreateHomeSchedule(CreateHomeScheduleRequest requestParameters) =>
100-
await baseUrl.ConfigureRequest(Configuration.ConfigureRequest)
100+
await baseUrl.WithSettings(Configuration.ConfigureRequest)
101101
.AppendPathSegment("/api/createnewhomeschedule")
102102
.WithOAuthBearerToken(credentialManager.AccessToken)
103103
.PostJsonAsync(requestParameters)
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1+
using System.Text.Json.Serialization;
12
using Netatmo.Models.Client.Air.HomesCoachs;
2-
using Newtonsoft.Json;
33

44
namespace Netatmo.Models.Client.Air;
55

66
public class GetHomeCoachsData
77
{
8-
[JsonProperty("devices")]
8+
[JsonPropertyName("devices")]
99
public Devices[] Devices { get; set; }
1010

11-
[JsonProperty("user")]
11+
[JsonPropertyName("user")]
1212
public User User { get; set; }
1313
}
Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,43 @@
1-
using Newtonsoft.Json;
1+
using System.Text.Json.Serialization;
22
using NodaTime;
33

44
namespace Netatmo.Models.Client.Air.HomesCoachs;
55

66
public class DashBoardData
77
{
8-
[JsonProperty("time_utc")]
8+
[JsonPropertyName("time_utc")]
99
public Instant TimeUtc { get; set; }
1010

11-
[JsonProperty("Temperature")]
11+
[JsonPropertyName("Temperature")]
1212
public double Temperature { get; set; }
1313

14-
[JsonProperty("CO2")]
14+
[JsonPropertyName("CO2")]
1515
public int CO2 { get; set; }
1616

17-
[JsonProperty("Humidity")]
17+
[JsonPropertyName("Humidity")]
1818
public int HumidityPercent { get; set; }
1919

20-
[JsonProperty("Noise")]
20+
[JsonPropertyName("Noise")]
2121
public double Noise { get; set; }
2222

23-
[JsonProperty("Pressure")]
23+
[JsonPropertyName("Pressure")]
2424
public double Pressure { get; set; }
2525

26-
[JsonProperty("AbsolutePressure")]
26+
[JsonPropertyName("AbsolutePressure")]
2727
public double AbsolutePressure { get; set; }
2828

29-
[JsonProperty("health_idx")]
29+
[JsonPropertyName("health_idx")]
3030
public HealthIdx HealthIdx { get; set; }
3131

32-
[JsonProperty("min_temp")]
32+
[JsonPropertyName("min_temp")]
3333
public decimal MinTemp { get; set; }
3434

35-
[JsonProperty("max_temp")]
35+
[JsonPropertyName("max_temp")]
3636
public decimal MaxTemp { get; set; }
3737

38-
[JsonProperty("date_min_temp")]
38+
[JsonPropertyName("date_min_temp")]
3939
public Instant DateMinTemp { get; set; }
4040

41-
[JsonProperty("date_max_temp")]
41+
[JsonPropertyName("date_max_temp")]
4242
public Instant DateMaxTemp { get; set; }
4343
}

src/Netatmo/Models/Client/Air/HomesCoachs/Devices.cs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,57 @@
1+
using System.Text.Json.Serialization;
12
using Netatmo.Enums;
2-
using Newtonsoft.Json;
33
using NodaTime;
44

55
namespace Netatmo.Models.Client.Air.HomesCoachs;
66

77
public class Devices
88
{
9-
[JsonProperty("_id")]
9+
[JsonPropertyName("_id")]
1010
public string Id { get; set; }
1111

12-
[JsonProperty("cipher_id")]
12+
[JsonPropertyName("cipher_id")]
1313
public string CipherId { get; set; }
1414

15-
[JsonProperty("last_status_store")]
15+
[JsonPropertyName("last_status_store")]
1616
public Instant LastStatusStore { get; set; }
1717

18-
[JsonProperty("place")]
18+
[JsonPropertyName("place")]
1919
public Place Place { get; set; }
2020

21-
[JsonProperty("type")]
21+
[JsonPropertyName("type")]
2222
public string Type { get; set; }
2323

24-
[JsonProperty("dashboard_data")]
24+
[JsonPropertyName("dashboard_data")]
2525
public DashBoardData DashboardData { get; set; }
2626

27-
[JsonProperty("data_type")]
27+
[JsonPropertyName("data_type")]
2828
public string[] DataType { get; set; }
2929

30-
[JsonProperty("co2_calibrating")]
30+
[JsonPropertyName("co2_calibrating")]
3131
public bool Co2Calibrating { get; set; }
3232

33-
[JsonProperty("reachable")]
33+
[JsonPropertyName("reachable")]
3434
public bool Reachable { get; set; }
3535

36-
[JsonProperty("date_setup")]
36+
[JsonPropertyName("date_setup")]
3737
public Instant DateSetup { get; set; }
3838

39-
[JsonProperty("last_setup")]
39+
[JsonPropertyName("last_setup")]
4040
public Instant LastSetup { get; set; }
4141

42-
[JsonProperty("module_name")]
42+
[JsonPropertyName("module_name")]
4343
public string ModuleName { get; set; }
4444

45-
[JsonProperty("firmware")]
45+
[JsonPropertyName("firmware")]
4646
public int Firmware { get; set; }
4747

48-
[JsonProperty("last_upgrade")]
48+
[JsonPropertyName("last_upgrade")]
4949
public Instant LastUpgrade { get; set; }
5050

51-
[JsonProperty("station_name")]
51+
[JsonPropertyName("station_name")]
5252
public string Name { get; set; }
5353

54-
[JsonProperty("wifi_status")]
54+
[JsonPropertyName("wifi_status")]
5555
public int WifiStatus { get; set; }
5656

5757
public WifiStrengthEnum WifiStrength

0 commit comments

Comments
 (0)