-
-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Removes HassClient from HassModel (#599)
* Removes HassClient from HassModel * Fix warnings
- Loading branch information
1 parent
bcd94cb
commit 9d6a4e0
Showing
47 changed files
with
622 additions
and
1,008 deletions.
There are no files selected for viewing
4 changes: 3 additions & 1 deletion
4
src/HassModel/NetDaemon.HassModel.CodeGenerator/EntitiesGenerator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 4 additions & 2 deletions
6
src/HassModel/NetDaemon.HassModel.CodeGenerator/ExtensionMethodsGenerator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletions
9
src/HassModel/NetDaemon.HassModel.CodeGenerator/Model/HassService.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
namespace NetDaemon.HassModel.CodeGenerator.Model; | ||
|
||
internal record HassService | ||
{ | ||
public string? Service { get; init; } | ||
public string? Description { get; init; } | ||
public IReadOnlyCollection<HassServiceField>? Fields { get; init; } | ||
public TargetSelector? Target { get; set; } | ||
} |
7 changes: 7 additions & 0 deletions
7
src/HassModel/NetDaemon.HassModel.CodeGenerator/Model/HassServiceDomain.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace NetDaemon.HassModel.CodeGenerator.Model; | ||
|
||
internal record HassServiceDomain | ||
{ | ||
public string? Domain { get; init; } | ||
public IReadOnlyCollection<HassService>? Services { get; init; } | ||
} |
10 changes: 10 additions & 0 deletions
10
src/HassModel/NetDaemon.HassModel.CodeGenerator/Model/HassServiceField.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace NetDaemon.HassModel.CodeGenerator.Model; | ||
|
||
internal record HassServiceField | ||
{ | ||
public string? Field { get; init; } | ||
public string? Description { get; init; } | ||
public bool? Required { get; set; } | ||
public object? Example { get; init; } | ||
public object? Selector { get; init; } | ||
} |
167 changes: 167 additions & 0 deletions
167
src/HassModel/NetDaemon.HassModel.CodeGenerator/Model/JsonExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
using System.Buffers; | ||
using System.Reflection; | ||
|
||
namespace NetDaemon.HassModel.CodeGenerator.Model; | ||
|
||
internal static class JsonExtensions | ||
{ | ||
private static readonly JsonSerializerOptions SnakeCaseNamingPolicySerializerOptions = new() | ||
{ | ||
PropertyNamingPolicy = SnakeCaseNamingPolicy.Instance | ||
}; | ||
|
||
/// <summary> | ||
/// Parses all json elements to instance result from GetServices call | ||
/// </summary> | ||
/// <param name="element">JsonElement containing the result data</param> | ||
public static IReadOnlyCollection<HassServiceDomain> ToServicesResult(this JsonElement element) | ||
{ | ||
var result = new List<HassServiceDomain>(); | ||
Type[] executingAssemblyTypes = Assembly.GetExecutingAssembly().GetTypes(); | ||
|
||
if (element.ValueKind != JsonValueKind.Object) | ||
throw new InvalidOperationException("Not expected result from the GetServices result"); | ||
|
||
foreach (var property in element.EnumerateObject()) | ||
{ | ||
var serviceDomain = new HassServiceDomain | ||
{ | ||
Domain = property.Name, | ||
Services = getServices(property.Value) | ||
}; | ||
result.Add(serviceDomain); | ||
} | ||
|
||
IReadOnlyCollection<HassService> getServices(JsonElement element) | ||
{ | ||
var servicesList = new List<HassService>(); | ||
foreach (var serviceDomainProperty in element.EnumerateObject()) | ||
{ | ||
servicesList.Add(getServiceFields(serviceDomainProperty.Name, serviceDomainProperty.Value)); | ||
} | ||
return servicesList; | ||
} | ||
|
||
HassService getServiceFields(string service, JsonElement element) | ||
{ | ||
var serviceFields = new List<HassServiceField>(); | ||
|
||
string? serviceDescription = null; | ||
TargetSelector? target = null; | ||
|
||
foreach (var serviceProperty in element.EnumerateObject()) | ||
{ | ||
switch (serviceProperty.Name) | ||
{ | ||
case "description": | ||
serviceDescription = serviceProperty.Value.GetString(); | ||
break; | ||
case "fields": | ||
foreach (var fieldsProperty in serviceProperty.Value.EnumerateObject()) | ||
{ | ||
serviceFields.Add(getField(fieldsProperty.Name, fieldsProperty.Value)); | ||
} | ||
break; | ||
case "target": | ||
target = getSelector(serviceProperty.Name, serviceProperty.Value) as TargetSelector; | ||
break; | ||
} | ||
} | ||
return new HassService | ||
{ | ||
Service = service, | ||
Fields = serviceFields, | ||
Description = serviceDescription, | ||
Target = target | ||
}; | ||
} | ||
|
||
object? getSelector(string selectorName, JsonElement element) | ||
{ | ||
var selectorType = executingAssemblyTypes.FirstOrDefault(x => string.Equals($"{selectorName}Selector", x.Name, StringComparison.OrdinalIgnoreCase)); | ||
|
||
if (selectorType is null) | ||
{ | ||
return null; | ||
} | ||
|
||
if (element.ValueKind == JsonValueKind.Object && !element.EnumerateObject().Any() || | ||
element.ValueKind != JsonValueKind.Object && element.GetString() is null) | ||
{ | ||
return Activator.CreateInstance(selectorType); | ||
} | ||
|
||
var bufferWriter = new ArrayBufferWriter<byte>(); | ||
using (var writer = new Utf8JsonWriter(bufferWriter)) | ||
{ | ||
element.WriteTo(writer); | ||
} | ||
|
||
return JsonSerializer.Deserialize(bufferWriter.WrittenSpan, | ||
selectorType, | ||
SnakeCaseNamingPolicySerializerOptions); | ||
} | ||
|
||
HassServiceField getField(string fieldName, JsonElement element) | ||
{ | ||
object? example = null; | ||
string? fieldDescription = null; | ||
bool? required = null; | ||
object? selector = null; | ||
|
||
foreach (var fieldProperty in element.EnumerateObject()) | ||
{ | ||
switch (fieldProperty.Name) | ||
{ | ||
case "description": | ||
fieldDescription = fieldProperty.Value.GetString(); | ||
break; | ||
case "required": | ||
required = fieldProperty.Value.GetBoolean(); | ||
break; | ||
case "example": | ||
switch (fieldProperty.Value.ValueKind) | ||
{ | ||
case JsonValueKind.String: | ||
example = fieldProperty.Value.GetString(); | ||
break; | ||
case JsonValueKind.Number: | ||
if (fieldProperty.Value.TryGetInt64(out long longVal)) | ||
example = longVal; | ||
else | ||
example = fieldProperty.Value.GetDouble(); | ||
break; | ||
case JsonValueKind.Object: | ||
|
||
example = fieldProperty.Value; | ||
break; | ||
case JsonValueKind.True: | ||
example = true; | ||
break; | ||
case JsonValueKind.False: | ||
example = false; | ||
break; | ||
case JsonValueKind.Array: | ||
example = fieldProperty.Value; | ||
break; | ||
} | ||
break; | ||
case "selector": | ||
var selectorProperty = fieldProperty.Value.EnumerateObject().First(); | ||
selector = getSelector(selectorProperty.Name, selectorProperty.Value); | ||
break; | ||
} | ||
} | ||
return new HassServiceField | ||
{ | ||
Field = fieldName, | ||
Example = example, | ||
Description = fieldDescription, | ||
Required = required, | ||
Selector = selector | ||
}; | ||
} | ||
|
||
return result; | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
src/HassModel/NetDaemon.HassModel.CodeGenerator/Model/NullableEnumStringConverter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
using System.ComponentModel; | ||
using System.Text.Json.Serialization; | ||
|
||
namespace NetDaemon.HassModel.CodeGenerator.Model; | ||
|
||
internal class NullableEnumStringConverter<TEnum> : JsonConverter<TEnum> | ||
{ | ||
private readonly bool _isNullable; | ||
private readonly Type _enumType; | ||
|
||
public NullableEnumStringConverter() { | ||
_isNullable = Nullable.GetUnderlyingType(typeof(TEnum)) is not null; | ||
|
||
_enumType = _isNullable ? | ||
Nullable.GetUnderlyingType(typeof(TEnum))! : | ||
typeof(TEnum); | ||
} | ||
|
||
public override TEnum? Read(ref Utf8JsonReader reader, | ||
Type typeToConvert, JsonSerializerOptions options) | ||
{ | ||
var value = reader.GetString(); | ||
|
||
if (_isNullable && string.IsNullOrEmpty(value)) | ||
return default; | ||
|
||
if (string.IsNullOrEmpty(value)) | ||
{ | ||
throw new InvalidEnumArgumentException( | ||
$"A value must be provided for non-nullable enum property of type \"{_enumType.FullName}\""); | ||
} | ||
|
||
if (Enum.TryParse(_enumType, value, true, out var result)) | ||
{ | ||
return (TEnum) result!; | ||
} | ||
|
||
return default; | ||
} | ||
|
||
public override void Write(Utf8JsonWriter writer, | ||
TEnum value, JsonSerializerOptions options) | ||
{ | ||
throw new NotSupportedException($"Serialization not supported for the enum \"{_enumType.Name}\""); | ||
} | ||
} |
93 changes: 93 additions & 0 deletions
93
src/HassModel/NetDaemon.HassModel.CodeGenerator/Model/Selectors.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
using System.ComponentModel.DataAnnotations; | ||
using System.Text.Json.Serialization; | ||
|
||
namespace NetDaemon.HassModel.CodeGenerator.Model; | ||
|
||
internal record ActionSelector | ||
{ | ||
} | ||
|
||
internal record AddonSelector | ||
{ | ||
} | ||
|
||
internal record AreaSelector | ||
{ | ||
public DeviceSelector? Device { get; init; } | ||
|
||
public EntitySelector? Entity { get; init; } | ||
} | ||
|
||
internal record BooleanSelector | ||
{ | ||
} | ||
|
||
internal record DeviceSelector | ||
{ | ||
public string? Integration { get; init; } | ||
|
||
public string? Manufacturer { get; init; } | ||
|
||
public string? Model { get; init; } | ||
|
||
public EntitySelector? Entity { get; init; } | ||
} | ||
|
||
internal record EntitySelector | ||
{ | ||
public string? Integration { get; init; } | ||
|
||
public string? Domain { get; init; } | ||
|
||
public string? DeviceClass { get; init; } | ||
} | ||
|
||
internal record NumberSelector | ||
{ | ||
[Required] | ||
public double Min { get; init; } | ||
|
||
[Required] | ||
public double Max { get; init; } | ||
|
||
public float? Step { get; init; } | ||
|
||
public string? UnitOfMeasurement { get; init; } | ||
|
||
[JsonConverter(typeof(NullableEnumStringConverter<NumberSelectorMode?>))] | ||
public NumberSelectorMode? Mode { get; init; } | ||
} | ||
|
||
internal enum NumberSelectorMode | ||
{ | ||
Box, | ||
Slider | ||
} | ||
|
||
internal record ObjectSelector | ||
{ | ||
} | ||
|
||
internal record SelectSelector | ||
{ | ||
[Required] | ||
public IReadOnlyCollection<string>? Options { get; init; } | ||
} | ||
|
||
internal record TargetSelector | ||
{ | ||
public AreaSelector? Area { get; init; } | ||
|
||
public DeviceSelector? Device { get; init; } | ||
|
||
public EntitySelector? Entity { get; init; } | ||
} | ||
|
||
internal record TextSelector | ||
{ | ||
public bool? Multiline { get; init; } | ||
} | ||
|
||
internal record TimeSelector | ||
{ | ||
} |
Oops, something went wrong.