diff --git a/NetDaemon.sln b/NetDaemon.sln index cb0001245..208bfbcac 100644 --- a/NetDaemon.sln +++ b/NetDaemon.sln @@ -57,6 +57,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DebugWebHost", "src\debug\D EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetDaemon.Tests.Integration", "tests\Integration\NetDaemon.Tests.Integration\NetDaemon.Tests.Integration.csproj", "{9B6A778A-A2D6-43A6-9FED-8D5B2BC18514}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyLibrary", "src\debug\MyLibrary\MyLibrary.csproj", "{CF7273C1-A4FE-4598-9C99-D746CE279A32}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyNDApp", "src\debug\MyNDApp\MyNDApp.csproj", "{FEE1EA29-4609-4200-A92C-C61ECB7A3D0B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -307,6 +311,30 @@ Global {9B6A778A-A2D6-43A6-9FED-8D5B2BC18514}.Release|x64.Build.0 = Release|Any CPU {9B6A778A-A2D6-43A6-9FED-8D5B2BC18514}.Release|x86.ActiveCfg = Release|Any CPU {9B6A778A-A2D6-43A6-9FED-8D5B2BC18514}.Release|x86.Build.0 = Release|Any CPU + {CF7273C1-A4FE-4598-9C99-D746CE279A32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CF7273C1-A4FE-4598-9C99-D746CE279A32}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CF7273C1-A4FE-4598-9C99-D746CE279A32}.Debug|x64.ActiveCfg = Debug|Any CPU + {CF7273C1-A4FE-4598-9C99-D746CE279A32}.Debug|x64.Build.0 = Debug|Any CPU + {CF7273C1-A4FE-4598-9C99-D746CE279A32}.Debug|x86.ActiveCfg = Debug|Any CPU + {CF7273C1-A4FE-4598-9C99-D746CE279A32}.Debug|x86.Build.0 = Debug|Any CPU + {CF7273C1-A4FE-4598-9C99-D746CE279A32}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CF7273C1-A4FE-4598-9C99-D746CE279A32}.Release|Any CPU.Build.0 = Release|Any CPU + {CF7273C1-A4FE-4598-9C99-D746CE279A32}.Release|x64.ActiveCfg = Release|Any CPU + {CF7273C1-A4FE-4598-9C99-D746CE279A32}.Release|x64.Build.0 = Release|Any CPU + {CF7273C1-A4FE-4598-9C99-D746CE279A32}.Release|x86.ActiveCfg = Release|Any CPU + {CF7273C1-A4FE-4598-9C99-D746CE279A32}.Release|x86.Build.0 = Release|Any CPU + {FEE1EA29-4609-4200-A92C-C61ECB7A3D0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FEE1EA29-4609-4200-A92C-C61ECB7A3D0B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FEE1EA29-4609-4200-A92C-C61ECB7A3D0B}.Debug|x64.ActiveCfg = Debug|Any CPU + {FEE1EA29-4609-4200-A92C-C61ECB7A3D0B}.Debug|x64.Build.0 = Debug|Any CPU + {FEE1EA29-4609-4200-A92C-C61ECB7A3D0B}.Debug|x86.ActiveCfg = Debug|Any CPU + {FEE1EA29-4609-4200-A92C-C61ECB7A3D0B}.Debug|x86.Build.0 = Debug|Any CPU + {FEE1EA29-4609-4200-A92C-C61ECB7A3D0B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FEE1EA29-4609-4200-A92C-C61ECB7A3D0B}.Release|Any CPU.Build.0 = Release|Any CPU + {FEE1EA29-4609-4200-A92C-C61ECB7A3D0B}.Release|x64.ActiveCfg = Release|Any CPU + {FEE1EA29-4609-4200-A92C-C61ECB7A3D0B}.Release|x64.Build.0 = Release|Any CPU + {FEE1EA29-4609-4200-A92C-C61ECB7A3D0B}.Release|x86.ActiveCfg = Release|Any CPU + {FEE1EA29-4609-4200-A92C-C61ECB7A3D0B}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -331,6 +359,8 @@ Global {F4B29B77-9B92-4037-A884-288CA5EF0B78} = {DFF3E7AA-7A50-4A1E-B3F8-EC01531FB83D} {3EB8C461-C91E-4900-BFBD-0986CBBE87A6} = {DFF3E7AA-7A50-4A1E-B3F8-EC01531FB83D} {AEBC7828-7C19-4A86-B6E2-58B5171347B1} = {E15D4280-7FFC-4F8B-9B8C-CF9AF2BF838C} + {CF7273C1-A4FE-4598-9C99-D746CE279A32} = {E15D4280-7FFC-4F8B-9B8C-CF9AF2BF838C} + {FEE1EA29-4609-4200-A92C-C61ECB7A3D0B} = {E15D4280-7FFC-4F8B-9B8C-CF9AF2BF838C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {7C5FBB7F-654C-4CAC-964F-6D71AF3D62F8} diff --git a/src/HassModel/NetDaemon.HassModel.CodeGenerator/CodeGeneration/EntitiesGenerator.cs b/src/HassModel/NetDaemon.HassModel.CodeGenerator/CodeGeneration/EntitiesGenerator.cs index e200dc1b6..3c788bdb1 100644 --- a/src/HassModel/NetDaemon.HassModel.CodeGenerator/CodeGeneration/EntitiesGenerator.cs +++ b/src/HassModel/NetDaemon.HassModel.CodeGenerator/CodeGeneration/EntitiesGenerator.cs @@ -18,15 +18,12 @@ public static IEnumerable Generate(IReadOnlyCollection< { yield return GenerateEntiesForDomainClass(domainMetadata.Key, domainMetadata); } - foreach (var domainMetadata in metaData) { yield return GenerateEntityType(domainMetadata); - yield return AttributeTypeGenerator.GenerateAttributeRecord(domainMetadata); } } - private static TypeDeclarationSyntax GenerateRootEntitiesInterface(IEnumerable domains) { var autoProperties = domains.Select(domain => @@ -79,22 +76,27 @@ private static MemberDeclarationSyntax GenerateEntityProperty(EntityMetaData ent /// private static MemberDeclarationSyntax GenerateEntityType(EntityDomainMetadata domainMetaData) { - string attributesGeneric = domainMetaData.AttributesClassName; + var attributesGeneric = domainMetaData.AttributesClassName; var baseType = domainMetaData.IsNumeric ? typeof(NumericEntity) : typeof(Entity); var entityStateType = domainMetaData.IsNumeric ? typeof(NumericEntityState) : typeof(EntityState); - var baseClass = $"{SimplifyTypeName(baseType)}<{domainMetaData.EntityClassName}, {SimplifyTypeName(entityStateType)}<{attributesGeneric}>, {attributesGeneric}>"; + var coreinterface = domainMetaData.CoreInterfaceName; + if (coreinterface != null) + { + baseClass += $", {coreinterface}"; + } + var (className, variableName) = GetNames(); var classDeclaration = $$""" record {{domainMetaData.EntityClassName}} : {{baseClass}} { - public {{domainMetaData.EntityClassName}}({{className}} {{variableName}}, string entityId) : base({{variableName}}, entityId) - {} + public {{domainMetaData.EntityClassName}}({{className}} {{variableName}}, string entityId) : base({{variableName}}, entityId) + {} - public {{domainMetaData.EntityClassName}}({{SimplifyTypeName(typeof(Entity))}} entity) : base(entity) - {} + public {{domainMetaData.EntityClassName}}({{SimplifyTypeName(typeof(IEntityCore))}} entity) : base(entity) + {} } """; diff --git a/src/HassModel/NetDaemon.HassModel.CodeGenerator/CodeGeneration/ExtensionMethodsGenerator.cs b/src/HassModel/NetDaemon.HassModel.CodeGenerator/CodeGeneration/ExtensionMethodsGenerator.cs index 8a71b6a08..324816a9d 100644 --- a/src/HassModel/NetDaemon.HassModel.CodeGenerator/CodeGeneration/ExtensionMethodsGenerator.cs +++ b/src/HassModel/NetDaemon.HassModel.CodeGenerator/CodeGeneration/ExtensionMethodsGenerator.cs @@ -27,7 +27,7 @@ internal static class ExtensionMethodsGenerator { public static IEnumerable Generate(IEnumerable serviceDomains, IReadOnlyCollection entityDomains) { - var entityClassNameByDomain = entityDomains.ToLookup(e => e.Domain, e => e.EntityClassName); + var entityClassNameByDomain = entityDomains.ToLookup(e => e.Domain, e => e.CoreInterfaceName ?? e.EntityClassName); return serviceDomains .Select(sd => GenerateDomainExtensionClass(sd, entityClassNameByDomain)) @@ -60,8 +60,9 @@ private static IEnumerable GenerateExtensionMethodsForS private static IEnumerable GenerateExtensionMethodsForService(string domain, HassService service, string targetEntityDomain, ILookup entityClassNameByDomain) { var entityTypeName = entityClassNameByDomain[targetEntityDomain].FirstOrDefault(); + if (entityTypeName == null) yield break; - + var serviceName = service.Service; var serviceArguments = ServiceArguments.Create(domain, service); var enumerableTargetTypeName = $"IEnumerable<{entityTypeName}>"; diff --git a/src/HassModel/NetDaemon.HassModel.CodeGenerator/CodeGeneration/HelpersGenerator.cs b/src/HassModel/NetDaemon.HassModel.CodeGenerator/CodeGeneration/HelpersGenerator.cs index 8d16e50d2..4faa74e54 100644 --- a/src/HassModel/NetDaemon.HassModel.CodeGenerator/CodeGeneration/HelpersGenerator.cs +++ b/src/HassModel/NetDaemon.HassModel.CodeGenerator/CodeGeneration/HelpersGenerator.cs @@ -33,15 +33,15 @@ private static ClassDeclarationSyntax GenerateServiceCollectionExtension(IReadOn /// Generates the AddHomeAssistantGenerated method /// // - // public static IServiceCollection AddGeneratedCode(this IServiceCollection serviceCollection) - // { - // serviceCollection.AddTransient(); - // serviceCollection.AddTransient(); - // serviceCollection.AddTransient(); - // serviceCollection.AddTransient(); - // serviceCollection.AddTransient(); - // return serviceCollection; - // } + // public static IServiceCollection AddGeneratedCode(this IServiceCollection serviceCollection) + // { + // serviceCollection.AddTransient(); + // serviceCollection.AddTransient(); + // serviceCollection.AddTransient(); + // serviceCollection.AddTransient(); + // serviceCollection.AddTransient(); + // return serviceCollection; + // } private static MethodDeclarationSyntax BuildAddHomeAssistantGenerated(IEnumerable domains, IEnumerable orderedServiceDomains) { diff --git a/src/HassModel/NetDaemon.HassModel.CodeGenerator/CodeGenerationSettings.cs b/src/HassModel/NetDaemon.HassModel.CodeGenerator/CodeGenerationSettings.cs index 321a8ddd2..b0d61bde7 100644 --- a/src/HassModel/NetDaemon.HassModel.CodeGenerator/CodeGenerationSettings.cs +++ b/src/HassModel/NetDaemon.HassModel.CodeGenerator/CodeGenerationSettings.cs @@ -1,6 +1,6 @@ namespace NetDaemon.HassModel.CodeGenerator; -public record CodeGenerationSettings +record CodeGenerationSettings { public string OutputFile { get; init; } = "HomeAssistantGenerated.cs"; public string OutputFolder { get; init; } = "NetDaemonCodegen"; diff --git a/src/HassModel/NetDaemon.HassModel.CodeGenerator/MetaData/EntityMetaData/EntityDomainMetadata.cs b/src/HassModel/NetDaemon.HassModel.CodeGenerator/MetaData/EntityMetaData/EntityDomainMetadata.cs index 2decf71f9..c6ccd00e3 100644 --- a/src/HassModel/NetDaemon.HassModel.CodeGenerator/MetaData/EntityMetaData/EntityDomainMetadata.cs +++ b/src/HassModel/NetDaemon.HassModel.CodeGenerator/MetaData/EntityMetaData/EntityDomainMetadata.cs @@ -18,11 +18,30 @@ record EntityDomainMetadata( IReadOnlyList Attributes ) { + private static readonly HashSet CoreInterfaces = + typeof(IEntityCore).Assembly.GetTypes() + .Where(t => t.IsInterface && t.IsAssignableTo(typeof(IEntityCore))) + .Select(t => t.Name) + .ToHashSet(); + private readonly string prefixedDomain = (IsNumeric && EntityIdHelper.MixedDomains.Contains(Domain) ? "numeric_" : "") + Domain; [JsonIgnore] public string EntityClassName => $"{prefixedDomain}Entity".ToValidCSharpPascalCase(); + /// + /// Returns the name of the corresponding Core Interface if it exists, or null if it does not + /// + [JsonIgnore] + public string? CoreInterfaceName + { + get + { + var name = $"I{Domain.ToValidCSharpPascalCase()}EntityCore"; + return CoreInterfaces.Contains(name) ? name : null; + } + } + [JsonIgnore] public string AttributesClassName => $"{prefixedDomain}Attributes".ToValidCSharpPascalCase(); diff --git a/src/HassModel/NetDaemon.HassModel.CodeGenerator/NetDaemon.HassModel.CodeGenerator.csproj b/src/HassModel/NetDaemon.HassModel.CodeGenerator/NetDaemon.HassModel.CodeGenerator.csproj index acc39370e..db8cae98f 100644 --- a/src/HassModel/NetDaemon.HassModel.CodeGenerator/NetDaemon.HassModel.CodeGenerator.csproj +++ b/src/HassModel/NetDaemon.HassModel.CodeGenerator/NetDaemon.HassModel.CodeGenerator.csproj @@ -18,7 +18,6 @@ Please advice this is still in beta Home Assistant - True diff --git a/src/HassModel/NetDaemon.HassModel.Tests/CodeGenerator/CodeGeneratorTest.cs b/src/HassModel/NetDaemon.HassModel.Tests/CodeGenerator/CodeGeneratorTest.cs index d13c7c831..129ff5799 100644 --- a/src/HassModel/NetDaemon.HassModel.Tests/CodeGenerator/CodeGeneratorTest.cs +++ b/src/HassModel/NetDaemon.HassModel.Tests/CodeGenerator/CodeGeneratorTest.cs @@ -52,6 +52,10 @@ public void Run(IHaContext ha) LightEntity light2 = entities.Light.Light2; SwitchEntity switch1 = entities.Switch.Switch1; SwitchEntity switch2 = entities.Switch.Switch2; + + // Now check if the entity classes implement the core interfaces + ILightEntityCore lightAsCore = entities.Light.Light1; + ISwitchEntityCore switch1AsCore = entities.Switch.Switch1; } } """; diff --git a/src/HassModel/NetDaemon.HassModel.Tests/CodeGenerator/ServicesGeneratorTest.cs b/src/HassModel/NetDaemon.HassModel.Tests/CodeGenerator/ServicesGeneratorTest.cs index a782444e0..f6b2ed900 100644 --- a/src/HassModel/NetDaemon.HassModel.Tests/CodeGenerator/ServicesGeneratorTest.cs +++ b/src/HassModel/NetDaemon.HassModel.Tests/CodeGenerator/ServicesGeneratorTest.cs @@ -63,12 +63,17 @@ public void Run(IHaContext ha) s.Light.TurnOff(new ServiceTarget()); - var light = new RootNameSpace.LightEntity(ha, "light.testLight"); - + LightEntity light = new RootNameSpace.LightEntity(ha, "light.testLight"); light.TurnOn(); light.TurnOn(transition: 12, brightness: 324.5f); light.TurnOn(new (){ Transition = 12L, Brightness = 12.3f }); light.TurnOff(); + + ILightEntityCore lightCore = light; + lightCore.TurnOn(); + lightCore.TurnOn(transition: 12, brightness: 324.5f); + lightCore.TurnOn(new (){ Transition = 12L, Brightness = 12.3f }); + lightCore.TurnOff(); } } """; @@ -179,7 +184,6 @@ public void Run(Entities entities, Services services) CodeGenTestHelper.AssertCodeCompiles(code.ToString(), appCode); } - [Fact] public void TestServiceWithKeyWordFieldName_ParamEscaped() { diff --git a/src/HassModel/NetDeamon.HassModel/Entities/Core/CoreInterfaces.cs b/src/HassModel/NetDeamon.HassModel/Entities/Core/CoreInterfaces.cs new file mode 100644 index 000000000..b8a464454 --- /dev/null +++ b/src/HassModel/NetDeamon.HassModel/Entities/Core/CoreInterfaces.cs @@ -0,0 +1,108 @@ +namespace NetDaemon.HassModel.Entities; + +// These 'Core' interfaces serve as common types between 3rd party libraries and classes that are generated by the end +// user using nd-codegen + +/// Core interface for automation entities +public interface IAutomationEntityCore: IEntityCore {} + +/// Core interface for binary_sensor entities +public interface IBinarySensorEntityCore: IEntityCore {} + +/// Core interface for button entities +public interface IButtonEntityCore: IEntityCore {} + +/// Core interface for calendar entities +public interface ICalendarEntityCore: IEntityCore {} + +/// Core interface for camera entities +public interface ICameraEntityCore: IEntityCore {} + +/// Core interface for climate entities +public interface IClimateEntityCore: IEntityCore {} + +/// Core interface for cover entities +public interface ICoverEntityCore: IEntityCore {} + +/// Core interface for device_tracker entities +public interface IDeviceTrackerEntityCore: IEntityCore {} + +/// Core interface for group entities +public interface IGroupEntityCore: IEntityCore {} + +/// Core interface for input_boolean entities +public interface IInputBooleanEntityCore: IEntityCore {} + +/// Core interface for input_button entities +public interface IInputButtonEntityCore: IEntityCore {} + +/// Core interface for input_datetime entities +public interface IInputDatetimeEntityCore: IEntityCore {} + +/// Core interface for input_number entities +public interface IInputNumberEntityCore: IEntityCore {} + +/// Core interface for input_select entities +public interface IInputSelectEntityCore: IEntityCore {} + +/// Core interface for input_text entities +public interface IInputTextEntityCore: IEntityCore {} + +/// Core interface for light entities +public interface ILightEntityCore: IEntityCore {} + +/// Core interface for lock entities +public interface ILockEntityCore: IEntityCore {} + +/// Core interface for media_player entities +public interface IMediaPlayerEntityCore: IEntityCore {} + +/// Core interface for number entities +public interface INumberEntityCore: IEntityCore {} + +/// Core interface for person entities +public interface IPersonEntityCore: IEntityCore {} + +/// Core interface for proximity entities +public interface IProximityEntityCore: IEntityCore {} + +/// Core interface for remote entities +public interface IRemoteEntityCore: IEntityCore {} + +/// Core interface for scene entities +public interface ISceneEntityCore: IEntityCore {} + +/// Core interface for schedule entities +public interface IScheduleEntityCore: IEntityCore {} + +/// Core interface for script entities +public interface IScriptEntityCore: IEntityCore {} + +/// Core interface for select entities +public interface ISelectEntityCore: IEntityCore {} + +/// Core interface for sensor entities +public interface ISensorEntityCore: IEntityCore {} + +/// Core interface for sun entities +public interface ISunEntityCore: IEntityCore {} + +/// Core interface for switch entities +public interface ISwitchEntityCore: IEntityCore {} + +/// Core interface for timer entities +public interface ITimerEntityCore: IEntityCore {} + +/// Core interface for update entities +public interface IUpdateEntityCore: IEntityCore {} + +/// Core interface for vacuum entities +public interface IVacuumEntityCore: IEntityCore {} + +/// Core interface for weather entities +public interface IWeatherEntityCore: IEntityCore {} + +/// Core interface for zone entities +public interface IZoneEntityCore: IEntityCore {} + + diff --git a/src/HassModel/NetDeamon.HassModel/Entities/Core/IEntityCore.cs b/src/HassModel/NetDeamon.HassModel/Entities/Core/IEntityCore.cs new file mode 100644 index 000000000..cc3c74a04 --- /dev/null +++ b/src/HassModel/NetDeamon.HassModel/Entities/Core/IEntityCore.cs @@ -0,0 +1,17 @@ +namespace NetDaemon.HassModel.Entities; + +/// +/// Core interface for any entity +/// +public interface IEntityCore +{ + /// + /// The IHAContext + /// + public IHaContext HaContext { get; } + + /// + /// Entity id being handled by this entity + /// + public string EntityId { get; } +} \ No newline at end of file diff --git a/src/HassModel/NetDeamon.HassModel/Entities/Entity.cs b/src/HassModel/NetDeamon.HassModel/Entities/Entity.cs index 5985ec259..0eb40c8e0 100644 --- a/src/HassModel/NetDeamon.HassModel/Entities/Entity.cs +++ b/src/HassModel/NetDeamon.HassModel/Entities/Entity.cs @@ -1,7 +1,7 @@ namespace NetDaemon.HassModel.Entities; /// Represents a Home Assistant entity with its state, changes and services -public record Entity +public record Entity : IEntityCore { /// /// The IHAContext @@ -23,6 +23,14 @@ public Entity(IHaContext haContext, string entityId) HaContext = haContext; EntityId = entityId; } + + /// Copy constructor from IEntityCore + public Entity(IEntityCore entity) + { + ArgumentNullException.ThrowIfNull(entity); + HaContext = entity.HaContext; + EntityId = entity.EntityId; + } /// /// Area name of entity @@ -78,13 +86,7 @@ public virtual IObservable StateChanges() => /// Data to provide public virtual void CallService(string service, object? data = null) { - ArgumentNullException.ThrowIfNull(service, nameof(service)); - - var (serviceDomain, serviceName) = service.SplitAtDot(); - - serviceDomain ??= EntityId.SplitAtDot().Left ?? throw new InvalidOperationException("EntityId must be formatted 'domain.name'"); - - HaContext.CallService(serviceDomain, serviceName, ServiceTarget.FromEntity(EntityId), data); + EntityExtensions.CallService(this, service, data); } } @@ -94,8 +96,8 @@ public abstract record Entity : Entity where TEntityState : EntityState where TAttributes : class { - /// Copy constructor from Base type - protected Entity(Entity entity) : base(entity) + /// Copy constructor from IEntityCore + protected Entity(IEntityCore entity) : base(entity) { } /// Constructor from haContext and entityId @@ -126,8 +128,8 @@ public record Entity : Entity, EntityStateCopy constructor from Base type - public Entity(Entity entity) : base(entity) { } + /// Copy constructor from IEntityCore + public Entity(IEntityCore entity) : base(entity) { } /// Constructor from haContext and entityId public Entity(IHaContext haContext, string entityId) : base(haContext, entityId) { } diff --git a/src/HassModel/NetDeamon.HassModel/Entities/EntityExtensions.cs b/src/HassModel/NetDeamon.HassModel/Entities/EntityExtensions.cs index 9f91bf18d..c1179619a 100644 --- a/src/HassModel/NetDeamon.HassModel/Entities/EntityExtensions.cs +++ b/src/HassModel/NetDeamon.HassModel/Entities/EntityExtensions.cs @@ -56,4 +56,22 @@ public static NumericEntity WithAttributesAs(this Nume internal static IObservable StateChangesOnly(this IObservable changes) where T : StateChange => changes.Where(c => c.New?.State != c.Old?.State); + + /// + /// Calls a service using this entity as the target + /// + /// The Entity to call the service for + /// Name of the service to call. If the Domain of the service is the same as the domain of the Entity it can be omitted + /// Data to provide + public static void CallService(this IEntityCore entity, string service, object? data = null) + { + ArgumentNullException.ThrowIfNull(entity); + ArgumentNullException.ThrowIfNull(service); + + var (serviceDomain, serviceName) = service.SplitAtDot(); + + serviceDomain ??= entity.EntityId.SplitAtDot().Left ?? throw new InvalidOperationException("EntityId must be formatted 'domain.name'"); + + entity.HaContext.CallService(serviceDomain, serviceName, ServiceTarget.FromEntity(entity.EntityId), data); + } } diff --git a/src/HassModel/NetDeamon.HassModel/Entities/EnumerableEntityExtensions.cs b/src/HassModel/NetDeamon.HassModel/Entities/EnumerableEntityExtensions.cs index 894f2eefd..735fa10b4 100644 --- a/src/HassModel/NetDeamon.HassModel/Entities/EnumerableEntityExtensions.cs +++ b/src/HassModel/NetDeamon.HassModel/Entities/EnumerableEntityExtensions.cs @@ -75,7 +75,7 @@ public static IObservable> StateChangesIEnumerable of Entities for which to call the service /// Name of the service to call. If the Domain of the service is the same as the domain of the Entities it can be omitted /// Data to provide - public static void CallService(this IEnumerable entities, string service, object? data = null) + public static void CallService(this IEnumerable entities, string service, object? data = null) { ArgumentNullException.ThrowIfNull(service); diff --git a/src/HassModel/NetDeamon.HassModel/Entities/NumericEntity.cs b/src/HassModel/NetDeamon.HassModel/Entities/NumericEntity.cs index bcb57b313..87dd4ccd6 100644 --- a/src/HassModel/NetDeamon.HassModel/Entities/NumericEntity.cs +++ b/src/HassModel/NetDeamon.HassModel/Entities/NumericEntity.cs @@ -6,7 +6,7 @@ public record NumericEntity : Entity { /// Copy constructor from base class - public NumericEntity(Entity entity) : base(entity) { } + public NumericEntity(IEntityCore entity) : base(entity) { } /// Constructor from haContext and entityId public NumericEntity(IHaContext haContext, string entityId) : base(haContext, entityId) { } @@ -36,7 +36,7 @@ public record NumericEntity : EntityCopy constructor from base class - public NumericEntity(Entity entity) : base(entity) { } + public NumericEntity(IEntityCore entity) : base(entity) { } /// Constructor from haContext and entityId public NumericEntity(IHaContext haContext, string entityId) : base(haContext, entityId) { } diff --git a/src/debug/MyLibrary/InternalHomeAssistantGenerated/LightEntityExtensionMethods.cs b/src/debug/MyLibrary/InternalHomeAssistantGenerated/LightEntityExtensionMethods.cs new file mode 100644 index 000000000..c8e8fbec6 --- /dev/null +++ b/src/debug/MyLibrary/InternalHomeAssistantGenerated/LightEntityExtensionMethods.cs @@ -0,0 +1,358 @@ +using System.Text.Json.Serialization; +using NetDaemon.HassModel; +using NetDaemon.HassModel.Entities; + +namespace MyLibrary; + +public partial record LightEntity : Entity, LightAttributes>, ILightEntityCore +{ + public LightEntity(IHaContext haContext, string entityId) : base(haContext, entityId) + { + } + + public LightEntity(IEntityCore entity) : base(entity) + { + } +} + +public partial record LightAttributes +{ + [JsonPropertyName("min_color_temp_kelvin")] + public double? MinColorTempKelvin { get; init; } + + [JsonPropertyName("max_color_temp_kelvin")] + public double? MaxColorTempKelvin { get; init; } + + [JsonPropertyName("color_temp_kelvin")] + public double? ColorTempKelvin { get; init; } + + [JsonPropertyName("off_with_transition")] + public bool? OffWithTransition { get; init; } + + [JsonPropertyName("off_brightness")] + public double? OffBrightness { get; init; } + + [JsonPropertyName("restored")] + public bool? Restored { get; init; } + + [JsonPropertyName("supported_color_modes")] + public IReadOnlyList? SupportedColorModes { get; init; } + + [JsonPropertyName("friendly_name")] + public string? FriendlyName { get; init; } + + [JsonPropertyName("supported_features")] + public double? SupportedFeatures { get; init; } + + [JsonPropertyName("min_mireds")] + public double? MinMireds { get; init; } + + [JsonPropertyName("max_mireds")] + public double? MaxMireds { get; init; } + + [JsonPropertyName("effect_list")] + public IReadOnlyList? EffectList { get; init; } + + [JsonPropertyName("entity_id")] + public IReadOnlyList? EntityId { get; init; } + + [JsonPropertyName("icon")] + public string? Icon { get; init; } + + [JsonPropertyName("color_mode")] + public string? ColorMode { get; init; } + + [JsonPropertyName("brightness")] + public double? Brightness { get; init; } + + [JsonPropertyName("color_temp")] + public double? ColorTemp { get; init; } + + [JsonPropertyName("hs_color")] + public IReadOnlyList? HsColor { get; init; } + + [JsonPropertyName("rgb_color")] + public IReadOnlyList? RgbColor { get; init; } + + [JsonPropertyName("xy_color")] + public IReadOnlyList? XyColor { get; init; } +} + + +public partial record LightToggleParameters +{ + ///Duration it takes to get to next state. + [JsonPropertyName("transition")] + public long? Transition { get; init; } + + ///Color for the light in RGB-format. eg: [255, 100, 100] + [JsonPropertyName("rgb_color")] + public object? RgbColor { get; init; } + + ///A human readable color name. + [JsonPropertyName("color_name")] + public object? ColorName { get; init; } + + ///Color for the light in hue/sat format. Hue is 0-360 and Sat is 0-100. eg: [300, 70] + [JsonPropertyName("hs_color")] + public object? HsColor { get; init; } + + ///Color for the light in XY-format. eg: [0.52, 0.43] + [JsonPropertyName("xy_color")] + public object? XyColor { get; init; } + + ///Color temperature for the light in mireds. + [JsonPropertyName("color_temp")] + public object? ColorTemp { get; init; } + + ///Color temperature for the light in Kelvin. + [JsonPropertyName("kelvin")] + public long? Kelvin { get; init; } + + ///Number indicating brightness, where 0 turns the light off, 1 is the minimum brightness and 255 is the maximum brightness supported by the light. + [JsonPropertyName("brightness")] + public long? Brightness { get; init; } + + ///Number indicating percentage of full brightness, where 0 turns the light off, 1 is the minimum brightness and 100 is the maximum brightness supported by the light. + [JsonPropertyName("brightness_pct")] + public long? BrightnessPct { get; init; } + + ///Name of a light profile to use. eg: relax + [JsonPropertyName("profile")] + public string? Profile { get; init; } + + ///If the light should flash. + [JsonPropertyName("flash")] + public object? Flash { get; init; } + + ///Light effect. + [JsonPropertyName("effect")] + public string? Effect { get; init; } +} + +public partial record LightTurnOffParameters +{ + ///Duration it takes to get to next state. + [JsonPropertyName("transition")] + public long? Transition { get; init; } + + ///If the light should flash. + [JsonPropertyName("flash")] + public object? Flash { get; init; } +} + +public partial record LightTurnOnParameters +{ + ///Duration it takes to get to next state. + [JsonPropertyName("transition")] + public long? Transition { get; init; } + + ///The color for the light (based on RGB - red, green, blue). + [JsonPropertyName("rgb_color")] + public object? RgbColor { get; init; } + + ///A list containing four integers between 0 and 255 representing the RGBW (red, green, blue, white) color for the light. eg: [255, 100, 100, 50] + [JsonPropertyName("rgbw_color")] + public object? RgbwColor { get; init; } + + ///A list containing five integers between 0 and 255 representing the RGBWW (red, green, blue, cold white, warm white) color for the light. eg: [255, 100, 100, 50, 70] + [JsonPropertyName("rgbww_color")] + public object? RgbwwColor { get; init; } + + ///A human readable color name. + [JsonPropertyName("color_name")] + public object? ColorName { get; init; } + + ///Color for the light in hue/sat format. Hue is 0-360 and Sat is 0-100. eg: [300, 70] + [JsonPropertyName("hs_color")] + public object? HsColor { get; init; } + + ///Color for the light in XY-format. eg: [0.52, 0.43] + [JsonPropertyName("xy_color")] + public object? XyColor { get; init; } + + ///Color temperature for the light in mireds. + [JsonPropertyName("color_temp")] + public object? ColorTemp { get; init; } + + ///Color temperature for the light in Kelvin. + [JsonPropertyName("kelvin")] + public long? Kelvin { get; init; } + + ///Number indicating brightness, where 0 turns the light off, 1 is the minimum brightness and 255 is the maximum brightness supported by the light. + [JsonPropertyName("brightness")] + public long? Brightness { get; init; } + + ///Number indicating percentage of full brightness, where 0 turns the light off, 1 is the minimum brightness and 100 is the maximum brightness supported by the light. + [JsonPropertyName("brightness_pct")] + public long? BrightnessPct { get; init; } + + ///Change brightness by an amount. + [JsonPropertyName("brightness_step")] + public long? BrightnessStep { get; init; } + + ///Change brightness by a percentage. + [JsonPropertyName("brightness_step_pct")] + public long? BrightnessStepPct { get; init; } + + ///Set the light to white mode and change its brightness, where 0 turns the light off, 1 is the minimum brightness and 255 is the maximum brightness supported by the light. + [JsonPropertyName("white")] + public long? White { get; init; } + + ///Name of a light profile to use. eg: relax + [JsonPropertyName("profile")] + public string? Profile { get; init; } + + ///If the light should flash. + [JsonPropertyName("flash")] + public object? Flash { get; init; } + + ///Light effect. + [JsonPropertyName("effect")] + public string? Effect { get; init; } +} + + +public static class LightEntityExtensionMethods +{ + ///Toggles one or more lights, from on to off, or, off to on, based on their current state. + public static void Toggle(this ILightEntityCore target, LightToggleParameters data) + { + target.CallService("toggle", data); + } + + ///Toggles one or more lights, from on to off, or, off to on, based on their current state. + public static void Toggle(this IEnumerable target, LightToggleParameters data) + { + target.CallService("toggle", data); + } + + ///Toggles one or more lights, from on to off, or, off to on, based on their current state. + ///The ILightEntity to call this service for + ///Duration it takes to get to next state. + ///Color for the light in RGB-format. eg: [255, 100, 100] + ///A human readable color name. + ///Color for the light in hue/sat format. Hue is 0-360 and Sat is 0-100. eg: [300, 70] + ///Color for the light in XY-format. eg: [0.52, 0.43] + ///Color temperature for the light in mireds. + ///Color temperature for the light in Kelvin. + ///Number indicating brightness, where 0 turns the light off, 1 is the minimum brightness and 255 is the maximum brightness supported by the light. + ///Number indicating percentage of full brightness, where 0 turns the light off, 1 is the minimum brightness and 100 is the maximum brightness supported by the light. + ///Name of a light profile to use. eg: relax + ///If the light should flash. + ///Light effect. + public static void Toggle(this ILightEntityCore target, long? transition = null, object? rgbColor = null, object? colorName = null, object? hsColor = null, object? xyColor = null, object? colorTemp = null, long? kelvin = null, long? brightness = null, long? brightnessPct = null, string? profile = null, object? flash = null, string? effect = null) + { + target.CallService("toggle", new LightToggleParameters { Transition = transition, RgbColor = rgbColor, ColorName = colorName, HsColor = hsColor, XyColor = xyColor, ColorTemp = colorTemp, Kelvin = kelvin, Brightness = brightness, BrightnessPct = brightnessPct, Profile = profile, Flash = flash, Effect = effect }); + } + + ///Toggles one or more lights, from on to off, or, off to on, based on their current state. + ///The IEnumerable<ILightEntity> to call this service for + ///Duration it takes to get to next state. + ///Color for the light in RGB-format. eg: [255, 100, 100] + ///A human readable color name. + ///Color for the light in hue/sat format. Hue is 0-360 and Sat is 0-100. eg: [300, 70] + ///Color for the light in XY-format. eg: [0.52, 0.43] + ///Color temperature for the light in mireds. + ///Color temperature for the light in Kelvin. + ///Number indicating brightness, where 0 turns the light off, 1 is the minimum brightness and 255 is the maximum brightness supported by the light. + ///Number indicating percentage of full brightness, where 0 turns the light off, 1 is the minimum brightness and 100 is the maximum brightness supported by the light. + ///Name of a light profile to use. eg: relax + ///If the light should flash. + ///Light effect. + public static void Toggle(this IEnumerable target, long? transition = null, object? rgbColor = null, object? colorName = null, object? hsColor = null, object? xyColor = null, object? colorTemp = null, long? kelvin = null, long? brightness = null, long? brightnessPct = null, string? profile = null, object? flash = null, string? effect = null) + { + target.CallService("toggle", new LightToggleParameters { Transition = transition, RgbColor = rgbColor, ColorName = colorName, HsColor = hsColor, XyColor = xyColor, ColorTemp = colorTemp, Kelvin = kelvin, Brightness = brightness, BrightnessPct = brightnessPct, Profile = profile, Flash = flash, Effect = effect }); + } + + ///Turns off one or more lights. + public static void TurnOff(this ILightEntityCore target, LightTurnOffParameters data) + { + target.CallService("turn_off", data); + } + + ///Turns off one or more lights. + public static void TurnOff(this IEnumerable target, LightTurnOffParameters data) + { + target.CallService("turn_off", data); + } + + ///Turns off one or more lights. + ///The ILightEntity to call this service for + ///Duration it takes to get to next state. + ///If the light should flash. + public static void TurnOff(this ILightEntityCore target, long? transition = null, object? flash = null) + { + target.CallService("turn_off", new LightTurnOffParameters { Transition = transition, Flash = flash }); + } + + ///Turns off one or more lights. + ///The IEnumerable<ILightEntity> to call this service for + ///Duration it takes to get to next state. + ///If the light should flash. + public static void TurnOff(this IEnumerable target, long? transition = null, object? flash = null) + { + target.CallService("turn_off", new LightTurnOffParameters { Transition = transition, Flash = flash }); + } + + ///Turn on one or more lights and adjust properties of the light, even when they are turned on already. + public static void TurnOn(this ILightEntityCore target, LightTurnOnParameters data) + { + target.CallService("turn_on", data); + } + + ///Turn on one or more lights and adjust properties of the light, even when they are turned on already. + public static void TurnOn(this IEnumerable target, LightTurnOnParameters data) + { + target.CallService("turn_on", data); + } + + ///Turn on one or more lights and adjust properties of the light, even when they are turned on already. + ///The ILightEntity to call this service for + ///Duration it takes to get to next state. + ///The color for the light (based on RGB - red, green, blue). + ///A list containing four integers between 0 and 255 representing the RGBW (red, green, blue, white) color for the light. eg: [255, 100, 100, 50] + ///A list containing five integers between 0 and 255 representing the RGBWW (red, green, blue, cold white, warm white) color for the light. eg: [255, 100, 100, 50, 70] + ///A human readable color name. + ///Color for the light in hue/sat format. Hue is 0-360 and Sat is 0-100. eg: [300, 70] + ///Color for the light in XY-format. eg: [0.52, 0.43] + ///Color temperature for the light in mireds. + ///Color temperature for the light in Kelvin. + ///Number indicating brightness, where 0 turns the light off, 1 is the minimum brightness and 255 is the maximum brightness supported by the light. + ///Number indicating percentage of full brightness, where 0 turns the light off, 1 is the minimum brightness and 100 is the maximum brightness supported by the light. + ///Change brightness by an amount. + ///Change brightness by a percentage. + ///Set the light to white mode and change its brightness, where 0 turns the light off, 1 is the minimum brightness and 255 is the maximum brightness supported by the light. + ///Name of a light profile to use. eg: relax + ///If the light should flash. + ///Light effect. + public static void TurnOn(this ILightEntityCore target, long? transition = null, object? rgbColor = null, object? rgbwColor = null, object? rgbwwColor = null, object? colorName = null, object? hsColor = null, object? xyColor = null, object? colorTemp = null, long? kelvin = null, long? brightness = null, long? brightnessPct = null, long? brightnessStep = null, long? brightnessStepPct = null, long? white = null, string? profile = null, object? flash = null, string? effect = null) + { + target.CallService("turn_on", new LightTurnOnParameters { Transition = transition, RgbColor = rgbColor, RgbwColor = rgbwColor, RgbwwColor = rgbwwColor, ColorName = colorName, HsColor = hsColor, XyColor = xyColor, ColorTemp = colorTemp, Kelvin = kelvin, Brightness = brightness, BrightnessPct = brightnessPct, BrightnessStep = brightnessStep, BrightnessStepPct = brightnessStepPct, White = white, Profile = profile, Flash = flash, Effect = effect }); + } + + ///Turn on one or more lights and adjust properties of the light, even when they are turned on already. + ///The IEnumerable<ILightEntity> to call this service for + ///Duration it takes to get to next state. + ///The color for the light (based on RGB - red, green, blue). + ///A list containing four integers between 0 and 255 representing the RGBW (red, green, blue, white) color for the light. eg: [255, 100, 100, 50] + ///A list containing five integers between 0 and 255 representing the RGBWW (red, green, blue, cold white, warm white) color for the light. eg: [255, 100, 100, 50, 70] + ///A human readable color name. + ///Color for the light in hue/sat format. Hue is 0-360 and Sat is 0-100. eg: [300, 70] + ///Color for the light in XY-format. eg: [0.52, 0.43] + ///Color temperature for the light in mireds. + ///Color temperature for the light in Kelvin. + ///Number indicating brightness, where 0 turns the light off, 1 is the minimum brightness and 255 is the maximum brightness supported by the light. + ///Number indicating percentage of full brightness, where 0 turns the light off, 1 is the minimum brightness and 100 is the maximum brightness supported by the light. + ///Change brightness by an amount. + ///Change brightness by a percentage. + ///Set the light to white mode and change its brightness, where 0 turns the light off, 1 is the minimum brightness and 255 is the maximum brightness supported by the light. + ///Name of a light profile to use. eg: relax + ///If the light should flash. + ///Light effect. + public static void TurnOn(this IEnumerable target, long? transition = null, object? rgbColor = null, object? rgbwColor = null, object? rgbwwColor = null, object? colorName = null, object? hsColor = null, object? xyColor = null, object? colorTemp = null, long? kelvin = null, long? brightness = null, long? brightnessPct = null, long? brightnessStep = null, long? brightnessStepPct = null, long? white = null, string? profile = null, object? flash = null, string? effect = null) + { + target.CallService("turn_on", new LightTurnOnParameters { Transition = transition, RgbColor = rgbColor, RgbwColor = rgbwColor, RgbwwColor = rgbwwColor, ColorName = colorName, HsColor = hsColor, XyColor = xyColor, ColorTemp = colorTemp, Kelvin = kelvin, Brightness = brightness, BrightnessPct = brightnessPct, BrightnessStep = brightnessStep, BrightnessStepPct = brightnessStepPct, White = white, Profile = profile, Flash = flash, Effect = effect }); + } +} + diff --git a/src/debug/MyLibrary/MyLibrary.csproj b/src/debug/MyLibrary/MyLibrary.csproj new file mode 100644 index 000000000..62d184b2f --- /dev/null +++ b/src/debug/MyLibrary/MyLibrary.csproj @@ -0,0 +1,13 @@ + + + + net7.0 + enable + enable + + + + + + + diff --git a/src/debug/MyLibrary/MyLibraryClass.cs b/src/debug/MyLibrary/MyLibraryClass.cs new file mode 100644 index 000000000..5cc703765 --- /dev/null +++ b/src/debug/MyLibrary/MyLibraryClass.cs @@ -0,0 +1,49 @@ +using NetDaemon.HassModel.Entities; + + +namespace MyLibrary; + +public class MyLibraryClass +{ + public LightEntity Target; + public IEnumerable TargetList; + + public MyLibraryClass(ILightEntityCore target, IEnumerable lights) + { + Target = new LightEntity(target); + TargetList = lights; + } + + public void ToggleTarget() + { + Target.Toggle(); + } + + + public void Increment() + { + var current = (long)(Target.Attributes?.Brightness ?? 0); + var newBrightness = current + 10; + if (newBrightness <= 256) + { + Target.TurnOn(brightness: newBrightness); + } + else + { + Target.TurnOff(); + } + } + + + public void ToggleTargetList() + { + TargetList.Toggle(); + } + + + public void HalfBrightness() + { + TargetList.TurnOn(brightnessPct: 50); + } + +} diff --git a/src/debug/MyNDApp/.gitignore b/src/debug/MyNDApp/.gitignore new file mode 100644 index 000000000..d209ae50d --- /dev/null +++ b/src/debug/MyNDApp/.gitignore @@ -0,0 +1,8 @@ +obj +bin +appsettings.Development.json +.vs +*.gen +.idea +#appsettings.json +#HomeAssistantGenerated.cs \ No newline at end of file diff --git a/src/debug/MyNDApp/HomeAssistantGenerated.cs b/src/debug/MyNDApp/HomeAssistantGenerated.cs new file mode 100644 index 000000000..c872b256d --- /dev/null +++ b/src/debug/MyNDApp/HomeAssistantGenerated.cs @@ -0,0 +1,136 @@ +//------------------------------------------------------------------------------ +// +// Generated using NetDaemon CodeGenerator nd-codegen v23.32.0.0 +// At: 2023-08-13T22:55:56.3430066+02:00 +// +// *** Make sure the version of the codegen tool and your nugets Joysoftware.NetDaemon.* have the same version.*** +// You can use following command to keep it up to date with the latest version: +// dotnet tool update JoySoftware.NetDaemon.HassModel.CodeGen +// +// To update this file with latest entities run this command in your project directory: +// dotnet tool run nd-codegen +// +// In the template projects we provided a convenience powershell script that will update +// the codegen and nugets to latest versions update_all_dependencies.ps1. +// +// For more information: https://netdaemon.xyz/docs/v3/hass_model/hass_model_codegen +// For more information about NetDaemon: https://netdaemon.xyz/ +// +//------------------------------------------------------------------------------ +#nullable enable +using System; +using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; +using System.Text.Json.Serialization; +using NetDaemon.HassModel; +using NetDaemon.HassModel.Entities; +using NetDaemon.HassModel.Entities.Core; + +namespace HomeAssistantGenerated; + +public partial class Entities +{ + private readonly IHaContext _haContext; + public Entities(IHaContext haContext) + { + _haContext = haContext; + } + + public LightEntities Light => new(_haContext); +} + + +public partial class LightEntities +{ + private readonly IHaContext _haContext; + public LightEntities(IHaContext haContext) + { + _haContext = haContext; + } + + ///Woonkamer + public LightEntity Woonkamer => new(_haContext, "light.woonkamer"); + ///Alles Beneden + ///Zolder + public LightEntity Zolder => new(_haContext, "light.zolder"); +} + +public partial record LightEntity : Entity, LightAttributes>, ILightEntityCore +{ + public LightEntity(IHaContext haContext, string entityId) : base(haContext, entityId) + { + } + + public LightEntity(Entity entity) : base(entity) + { + } +} + +public partial record LightAttributes +{ + [JsonPropertyName("min_color_temp_kelvin")] + public double? MinColorTempKelvin { get; init; } + + [JsonPropertyName("max_color_temp_kelvin")] + public double? MaxColorTempKelvin { get; init; } + + [JsonPropertyName("color_temp_kelvin")] + public double? ColorTempKelvin { get; init; } + + [JsonPropertyName("off_with_transition")] + public bool? OffWithTransition { get; init; } + + [JsonPropertyName("off_brightness")] + public double? OffBrightness { get; init; } + + [JsonPropertyName("restored")] + public bool? Restored { get; init; } + + [JsonPropertyName("supported_color_modes")] + public IReadOnlyList? SupportedColorModes { get; init; } + + [JsonPropertyName("friendly_name")] + public string? FriendlyName { get; init; } + + [JsonPropertyName("supported_features")] + public double? SupportedFeatures { get; init; } + + [JsonPropertyName("min_mireds")] + public double? MinMireds { get; init; } + + [JsonPropertyName("max_mireds")] + public double? MaxMireds { get; init; } + + [JsonPropertyName("effect_list")] + public IReadOnlyList? EffectList { get; init; } + + [JsonPropertyName("entity_id")] + public IReadOnlyList? EntityId { get; init; } + + [JsonPropertyName("icon")] + public string? Icon { get; init; } + + [JsonPropertyName("color_mode")] + public string? ColorMode { get; init; } + + [JsonPropertyName("brightness")] + public double? Brightness { get; init; } + + [JsonPropertyName("color_temp")] + public double? ColorTemp { get; init; } + + [JsonPropertyName("hs_color")] + public IReadOnlyList? HsColor { get; init; } + + [JsonPropertyName("rgb_color")] + public IReadOnlyList? RgbColor { get; init; } + + [JsonPropertyName("xy_color")] + public IReadOnlyList? XyColor { get; init; } +} + + + + + + diff --git a/src/debug/MyNDApp/MyNDApp.csproj b/src/debug/MyNDApp/MyNDApp.csproj new file mode 100644 index 000000000..ed005da15 --- /dev/null +++ b/src/debug/MyNDApp/MyNDApp.csproj @@ -0,0 +1,52 @@ + + + + Exe + net7.0 + 11.0 + enable + Debug + + + + Always + + + Always + + + Always + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/debug/MyNDApp/apps/HassModel/MyInterfaceAutomation/InterfaceUsage.cs b/src/debug/MyNDApp/apps/HassModel/MyInterfaceAutomation/InterfaceUsage.cs new file mode 100644 index 000000000..aa599b3ac --- /dev/null +++ b/src/debug/MyNDApp/apps/HassModel/MyInterfaceAutomation/InterfaceUsage.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Reactive.Concurrency; +using HomeAssistantGenerated; +using Microsoft.Extensions.Logging; +using MyLibrary; +using NetDaemon.AppModel; +using NetDaemon.HassModel; +using NetDaemon.HassModel.Entities; + +namespace Debug.apps.HassModel.MyInterfaceAutomation; + +[NetDaemonApp] +[Focus] +public class InterfaceUsage +{ + public InterfaceUsage(IHaContext haContext, ILogger logger, IScheduler scheduler) + { + var entities = new Entities(haContext); + IEnumerable lights = new[] { entities.Light.Zolder, entities.Light.Woonkamer }; + + + // pass generated types to the library using the commonly known interfaces + var myLibraryClass = new MyLibraryClass(entities.Light.Zolder, lights); + + scheduler.SchedulePeriodic(TimeSpan.FromSeconds(1), () => myLibraryClass.Increment()); + } +} \ No newline at end of file diff --git a/src/debug/MyNDApp/program.cs b/src/debug/MyNDApp/program.cs new file mode 100644 index 000000000..3835e285c --- /dev/null +++ b/src/debug/MyNDApp/program.cs @@ -0,0 +1,38 @@ +using System; +using System.Reflection; +using HomeAssistantGenerated; +using Microsoft.Extensions.Hosting; +using NetDaemon.AppModel; +using NetDaemon.Extensions.Logging; +using NetDaemon.Extensions.Scheduler; +using NetDaemon.Extensions.Tts; +using NetDaemon.Runtime; + +// Add next line if using code generator + +#pragma warning disable CA1812 + +try +{ + await Host.CreateDefaultBuilder(args) + .UseNetDaemonAppSettings() + .UseNetDaemonDefaultLogging() + .UseNetDaemonRuntime() + .UseNetDaemonTextToSpeech() + .ConfigureServices((_, services) => + services + .AddAppsFromAssembly(Assembly.GetExecutingAssembly()) + .AddNetDaemonStateManager() + .AddNetDaemonScheduler() + // Add next line if using code generator + //.AddHomeAssistantGenerated() + ) + .Build() + .RunAsync() + .ConfigureAwait(false); +} +catch (Exception e) +{ + Console.WriteLine($"Failed to start host... {e}"); + throw; +} \ No newline at end of file