diff --git a/src/Client/NetDaemon.HassClient.Tests/Json/EnsureStringConverterTests.cs b/src/Client/NetDaemon.HassClient.Tests/Json/EnsureStringConverterTests.cs
index 18434d2b..4e72fd44 100644
--- a/src/Client/NetDaemon.HassClient.Tests/Json/EnsureStringConverterTests.cs
+++ b/src/Client/NetDaemon.HassClient.Tests/Json/EnsureStringConverterTests.cs
@@ -3,35 +3,26 @@ namespace NetDaemon.HassClient.Tests.Json;
public class EnsureStringConverterTests
{
- ///
- /// Default Json serialization options, Hass expects intended
- ///
- private readonly JsonSerializerOptions _defaultSerializerOptions = new()
- {
- WriteIndented = false,
- DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
- };
-
[Fact]
public void TestConvertAValidString()
{
- const string jsonDevice = @"
- {
- ""config_entries"": [],
- ""connections"": [],
- ""manufacturer"": ""Google Inc."",
- ""model"": 123123,
- ""name"": 123,
- ""serial_number"": ""1.0"",
- ""sw_version"": ""100"",
- ""hw_version"": null,
- ""id"": ""42cdda32a2a3428e86c2e27699d79ead"",
- ""via_device_id"": null,
- ""area_id"": null,
- ""name_by_user"": null
- }
- ";
- var hassDevice = JsonSerializer.Deserialize(jsonDevice, _defaultSerializerOptions);
+ var hassDevice = JsonSerializer.Deserialize("""
+ {
+ "config_entries": [],
+ "connections": [],
+ "manufacturer": "Google Inc.",
+ "model": 123123,
+ "name": 123,
+ "serial_number": "1.0",
+ "sw_version": "100",
+ "hw_version": null,
+ "id": "42cdda32a2a3428e86c2e27699d79ead",
+ "via_device_id": null,
+ "area_id": null,
+ "name_by_user": null
+ }
+ """);
+
hassDevice!.SerialNumber.Should().Be("1.0");
hassDevice!.SoftwareVersion.Should().Be("100");
hassDevice!.HardwareVersion.Should().BeNull();
@@ -40,30 +31,53 @@ public void TestConvertAValidString()
[Fact]
public void TestConverAInvalidString()
{
- const string jsonDevice = @"
- {
- ""config_entries"": [],
- ""connections"": [],
- ""model"": ""Chromecast"",
- ""serial_number"": [""1.0"", ""2.0""],
- ""name"": ""My TV"",
- ""sw_version"": { ""attribute"": ""1.0"" },
- ""manufacturer"": ""Google Inc."",
- ""hw_version"": 100,
- ""id"": ""42cdda32a2a3428e86c2e27699d79ead"",
- ""via_device_id"": null,
- ""area_id"": null,
- ""name_by_user"": null
- }
- ";
- var hassDevice = JsonSerializer.Deserialize(jsonDevice, _defaultSerializerOptions);
+ var hassDevice = JsonSerializer.Deserialize("""
+ {
+ "config_entries": [],
+ "connections": [],
+ "model": "Chromecast",
+ "serial_number": ["1.0", "2.0"],
+ "name": "My TV",
+ "sw_version": { "attribute": "1.0" },
+ "manufacturer": "Google Inc.",
+ "hw_version": 100,
+ "id": "42cdda32a2a3428e86c2e27699d79ead",
+ "via_device_id": null,
+ "area_id": null,
+ "name_by_user": null
+ }
+ """);
+
hassDevice!.SerialNumber.Should().BeNull();
hassDevice!.SoftwareVersion.Should().BeNull();
- hassDevice!.HardwareVersion.Should().BeNull();
+ hassDevice!.HardwareVersion.Should().Be("100");
// Make sure it is skipped correctly by checking the next property is read
hassDevice!.Manufacturer.Should().Be("Google Inc.");
hassDevice!.Id.Should().Be("42cdda32a2a3428e86c2e27699d79ead");
hassDevice!.Name.Should().Be("My TV");
}
+
+ [Fact]
+ public void TestConverModelIsArrayInvalidString()
+ {
+ var hassDevice = JsonSerializer.Deserialize("""
+ {
+ "config_entries": [],
+ "connections": [],
+ "model": ["Chromecast"],
+ "serial_number": ["1.0", "2.0"],
+ "name": "My TV",
+ "sw_version": { "attribute": "1.0" },
+ "manufacturer": "Google Inc.",
+ "hw_version": 100,
+ "id": "42cdda32a2a3428e86c2e27699d79ead",
+ "via_device_id": null,
+ "area_id": null,
+ "name_by_user": null
+ }
+ """);
+
+ hassDevice!.Model.Should().BeNull();
+ }
}
diff --git a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassDevice.cs b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassDevice.cs
index d7a7241d..2869b8f0 100644
--- a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassDevice.cs
+++ b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassDevice.cs
@@ -5,14 +5,13 @@ public record HassDevice
[JsonPropertyName("manufacturer")] public string? Manufacturer { get; init; }
[JsonPropertyName("model")]
- [JsonConverter(typeof(ReadNumberAsStringConverter))]
+ [JsonConverter(typeof(EnsureStringConverter))]
public string? Model { get; init; }
[JsonPropertyName("id")] public string? Id { get; init; }
[JsonPropertyName("area_id")] public string? AreaId { get; init; }
-
- [JsonConverter(typeof(ReadNumberAsStringConverter))]
+ [JsonConverter(typeof(EnsureStringConverter))]
[JsonPropertyName("name")] public string? Name { get; init; }
[JsonPropertyName("name_by_user")] public string? NameByUser { get; init; }
diff --git a/src/Client/NetDaemon.HassClient/Internal/Json/EnsureStringConverter.cs b/src/Client/NetDaemon.HassClient/Internal/Json/EnsureStringConverter.cs
index 1e09bd25..470c25db 100644
--- a/src/Client/NetDaemon.HassClient/Internal/Json/EnsureStringConverter.cs
+++ b/src/Client/NetDaemon.HassClient/Internal/Json/EnsureStringConverter.cs
@@ -1,23 +1,26 @@
-using System.Diagnostics;
-
namespace NetDaemon.Client.Internal.Json;
///
-/// Converts a Json element that can be a string or returns null if it is not a string
+/// Converts a Json element that can be a string or a number to as string, and returns null if not
///
class EnsureStringConverter : JsonConverter
{
public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
- if (reader.TokenType == JsonTokenType.String)
+ switch (reader.TokenType)
{
- return reader.GetString() ?? throw new UnreachableException("Token is expected to be a string");
- }
+ case JsonTokenType.String:
+ return reader.GetString();
- // Skip the children of current token
- reader.Skip();
- return null;
+ case JsonTokenType.Number:
+ var stringValue = reader.GetInt32();
+ return stringValue.ToString(CultureInfo.InvariantCulture);
+
+ default:
+ reader.Skip();
+ return null;
+ }
}
- public override void Write(Utf8JsonWriter writer, string? value, JsonSerializerOptions options) => throw new NotSupportedException();
+ public override void Write(Utf8JsonWriter writer, string? value, JsonSerializerOptions options) => writer.WriteStringValue(value);
}
diff --git a/src/Client/NetDaemon.HassClient/Internal/Json/ReadNumberAsStringConverter.cs b/src/Client/NetDaemon.HassClient/Internal/Json/ReadNumberAsStringConverter.cs
deleted file mode 100644
index faa5db56..00000000
--- a/src/Client/NetDaemon.HassClient/Internal/Json/ReadNumberAsStringConverter.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-namespace NetDaemon.Client.Internal.Json;
-
-internal class ReadNumberAsStringConverter : JsonConverter
-{
- public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
- {
- switch (reader.TokenType)
- {
- case JsonTokenType.Number:
- {
- var stringValue = reader.GetInt32();
- return stringValue.ToString(CultureInfo.InvariantCulture);
- }
- case JsonTokenType.String:
- return reader.GetString();
- default:
- throw new JsonException();
- }
- }
-
- public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
- {
- writer.WriteStringValue(value);
- }
-}
\ No newline at end of file