diff --git a/dev/DebugHost/apps/ConcurrencyTestApp.cs b/dev/DebugHost/apps/ConcurrencyTestApp.cs index 063dcf06f..59f5654f8 100644 --- a/dev/DebugHost/apps/ConcurrencyTestApp.cs +++ b/dev/DebugHost/apps/ConcurrencyTestApp.cs @@ -3,7 +3,7 @@ using System.Threading.Tasks; using Microsoft.Extensions.Logging; using NetDaemon.AppModel; -using NetDaemon.HassModel.Common; +using NetDaemon.HassModel; namespace Apps; diff --git a/dev/DebugHost/apps/HelloApp/HelloApp.cs b/dev/DebugHost/apps/HelloApp/HelloApp.cs index 9a2fe7fc9..ccef477dc 100644 --- a/dev/DebugHost/apps/HelloApp/HelloApp.cs +++ b/dev/DebugHost/apps/HelloApp/HelloApp.cs @@ -2,7 +2,7 @@ using System.Reactive.Linq; using Microsoft.Extensions.Logging; using NetDaemon.AppModel; -using NetDaemon.HassModel.Common; +using NetDaemon.HassModel; namespace Apps; diff --git a/dev/DebugHost/apps/YamlApp/YamlApp.cs b/dev/DebugHost/apps/YamlApp/YamlApp.cs index ff260d920..d2ff8d2a3 100644 --- a/dev/DebugHost/apps/YamlApp/YamlApp.cs +++ b/dev/DebugHost/apps/YamlApp/YamlApp.cs @@ -1,6 +1,6 @@ using NetDaemon.AppModel; -using NetDaemon.HassModel.Common; +using NetDaemon.HassModel; namespace Apps; diff --git a/src/Client/NetDaemon.HassClient.Debug/GlobalUsings.cs b/src/Client/NetDaemon.HassClient.Debug/GlobalUsings.cs index bf50b0865..a1b0b1732 100644 --- a/src/Client/NetDaemon.HassClient.Debug/GlobalUsings.cs +++ b/src/Client/NetDaemon.HassClient.Debug/GlobalUsings.cs @@ -3,8 +3,8 @@ global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Hosting; global using Microsoft.Extensions.Options; -global using NetDaemon.Client.Common; -global using NetDaemon.Client.Common.Extensions; -global using NetDaemon.Client.Common.HomeAssistant.Extensions; -global using NetDaemon.Client.Common.HomeAssistant.Model; -global using NetDaemon.Client.Common.Settings; \ No newline at end of file +global using NetDaemon.Client; +global using NetDaemon.Client.Extensions; +global using NetDaemon.Client.HomeAssistant.Extensions; +global using NetDaemon.Client.HomeAssistant.Model; +global using NetDaemon.Client.Settings; \ No newline at end of file diff --git a/src/Client/NetDaemon.HassClient.Tests/ExtensionsTest/ServiceCollectionExtensionTests.cs b/src/Client/NetDaemon.HassClient.Tests/ExtensionsTest/ServiceCollectionExtensionTests.cs index 48d940b04..dbcd9ec9b 100644 --- a/src/Client/NetDaemon.HassClient.Tests/ExtensionsTest/ServiceCollectionExtensionTests.cs +++ b/src/Client/NetDaemon.HassClient.Tests/ExtensionsTest/ServiceCollectionExtensionTests.cs @@ -1,4 +1,4 @@ -using NetDaemon.Client.Common.Extensions; +using NetDaemon.Client.Extensions; namespace NetDaemon.HassClient.Tests.ExtensionsTest; diff --git a/src/Client/NetDaemon.HassClient.Tests/GlobalUsings.cs b/src/Client/NetDaemon.HassClient.Tests/GlobalUsings.cs index 9b1593d29..44cd32ddd 100644 --- a/src/Client/NetDaemon.HassClient.Tests/GlobalUsings.cs +++ b/src/Client/NetDaemon.HassClient.Tests/GlobalUsings.cs @@ -13,14 +13,14 @@ global using FluentAssertions; global using Moq; global using Xunit; -global using NetDaemon.Client.Common; -global using NetDaemon.Client.Common.HomeAssistant.Model; +global using NetDaemon.Client; +global using NetDaemon.Client.HomeAssistant.Model; global using NetDaemon.Client.Internal; global using NetDaemon.Client.Internal.Helpers; global using NetDaemon.Client.Internal.Net; -global using NetDaemon.Client.Common.Exceptions; +global using NetDaemon.Client.Exceptions; global using NetDaemon.Client.Internal.Extensions; global using NetDaemon.Client.Internal.HomeAssistant.Commands; -global using NetDaemon.Client.Common.Settings; -global using NetDaemon.Client.Common.HomeAssistant.Extensions; +global using NetDaemon.Client.Settings; +global using NetDaemon.Client.HomeAssistant.Extensions; global using NetDaemon.HassClient.Tests.Helpers; \ No newline at end of file diff --git a/src/Client/NetDaemon.HassClient/Common/DisconnectReason.cs b/src/Client/NetDaemon.HassClient/Common/DisconnectReason.cs index 596641171..8375ae7aa 100644 --- a/src/Client/NetDaemon.HassClient/Common/DisconnectReason.cs +++ b/src/Client/NetDaemon.HassClient/Common/DisconnectReason.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common; +namespace NetDaemon.Client; /// /// The reason websocket connection disconnected diff --git a/src/Client/NetDaemon.HassClient/Common/Exceptions/HomeAssistantConnectionException.cs b/src/Client/NetDaemon.HassClient/Common/Exceptions/HomeAssistantConnectionException.cs index bc724f3e2..e3ddf91a6 100644 --- a/src/Client/NetDaemon.HassClient/Common/Exceptions/HomeAssistantConnectionException.cs +++ b/src/Client/NetDaemon.HassClient/Common/Exceptions/HomeAssistantConnectionException.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common.Exceptions; +namespace NetDaemon.Client.Exceptions; // We allow exception not to have default constructors since // in this case it only makes sense to have a reason diff --git a/src/Client/NetDaemon.HassClient/Common/Extensions/ServiceCollectionExtension.cs b/src/Client/NetDaemon.HassClient/Common/Extensions/ServiceCollectionExtension.cs index f71b9da18..c8381b892 100644 --- a/src/Client/NetDaemon.HassClient/Common/Extensions/ServiceCollectionExtension.cs +++ b/src/Client/NetDaemon.HassClient/Common/Extensions/ServiceCollectionExtension.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common.Extensions; +namespace NetDaemon.Client.Extensions; /// /// ServiceCollectionExtensions diff --git a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Extensions/HassEventExtensions.cs b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Extensions/HassEventExtensions.cs index 2d6acb514..f8e4073fc 100644 --- a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Extensions/HassEventExtensions.cs +++ b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Extensions/HassEventExtensions.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common.HomeAssistant.Extensions; +namespace NetDaemon.Client.HomeAssistant.Extensions; /// /// Extensions to HassEvents to convert to more specific event types diff --git a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Extensions/HomeAssistantApiManagerExtensions.cs b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Extensions/HomeAssistantApiManagerExtensions.cs index 4b48466a2..a55e78969 100644 --- a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Extensions/HomeAssistantApiManagerExtensions.cs +++ b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Extensions/HomeAssistantApiManagerExtensions.cs @@ -1,6 +1,6 @@ using System.Web; -namespace NetDaemon.Client.Common.HomeAssistant.Extensions; +namespace NetDaemon.Client.HomeAssistant.Extensions; /// /// Adds extensions to the IHomeAssistantApiManager diff --git a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Extensions/IHomeAssistantConnectionExtensions.cs b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Extensions/IHomeAssistantConnectionExtensions.cs index c1ed138c9..45477ef90 100644 --- a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Extensions/IHomeAssistantConnectionExtensions.cs +++ b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Extensions/IHomeAssistantConnectionExtensions.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common.HomeAssistant.Extensions; +namespace NetDaemon.Client.HomeAssistant.Extensions; /// /// HomeAssistantConnection extensions diff --git a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/CommandMessage.cs b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/CommandMessage.cs index 0722322d9..7aa889f6b 100644 --- a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/CommandMessage.cs +++ b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/CommandMessage.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common.HomeAssistant.Model; +namespace NetDaemon.Client.HomeAssistant.Model; public record CommandMessage : HassMessageBase { diff --git a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassArea.cs b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassArea.cs index d24271908..2c06dae94 100644 --- a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassArea.cs +++ b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassArea.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common.HomeAssistant.Model; +namespace NetDaemon.Client.HomeAssistant.Model; public record HassArea { diff --git a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassConfig.cs b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassConfig.cs index e7f31d044..fdba26390 100644 --- a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassConfig.cs +++ b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassConfig.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common.HomeAssistant.Model; +namespace NetDaemon.Client.HomeAssistant.Model; public record HassConfig { diff --git a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassContext.cs b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassContext.cs index 8daf728f2..e17725155 100644 --- a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassContext.cs +++ b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassContext.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common.HomeAssistant.Model; +namespace NetDaemon.Client.HomeAssistant.Model; public record HassContext { diff --git a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassDevice.cs b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassDevice.cs index 9a8a8ab3c..b3e74f826 100644 --- a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassDevice.cs +++ b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassDevice.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common.HomeAssistant.Model; +namespace NetDaemon.Client.HomeAssistant.Model; public record HassDevice { diff --git a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassEntity.cs b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassEntity.cs index b70b4462f..a27be76c8 100644 --- a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassEntity.cs +++ b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassEntity.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common.HomeAssistant.Model; +namespace NetDaemon.Client.HomeAssistant.Model; public record HassEntity { diff --git a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassError.cs b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassError.cs index df0c74605..9d64d1408 100644 --- a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassError.cs +++ b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassError.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common.HomeAssistant.Model; +namespace NetDaemon.Client.HomeAssistant.Model; public record HassError { diff --git a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassEvent.cs b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassEvent.cs index cc1ed96db..c74c59792 100644 --- a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassEvent.cs +++ b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassEvent.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common.HomeAssistant.Model; +namespace NetDaemon.Client.HomeAssistant.Model; public record HassEvent { diff --git a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassMessageBase.cs b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassMessageBase.cs index 998c4a73c..e4778ac17 100644 --- a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassMessageBase.cs +++ b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassMessageBase.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common.HomeAssistant.Model; +namespace NetDaemon.Client.HomeAssistant.Model; public record HassMessageBase { diff --git a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassServiceEventData.cs b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassServiceEventData.cs index 5e128cf43..581cee23a 100644 --- a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassServiceEventData.cs +++ b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassServiceEventData.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common.HomeAssistant.Model; +namespace NetDaemon.Client.HomeAssistant.Model; public record HassServiceEventData { diff --git a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassState.cs b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassState.cs index b54a83c8e..6c6cf6cc8 100644 --- a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassState.cs +++ b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassState.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common.HomeAssistant.Model; +namespace NetDaemon.Client.HomeAssistant.Model; public record HassState { diff --git a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassStateChangedEventData.cs b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassStateChangedEventData.cs index 2d95aece4..59dc85bec 100644 --- a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassStateChangedEventData.cs +++ b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassStateChangedEventData.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common.HomeAssistant.Model; +namespace NetDaemon.Client.HomeAssistant.Model; public record HassStateChangedEventData { diff --git a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassUnitSystem.cs b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassUnitSystem.cs index 388ef5653..a00a96713 100644 --- a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassUnitSystem.cs +++ b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassUnitSystem.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common.HomeAssistant.Model; +namespace NetDaemon.Client.HomeAssistant.Model; public record HassUnitSystem { diff --git a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/Targets.cs b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/Targets.cs index 4e26763a8..cb03e9e3f 100644 --- a/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/Targets.cs +++ b/src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/Targets.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common.HomeAssistant.Model; +namespace NetDaemon.Client.HomeAssistant.Model; /// /// Represents a target for a service call in Home Assistant diff --git a/src/Client/NetDaemon.HassClient/Common/HomeAssistantClientConnector.cs b/src/Client/NetDaemon.HassClient/Common/HomeAssistantClientConnector.cs index fd5bf506b..23187b3f3 100644 --- a/src/Client/NetDaemon.HassClient/Common/HomeAssistantClientConnector.cs +++ b/src/Client/NetDaemon.HassClient/Common/HomeAssistantClientConnector.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common; +namespace NetDaemon.Client; /// /// Make connection to Home Assistant diff --git a/src/Client/NetDaemon.HassClient/Common/IHomeAssistantApiManager.cs b/src/Client/NetDaemon.HassClient/Common/IHomeAssistantApiManager.cs index a5d836b4f..798ebe0d0 100644 --- a/src/Client/NetDaemon.HassClient/Common/IHomeAssistantApiManager.cs +++ b/src/Client/NetDaemon.HassClient/Common/IHomeAssistantApiManager.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common; +namespace NetDaemon.Client; /// /// Handle home assistant API calls using json over http diff --git a/src/Client/NetDaemon.HassClient/Common/IHomeAssistantClient.cs b/src/Client/NetDaemon.HassClient/Common/IHomeAssistantClient.cs index 204d42fb7..9aeaeeaf3 100644 --- a/src/Client/NetDaemon.HassClient/Common/IHomeAssistantClient.cs +++ b/src/Client/NetDaemon.HassClient/Common/IHomeAssistantClient.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common; +namespace NetDaemon.Client; /// /// HomeAssistantClient diff --git a/src/Client/NetDaemon.HassClient/Common/IHomeAssistantConnection.cs b/src/Client/NetDaemon.HassClient/Common/IHomeAssistantConnection.cs index 92f3c25d2..cf07158d2 100644 --- a/src/Client/NetDaemon.HassClient/Common/IHomeAssistantConnection.cs +++ b/src/Client/NetDaemon.HassClient/Common/IHomeAssistantConnection.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common; +namespace NetDaemon.Client; public interface IHomeAssistantConnection : IHomeAssistantApiManager, IAsyncDisposable { diff --git a/src/Client/NetDaemon.HassClient/Common/IHomeAssistantRunner.cs b/src/Client/NetDaemon.HassClient/Common/IHomeAssistantRunner.cs index 1237d33a7..6aa54a687 100644 --- a/src/Client/NetDaemon.HassClient/Common/IHomeAssistantRunner.cs +++ b/src/Client/NetDaemon.HassClient/Common/IHomeAssistantRunner.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common; +namespace NetDaemon.Client; public interface IHomeAssistantRunner : IAsyncDisposable { diff --git a/src/Client/NetDaemon.HassClient/Common/Settings/Settings.cs b/src/Client/NetDaemon.HassClient/Common/Settings/Settings.cs index e43ddd59d..0d07553db 100644 --- a/src/Client/NetDaemon.HassClient/Common/Settings/Settings.cs +++ b/src/Client/NetDaemon.HassClient/Common/Settings/Settings.cs @@ -1,4 +1,4 @@ -namespace NetDaemon.Client.Common.Settings; +namespace NetDaemon.Client.Settings; /// /// Home Assistant related settings diff --git a/src/Client/NetDaemon.HassClient/GlobalUsings.cs b/src/Client/NetDaemon.HassClient/GlobalUsings.cs index 2d4f9c4fc..36bca4cff 100644 --- a/src/Client/NetDaemon.HassClient/GlobalUsings.cs +++ b/src/Client/NetDaemon.HassClient/GlobalUsings.cs @@ -18,17 +18,16 @@ global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Options; // HassClient usings -global using NetDaemon.Client.Common; -global using NetDaemon.Client.Common.HomeAssistant.Model; +global using NetDaemon.Client.HomeAssistant.Model; global using NetDaemon.Client.Internal; global using NetDaemon.Client.Internal.Helpers; global using NetDaemon.Client.Internal.Json; global using NetDaemon.Client.Internal.Net; -global using NetDaemon.Client.Common.Exceptions; +global using NetDaemon.Client.Exceptions; global using NetDaemon.Client.Internal.Extensions; global using NetDaemon.Client.Internal.HomeAssistant.Commands; global using NetDaemon.Client.Internal.HomeAssistant.Messages; -global using NetDaemon.Client.Common.Settings; +global using NetDaemon.Client.Settings; // Make the internal visible to test project [assembly: InternalsVisibleTo("NetDaemon.HassClient.Tests")] diff --git a/src/Client/NetDaemon.HassClient/NetDaemon.Client.csproj b/src/Client/NetDaemon.HassClient/NetDaemon.Client.csproj index c2dbb22ef..ac01471a4 100644 --- a/src/Client/NetDaemon.HassClient/NetDaemon.Client.csproj +++ b/src/Client/NetDaemon.HassClient/NetDaemon.Client.csproj @@ -17,7 +17,6 @@ First alpha version, expect things to change! Home Assistant - JoySoftware.NetDaemon.Client diff --git a/src/Extensions/NetDaemon.Extensions.Scheduling/INetDaemonScheduler.cs b/src/Extensions/NetDaemon.Extensions.Scheduling/INetDaemonScheduler.cs index 421e94a24..4b05c83ea 100644 --- a/src/Extensions/NetDaemon.Extensions.Scheduling/INetDaemonScheduler.cs +++ b/src/Extensions/NetDaemon.Extensions.Scheduling/INetDaemonScheduler.cs @@ -1,44 +1,43 @@ using System; -namespace NetDaemon.Extensions.Scheduler +namespace NetDaemon.Extensions.Scheduler; + +/// +/// Scheduler interface +/// +public interface INetDaemonScheduler { /// - /// Scheduler interface + /// Schedules an action every (timespan) /// - public interface INetDaemonScheduler - { - /// - /// Schedules an action every (timespan) - /// - /// The period to schedule - /// Action to run - IDisposable RunEvery(TimeSpan period, Action action); + /// The period to schedule + /// Action to run + IDisposable RunEvery(TimeSpan period, Action action); - /// - /// Schedules an action every (timespan) - /// - /// The period to schedule - /// The time to start the schedule - /// Action to run - IDisposable RunEvery(TimeSpan period, DateTimeOffset startTime, Action action); + /// + /// Schedules an action every (timespan) + /// + /// The period to schedule + /// The time to start the schedule + /// Action to run + IDisposable RunEvery(TimeSpan period, DateTimeOffset startTime, Action action); - /// - /// Delays execution of an action (timespan) time - /// - /// Timespan to delay - /// Action to run - IDisposable RunIn(TimeSpan timespan, Action action); + /// + /// Delays execution of an action (timespan) time + /// + /// Timespan to delay + /// Action to run + IDisposable RunIn(TimeSpan timespan, Action action); - /// - /// Runs an action at a specific time - /// - /// Absolute time to run the action - /// Action to run - IDisposable RunAt(DateTimeOffset timeOffset, Action action); + /// + /// Runs an action at a specific time + /// + /// Absolute time to run the action + /// Action to run + IDisposable RunAt(DateTimeOffset timeOffset, Action action); - /// - /// The current time of the scheduler - /// - DateTimeOffset Now { get; } - } + /// + /// The current time of the scheduler + /// + DateTimeOffset Now { get; } } \ No newline at end of file diff --git a/src/Extensions/NetDaemon.Extensions.Tts/GlobalUsings.cs b/src/Extensions/NetDaemon.Extensions.Tts/GlobalUsings.cs index 983d3f2ce..9749f92e9 100644 --- a/src/Extensions/NetDaemon.Extensions.Tts/GlobalUsings.cs +++ b/src/Extensions/NetDaemon.Extensions.Tts/GlobalUsings.cs @@ -4,6 +4,6 @@ global using System.Threading.Channels; global using System.Threading.Tasks; global using Microsoft.Extensions.Logging; -global using NetDaemon.Client.Common; -global using NetDaemon.Client.Common.HomeAssistant.Extensions; -global using NetDaemon.Client.Common.HomeAssistant.Model; \ No newline at end of file +global using NetDaemon.Client; +global using NetDaemon.Client.HomeAssistant.Extensions; +global using NetDaemon.Client.HomeAssistant.Model; \ No newline at end of file diff --git a/src/HassModel/NetDaemon.HassModel.CodeGenerator/EntitiesGenerator.cs b/src/HassModel/NetDaemon.HassModel.CodeGenerator/EntitiesGenerator.cs index 021a27b26..8f6a1378b 100644 --- a/src/HassModel/NetDaemon.HassModel.CodeGenerator/EntitiesGenerator.cs +++ b/src/HassModel/NetDaemon.HassModel.CodeGenerator/EntitiesGenerator.cs @@ -1,4 +1,4 @@ -using NetDaemon.Client.Common.HomeAssistant.Model; +using NetDaemon.Client.HomeAssistant.Model; namespace NetDaemon.HassModel.CodeGenerator; diff --git a/src/HassModel/NetDaemon.HassModel.CodeGenerator/EntitySet.cs b/src/HassModel/NetDaemon.HassModel.CodeGenerator/EntitySet.cs index a0bd4f1ea..50d58277f 100644 --- a/src/HassModel/NetDaemon.HassModel.CodeGenerator/EntitySet.cs +++ b/src/HassModel/NetDaemon.HassModel.CodeGenerator/EntitySet.cs @@ -1,4 +1,4 @@ -using NetDaemon.Client.Common.HomeAssistant.Model; +using NetDaemon.Client.HomeAssistant.Model; namespace NetDaemon.HassModel.CodeGenerator; diff --git a/src/HassModel/NetDaemon.HassModel.CodeGenerator/ExtensionMethodsGenerator.cs b/src/HassModel/NetDaemon.HassModel.CodeGenerator/ExtensionMethodsGenerator.cs index 8769c3061..ece6fa374 100644 --- a/src/HassModel/NetDaemon.HassModel.CodeGenerator/ExtensionMethodsGenerator.cs +++ b/src/HassModel/NetDaemon.HassModel.CodeGenerator/ExtensionMethodsGenerator.cs @@ -1,4 +1,4 @@ -using NetDaemon.Client.Common.HomeAssistant.Model; +using NetDaemon.Client.HomeAssistant.Model; namespace NetDaemon.HassModel.CodeGenerator; diff --git a/src/HassModel/NetDaemon.HassModel.CodeGenerator/Generator.cs b/src/HassModel/NetDaemon.HassModel.CodeGenerator/Generator.cs index 4aeea3636..e7c2facba 100644 --- a/src/HassModel/NetDaemon.HassModel.CodeGenerator/Generator.cs +++ b/src/HassModel/NetDaemon.HassModel.CodeGenerator/Generator.cs @@ -1,5 +1,5 @@ using System.Runtime.CompilerServices; -using NetDaemon.Client.Common.HomeAssistant.Model; +using NetDaemon.Client.HomeAssistant.Model; using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; [assembly: InternalsVisibleTo("NetDaemon.Daemon.Tests")] diff --git a/src/HassModel/NetDaemon.HassModel.CodeGenerator/GlobalUsings.cs b/src/HassModel/NetDaemon.HassModel.CodeGenerator/GlobalUsings.cs index 023a3f553..713ecf8b6 100644 --- a/src/HassModel/NetDaemon.HassModel.CodeGenerator/GlobalUsings.cs +++ b/src/HassModel/NetDaemon.HassModel.CodeGenerator/GlobalUsings.cs @@ -7,7 +7,6 @@ global using NetDaemon.HassModel.CodeGenerator.Model; global using NetDaemon.HassModel.CodeGenerator.Helpers; global using NetDaemon.HassModel.CodeGenerator.Extensions; -global using NetDaemon.HassModel.Common; global using NetDaemon.HassModel.Entities; global using Microsoft.CodeAnalysis; global using static NetDaemon.HassModel.CodeGenerator.Helpers.NamingHelper; diff --git a/src/HassModel/NetDaemon.HassModel.CodeGenerator/Program.cs b/src/HassModel/NetDaemon.HassModel.CodeGenerator/Program.cs index 5d24a88c3..cd9fce374 100644 --- a/src/HassModel/NetDaemon.HassModel.CodeGenerator/Program.cs +++ b/src/HassModel/NetDaemon.HassModel.CodeGenerator/Program.cs @@ -5,11 +5,11 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; -using NetDaemon.Client.Common; -using NetDaemon.Client.Common.Extensions; -using NetDaemon.Client.Common.HomeAssistant.Extensions; -using NetDaemon.Client.Common.HomeAssistant.Model; -using NetDaemon.Client.Common.Settings; +using NetDaemon.Client; +using NetDaemon.Client.Extensions; +using NetDaemon.Client.HomeAssistant.Extensions; +using NetDaemon.Client.HomeAssistant.Model; +using NetDaemon.Client.Settings; #pragma warning disable CA1303 #pragma warning disable CA2007 diff --git a/src/HassModel/NetDaemon.HassModel.Integration/IntegrationHaContextExtensions.cs b/src/HassModel/NetDaemon.HassModel.Integration/IntegrationHaContextExtensions.cs index d873f4048..7d87f3f38 100644 --- a/src/HassModel/NetDaemon.HassModel.Integration/IntegrationHaContextExtensions.cs +++ b/src/HassModel/NetDaemon.HassModel.Integration/IntegrationHaContextExtensions.cs @@ -1,5 +1,4 @@ using System.Reactive.Linq; -using NetDaemon.HassModel.Common; namespace NetDaemon.HassModel.Integration; diff --git a/src/HassModel/NetDaemon.HassModel.Tests/CodeGenerator/CodeGeneratorTest.cs b/src/HassModel/NetDaemon.HassModel.Tests/CodeGenerator/CodeGeneratorTest.cs index a0e38e101..3b771eef3 100644 --- a/src/HassModel/NetDaemon.HassModel.Tests/CodeGenerator/CodeGeneratorTest.cs +++ b/src/HassModel/NetDaemon.HassModel.Tests/CodeGenerator/CodeGeneratorTest.cs @@ -5,41 +5,41 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -using NetDaemon.Client.Common.HomeAssistant.Model; +using NetDaemon.Client.HomeAssistant.Model; using NetDaemon.HassModel.CodeGenerator; using NetDaemon.HassModel.CodeGenerator.Model; using NetDaemon.HassModel.Tests.TestHelpers; using Xunit; -namespace NetDaemon.HassModel.Tests.CodeGenerator +namespace NetDaemon.HassModel.Tests.CodeGenerator; + +public class CodeGeneratorTest { - public class CodeGeneratorTest + [Fact] + public void RunCodeGenEMpy() { - [Fact] - public void RunCodeGenEMpy() - { - var code = Generator.CreateCompilationUnitSyntax("RootNameSpace", Array.Empty(), new HassServiceDomain[0]); + var code = Generator.CreateCompilationUnitSyntax("RootNameSpace", Array.Empty(), new HassServiceDomain[0]); - code.DescendantNodes().OfType().First().Name.ToString().Should().Be("RootNameSpace"); + code.DescendantNodes().OfType().First().Name.ToString().Should().Be("RootNameSpace"); - AssertCodeCompiles(code.ToString(), string.Empty); - } + AssertCodeCompiles(code.ToString(), string.Empty); + } - [Fact] - public void TestIEntityGeneration() + [Fact] + public void TestIEntityGeneration() + { + var entityStates = new HassState[] { - var entityStates = new HassState[] - { - new() { EntityId = "light.light1" }, - new() { EntityId = "light.light2" }, - new() { EntityId = "switch.switch1" }, - new() { EntityId = "switch.switch2" }, - }; + new() { EntityId = "light.light1" }, + new() { EntityId = "light.light2" }, + new() { EntityId = "switch.switch1" }, + new() { EntityId = "switch.switch2" }, + }; - var generatedCode = Generator.CreateCompilationUnitSyntax("RootNameSpace", entityStates, Array.Empty()); - var appCode = @" + var generatedCode = Generator.CreateCompilationUnitSyntax("RootNameSpace", entityStates, Array.Empty()); + var appCode = @" using NetDaemon.HassModel.Entities; -using NetDaemon.HassModel.Common; +using NetDaemon.HassModel; using RootNameSpace; public class Root @@ -53,39 +53,39 @@ public void Run(IHaContext ha) SwitchEntity switch2 = entities.Switch.Switch2; } }"; - AssertCodeCompiles(generatedCode.ToString(), appCode); - } + AssertCodeCompiles(generatedCode.ToString(), appCode); + } - [Fact] - public void TestNumericSensorEntityGeneration() + [Fact] + public void TestNumericSensorEntityGeneration() + { + // Numeric entities should be generated for input_numbers and sensors with a unit_of_measurement attribute + var entityStates = new HassState[] { - // Numeric entities should be generated for input_numbers and sensors with a unit_of_measurement attribute - var entityStates = new HassState[] + new() { + EntityId = "number.living_bass", + AttributesJson = new { unit_of_measurement = "%", }.AsJsonElement() + }, + new() { - new() { - EntityId = "number.living_bass", - AttributesJson = new { unit_of_measurement = "%", }.AsJsonElement() - }, - new() - { - EntityId = "input_number.target_temperature", - AttributesJson = new { unit_of_measurement = "Kwh", }.AsJsonElement() - }, - new() - { - EntityId = "sensor.daily_power_consumption", - AttributesJson = new { unit_of_measurement = "Kwh", }.AsJsonElement() - }, - new() - { - EntityId = "sensor.Pir", - }, - }; + EntityId = "input_number.target_temperature", + AttributesJson = new { unit_of_measurement = "Kwh", }.AsJsonElement() + }, + new() + { + EntityId = "sensor.daily_power_consumption", + AttributesJson = new { unit_of_measurement = "Kwh", }.AsJsonElement() + }, + new() + { + EntityId = "sensor.Pir", + }, + }; - var generatedCode = Generator.CreateCompilationUnitSyntax("RootNameSpace", entityStates, Array.Empty()); - var appCode = @" + var generatedCode = Generator.CreateCompilationUnitSyntax("RootNameSpace", entityStates, Array.Empty()); + var appCode = @" using NetDaemon.HassModel.Entities; -using NetDaemon.HassModel.Common; +using NetDaemon.HassModel; using RootNameSpace; public class Root @@ -106,47 +106,47 @@ public void Run(IHaContext ha) string? pir = pirSensor.State; } }"; - AssertCodeCompiles(generatedCode.ToString(), appCode); - } + AssertCodeCompiles(generatedCode.ToString(), appCode); + } - [Fact] - public void TestNumberExtensionMethodGeneration() - { - var entityStates = new HassState[] { - new() { - EntityId = "number.living_bass", - AttributesJson = new { unit_of_measurement = "%", }.AsJsonElement() - }, - new() { - EntityId = "unknown.number", - AttributesJson = new { unit_of_measurement = "pcs", }.AsJsonElement() - }, - new() { - EntityId = "unknown.string", - }, - }; + [Fact] + public void TestNumberExtensionMethodGeneration() + { + var entityStates = new HassState[] { + new() { + EntityId = "number.living_bass", + AttributesJson = new { unit_of_measurement = "%", }.AsJsonElement() + }, + new() { + EntityId = "unknown.number", + AttributesJson = new { unit_of_measurement = "pcs", }.AsJsonElement() + }, + new() { + EntityId = "unknown.string", + }, + }; - var hassServiceDomains = new HassServiceDomain[] { - new() { - Domain = "number", - Services = new HassService[] { - new() { - Service = "set_value", - Target = new TargetSelector { - Entity = new() { Domain = "number" } - }, - Fields = new HassServiceField[] { - new() { Field = "value", Selector = new NumberSelector(), }, - }, - } + var hassServiceDomains = new HassServiceDomain[] { + new() { + Domain = "number", + Services = new HassService[] { + new() { + Service = "set_value", + Target = new TargetSelector { + Entity = new() { Domain = "number" } + }, + Fields = new HassServiceField[] { + new() { Field = "value", Selector = new NumberSelector(), }, + }, } } - }; + } + }; - var generatedCode = Generator.CreateCompilationUnitSyntax("RootNameSpace", entityStates, hassServiceDomains); - var appCode = @" + var generatedCode = Generator.CreateCompilationUnitSyntax("RootNameSpace", entityStates, hassServiceDomains); + var appCode = @" using NetDaemon.HassModel.Entities; -using NetDaemon.HassModel.Common; +using NetDaemon.HassModel; using RootNameSpace; public class Root @@ -158,37 +158,37 @@ public void Run(IHaContext ha) entities.Number.LivingBass.SetValue(12); } }"; - AssertCodeCompiles(generatedCode.ToString(), appCode); - } + AssertCodeCompiles(generatedCode.ToString(), appCode); + } - [Fact] - public void TestAttributeClassGeneration() + [Fact] + public void TestAttributeClassGeneration() + { + var entityStates = new HassState[] { - var entityStates = new HassState[] + new() { - new() + EntityId = "light.light1", + AttributesJson = new { - EntityId = "light.light1", - AttributesJson = new - { - brightness = 255L, - friendly_name = "attic", - FriendlyName = "attic", - start_date = new DateTime(2010, 12, 23, 23, 12, 00), - not_used = (string?)null, - trueValue = true, - falseValue = false, - dict = new {}, - arr = new []{"red", "blue"} - }.AsJsonElement() - }, - }; + brightness = 255L, + friendly_name = "attic", + FriendlyName = "attic", + start_date = new DateTime(2010, 12, 23, 23, 12, 00), + not_used = (string?)null, + trueValue = true, + falseValue = false, + dict = new {}, + arr = new []{"red", "blue"} + }.AsJsonElement() + }, + }; - var generatedCode = Generator.GenerateCode("RootNameSpace", entityStates, Array.Empty()); + var generatedCode = Generator.GenerateCode("RootNameSpace", entityStates, Array.Empty()); - var appCode = @" + var appCode = @" using NetDaemon.HassModel.Entities; -using NetDaemon.HassModel.Common; +using NetDaemon.HassModel; using RootNameSpace; public class Root @@ -204,48 +204,48 @@ public void Run(IHaContext ha) string? startDate = light1.Attributes?.StartDate; } }"; - AssertCodeCompiles(generatedCode, appCode); - } + AssertCodeCompiles(generatedCode, appCode); + } - [Fact] - public void TestServicesGeneration() + [Fact] + public void TestServicesGeneration() + { + var readOnlyCollection = new HassState[] { - var readOnlyCollection = new HassState[] - { - new() { EntityId = "light.light1" }, - }; + new() { EntityId = "light.light1" }, + }; - var hassServiceDomains = new HassServiceDomain[] + var hassServiceDomains = new HassServiceDomain[] + { + new() { - new() - { - Domain = "light", - Services = new HassService[] { - new() { - Service = "turn_off", - Target = new TargetSelector { Entity = new() { Domain = "light" } } + Domain = "light", + Services = new HassService[] { + new() { + Service = "turn_off", + Target = new TargetSelector { Entity = new() { Domain = "light" } } + }, + new() { + Service = "turn_on", + Fields = new HassServiceField[] { + new() { Field = "transition", Selector = new NumberSelector(), }, + new() { Field = "brightness", Selector = new NumberSelector { Step = 0.2f }, } }, - new() { - Service = "turn_on", - Fields = new HassServiceField[] { - new() { Field = "transition", Selector = new NumberSelector(), }, - new() { Field = "brightness", Selector = new NumberSelector { Step = 0.2f }, } - }, - Target = new TargetSelector { Entity = new() { Domain = "light" } } - } + Target = new TargetSelector { Entity = new() { Domain = "light" } } } } - }; + } + }; - // Act: - var code = Generator.CreateCompilationUnitSyntax("RootNameSpace", readOnlyCollection, hassServiceDomains); - // uncomment for debugging - // File.WriteAllText(@"c:\temp\generated.cs", code.ToString()); + // Act: + var code = Generator.CreateCompilationUnitSyntax("RootNameSpace", readOnlyCollection, hassServiceDomains); + // uncomment for debugging + // File.WriteAllText(@"c:\temp\generated.cs", code.ToString()); - // Assert: + // Assert: - var appCode = @" -using NetDaemon.HassModel.Common; + var appCode = @" +using NetDaemon.HassModel; using NetDaemon.HassModel.Entities; using RootNameSpace; @@ -270,30 +270,29 @@ public void Run(IHaContext ha) light.TurnOff(); } }"; - AssertCodeCompiles(code.ToString(), appCode); - } + AssertCodeCompiles(code.ToString(), appCode); + } - private void AssertCodeCompiles(string generated, string appCode) + private void AssertCodeCompiles(string generated, string appCode) + { + var syntaxtrees = new [] { - var syntaxtrees = new [] - { - SyntaxFactory.ParseSyntaxTree(generated, path: "generated.cs"), - SyntaxFactory.ParseSyntaxTree(appCode, path: "appcode.cs") + SyntaxFactory.ParseSyntaxTree(generated, path: "generated.cs"), + SyntaxFactory.ParseSyntaxTree(appCode, path: "appcode.cs") - }; + }; - var compilation = CSharpCompilation.Create("tempAssembly", - syntaxtrees, - AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic).Select(a => MetadataReference.CreateFromFile(a.Location)).ToArray(), - new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, nullableContextOptions: NullableContextOptions.Enable) - ); + var compilation = CSharpCompilation.Create("tempAssembly", + syntaxtrees, + AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic).Select(a => MetadataReference.CreateFromFile(a.Location)).ToArray(), + new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, nullableContextOptions: NullableContextOptions.Enable) + ); - var emitResult = compilation.Emit(Stream.Null); + var emitResult = compilation.Emit(Stream.Null); - emitResult.Diagnostics - .Where(d => d.Severity is DiagnosticSeverity.Error or DiagnosticSeverity.Warning) - .Should().BeEmpty(); + emitResult.Diagnostics + .Where(d => d.Severity is DiagnosticSeverity.Error or DiagnosticSeverity.Warning) + .Should().BeEmpty(); - } } } \ No newline at end of file diff --git a/src/HassModel/NetDaemon.HassModel.Tests/Common/ServiceTargetTest.cs b/src/HassModel/NetDaemon.HassModel.Tests/Common/ServiceTargetTest.cs deleted file mode 100644 index a9466bcde..000000000 --- a/src/HassModel/NetDaemon.HassModel.Tests/Common/ServiceTargetTest.cs +++ /dev/null @@ -1,33 +0,0 @@ -using FluentAssertions; -using NetDaemon.HassModel.Entities; -using Xunit; - -namespace NetDaemon.HassModel.Tests.Common -{ - public class ServiceTargetTest - { - [Fact] - public void ServiceTargetShouldContainCorrectEntity() - { - var serviceTarget = ServiceTarget.FromEntity("light.kitchen"); - - serviceTarget.EntityIds.Should().BeEquivalentTo("light.kitchen"); - } - - [Fact] - public void ServiceTargetShouldContainCorrectEntities() - { - var serviceTarget = ServiceTarget.FromEntities(new[] { "light.kitchen", "light.livingroom" }); - - serviceTarget.EntityIds.Should().BeEquivalentTo("light.kitchen", "light.livingroom"); - } - - [Fact] - public void ServiceTargetShouldContainCorrectEntitiesUsingParams() - { - var serviceTarget = ServiceTarget.FromEntities("light.kitchen", "light.livingroom"); - - serviceTarget.EntityIds.Should().BeEquivalentTo("light.kitchen", "light.livingroom"); - } - } -} \ No newline at end of file diff --git a/src/HassModel/NetDaemon.HassModel.Tests/Entities/EntityExtensionsTest.cs b/src/HassModel/NetDaemon.HassModel.Tests/Entities/EntityExtensionsTest.cs index 13cade65a..0257482d7 100644 --- a/src/HassModel/NetDaemon.HassModel.Tests/Entities/EntityExtensionsTest.cs +++ b/src/HassModel/NetDaemon.HassModel.Tests/Entities/EntityExtensionsTest.cs @@ -1,47 +1,45 @@ using FluentAssertions; using Moq; -using NetDaemon.HassModel.Common; using NetDaemon.HassModel.Entities; using Xunit; -namespace NetDaemon.HassModel.Tests.Entities +namespace NetDaemon.HassModel.Tests.Entities; + +public class EntityExtensionsTest { - public class EntityExtensionsTest + [Theory] + [InlineData("on", true)] + [InlineData("ON", true)] + [InlineData("off", false)] + [InlineData("blabla", false)] + [InlineData("unavaliable", false)] + [InlineData(null, false)] + public void IsOntest(string? state, bool isOn) { - [Theory] - [InlineData("on", true)] - [InlineData("ON", true)] - [InlineData("off", false)] - [InlineData("blabla", false)] - [InlineData("unavaliable", false)] - [InlineData(null, false)] - public void IsOntest(string? state, bool isOn) - { - GetEntityWitState(state).IsOn().Should().Be(isOn); - GetEntityWitState(state).EntityState.IsOn().Should().Be(isOn); - } + GetEntityWitState(state).IsOn().Should().Be(isOn); + GetEntityWitState(state).EntityState.IsOn().Should().Be(isOn); + } - [Theory] - [InlineData("off", true)] - [InlineData("OFF", true)] - [InlineData("on", false)] - [InlineData("blabla", false)] - [InlineData("unavaliable", false)] - [InlineData(null, false)] - public void IsOftest(string? state, bool isOn) - { - GetEntityWitState(state).IsOff().Should().Be(isOn); - GetEntityWitState(state).EntityState.IsOff().Should().Be(isOn); - } + [Theory] + [InlineData("off", true)] + [InlineData("OFF", true)] + [InlineData("on", false)] + [InlineData("blabla", false)] + [InlineData("unavaliable", false)] + [InlineData(null, false)] + public void IsOftest(string? state, bool isOn) + { + GetEntityWitState(state).IsOff().Should().Be(isOn); + GetEntityWitState(state).EntityState.IsOff().Should().Be(isOn); + } - private Entity GetEntityWitState(string? state) - { - var haContextMock = new Mock(); + private Entity GetEntityWitState(string? state) + { + var haContextMock = new Mock(); - var entityState = new EntityState { State = state }; + var entityState = new EntityState { State = state }; - haContextMock.Setup(t => t.GetState("domain.testEntity")).Returns(entityState); - return new Entity(haContextMock.Object, "domain.testEntity"); - } + haContextMock.Setup(t => t.GetState("domain.testEntity")).Returns(entityState); + return new Entity(haContextMock.Object, "domain.testEntity"); } } \ No newline at end of file diff --git a/src/HassModel/NetDaemon.HassModel.Tests/Entities/EntityTest.cs b/src/HassModel/NetDaemon.HassModel.Tests/Entities/EntityTest.cs index c1dc0f7b8..4899dc253 100644 --- a/src/HassModel/NetDaemon.HassModel.Tests/Entities/EntityTest.cs +++ b/src/HassModel/NetDaemon.HassModel.Tests/Entities/EntityTest.cs @@ -2,111 +2,109 @@ using System.Linq; using System.Reactive.Subjects; using Moq; -using NetDaemon.HassModel.Common; using NetDaemon.HassModel.Entities; using FluentAssertions; using NetDaemon.HassModel.Tests.TestHelpers; using NetDaemon.HassModel.Tests.TestHelpers.HassClient; using Xunit; -namespace NetDaemon.HassModel.Tests.Entities +namespace NetDaemon.HassModel.Tests.Entities; + +public class EntityTest { - public class EntityTest + [Fact] + public void ShouldWrapStateFromHaContext() { - [Fact] - public void ShouldWrapStateFromHaContext() - { - // Arrange - var haContextMock = new Mock(); - - var entityState = - new EntityState() - { - State = "CurrentState", - AttributesJson = new { name = "FirstName" }.AsJsonElement() - }; - - haContextMock.Setup(t => t.GetState("domain.testEntity")).Returns(entityState); - - // Act - var target = new TestEntity(haContextMock.Object, "domain.testEntity"); - - // Assert - target.State.Should().Be("CurrentState"); - target.Attributes!.Name.Should().Be("FirstName"); - - target.EntityState!.State.Should().Be("CurrentState"); - target.EntityState!.Attributes!.Name.Should().Be("FirstName"); - - // Act2: update the state - var newEntityState = - new EntityState() - { - State = "NewState", - AttributesJson = new { name = "SecondName" }.AsJsonElement() - }; - - haContextMock.Setup(t => t.GetState("domain.testEntity")).Returns(newEntityState); - - // Assert - target.State.Should().Be("NewState"); - target.Attributes!.Name.Should().Be("SecondName"); - - target.EntityState!.State.Should().Be("NewState"); - target.EntityState!.Attributes!.Name.Should().Be("SecondName"); - } - - [Fact] - public void ShouldShowStateChangesFromContext() - { - var stateChangesSubject = new Subject(); - var haContextMock = new Mock(); - haContextMock.Setup(h => h.StateAllChanges()).Returns(stateChangesSubject); - - var target = new TestEntity(haContextMock.Object, "domain.testEntity"); - var stateChangeObserverMock = new Mock>(); - var stateAllChangeObserverMock = new Mock>(); - - target.StateAllChanges().Subscribe(stateAllChangeObserverMock.Object); - target.StateChanges().Subscribe(stateChangeObserverMock.Object); - - stateChangesSubject.OnNext( - new StateChange(target, new EntityState { State = "old" }, - new EntityState { State = "new" })); - - stateChangesSubject.OnNext( - new StateChange(target, new EntityState() { State = "same" }, - new EntityState { State = "same" })); - - stateChangeObserverMock.Verify(o => o.OnNext(It.IsAny()), Times.Once); - stateAllChangeObserverMock.Verify(o => o.OnNext(It.IsAny()), Times.Exactly(2)); - } - - [Fact] - public void ShouldCallServiceOnContext() - { - var haContextMock = new Mock(); - - var entity = new TestEntity(haContextMock.Object, "domain.testEntity"); - var data = "payload"; - - entity.CallService("service", data); - - haContextMock.Verify(h => h.CallService("domain", "service", It.Is(t => t.EntityIds!.Single() == entity.EntityId), data), Times.Once); - } - - [Fact] - public void ShouldWrapAreaFromContext() - { - // Arrange - var haContextMock = new Mock(); - haContextMock.Setup(t => t.GetAreaFromEntityId("domain.testEntity")).Returns(new Area() { Name = "Area Name" }); - - // Act - var target = new TestEntity(haContextMock.Object, "domain.testEntity"); - - // Assert - Assert.Equal("Area Name", target.Area); - } + // Arrange + var haContextMock = new Mock(); + + var entityState = + new EntityState() + { + State = "CurrentState", + AttributesJson = new { name = "FirstName" }.AsJsonElement() + }; + + haContextMock.Setup(t => t.GetState("domain.testEntity")).Returns(entityState); + + // Act + var target = new TestEntity(haContextMock.Object, "domain.testEntity"); + + // Assert + target.State.Should().Be("CurrentState"); + target.Attributes!.Name.Should().Be("FirstName"); + + target.EntityState!.State.Should().Be("CurrentState"); + target.EntityState!.Attributes!.Name.Should().Be("FirstName"); + + // Act2: update the state + var newEntityState = + new EntityState() + { + State = "NewState", + AttributesJson = new { name = "SecondName" }.AsJsonElement() + }; + + haContextMock.Setup(t => t.GetState("domain.testEntity")).Returns(newEntityState); + + // Assert + target.State.Should().Be("NewState"); + target.Attributes!.Name.Should().Be("SecondName"); + + target.EntityState!.State.Should().Be("NewState"); + target.EntityState!.Attributes!.Name.Should().Be("SecondName"); + } + + [Fact] + public void ShouldShowStateChangesFromContext() + { + var stateChangesSubject = new Subject(); + var haContextMock = new Mock(); + haContextMock.Setup(h => h.StateAllChanges()).Returns(stateChangesSubject); + + var target = new TestEntity(haContextMock.Object, "domain.testEntity"); + var stateChangeObserverMock = new Mock>(); + var stateAllChangeObserverMock = new Mock>(); + + target.StateAllChanges().Subscribe(stateAllChangeObserverMock.Object); + target.StateChanges().Subscribe(stateChangeObserverMock.Object); + + stateChangesSubject.OnNext( + new StateChange(target, new EntityState { State = "old" }, + new EntityState { State = "new" })); + + stateChangesSubject.OnNext( + new StateChange(target, new EntityState() { State = "same" }, + new EntityState { State = "same" })); + + stateChangeObserverMock.Verify(o => o.OnNext(It.IsAny()), Times.Once); + stateAllChangeObserverMock.Verify(o => o.OnNext(It.IsAny()), Times.Exactly(2)); + } + + [Fact] + public void ShouldCallServiceOnContext() + { + var haContextMock = new Mock(); + + var entity = new TestEntity(haContextMock.Object, "domain.testEntity"); + var data = "payload"; + + entity.CallService("service", data); + + haContextMock.Verify(h => h.CallService("domain", "service", It.Is(t => t.EntityIds!.Single() == entity.EntityId), data), Times.Once); + } + + [Fact] + public void ShouldWrapAreaFromContext() + { + // Arrange + var haContextMock = new Mock(); + haContextMock.Setup(t => t.GetAreaFromEntityId("domain.testEntity")).Returns(new Area() { Name = "Area Name" }); + + // Act + var target = new TestEntity(haContextMock.Object, "domain.testEntity"); + + // Assert + Assert.Equal("Area Name", target.Area); } } \ No newline at end of file diff --git a/src/HassModel/NetDaemon.HassModel.Tests/Entities/EnumerableEntityExtensionsTest.cs b/src/HassModel/NetDaemon.HassModel.Tests/Entities/EnumerableEntityExtensionsTest.cs index 6320c287d..aa00083e4 100644 --- a/src/HassModel/NetDaemon.HassModel.Tests/Entities/EnumerableEntityExtensionsTest.cs +++ b/src/HassModel/NetDaemon.HassModel.Tests/Entities/EnumerableEntityExtensionsTest.cs @@ -4,89 +4,87 @@ using System.Reactive.Subjects; using FluentAssertions; using Moq; -using NetDaemon.HassModel.Common; using NetDaemon.HassModel.Entities; using NetDaemon.HassModel.Tests.TestHelpers; using NetDaemon.HassModel.Tests.TestHelpers.HassClient; using Xunit; -namespace NetDaemon.HassModel.Tests.Entities +namespace NetDaemon.HassModel.Tests.Entities; + +public class EnumerableEntityExtensionsTest { - public class EnumerableEntityExtensionsTest + [Fact] + public void TestStateChanges() { - [Fact] - public void TestStateChanges() - { - var observerMock = new Mock>(); + var observerMock = new Mock>(); - Subject stateChangesSubject = new(); - var haMock = new Mock(); - haMock.Setup(h => h.StateAllChanges()).Returns(stateChangesSubject); + Subject stateChangesSubject = new(); + var haMock = new Mock(); + haMock.Setup(h => h.StateAllChanges()).Returns(stateChangesSubject); - var switch1 = new Entity(haMock.Object, "switch.Living1"); - var switch2 = new Entity(haMock.Object, "switch.Living2"); + var switch1 = new Entity(haMock.Object, "switch.Living1"); + var switch2 = new Entity(haMock.Object, "switch.Living2"); - // Act: Subscribe to both entities - using var _ = new[] { switch1, switch2 }.StateChanges().Subscribe(observerMock.Object); + // Act: Subscribe to both entities + using var _ = new[] { switch1, switch2 }.StateChanges().Subscribe(observerMock.Object); - stateChangesSubject.OnNext(new StateChange(switch1, new EntityState { State = "OldState1" }, new EntityState { State = "NewState1" })); + stateChangesSubject.OnNext(new StateChange(switch1, new EntityState { State = "OldState1" }, new EntityState { State = "NewState1" })); - observerMock.Verify(m => m.OnNext(It.Is(s => s.Entity == switch1 && s.New!.State == "NewState1")), Times.Once); - observerMock.VerifyNoOtherCalls(); + observerMock.Verify(m => m.OnNext(It.Is(s => s.Entity == switch1 && s.New!.State == "NewState1")), Times.Once); + observerMock.VerifyNoOtherCalls(); - stateChangesSubject.OnNext(new StateChange(switch2, new EntityState { State = "OldState2" }, new EntityState { State = "NewState2" })); + stateChangesSubject.OnNext(new StateChange(switch2, new EntityState { State = "OldState2" }, new EntityState { State = "NewState2" })); - observerMock.Verify(m => m.OnNext(It.Is(s => s.Entity == switch2 && s.New!.State == "NewState2")), Times.Once); - observerMock.VerifyNoOtherCalls(); - } + observerMock.Verify(m => m.OnNext(It.Is(s => s.Entity == switch2 && s.New!.State == "NewState2")), Times.Once); + observerMock.VerifyNoOtherCalls(); + } - [Fact] - public void TestTypedStateChanges() - { - var observerMock = new Mock>(); + [Fact] + public void TestTypedStateChanges() + { + var observerMock = new Mock>(); - Subject stateChangesSubject = new(); - var haMock = new Mock(); - haMock.Setup(h => h.StateAllChanges()).Returns(stateChangesSubject); + Subject stateChangesSubject = new(); + var haMock = new Mock(); + haMock.Setup(h => h.StateAllChanges()).Returns(stateChangesSubject); - var switch1 = new TestEntity(haMock.Object, "switch.Living1"); - var switch2 = new TestEntity(haMock.Object, "switch.Living2"); + var switch1 = new TestEntity(haMock.Object, "switch.Living1"); + var switch2 = new TestEntity(haMock.Object, "switch.Living2"); - // Act: Subscribe to both entities, filter on attribute - using var _ = new[] { switch1, switch2 }.StateAllChanges().Where(e => e.New?.Attributes?.Name == "Do").Subscribe(observerMock.Object); + // Act: Subscribe to both entities, filter on attribute + using var _ = new[] { switch1, switch2 }.StateAllChanges().Where(e => e.New?.Attributes?.Name == "Do").Subscribe(observerMock.Object); - stateChangesSubject.OnNext(new StateChange(switch1, - new EntityState { State = "State", AttributesJson = new { name = "John" }.AsJsonElement() }, - new EntityState { State = "State", AttributesJson = new { name = "Do" }.AsJsonElement() } - )); + stateChangesSubject.OnNext(new StateChange(switch1, + new EntityState { State = "State", AttributesJson = new { name = "John" }.AsJsonElement() }, + new EntityState { State = "State", AttributesJson = new { name = "Do" }.AsJsonElement() } + )); - observerMock.Verify(m => m.OnNext(It.Is(s => s.Entity == switch1 && s.New!.State == "State")), Times.Once); - observerMock.VerifyNoOtherCalls(); + observerMock.Verify(m => m.OnNext(It.Is(s => s.Entity == switch1 && s.New!.State == "State")), Times.Once); + observerMock.VerifyNoOtherCalls(); - stateChangesSubject.OnNext(new StateChange(switch2, new EntityState { State = "OldState2" }, new EntityState { State = "NewState2" })); + stateChangesSubject.OnNext(new StateChange(switch2, new EntityState { State = "OldState2" }, new EntityState { State = "NewState2" })); - observerMock.Verify(m => m.OnNext(It.IsAny()), Times.Once); - } + observerMock.Verify(m => m.OnNext(It.IsAny()), Times.Once); + } - [Fact] - public void TestCallService() - { - Subject stateChangesSubject = new(); - var haMock = new Mock(); - haMock.Setup(h => h.StateAllChanges()).Returns(stateChangesSubject); + [Fact] + public void TestCallService() + { + Subject stateChangesSubject = new(); + var haMock = new Mock(); + haMock.Setup(h => h.StateAllChanges()).Returns(stateChangesSubject); - var switch1 = new Entity(haMock.Object, "switch.Living1"); - var switch2 = new Entity(haMock.Object, "switch.Living2"); + var switch1 = new Entity(haMock.Object, "switch.Living1"); + var switch2 = new Entity(haMock.Object, "switch.Living2"); - // Act: Subscribe to both entities - var data = new { Name = "John", Age = 12 }; - new[] { switch1, switch2 }.CallService("switch", "set_state", data); + // Act: Subscribe to both entities + var data = new { Name = "John", Age = 12 }; + new[] { switch1, switch2 }.CallService("switch", "set_state", data); - haMock.Verify(m => m.CallService("switch", "set_state", It.IsAny(), data)); + haMock.Verify(m => m.CallService("switch", "set_state", It.IsAny(), data)); - haMock.Invocations.First().Arguments[2].As().EntityIds - .Should().BeEquivalentTo("switch.Living1", "switch.Living2"); - } + haMock.Invocations.First().Arguments[2].As().EntityIds + .Should().BeEquivalentTo("switch.Living1", "switch.Living2"); } } \ No newline at end of file diff --git a/src/HassModel/NetDaemon.HassModel.Tests/Entities/NumericEntityTest.cs b/src/HassModel/NetDaemon.HassModel.Tests/Entities/NumericEntityTest.cs index c4d0b4811..7ffbe92c7 100644 --- a/src/HassModel/NetDaemon.HassModel.Tests/Entities/NumericEntityTest.cs +++ b/src/HassModel/NetDaemon.HassModel.Tests/Entities/NumericEntityTest.cs @@ -10,196 +10,195 @@ using NetDaemon.HassModel.Tests.TestHelpers.HassClient; using Xunit; -namespace NetDaemon.HassModel.Tests.Entities +namespace NetDaemon.HassModel.Tests.Entities; + +public class NumericEntityTest { - public class NumericEntityTest + [Fact] + public void AsNumeric_Than_WithAttributesAs() + { + var entityId = "sensor.temperature"; + + var haContextMock = new HaContextMock(); + haContextMock.Setup(m => m.GetState(entityId)).Returns( + new EntityState + { + EntityId = entityId, + State = "12.3", + AttributesJson = JsonSerializer.Deserialize(@"{""setPoint"": 21.5, ""units"": ""Celcius""}") + }); + + var entity = new Entity(haContextMock.Object, entityId); + entity.State.Should().Be("12.3"); + + // Act: AsNumeric + var numericEntity = entity.AsNumeric(); + + // Assert + numericEntity.State!.Value!.Should().Be(12.3d); + numericEntity.EntityState!.State!.Value!.Should().Be(12.3d); + numericEntity.StateAllChanges().Where(e => e.New?.State > 1.2); + // Act: WithAttributesAs + var withAttributes = numericEntity.WithAttributesAs(); + + // Assert + withAttributes.State!.Value!.Should().Be(12.3d); + withAttributes.EntityState!.State!.Value!.Should().Be(12.3d); + + withAttributes.Attributes!.units.Should().Be("Celcius"); + withAttributes.Attributes!.setPoint.Should().Be(21.5); + withAttributes.EntityState!.Attributes!.units.Should().Be("Celcius"); + withAttributes.EntityState!.Attributes!.setPoint.Should().Be(21.5); + withAttributes.StateAllChanges().Where(e => e.New?.State > 1.2 && e.Entity != null); + + } + + [Fact] + public void WithAttributesAs_Than_AsNumeric() + { + var entityId = "sensor.temperature"; + + var haContextMock = new HaContextMock(); + haContextMock.Setup(m => m.GetState(entityId)).Returns( + new EntityState + { + EntityId = entityId, + State = "12.3", + AttributesJson = JsonSerializer.Deserialize(@"{""setPoint"": 21.5, ""units"": ""Celcius""}") + }); + + var entity = new Entity(haContextMock.Object, entityId); + + // Act: WithAttributesAs + Entity withAttributes = entity.WithAttributesAs(); + NumericEntity numericEntity = withAttributes.AsNumeric(); + + // Assert + withAttributes.State.Should().Be("12.3", because: "State is still a string"); + + withAttributes.Attributes!.units.Should().Be("Celcius"); + withAttributes.Attributes!.setPoint.Should().Be(21.5); + withAttributes.EntityState!.Attributes!.units.Should().Be("Celcius"); + withAttributes.EntityState!.Attributes!.setPoint.Should().Be(21.5); + + // Act: AsNumeric() + var numericWithAttributes = withAttributes.AsNumeric(); + + numericWithAttributes.State!.Value!.Should().Be(12.3d); + numericWithAttributes.EntityState!.State!.Value!.Should().Be(12.3d); + + numericWithAttributes.Attributes!.units.Should().Be("Celcius"); + numericWithAttributes.Attributes!.setPoint.Should().Be(21.5); + numericWithAttributes.EntityState!.Attributes!.units.Should().Be("Celcius"); + numericWithAttributes.EntityState!.Attributes!.setPoint.Should().Be(21.5); + + haContextMock.StateAllChangeSubject.OnNext(new StateChange(entity, new EntityState(), new EntityState())); + numericWithAttributes.StateAllChanges().Where(e => e.New?.State > 1.2 && e.Entity != null).Subscribe(); + + } + + record TestSensorAttributes(double setPoint, string units); + + [Fact] + public void ShouldShowStateChangesFromContext() { - [Fact] - public void AsNumeric_Than_WithAttributesAs() - { - var entityId = "sensor.temperature"; - - var haContextMock = new HaContextMock(); - haContextMock.Setup(m => m.GetState(entityId)).Returns( - new EntityState - { - EntityId = entityId, - State = "12.3", - AttributesJson = JsonSerializer.Deserialize(@"{""setPoint"": 21.5, ""units"": ""Celcius""}") - }); - - var entity = new Entity(haContextMock.Object, entityId); - entity.State.Should().Be("12.3"); - - // Act: AsNumeric - var numericEntity = entity.AsNumeric(); - - // Assert - numericEntity.State!.Value!.Should().Be(12.3d); - numericEntity.EntityState!.State!.Value!.Should().Be(12.3d); - numericEntity.StateAllChanges().Where(e => e.New?.State > 1.2); - // Act: WithAttributesAs - var withAttributes = numericEntity.WithAttributesAs(); - - // Assert - withAttributes.State!.Value!.Should().Be(12.3d); - withAttributes.EntityState!.State!.Value!.Should().Be(12.3d); - - withAttributes.Attributes!.units.Should().Be("Celcius"); - withAttributes.Attributes!.setPoint.Should().Be(21.5); - withAttributes.EntityState!.Attributes!.units.Should().Be("Celcius"); - withAttributes.EntityState!.Attributes!.setPoint.Should().Be(21.5); - withAttributes.StateAllChanges().Where(e => e.New?.State > 1.2 && e.Entity != null); - - } - - [Fact] - public void WithAttributesAs_Than_AsNumeric() - { - var entityId = "sensor.temperature"; - - var haContextMock = new HaContextMock(); - haContextMock.Setup(m => m.GetState(entityId)).Returns( - new EntityState - { - EntityId = entityId, - State = "12.3", - AttributesJson = JsonSerializer.Deserialize(@"{""setPoint"": 21.5, ""units"": ""Celcius""}") - }); - - var entity = new Entity(haContextMock.Object, entityId); - - // Act: WithAttributesAs - Entity withAttributes = entity.WithAttributesAs(); - NumericEntity numericEntity = withAttributes.AsNumeric(); - - // Assert - withAttributes.State.Should().Be("12.3", because: "State is still a string"); - - withAttributes.Attributes!.units.Should().Be("Celcius"); - withAttributes.Attributes!.setPoint.Should().Be(21.5); - withAttributes.EntityState!.Attributes!.units.Should().Be("Celcius"); - withAttributes.EntityState!.Attributes!.setPoint.Should().Be(21.5); - - // Act: AsNumeric() - var numericWithAttributes = withAttributes.AsNumeric(); - - numericWithAttributes.State!.Value!.Should().Be(12.3d); - numericWithAttributes.EntityState!.State!.Value!.Should().Be(12.3d); - - numericWithAttributes.Attributes!.units.Should().Be("Celcius"); - numericWithAttributes.Attributes!.setPoint.Should().Be(21.5); - numericWithAttributes.EntityState!.Attributes!.units.Should().Be("Celcius"); - numericWithAttributes.EntityState!.Attributes!.setPoint.Should().Be(21.5); - - haContextMock.StateAllChangeSubject.OnNext(new StateChange(entity, new EntityState(), new EntityState())); - numericWithAttributes.StateAllChanges().Where(e => e.New?.State > 1.2 && e.Entity != null).Subscribe(); - - } - - record TestSensorAttributes(double setPoint, string units); - - [Fact] - public void ShouldShowStateChangesFromContext() - { - var haContextMock = new HaContextMock(); - - var entity = new Entity(haContextMock.Object, "domain.testEntity"); - var target = new NumericEntity(entity); - - haContextMock.Setup(m => m.GetState(entity.EntityId)).Returns(new EntityState() { State = "3.14" }); - - var stateAllChangeObserverMock = target.StateAllChanges().SubscribeMock(); - var stateChangeObserverMock = target.StateChanges().SubscribeMock(); - - haContextMock.StateAllChangeSubject.OnNext(new StateChange(entity, - old: new EntityState { State = "1" }, - @new: new EntityState { State = "1" })); - - haContextMock.StateAllChangeSubject.OnNext(new StateChange(entity, - old: new EntityState { State = "1" }, - @new: new EntityState { State = "2" })); - - // Assert - stateChangeObserverMock.Verify(o => o.OnNext(It.Is - (e => e.Entity.State.Equals(3.14) && - e.Old!.State.Equals(1.0) && - e.New!.State.Equals(2.0))), Times.Once); - stateChangeObserverMock.VerifyNoOtherCalls(); - - stateAllChangeObserverMock.Verify(o => o.OnNext(It.Is - (e => e.Entity.State.Equals(3.14) && - e.Old!.State.Equals(1.0) && - e.New!.State.Equals(2.0))), Times.Once); - - stateAllChangeObserverMock.Verify(o => o.OnNext(It.Is - (e => e.Entity.State.Equals(3.14) && - e.Old!.State.Equals(1.0) && - e.New!.State.Equals(1.0))), Times.Once); - stateAllChangeObserverMock.VerifyNoOtherCalls(); - } - - [Fact] - public void GenericNumericEntityShouldShowStateChangesFromContext() - { - // Arrange - var haContextMock = new HaContextMock(); - - var entity = new Entity(haContextMock.Object, "domain.testEntity"); - var target = new NumericTestEntity(entity); - - var stateChangeObserverMock = target.StateChanges().SubscribeMock(); - var stateAllChangeObserverMock = target.StateAllChanges().SubscribeMock(); + var haContextMock = new HaContextMock(); + + var entity = new Entity(haContextMock.Object, "domain.testEntity"); + var target = new NumericEntity(entity); + + haContextMock.Setup(m => m.GetState(entity.EntityId)).Returns(new EntityState() { State = "3.14" }); + + var stateAllChangeObserverMock = target.StateAllChanges().SubscribeMock(); + var stateChangeObserverMock = target.StateChanges().SubscribeMock(); + + haContextMock.StateAllChangeSubject.OnNext(new StateChange(entity, + old: new EntityState { State = "1" }, + @new: new EntityState { State = "1" })); + + haContextMock.StateAllChangeSubject.OnNext(new StateChange(entity, + old: new EntityState { State = "1" }, + @new: new EntityState { State = "2" })); + + // Assert + stateChangeObserverMock.Verify(o => o.OnNext(It.Is + (e => e.Entity.State.Equals(3.14) && + e.Old!.State.Equals(1.0) && + e.New!.State.Equals(2.0))), Times.Once); + stateChangeObserverMock.VerifyNoOtherCalls(); + + stateAllChangeObserverMock.Verify(o => o.OnNext(It.Is + (e => e.Entity.State.Equals(3.14) && + e.Old!.State.Equals(1.0) && + e.New!.State.Equals(2.0))), Times.Once); + + stateAllChangeObserverMock.Verify(o => o.OnNext(It.Is + (e => e.Entity.State.Equals(3.14) && + e.Old!.State.Equals(1.0) && + e.New!.State.Equals(1.0))), Times.Once); + stateAllChangeObserverMock.VerifyNoOtherCalls(); + } + + [Fact] + public void GenericNumericEntityShouldShowStateChangesFromContext() + { + // Arrange + var haContextMock = new HaContextMock(); + + var entity = new Entity(haContextMock.Object, "domain.testEntity"); + var target = new NumericTestEntity(entity); + + var stateChangeObserverMock = target.StateChanges().SubscribeMock(); + var stateAllChangeObserverMock = target.StateAllChanges().SubscribeMock(); + + haContextMock.Setup(m => m.GetState(entity.EntityId)).Returns(new EntityState() { State = "3.14" }); + + // Act + haContextMock.StateAllChangeSubject.OnNext(new StateChange(entity, + old: new EntityState { State = "1" }, + @new: new EntityState { State = "1" })); + + haContextMock.StateAllChangeSubject.OnNext(new StateChange(entity, + old: new EntityState { State = "1" }, + @new: new EntityState { State = "2" })); + + // Assert + stateChangeObserverMock.Verify(o => o.OnNext(It.Is>> + (e => e.Entity.State.Equals(3.14) && + e.Old!.State.Equals(1.0) && + e.New!.State.Equals(2.0))), Times.Once); + stateChangeObserverMock.VerifyNoOtherCalls(); + + stateAllChangeObserverMock.Verify(o => o.OnNext(It.Is>> + (e => e.Entity.State.Equals(3.14) && + e.Old!.State.Equals(1.0) && + e.New!.State.Equals(2.0))), Times.Once); + + stateAllChangeObserverMock.Verify(o => o.OnNext(It.Is>> + (e => e.Entity.State.Equals(3.14) && + e.Old!.State.Equals(1.0) && + e.New!.State.Equals(1.0))), Times.Once); + stateAllChangeObserverMock.VerifyNoOtherCalls(); + } + + [Fact] + public void StatePropertyShouldBeCultureUnaware() + { + Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("De-de"); + + var entityId = "sensor.temperature"; - haContextMock.Setup(m => m.GetState(entity.EntityId)).Returns(new EntityState() { State = "3.14" }); - - // Act - haContextMock.StateAllChangeSubject.OnNext(new StateChange(entity, - old: new EntityState { State = "1" }, - @new: new EntityState { State = "1" })); - - haContextMock.StateAllChangeSubject.OnNext(new StateChange(entity, - old: new EntityState { State = "1" }, - @new: new EntityState { State = "2" })); - - // Assert - stateChangeObserverMock.Verify(o => o.OnNext(It.Is>> - (e => e.Entity.State.Equals(3.14) && - e.Old!.State.Equals(1.0) && - e.New!.State.Equals(2.0))), Times.Once); - stateChangeObserverMock.VerifyNoOtherCalls(); + var haContextMock = new HaContextMock(); + haContextMock.Setup(m => m.GetState(entityId)).Returns(new EntityState { EntityId = entityId, State = "12.5" }); - stateAllChangeObserverMock.Verify(o => o.OnNext(It.Is>> - (e => e.Entity.State.Equals(3.14) && - e.Old!.State.Equals(1.0) && - e.New!.State.Equals(2.0))), Times.Once); - - stateAllChangeObserverMock.Verify(o => o.OnNext(It.Is>> - (e => e.Entity.State.Equals(3.14) && - e.Old!.State.Equals(1.0) && - e.New!.State.Equals(1.0))), Times.Once); - stateAllChangeObserverMock.VerifyNoOtherCalls(); - } + var entity = new Entity(haContextMock.Object, entityId); - [Fact] - public void StatePropertyShouldBeCultureUnaware() - { - Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("De-de"); - - var entityId = "sensor.temperature"; - - var haContextMock = new HaContextMock(); - haContextMock.Setup(m => m.GetState(entityId)).Returns(new EntityState { EntityId = entityId, State = "12.5" }); + var numericEntity = entity.AsNumeric(); + numericEntity.State.Should().Be(12.5); + numericEntity.EntityState!.State.Should().Be(12.5); - var entity = new Entity(haContextMock.Object, entityId); - - var numericEntity = entity.AsNumeric(); - numericEntity.State.Should().Be(12.5); - numericEntity.EntityState!.State.Should().Be(12.5); - - var withAttributesAs = numericEntity.WithAttributesAs(); - withAttributesAs.State.Should().Be(12.5); - withAttributesAs.EntityState!.State.Should().Be(12.5); - } + var withAttributesAs = numericEntity.WithAttributesAs(); + withAttributesAs.State.Should().Be(12.5); + withAttributesAs.EntityState!.State.Should().Be(12.5); } } \ No newline at end of file diff --git a/src/HassModel/NetDaemon.HassModel.Tests/Integration/IntegrationHaContextExtensionsTests.cs b/src/HassModel/NetDaemon.HassModel.Tests/Integration/IntegrationHaContextExtensionsTests.cs index 23de61e0f..ad06678d7 100644 --- a/src/HassModel/NetDaemon.HassModel.Tests/Integration/IntegrationHaContextExtensionsTests.cs +++ b/src/HassModel/NetDaemon.HassModel.Tests/Integration/IntegrationHaContextExtensionsTests.cs @@ -1,6 +1,5 @@ using System; using Moq; -using NetDaemon.HassModel.Common; using NetDaemon.HassModel.Entities; using NetDaemon.HassModel.Integration; using NetDaemon.HassModel.Tests.TestHelpers; diff --git a/src/HassModel/NetDaemon.HassModel.Tests/Internal/AppScopedHaContextProviderTest.cs b/src/HassModel/NetDaemon.HassModel.Tests/Internal/AppScopedHaContextProviderTest.cs index 9dfa7efa8..4c8454060 100644 --- a/src/HassModel/NetDaemon.HassModel.Tests/Internal/AppScopedHaContextProviderTest.cs +++ b/src/HassModel/NetDaemon.HassModel.Tests/Internal/AppScopedHaContextProviderTest.cs @@ -7,10 +7,9 @@ using FluentAssertions; using Microsoft.Extensions.DependencyInjection; using Moq; -using NetDaemon.Client.Common; -using NetDaemon.Client.Common.HomeAssistant.Model; +using NetDaemon.Client; +using NetDaemon.Client.HomeAssistant.Model; using NetDaemon.Client.Internal.HomeAssistant.Commands; -using NetDaemon.HassModel.Common; using NetDaemon.HassModel.Entities; using NetDaemon.HassModel.Tests.TestHelpers; using Xunit; diff --git a/src/HassModel/NetDaemon.HassModel.Tests/Internal/EntityAreaCachTests.cs b/src/HassModel/NetDaemon.HassModel.Tests/Internal/EntityAreaCachTests.cs index 1e9e204ba..0425ac66f 100644 --- a/src/HassModel/NetDaemon.HassModel.Tests/Internal/EntityAreaCachTests.cs +++ b/src/HassModel/NetDaemon.HassModel.Tests/Internal/EntityAreaCachTests.cs @@ -7,8 +7,8 @@ using Moq; using Xunit; -using NetDaemon.Client.Common; -using NetDaemon.Client.Common.HomeAssistant.Model; +using NetDaemon.Client; +using NetDaemon.Client.HomeAssistant.Model; using NetDaemon.Client.Internal.HomeAssistant.Commands; using NetDaemon.HassModel.Internal; diff --git a/src/HassModel/NetDaemon.HassModel.Tests/Internal/EntityStateCacheTest.cs b/src/HassModel/NetDaemon.HassModel.Tests/Internal/EntityStateCacheTest.cs index 55d21f8c1..bc0b4cb18 100644 --- a/src/HassModel/NetDaemon.HassModel.Tests/Internal/EntityStateCacheTest.cs +++ b/src/HassModel/NetDaemon.HassModel.Tests/Internal/EntityStateCacheTest.cs @@ -6,8 +6,8 @@ using Moq; using Xunit; -using NetDaemon.Client.Common; -using NetDaemon.Client.Common.HomeAssistant.Model; +using NetDaemon.Client; +using NetDaemon.Client.HomeAssistant.Model; using NetDaemon.Client.Internal.HomeAssistant.Commands; using NetDaemon.HassModel.Tests.TestHelpers; using Microsoft.Extensions.DependencyInjection; diff --git a/src/HassModel/NetDaemon.HassModel.Tests/Internal/QueuedObservabeTest.cs b/src/HassModel/NetDaemon.HassModel.Tests/Internal/QueuedObservabeTest.cs index f4c8e74fa..a189bc702 100644 --- a/src/HassModel/NetDaemon.HassModel.Tests/Internal/QueuedObservabeTest.cs +++ b/src/HassModel/NetDaemon.HassModel.Tests/Internal/QueuedObservabeTest.cs @@ -5,7 +5,6 @@ using FluentAssertions; using Microsoft.Extensions.Logging; using Moq; -using NetDaemon.HassModel.Common; using NetDaemon.HassModel.Internal; using NetDaemon.HassModel.Tests.TestHelpers; using Xunit; diff --git a/src/HassModel/NetDaemon.HassModel.Tests/Internal/ScopedObservableTests.cs b/src/HassModel/NetDaemon.HassModel.Tests/Internal/ScopedObservableTests.cs index 114c4cdc1..3ea10b3b9 100644 --- a/src/HassModel/NetDaemon.HassModel.Tests/Internal/ScopedObservableTests.cs +++ b/src/HassModel/NetDaemon.HassModel.Tests/Internal/ScopedObservableTests.cs @@ -2,48 +2,46 @@ using System.Reactive.Subjects; using Moq; using Xunit; -using Microsoft.Extensions.Logging; using NetDaemon.HassModel.Internal; -namespace NetDaemon.HassModel.Tests.Internal +namespace NetDaemon.HassModel.Tests.Internal; + +public class ScopedObservableTests { - public class ScopedObservableTests + [Fact] + public void WhenScopeIsDisposedSubscribersAreDetached() { - [Fact] - public void WhenScopeIsDisposedSubscribersAreDetached() - { - var testSubject = new Subject(); - // Create 2 ScopedObservables for the same subject - var scoped1 = new ScopedObservable(testSubject); - var scoped2 = new ScopedObservable(testSubject); - - // First scope has 2 subscribers, second has 1 - var scope1AObserverMock = new Mock>(); - var scope1BObserverMock = new Mock>(); - scoped1.Subscribe(scope1AObserverMock.Object); - scoped1.Subscribe(scope1BObserverMock.Object); - - var scope2ObserverMock = new Mock>(); - scoped2.Subscribe(scope2ObserverMock.Object); - - // Now start firing events - testSubject.OnNext("Event1"); - scope1AObserverMock.Verify(o => o.OnNext("Event1"), Times.Once); - scope1BObserverMock.Verify(o => o.OnNext("Event1"), Times.Once); - scope2ObserverMock.Verify(o => o.OnNext("Event1"), Times.Once); - - scoped1.Dispose(); - testSubject.OnNext("Event2"); - - scope1AObserverMock.Verify(o => o.OnNext("Event2"), Times.Never, "Event should not reach Observer of disposed scope"); - scope1BObserverMock.Verify(o => o.OnNext("Event2"), Times.Never, "Event should not reach Observer of disposed scope"); - scope2ObserverMock.Verify(o => o.OnNext("Event2"), Times.Once); - - scoped2.Dispose(); - testSubject.OnNext("Event3"); - scope1AObserverMock.Verify(o => o.OnNext("Event3"), Times.Never, "Event should not reach Observer of disposed scope"); - scope1BObserverMock.Verify(o => o.OnNext("Event3"), Times.Never, "Event should not reach Observer of disposed scope"); - scope2ObserverMock.Verify(o => o.OnNext("Event3"), Times.Never, "Event should not reach Observer of disposed scope"); - } + var testSubject = new Subject(); + // Create 2 ScopedObservables for the same subject + var scoped1 = new ScopedObservable(testSubject); + var scoped2 = new ScopedObservable(testSubject); + + // First scope has 2 subscribers, second has 1 + var scope1AObserverMock = new Mock>(); + var scope1BObserverMock = new Mock>(); + scoped1.Subscribe(scope1AObserverMock.Object); + scoped1.Subscribe(scope1BObserverMock.Object); + + var scope2ObserverMock = new Mock>(); + scoped2.Subscribe(scope2ObserverMock.Object); + + // Now start firing events + testSubject.OnNext("Event1"); + scope1AObserverMock.Verify(o => o.OnNext("Event1"), Times.Once); + scope1BObserverMock.Verify(o => o.OnNext("Event1"), Times.Once); + scope2ObserverMock.Verify(o => o.OnNext("Event1"), Times.Once); + + scoped1.Dispose(); + testSubject.OnNext("Event2"); + + scope1AObserverMock.Verify(o => o.OnNext("Event2"), Times.Never, "Event should not reach Observer of disposed scope"); + scope1BObserverMock.Verify(o => o.OnNext("Event2"), Times.Never, "Event should not reach Observer of disposed scope"); + scope2ObserverMock.Verify(o => o.OnNext("Event2"), Times.Once); + + scoped2.Dispose(); + testSubject.OnNext("Event3"); + scope1AObserverMock.Verify(o => o.OnNext("Event3"), Times.Never, "Event should not reach Observer of disposed scope"); + scope1BObserverMock.Verify(o => o.OnNext("Event3"), Times.Never, "Event should not reach Observer of disposed scope"); + scope2ObserverMock.Verify(o => o.OnNext("Event3"), Times.Never, "Event should not reach Observer of disposed scope"); } } \ No newline at end of file diff --git a/src/HassModel/NetDaemon.HassModel.Tests/Common/ObservableExtensionsTest.cs b/src/HassModel/NetDaemon.HassModel.Tests/ObservableExtensionsTest.cs similarity index 96% rename from src/HassModel/NetDaemon.HassModel.Tests/Common/ObservableExtensionsTest.cs rename to src/HassModel/NetDaemon.HassModel.Tests/ObservableExtensionsTest.cs index b53cd912b..d814979df 100644 --- a/src/HassModel/NetDaemon.HassModel.Tests/Common/ObservableExtensionsTest.cs +++ b/src/HassModel/NetDaemon.HassModel.Tests/ObservableExtensionsTest.cs @@ -3,10 +3,9 @@ using System.Threading.Tasks; using FluentAssertions; using Moq; -using NetDaemon.HassModel.Common; using Xunit; -namespace NetDaemon.HassModel.Tests.Common; +namespace NetDaemon.HassModel.Tests; public class ObservableExtensionsTest { diff --git a/src/HassModel/NetDaemon.HassModel.Tests/ServiceTargetTest.cs b/src/HassModel/NetDaemon.HassModel.Tests/ServiceTargetTest.cs new file mode 100644 index 000000000..2ce3002e3 --- /dev/null +++ b/src/HassModel/NetDaemon.HassModel.Tests/ServiceTargetTest.cs @@ -0,0 +1,32 @@ +using FluentAssertions; +using NetDaemon.HassModel.Entities; +using Xunit; + +namespace NetDaemon.HassModel.Tests; + +public class ServiceTargetTest +{ + [Fact] + public void ServiceTargetShouldContainCorrectEntity() + { + var serviceTarget = ServiceTarget.FromEntity("light.kitchen"); + + serviceTarget.EntityIds.Should().BeEquivalentTo("light.kitchen"); + } + + [Fact] + public void ServiceTargetShouldContainCorrectEntities() + { + var serviceTarget = ServiceTarget.FromEntities(new[] { "light.kitchen", "light.livingroom" }); + + serviceTarget.EntityIds.Should().BeEquivalentTo("light.kitchen", "light.livingroom"); + } + + [Fact] + public void ServiceTargetShouldContainCorrectEntitiesUsingParams() + { + var serviceTarget = ServiceTarget.FromEntities("light.kitchen", "light.livingroom"); + + serviceTarget.EntityIds.Should().BeEquivalentTo("light.kitchen", "light.livingroom"); + } +} \ No newline at end of file diff --git a/src/HassModel/NetDaemon.HassModel.Tests/TestHelpers/HassClient/HaContextMock.cs b/src/HassModel/NetDaemon.HassModel.Tests/TestHelpers/HassClient/HaContextMock.cs index df627ba90..f0846be22 100644 --- a/src/HassModel/NetDaemon.HassModel.Tests/TestHelpers/HassClient/HaContextMock.cs +++ b/src/HassModel/NetDaemon.HassModel.Tests/TestHelpers/HassClient/HaContextMock.cs @@ -1,19 +1,17 @@ using System.Reactive.Subjects; using Moq; -using NetDaemon.HassModel.Common; using NetDaemon.HassModel.Entities; -namespace NetDaemon.HassModel.Tests.TestHelpers.HassClient +namespace NetDaemon.HassModel.Tests.TestHelpers.HassClient; + +internal class HaContextMock : Mock { - internal class HaContextMock : Mock + public HaContextMock() { - public HaContextMock() - { - Setup(m => m.StateAllChanges()).Returns(StateAllChangeSubject); - Setup(m => m.Events).Returns(EventsSubject); - } - - public Subject StateAllChangeSubject { get; } = new(); - public Subject EventsSubject { get; } = new(); + Setup(m => m.StateAllChanges()).Returns(StateAllChangeSubject); + Setup(m => m.Events).Returns(EventsSubject); } + + public Subject StateAllChangeSubject { get; } = new(); + public Subject EventsSubject { get; } = new(); } \ No newline at end of file diff --git a/src/HassModel/NetDaemon.HassModel.Tests/TestHelpers/HassClient/TestEntity.cs b/src/HassModel/NetDaemon.HassModel.Tests/TestHelpers/HassClient/TestEntity.cs index d611e7761..93c137959 100644 --- a/src/HassModel/NetDaemon.HassModel.Tests/TestHelpers/HassClient/TestEntity.cs +++ b/src/HassModel/NetDaemon.HassModel.Tests/TestHelpers/HassClient/TestEntity.cs @@ -1,25 +1,23 @@ using System.Text.Json.Serialization; -using NetDaemon.HassModel.Common; using NetDaemon.HassModel.Entities; -namespace NetDaemon.HassModel.Tests.TestHelpers.HassClient +namespace NetDaemon.HassModel.Tests.TestHelpers.HassClient; + +record TestEntity : Entity, TestEntityAttributes> { - record TestEntity : Entity, TestEntityAttributes> - { - public TestEntity(IHaContext haContext, string entityId) : base(haContext, entityId) { } - } + public TestEntity(IHaContext haContext, string entityId) : base(haContext, entityId) { } +} - public record TestEntityAttributes - { - [JsonPropertyName("name")] public string Name { get; set; } = ""; - } +public record TestEntityAttributes +{ + [JsonPropertyName("name")] public string Name { get; set; } = ""; +} - public record NumericTestEntity : NumericEntity, TestEntityAttributes> - { - public NumericTestEntity(Entity entity) : base(entity) - { } +public record NumericTestEntity : NumericEntity, TestEntityAttributes> +{ + public NumericTestEntity(Entity entity) : base(entity) + { } - public NumericTestEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { } - } + public NumericTestEntity(IHaContext haContext, string entityId) : base(haContext, entityId) + { } } \ No newline at end of file diff --git a/src/HassModel/NetDaemon.HassModel.Tests/TestHelpers/NonQueuedObservableMock.cs b/src/HassModel/NetDaemon.HassModel.Tests/TestHelpers/NonQueuedObservableMock.cs deleted file mode 100644 index b9b4b5976..000000000 --- a/src/HassModel/NetDaemon.HassModel.Tests/TestHelpers/NonQueuedObservableMock.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Reactive.Subjects; -using System.Threading.Tasks; -using Microsoft.Extensions.Logging; -using NetDaemon.HassModel.Common; -using NetDaemon.Infrastructure.ObservableHelpers; - -namespace NetDaemon.HassModel.Tests.TestHelpers; - -/// -/// Non queued to allow easier testing -/// -internal sealed class NonQueuedObservableMock : IQueuedObservable -{ - private IDisposable? _subscription; - private readonly Subject _subject = new(); - - public NonQueuedObservableMock(ILogger _) - { - } - - public IDisposable Subscribe(IObserver observer) => _subject.Subscribe(observer); - - public void Initialize(IObservable innerObservable) - { - _subscription = innerObservable.Subscribe(_subject); - } - - public ValueTask DisposeAsync() - { - // When disposed unsubscribe from inner observable - // this will make all subscribers of our Subject stop receiving events - _subscription?.Dispose(); - _subject.Dispose(); - return ValueTask.CompletedTask; - } -} \ No newline at end of file diff --git a/src/HassModel/NetDeamon.HassModel/Common/Context.cs b/src/HassModel/NetDeamon.HassModel/Common/Context.cs deleted file mode 100644 index 2e69ca8fb..000000000 --- a/src/HassModel/NetDeamon.HassModel/Common/Context.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace NetDaemon.HassModel.Common -{ - /// - /// Context - /// - public class Context - { - /// - /// Id - /// - public string Id { get; set; } = ""; - - /// - /// ParentId - /// - public string? ParentId { get; set; } - /// - /// The id of the user who is responsible for the connected item. - /// - public string? UserId { get; set; } - } -} \ No newline at end of file diff --git a/src/HassModel/NetDeamon.HassModel/Common/Event.cs b/src/HassModel/NetDeamon.HassModel/Common/Event.cs deleted file mode 100644 index d2bd2266e..000000000 --- a/src/HassModel/NetDeamon.HassModel/Common/Event.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Text.Json; -using System.Text.Json.Serialization; -using NetDaemon.HassModel.Internal; - -namespace NetDaemon.HassModel.Common -{ - /// - /// Represents an Event from Home Assistant - /// - public record Event - { - /// - /// The EventData as a JsonElement - /// - [JsonPropertyName("data")] - public JsonElement? DataElement { get; init; } - - /// - /// The type of the Event - /// - [JsonPropertyName("event_type")] - public string EventType { get; init; } = string.Empty; - - /// - /// The Event Origin - /// - [JsonPropertyName("origin")] - public string Origin { get; init; } = string.Empty; - - /// - /// The Time the Event fired - /// - [JsonPropertyName("time_fired")] - public DateTime? TimeFired { get; init; } - } - - /// - /// Event with typed Data field - /// - /// The type to - public record Event : Event - where TData : class - { - /// Copy constructor from Base type - public Event(Event source) : base(source) - { - _lazyData = new Lazy(() => DataElement?.ToObject()); - } - - private Lazy _lazyData; - - /// - /// The Data of this Event deserialized as TData - /// - public TData? Data => _lazyData.Value; - } -} diff --git a/src/HassModel/NetDeamon.HassModel/Common/HaContextExtensions.cs b/src/HassModel/NetDeamon.HassModel/Common/HaContextExtensions.cs deleted file mode 100644 index 8abd33aa1..000000000 --- a/src/HassModel/NetDeamon.HassModel/Common/HaContextExtensions.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Reactive.Linq; -using NetDaemon.HassModel.Entities; - -namespace NetDaemon.HassModel.Common -{ - /// - /// Extension methods for HaContext - /// - public static class HaContextExtensions - { - /// - /// The observable state stream state change - /// - /// - /// Old state != New state - /// - public static IObservable StateChanges(this IHaContext haContext) - { - if (haContext == null) throw new ArgumentNullException(nameof(haContext)); - return haContext.StateAllChanges().StateChangesOnly(); - } - - /// - /// Creates a new Entity instance - /// - public static Entity Entity(this IHaContext haContext, string entityId) => new (haContext, entityId); - - /// - /// Filters events on their EventType and retrieves their data in a types object - /// - /// The Event stream - /// The event_type to filter on - /// Type to deserialize of the data json element - /// Observable of matching events with deserialized data - public static IObservable> Filter(this IObservable events, string eventType) - where T : class - => events - .Where(e => e.EventType == eventType && e.DataElement != null) - .Select(e => new Event(e)); - } -} \ No newline at end of file diff --git a/src/HassModel/NetDeamon.HassModel/Common/IHaContext.cs b/src/HassModel/NetDeamon.HassModel/Common/IHaContext.cs deleted file mode 100644 index be4aabf79..000000000 --- a/src/HassModel/NetDeamon.HassModel/Common/IHaContext.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using System.Collections.Generic; -using NetDaemon.HassModel.Entities; - -namespace NetDaemon.HassModel.Common -{ - /// - /// Represents a context for interacting with Home Assistant - /// - public interface IHaContext - { - /// - /// All Events from Home Assistant - /// - IObservable Events { get; } - - /// - /// The observable state stream, all changes including attributes - /// - IObservable StateAllChanges(); - - /// - /// Get state for a single entity - /// - /// - EntityState? GetState(string entityId); - - /// - /// Gets all the entities in HomeAssistant - /// - IReadOnlyList GetAllEntities(); - - /// - /// Calls a service in Home Assistant - /// - /// Domain of service - /// Service name - /// The target that is targeted by this service call - /// Data provided to service. Should be Json-serializable to the data expected by the service - void CallService(string domain, string service, ServiceTarget? target = null, object? data = null); - - /// - /// Get area for a single entity - /// - /// - /// - Area? GetAreaFromEntityId(string entityId); - - /// - /// Sends an event to Home Assistant - /// - /// The event_type for the event - /// The data for the event, will be json serialized as the date element - void SendEvent(string eventType, object? data = null); - } -} diff --git a/src/HassModel/NetDeamon.HassModel/Common/ServiceTarget.cs b/src/HassModel/NetDeamon.HassModel/Common/ServiceTarget.cs deleted file mode 100644 index 5971b3541..000000000 --- a/src/HassModel/NetDeamon.HassModel/Common/ServiceTarget.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -namespace NetDaemon.HassModel.Entities -{ - /// - /// Target for a service call - /// - public class ServiceTarget - { - /// - /// Creates a new ServiceTarget from an EntityId - /// - /// The Id of teh entity - /// A new ServiceTarget - public static ServiceTarget FromEntity(string entityId) => - new() { EntityIds = new[] { entityId } }; - - /// - /// Creates a new ServiceTarget from a list of EntityIds - /// - /// The Ids of entities - /// A new ServiceTarget - public static ServiceTarget FromEntities(IEnumerable entityIds) => - new() { EntityIds = entityIds.ToArray() }; - - /// - /// Creates a new ServiceTarget from EntityIds - /// - /// The Ids of entities - /// A new ServiceTarget - public static ServiceTarget FromEntities(params string[] entityIds) => - new() { EntityIds = entityIds.ToArray() }; - - /// - /// Creates a new empty ServiceTarget - /// - public ServiceTarget() - { } - - /// - /// IDs of entities to invoke a service on - /// - public IReadOnlyCollection? EntityIds { get; init; } - - /// - /// Ids of Devices to invoke a service on - /// - public IReadOnlyCollection? DeviceIds { get; init; } - - /// - /// Ids of Areas to invoke a service on - /// - public IReadOnlyCollection? AreaIds { get; init; } - } -} \ No newline at end of file diff --git a/src/HassModel/NetDeamon.HassModel/Context.cs b/src/HassModel/NetDeamon.HassModel/Context.cs new file mode 100644 index 000000000..d0f3943e3 --- /dev/null +++ b/src/HassModel/NetDeamon.HassModel/Context.cs @@ -0,0 +1,21 @@ +namespace NetDaemon.HassModel; + +/// +/// Context +/// +public class Context +{ + /// + /// Id + /// + public string Id { get; set; } = ""; + + /// + /// ParentId + /// + public string? ParentId { get; set; } + /// + /// The id of the user who is responsible for the connected item. + /// + public string? UserId { get; set; } +} \ No newline at end of file diff --git a/src/HassModel/NetDeamon.HassModel/DependencyInjectionSetup.cs b/src/HassModel/NetDeamon.HassModel/DependencyInjectionSetup.cs index fb6df197b..c0f2880ff 100644 --- a/src/HassModel/NetDeamon.HassModel/DependencyInjectionSetup.cs +++ b/src/HassModel/NetDeamon.HassModel/DependencyInjectionSetup.cs @@ -1,38 +1,32 @@ -using System; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using NetDaemon.Client.Common.HomeAssistant.Model; -using NetDaemon.HassModel.Common; -using NetDaemon.HassModel.Internal; +using Microsoft.Extensions.Hosting; using NetDaemon.Infrastructure.ObservableHelpers; -namespace NetDaemon.HassModel +namespace NetDaemon.HassModel; + +/// +/// Setup methods for services configuration +/// +public static class DependencyInjectionSetup { /// - /// Setup methods for services configuration + /// Registers services for using the IHaContext interface scoped to NetDemonApps /// - public static class DependencyInjectionSetup + public static IHostBuilder UseAppScopedHaContext(this IHostBuilder hostBuilder) { - /// - /// Registers services for using the IHaContext interface scoped to NetDemonApps - /// - public static IHostBuilder UseAppScopedHaContext(this IHostBuilder hostBuilder) - { - if (hostBuilder == null) throw new ArgumentNullException(nameof(hostBuilder)); + if (hostBuilder == null) throw new ArgumentNullException(nameof(hostBuilder)); - return hostBuilder - .ConfigureServices((_, services) => services.AddScopedHaContext()); - } + return hostBuilder + .ConfigureServices((_, services) => services.AddScopedHaContext()); + } - internal static void AddScopedHaContext(this IServiceCollection services) - { - services.AddSingleton(); - services.AddSingleton(); - services.AddScoped(); - services.AddTransient(); - services.AddTransient(s => s.GetRequiredService()); - services.AddScoped>(); - services.AddScoped>(s => s.GetRequiredService>()); - } + internal static void AddScopedHaContext(this IServiceCollection services) + { + services.AddSingleton(); + services.AddSingleton(); + services.AddScoped(); + services.AddTransient(); + services.AddTransient(s => s.GetRequiredService()); + services.AddScoped>(); + services.AddScoped>(s => s.GetRequiredService>()); } } \ 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 209bf6795..c4125dc12 100644 --- a/src/HassModel/NetDeamon.HassModel/Entities/Entity.cs +++ b/src/HassModel/NetDeamon.HassModel/Entities/Entity.cs @@ -1,124 +1,117 @@ -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -using System; -using System.Reactive.Linq; -using NetDaemon.HassModel.Common; -using NetDaemon.HassModel.Internal; +namespace NetDaemon.HassModel.Entities; -namespace NetDaemon.HassModel.Entities +/// Represents a Home Assistant entity with its state, changes and services +public record Entity { - /// Represents a Home Assistant entity with its state, changes and services - public record Entity + /// + /// The IHAContext + /// + public IHaContext HaContext { get; } + + /// + /// Entity id being handled by this entity + /// + public string EntityId { get; } + + /// + /// Creates a new instance of a Entity class + /// + /// The Home Assistant context associated with this Entity + /// The id of this Entity + public Entity(IHaContext haContext, string entityId) { - /// - /// The IHAContext - /// - public IHaContext HaContext { get; } - - /// - /// Entity id being handled by this entity - /// - public string EntityId { get; } - - /// - /// Creates a new instance of a Entity class - /// - /// The Home Assistant context associated with this Entity - /// The id of this Entity - public Entity(IHaContext haContext, string entityId) - { - HaContext = haContext; - EntityId = entityId; - } + HaContext = haContext; + EntityId = entityId; + } - /// - /// Area name of entity - /// - public string? Area => HaContext.GetAreaFromEntityId(EntityId)?.Name; - - /// The current state of this Entity - public string? State => EntityState?.State; - - /// - /// The current Attributes of this Entity - /// - public virtual object? Attributes => EntityState?.Attributes; - - /// - /// The full state of this Entity - /// - public virtual EntityState? EntityState => HaContext.GetState(EntityId); - - /// - /// Observable, All state changes including attributes - /// - public virtual IObservable StateAllChanges() => - HaContext.StateAllChanges().Where(e => e.Entity.EntityId == EntityId); - - /// - /// Observable, All state changes. New.State!=Old.State - /// - public virtual IObservable StateChanges() => - StateAllChanges().StateChangesOnly(); - - /// - /// Calls a service using this entity as the target - /// - /// 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 virtual void CallService(string service, object? data = null) - { - ArgumentNullException.ThrowIfNull(service, nameof(service)); + /// + /// Area name of entity + /// + public string? Area => HaContext.GetAreaFromEntityId(EntityId)?.Name; + + /// The current state of this Entity + public string? State => EntityState?.State; + + /// + /// The current Attributes of this Entity + /// + public virtual object? Attributes => EntityState?.Attributes; + + /// + /// The full state of this Entity + /// + public virtual EntityState? EntityState => HaContext.GetState(EntityId); + + /// + /// Observable, All state changes including attributes + /// + public virtual IObservable StateAllChanges() => + HaContext.StateAllChanges().Where(e => e.Entity.EntityId == EntityId); + + /// + /// Observable, All state changes. New.State!=Old.State + /// + public virtual IObservable StateChanges() => + StateAllChanges().StateChangesOnly(); + + /// + /// Calls a service using this entity as the target + /// + /// 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 virtual void CallService(string service, object? data = null) + { + ArgumentNullException.ThrowIfNull(service, nameof(service)); - var (serviceDomain, serviceName) = service.SplitAtDot(); + var (serviceDomain, serviceName) = service.SplitAtDot(); - serviceDomain ??= EntityId.SplitAtDot().Left ?? throw new InvalidOperationException("EntityId must be formatted 'domain.name'"); + serviceDomain ??= EntityId.SplitAtDot().Left ?? throw new InvalidOperationException("EntityId must be formatted 'domain.name'"); - HaContext.CallService(serviceDomain, serviceName, ServiceTarget.FromEntity(EntityId), data); - } + HaContext.CallService(serviceDomain, serviceName, ServiceTarget.FromEntity(EntityId), data); } +} - /// Represents a Home Assistant entity with its state, changes and services - public abstract record Entity : Entity - where TEntity : Entity - where TEntityState : EntityState - where TAttributes : class - { - /// Copy constructor from Base type - protected Entity(Entity entity) : base(entity) - { } +/// Represents a Home Assistant entity with its state, changes and services +public abstract record Entity : Entity + where TEntity : Entity + where TEntityState : EntityState + where TAttributes : class +{ + /// Copy constructor from Base type + protected Entity(Entity entity) : base(entity) + { } - /// Constructor from haContext and entityId - protected Entity(IHaContext haContext, string entityId) : base(haContext, entityId) - { } + /// Constructor from haContext and entityId + protected Entity(IHaContext haContext, string entityId) : base(haContext, entityId) + { } - /// - public override TAttributes? Attributes => EntityState?.Attributes; + /// + public override TAttributes? Attributes => EntityState?.Attributes; - /// - public override TEntityState? EntityState => MapState(base.EntityState); + /// + public override TEntityState? EntityState => MapState(base.EntityState); - /// - public override IObservable> StateAllChanges() => - base.StateAllChanges().Select(e => new StateChange((TEntity)this, - Entities.EntityState.Map(e.Old), - Entities.EntityState.Map(e.New))); + /// + public override IObservable> StateAllChanges() => + base.StateAllChanges().Select(e => new StateChange((TEntity)this, + Entities.EntityState.Map(e.Old), + Entities.EntityState.Map(e.New))); - /// - public override IObservable> StateChanges() => StateAllChanges().StateChangesOnly(); + /// + public override IObservable> StateChanges() => StateAllChanges().StateChangesOnly(); - private static TEntityState? MapState(EntityState? state) => Entities.EntityState.Map(state); - } + private static TEntityState? MapState(EntityState? state) => Entities.EntityState.Map(state); +} - /// Represents a Home Assistant entity with its state, changes and services - public record Entity : Entity, EntityState, TAttributes> - where TAttributes : class - { - // This type is needed because the base type has a recursive type parameter so it can not be used as a return value +/// Represents a Home Assistant entity with its state, changes and services +public record Entity : Entity, EntityState, TAttributes> + where TAttributes : class +{ + // This type is needed because the base type has a recursive type parameter so it can not be used as a return value - /// Copy constructor from Base type - public Entity(Entity entity) : base(entity) { } + /// Copy constructor from Base type + public Entity(Entity entity) : base(entity) { } - /// Constructor from haContext and entityId - public Entity(IHaContext haContext, string entityId) : base(haContext, entityId) { } - } -} + /// Constructor from haContext and entityId + public Entity(IHaContext haContext, string entityId) : base(haContext, entityId) { } +} \ No newline at end of file diff --git a/src/HassModel/NetDeamon.HassModel/Entities/EntityExtensions.cs b/src/HassModel/NetDeamon.HassModel/Entities/EntityExtensions.cs index f1104409d..43c805db6 100644 --- a/src/HassModel/NetDeamon.HassModel/Entities/EntityExtensions.cs +++ b/src/HassModel/NetDeamon.HassModel/Entities/EntityExtensions.cs @@ -1,63 +1,59 @@ -using System; -using System.Reactive.Linq; +namespace NetDaemon.HassModel.Entities; -namespace NetDaemon.HassModel.Entities +/// +/// Provides Extension methods for Entities +/// +public static class EntityExtensions { /// - /// Provides Extension methods for Entities + /// Checks if en EntityState has the state "on" /// - public static class EntityExtensions - { - /// - /// Checks if en EntityState has the state "on" - /// - /// The state to check - /// true if the state equals "on", otherwise false - public static bool IsOn(this EntityState? entityState) => string.Equals(entityState?.State, "on", StringComparison.OrdinalIgnoreCase); - - /// - /// Checks if en EntityState has the state "off" - /// - /// The state to check - /// true if the state equals "off", otherwise false - public static bool IsOff(this EntityState? entityState) => string.Equals(entityState?.State, "off", StringComparison.OrdinalIgnoreCase); - - /// - /// Checks if en Entity has the state "on" - /// - /// The state to check - /// true if the state equals "on", otherwise false - public static bool IsOn(this Entity? entity) => entity?.EntityState?.IsOn() ?? false; - - /// - /// Checks if en Entity has the state "off" - /// - /// The state to check - /// true if the state equals "off", otherwise false - public static bool IsOff(this Entity? entity) => entity?.EntityState?.IsOff() ?? false; - - /// Gets a NumericEntity from a given Entity - public static NumericEntity AsNumeric(this Entity entity) => new(entity); - - /// Gets a NumericEntity from a given Entity - public static NumericEntity - AsNumeric(this Entity entity) - where TEntity : Entity - where TEntityState : EntityState - where TAttributes : class - => new(entity); - - /// Gets a new Entity from this Entity with the specified type of attributes - public static Entity WithAttributesAs(this Entity entity) - where TAttributes : class - => new(entity); - - /// Gets a new Entity from this Entity with the specified type of attributes - public static NumericEntity WithAttributesAs(this NumericEntity entity) - where TAttributes : class - => new (entity); - - internal static IObservable StateChangesOnly(this IObservable changes) where T : StateChange - => changes.Where(c => c.New?.State != c.Old?.State); - } + /// The state to check + /// true if the state equals "on", otherwise false + public static bool IsOn(this EntityState? entityState) => string.Equals(entityState?.State, "on", StringComparison.OrdinalIgnoreCase); + + /// + /// Checks if en EntityState has the state "off" + /// + /// The state to check + /// true if the state equals "off", otherwise false + public static bool IsOff(this EntityState? entityState) => string.Equals(entityState?.State, "off", StringComparison.OrdinalIgnoreCase); + + /// + /// Checks if en Entity has the state "on" + /// + /// The state to check + /// true if the state equals "on", otherwise false + public static bool IsOn(this Entity? entity) => entity?.EntityState?.IsOn() ?? false; + + /// + /// Checks if en Entity has the state "off" + /// + /// The state to check + /// true if the state equals "off", otherwise false + public static bool IsOff(this Entity? entity) => entity?.EntityState?.IsOff() ?? false; + + /// Gets a NumericEntity from a given Entity + public static NumericEntity AsNumeric(this Entity entity) => new(entity); + + /// Gets a NumericEntity from a given Entity + public static NumericEntity + AsNumeric(this Entity entity) + where TEntity : Entity + where TEntityState : EntityState + where TAttributes : class + => new(entity); + + /// Gets a new Entity from this Entity with the specified type of attributes + public static Entity WithAttributesAs(this Entity entity) + where TAttributes : class + => new(entity); + + /// Gets a new Entity from this Entity with the specified type of attributes + public static NumericEntity WithAttributesAs(this NumericEntity entity) + where TAttributes : class + => new (entity); + + internal static IObservable StateChangesOnly(this IObservable changes) where T : StateChange + => changes.Where(c => c.New?.State != c.Old?.State); } \ No newline at end of file diff --git a/src/HassModel/NetDeamon.HassModel/Entities/EntityState.cs b/src/HassModel/NetDeamon.HassModel/Entities/EntityState.cs index 579f95adf..45710cb16 100644 --- a/src/HassModel/NetDeamon.HassModel/Entities/EntityState.cs +++ b/src/HassModel/NetDeamon.HassModel/Entities/EntityState.cs @@ -1,61 +1,54 @@ -using System; -using System.Collections.Generic; -using System.Text.Json; -using NetDaemon.HassModel.Common; -using NetDaemon.HassModel.Internal; +namespace NetDaemon.HassModel.Entities; -namespace NetDaemon.HassModel.Entities +/// +/// Detailed state information +/// +public record EntityState { - /// - /// Detailed state information - /// - public record EntityState - { - /// Unique id of the entity - public string EntityId { get; init; } = ""; + /// Unique id of the entity + public string EntityId { get; init; } = ""; - /// The state - public string? State { get; init; } + /// The state + public string? State { get; init; } - internal JsonElement? AttributesJson { get; init; } + internal JsonElement? AttributesJson { get; init; } - /// - /// The attributes - /// - public virtual object? Attributes => AttributesJson?.ToObject>() ?? new Dictionary(); + /// + /// The attributes + /// + public virtual object? Attributes => AttributesJson?.ToObject>() ?? new Dictionary(); - /// Last changed, when state changed from and to different values - public DateTime? LastChanged { get; init; } + /// Last changed, when state changed from and to different values + public DateTime? LastChanged { get; init; } - /// Last updated, when entity state or attributes changed - public DateTime? LastUpdated { get; init; } + /// Last updated, when entity state or attributes changed + public DateTime? LastUpdated { get; init; } - /// Context - public Context? Context { get; init; } + /// Context + public Context? Context { get; init; } - internal static TEntityState? Map(EntityState? state) - where TEntityState : class => - state == null ? null : (TEntityState)Activator.CreateInstance(typeof(TEntityState), state)!; } + internal static TEntityState? Map(EntityState? state) + where TEntityState : class => + state == null ? null : (TEntityState)Activator.CreateInstance(typeof(TEntityState), state)!; } +/// +/// Generic EntityState with specific types of State and Attributes +/// +/// The type of the Attributes Property +public record EntityState : EntityState + where TAttributes : class +{ + private readonly Lazy _attributesLazy; + /// - /// Generic EntityState with specific types of State and Attributes + /// Copy constructor from base class /// - /// The type of the Attributes Property - public record EntityState : EntityState - where TAttributes : class + /// + public EntityState(EntityState source) : base(source) { - private readonly Lazy _attributesLazy; - - /// - /// Copy constructor from base class - /// - /// - public EntityState(EntityState source) : base(source) - { - _attributesLazy = new (() => AttributesJson?.ToObject() ?? default); - } - - /// - public override TAttributes? Attributes => _attributesLazy.Value; + _attributesLazy = new (() => AttributesJson?.ToObject() ?? default); } + + /// + public override TAttributes? Attributes => _attributesLazy.Value; } \ No newline at end of file diff --git a/src/HassModel/NetDeamon.HassModel/Entities/EnumerableEntityExtensions.cs b/src/HassModel/NetDeamon.HassModel/Entities/EnumerableEntityExtensions.cs index 2e441c3ac..5f863d4da 100644 --- a/src/HassModel/NetDeamon.HassModel/Entities/EnumerableEntityExtensions.cs +++ b/src/HassModel/NetDeamon.HassModel/Entities/EnumerableEntityExtensions.cs @@ -1,58 +1,52 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reactive.Linq; +namespace NetDaemon.HassModel.Entities; -namespace NetDaemon.HassModel.Entities +/// +/// Provides extension methods for IEnumerable<Entity> +/// +public static class EnumerableEntityExtensions { /// - /// Provides extension methods for IEnumerable<Entity> + /// Observable, All state changes including attributes /// - public static class EnumerableEntityExtensions - { - /// - /// Observable, All state changes including attributes - /// - public static IObservable StateAllChanges(this IEnumerable entities) => - entities.Select(t => t.StateAllChanges()).Merge(); + public static IObservable StateAllChanges(this IEnumerable entities) => + entities.Select(t => t.StateAllChanges()).Merge(); - /// - /// Observable, All state changes. New.State != Old.State - /// - public static IObservable StateChanges(this IEnumerable entities) => - entities.StateAllChanges().StateChangesOnly(); + /// + /// Observable, All state changes. New.State != Old.State + /// + public static IObservable StateChanges(this IEnumerable entities) => + entities.StateAllChanges().StateChangesOnly(); - /// - /// Observable, All state changes including attributes - /// - public static IObservable> StateAllChanges(this IEnumerable> entities) - where TEntity : Entity - where TEntityState : EntityState - where TAttributes : class => - entities.Select(t => t.StateAllChanges()).Merge(); + /// + /// Observable, All state changes including attributes + /// + public static IObservable> StateAllChanges(this IEnumerable> entities) + where TEntity : Entity + where TEntityState : EntityState + where TAttributes : class => + entities.Select(t => t.StateAllChanges()).Merge(); - /// - /// Observable, All state changes. New.State != Old.State - /// - public static IObservable> StateChanges(this IEnumerable> entities) - where TEntity : Entity - where TEntityState : EntityState - where TAttributes : class => - entities.StateAllChanges().StateChangesOnly(); + /// + /// Observable, All state changes. New.State != Old.State + /// + public static IObservable> StateChanges(this IEnumerable> entities) + where TEntity : Entity + where TEntityState : EntityState + where TAttributes : class => + entities.StateAllChanges().StateChangesOnly(); - /// - /// Calls a service with a set of Entities as the target - /// - public static void CallService(this IEnumerable entities, string domain, string service, object? data) - { - // Usually each Entity will have the same IHaContext, but just in case group by the context and call the - // service for each context separately + /// + /// Calls a service with a set of Entities as the target + /// + public static void CallService(this IEnumerable entities, string domain, string service, object? data) + { + // Usually each Entity will have the same IHaContext, but just in case group by the context and call the + // service for each context separately - var perContext = entities.GroupBy(e => e.HaContext); - foreach (var group in perContext) - { - group.Key.CallService(domain, service, new ServiceTarget { EntityIds = group.Select(e => e.EntityId).ToList() }, data); - } + var perContext = entities.GroupBy(e => e.HaContext); + foreach (var group in perContext) + { + group.Key.CallService(domain, service, new ServiceTarget { EntityIds = group.Select(e => e.EntityId).ToList() }, data); } } } \ No newline at end of file diff --git a/src/HassModel/NetDeamon.HassModel/Entities/NumericEntity.cs b/src/HassModel/NetDeamon.HassModel/Entities/NumericEntity.cs index b64d8af80..bcb57b313 100644 --- a/src/HassModel/NetDeamon.HassModel/Entities/NumericEntity.cs +++ b/src/HassModel/NetDeamon.HassModel/Entities/NumericEntity.cs @@ -1,8 +1,4 @@ -using System; -using System.Reactive.Linq; -using NetDaemon.HassModel.Common; - -namespace NetDaemon.HassModel.Entities; +namespace NetDaemon.HassModel.Entities; /// /// Entity that has a numeric (double) State value diff --git a/src/HassModel/NetDeamon.HassModel/Entities/NumericEntityState.cs b/src/HassModel/NetDeamon.HassModel/Entities/NumericEntityState.cs index 7fe2aa8ea..121f1feda 100644 --- a/src/HassModel/NetDeamon.HassModel/Entities/NumericEntityState.cs +++ b/src/HassModel/NetDeamon.HassModel/Entities/NumericEntityState.cs @@ -1,5 +1,3 @@ -using NetDaemon.HassModel.Internal; - namespace NetDaemon.HassModel.Entities; /// diff --git a/src/HassModel/NetDeamon.HassModel/Event.cs b/src/HassModel/NetDeamon.HassModel/Event.cs new file mode 100644 index 000000000..13af79399 --- /dev/null +++ b/src/HassModel/NetDeamon.HassModel/Event.cs @@ -0,0 +1,52 @@ +namespace NetDaemon.HassModel; + +/// +/// Represents an Event from Home Assistant +/// +public record Event +{ + /// + /// The EventData as a JsonElement + /// + [JsonPropertyName("data")] + public JsonElement? DataElement { get; init; } + + /// + /// The type of the Event + /// + [JsonPropertyName("event_type")] + public string EventType { get; init; } = string.Empty; + + /// + /// The Event Origin + /// + [JsonPropertyName("origin")] + public string Origin { get; init; } = string.Empty; + + /// + /// The Time the Event fired + /// + [JsonPropertyName("time_fired")] + public DateTime? TimeFired { get; init; } +} + +/// +/// Event with typed Data field +/// +/// The type to +public record Event : Event + where TData : class +{ + /// Copy constructor from Base type + public Event(Event source) : base(source) + { + _lazyData = new Lazy(() => DataElement?.ToObject()); + } + + private Lazy _lazyData; + + /// + /// The Data of this Event deserialized as TData + /// + public TData? Data => _lazyData.Value; +} \ No newline at end of file diff --git a/src/HassModel/NetDeamon.HassModel/GlobalUsings.cs b/src/HassModel/NetDeamon.HassModel/GlobalUsings.cs new file mode 100644 index 000000000..d7fec7db7 --- /dev/null +++ b/src/HassModel/NetDeamon.HassModel/GlobalUsings.cs @@ -0,0 +1,17 @@ +global using System; +global using System.Buffers; +global using System.Linq; +global using System.Collections.Generic; +global using System.Diagnostics.CodeAnalysis; +global using System.Globalization; +global using System.Text.Json; +global using System.Text.Json.Serialization; +global using System.Threading.Tasks; +global using System.Reactive.Subjects; +global using System.Reactive.Linq; +global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.Logging; +global using NetDaemon.Client; +global using NetDaemon.Client.HomeAssistant.Model; +global using NetDaemon.HassModel.Internal; +global using NetDaemon.HassModel.Entities; diff --git a/src/HassModel/NetDeamon.HassModel/HaContextExtensions.cs b/src/HassModel/NetDeamon.HassModel/HaContextExtensions.cs new file mode 100644 index 000000000..a725d3c82 --- /dev/null +++ b/src/HassModel/NetDeamon.HassModel/HaContextExtensions.cs @@ -0,0 +1,37 @@ +namespace NetDaemon.HassModel; + +/// +/// Extension methods for HaContext +/// +public static class HaContextExtensions +{ + /// + /// The observable state stream state change + /// + /// + /// Old state != New state + /// + public static IObservable StateChanges(this IHaContext haContext) + { + if (haContext == null) throw new ArgumentNullException(nameof(haContext)); + return haContext.StateAllChanges().StateChangesOnly(); + } + + /// + /// Creates a new Entity instance + /// + public static Entity Entity(this IHaContext haContext, string entityId) => new (haContext, entityId); + + /// + /// Filters events on their EventType and retrieves their data in a types object + /// + /// The Event stream + /// The event_type to filter on + /// Type to deserialize of the data json element + /// Observable of matching events with deserialized data + public static IObservable> Filter(this IObservable events, string eventType) + where T : class + => events + .Where(e => e.EventType == eventType && e.DataElement != null) + .Select(e => new Event(e)); +} \ No newline at end of file diff --git a/src/HassModel/NetDeamon.HassModel/Common/ICacheManager.cs b/src/HassModel/NetDeamon.HassModel/ICacheManager.cs similarity index 86% rename from src/HassModel/NetDeamon.HassModel/Common/ICacheManager.cs rename to src/HassModel/NetDeamon.HassModel/ICacheManager.cs index cbfbc58b0..fc7f4df02 100644 --- a/src/HassModel/NetDeamon.HassModel/Common/ICacheManager.cs +++ b/src/HassModel/NetDeamon.HassModel/ICacheManager.cs @@ -1,7 +1,6 @@ using System.Threading; -using System.Threading.Tasks; -namespace NetDaemon.HassModel.Common; +namespace NetDaemon.HassModel; /// /// Allows initialization and refreshing of the HassModel internal caches diff --git a/src/HassModel/NetDeamon.HassModel/IHaContext.cs b/src/HassModel/NetDeamon.HassModel/IHaContext.cs new file mode 100644 index 000000000..cbcb63600 --- /dev/null +++ b/src/HassModel/NetDeamon.HassModel/IHaContext.cs @@ -0,0 +1,51 @@ +namespace NetDaemon.HassModel; + +/// +/// Represents a context for interacting with Home Assistant +/// +public interface IHaContext +{ + /// + /// All Events from Home Assistant + /// + IObservable Events { get; } + + /// + /// The observable state stream, all changes including attributes + /// + IObservable StateAllChanges(); + + /// + /// Get state for a single entity + /// + /// + EntityState? GetState(string entityId); + + /// + /// Gets all the entities in HomeAssistant + /// + IReadOnlyList GetAllEntities(); + + /// + /// Calls a service in Home Assistant + /// + /// Domain of service + /// Service name + /// The target that is targeted by this service call + /// Data provided to service. Should be Json-serializable to the data expected by the service + void CallService(string domain, string service, ServiceTarget? target = null, object? data = null); + + /// + /// Get area for a single entity + /// + /// + /// + Area? GetAreaFromEntityId(string entityId); + + /// + /// Sends an event to Home Assistant + /// + /// The event_type for the event + /// The data for the event, will be json serialized as the date element + void SendEvent(string eventType, object? data = null); +} \ No newline at end of file diff --git a/src/HassModel/NetDeamon.HassModel/Common/IQueuedObservable.cs b/src/HassModel/NetDeamon.HassModel/IQueuedObservable.cs similarity index 86% rename from src/HassModel/NetDeamon.HassModel/Common/IQueuedObservable.cs rename to src/HassModel/NetDeamon.HassModel/IQueuedObservable.cs index 407079aa0..b0dbc9fc6 100644 --- a/src/HassModel/NetDeamon.HassModel/Common/IQueuedObservable.cs +++ b/src/HassModel/NetDeamon.HassModel/IQueuedObservable.cs @@ -1,6 +1,4 @@ -using System; - -namespace NetDaemon.Infrastructure.ObservableHelpers; +namespace NetDaemon.Infrastructure.ObservableHelpers; /// /// The observable that queues the events diff --git a/src/HassModel/NetDeamon.HassModel/Internal/AppScopedHaContextProvider.cs b/src/HassModel/NetDeamon.HassModel/Internal/AppScopedHaContextProvider.cs index a9b3f4f0b..3869226b0 100644 --- a/src/HassModel/NetDeamon.HassModel/Internal/AppScopedHaContextProvider.cs +++ b/src/HassModel/NetDeamon.HassModel/Internal/AppScopedHaContextProvider.cs @@ -1,15 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Reactive.Linq; -using System.Threading; -using System.Threading.Tasks; -using NetDaemon.Client.Common; -using NetDaemon.Client.Common.HomeAssistant.Extensions; -using NetDaemon.Client.Common.HomeAssistant.Model; -using NetDaemon.HassModel.Common; -using NetDaemon.HassModel.Entities; +using System.Threading; +using NetDaemon.Client.HomeAssistant.Extensions; using NetDaemon.Infrastructure.ObservableHelpers; namespace NetDaemon.HassModel.Internal; diff --git a/src/HassModel/NetDeamon.HassModel/Internal/CacheManager.cs b/src/HassModel/NetDeamon.HassModel/Internal/CacheManager.cs index daa956da6..150966599 100644 --- a/src/HassModel/NetDeamon.HassModel/Internal/CacheManager.cs +++ b/src/HassModel/NetDeamon.HassModel/Internal/CacheManager.cs @@ -1,6 +1,4 @@ using System.Threading; -using System.Threading.Tasks; -using NetDaemon.HassModel.Common; namespace NetDaemon.HassModel.Internal; diff --git a/src/HassModel/NetDeamon.HassModel/Internal/EntityAreaCache.cs b/src/HassModel/NetDeamon.HassModel/Internal/EntityAreaCache.cs index 9bb064cfa..9431e8ecf 100644 --- a/src/HassModel/NetDeamon.HassModel/Internal/EntityAreaCache.cs +++ b/src/HassModel/NetDeamon.HassModel/Internal/EntityAreaCache.cs @@ -1,12 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; -using NetDaemon.Client.Common; -using NetDaemon.Client.Common.HomeAssistant.Extensions; -using NetDaemon.Client.Common.HomeAssistant.Model; +using System.Threading; +using NetDaemon.Client.HomeAssistant.Extensions; namespace NetDaemon.HassModel.Internal; diff --git a/src/HassModel/NetDeamon.HassModel/Internal/EntityStateCache.cs b/src/HassModel/NetDeamon.HassModel/Internal/EntityStateCache.cs index fd8980826..4b45f7fe9 100644 --- a/src/HassModel/NetDeamon.HassModel/Internal/EntityStateCache.cs +++ b/src/HassModel/NetDeamon.HassModel/Internal/EntityStateCache.cs @@ -1,15 +1,6 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Reactive.Subjects; +using System.Collections.Concurrent; using System.Threading; -using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; -using NetDaemon.Client.Common; -using NetDaemon.Client.Common.HomeAssistant.Extensions; -using NetDaemon.Client.Common.HomeAssistant.Model; +using NetDaemon.Client.HomeAssistant.Extensions; namespace NetDaemon.HassModel.Internal; diff --git a/src/HassModel/NetDeamon.HassModel/Internal/ExtensionMethods.cs b/src/HassModel/NetDeamon.HassModel/Internal/ExtensionMethods.cs index 4442cbbc4..3ff0a71e4 100644 --- a/src/HassModel/NetDeamon.HassModel/Internal/ExtensionMethods.cs +++ b/src/HassModel/NetDeamon.HassModel/Internal/ExtensionMethods.cs @@ -1,31 +1,27 @@ -using System.Buffers; -using System.Text.Json; +namespace NetDaemon.HassModel.Internal; -namespace NetDaemon.HassModel.Internal +/// +/// Useful extension methods used +/// +internal static class NetDaemonExtensions { - /// - /// Useful extension methods used - /// - internal static class NetDaemonExtensions + public static T ToObject(this JsonElement element, JsonSerializerOptions? options = null) { - public static T ToObject(this JsonElement element, JsonSerializerOptions? options = null) + var bufferWriter = new ArrayBufferWriter(); + using (var writer = new Utf8JsonWriter(bufferWriter)) { - var bufferWriter = new ArrayBufferWriter(); - using (var writer = new Utf8JsonWriter(bufferWriter)) - { - element.WriteTo(writer); - } + element.WriteTo(writer); + } - return JsonSerializer.Deserialize(bufferWriter.WrittenSpan, options) ?? default!; - } + return JsonSerializer.Deserialize(bufferWriter.WrittenSpan, options) ?? default!; + } - public static (string? Left, string Right) SplitAtDot(this string id) - { - var firstDot = id.IndexOf('.', System.StringComparison.InvariantCulture); - if (firstDot == -1) return (null, id); + public static (string? Left, string Right) SplitAtDot(this string id) + { + var firstDot = id.IndexOf('.', System.StringComparison.InvariantCulture); + if (firstDot == -1) return (null, id); - return (id[.. firstDot ], id[ firstDot .. ]); - } - + return (id[.. firstDot ], id[ firstDot .. ]); } + } \ No newline at end of file diff --git a/src/HassModel/NetDeamon.HassModel/Internal/Extensions/ObservableExtensions.cs b/src/HassModel/NetDeamon.HassModel/Internal/Extensions/ObservableExtensions.cs deleted file mode 100644 index 7a58d8748..000000000 --- a/src/HassModel/NetDeamon.HassModel/Internal/Extensions/ObservableExtensions.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Reactive; -using System.Reactive.Linq; -using System.Threading.Tasks; - -namespace NetDaemon.HassModel.Internal.Extensions; -static class ObservableExtensions -{ - /// - /// IObservable wrapper that calls each subscriber in a separate background task - /// - public static IObservable AsConcurrent(this IObservable observable, Action trackTask) => - Observable.Create(subscribe: a => observable.Subscribe(a.AsConcurrent(trackTask))); - - /// - /// IObserver wrapper that calls OnNext in a separate background task that can be tracked - /// - private static IObserver AsConcurrent(this IObserver inner, Action trackTask) - => Observer.Create(onNext: obj => - { - var task = Task.Run(() => inner.OnNext(obj)); - trackTask(task); - }); -} \ No newline at end of file diff --git a/src/HassModel/NetDeamon.HassModel/Internal/FormatHelpers.cs b/src/HassModel/NetDeamon.HassModel/Internal/FormatHelpers.cs index d1ff19d69..4d1904c9b 100644 --- a/src/HassModel/NetDeamon.HassModel/Internal/FormatHelpers.cs +++ b/src/HassModel/NetDeamon.HassModel/Internal/FormatHelpers.cs @@ -1,6 +1,4 @@ -using System.Globalization; - -namespace NetDaemon.HassModel.Internal; +namespace NetDaemon.HassModel.Internal; internal class FormatHelpers { diff --git a/src/HassModel/NetDeamon.HassModel/Internal/HassObjectMapper.cs b/src/HassModel/NetDeamon.HassModel/Internal/HassObjectMapper.cs index 57f01ed8e..59822a64f 100644 --- a/src/HassModel/NetDeamon.HassModel/Internal/HassObjectMapper.cs +++ b/src/HassModel/NetDeamon.HassModel/Internal/HassObjectMapper.cs @@ -1,8 +1,4 @@ -using NetDaemon.Client.Common.HomeAssistant.Model; -using NetDaemon.HassModel.Common; -using NetDaemon.HassModel.Entities; - -namespace NetDaemon.HassModel.Internal; +namespace NetDaemon.HassModel.Internal; internal static class HassObjectMapper { diff --git a/src/HassModel/NetDeamon.HassModel/Internal/QueuedObservable.cs b/src/HassModel/NetDeamon.HassModel/Internal/QueuedObservable.cs index 13911b858..401f5e2da 100644 --- a/src/HassModel/NetDeamon.HassModel/Internal/QueuedObservable.cs +++ b/src/HassModel/NetDeamon.HassModel/Internal/QueuedObservable.cs @@ -1,11 +1,5 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using System.Reactive.Subjects; -using System.Threading; +using System.Threading; using System.Threading.Channels; -using System.Threading.Tasks; -using Microsoft.Extensions.Logging; -using NetDaemon.HassModel.Common; using NetDaemon.Infrastructure.ObservableHelpers; namespace NetDaemon.HassModel.Internal; diff --git a/src/HassModel/NetDeamon.HassModel/Internal/ScopedObservable.cs b/src/HassModel/NetDeamon.HassModel/Internal/ScopedObservable.cs index e910d3204..565ddc7ad 100644 --- a/src/HassModel/NetDeamon.HassModel/Internal/ScopedObservable.cs +++ b/src/HassModel/NetDeamon.HassModel/Internal/ScopedObservable.cs @@ -1,31 +1,25 @@ -using System; -using System.Reactive.Subjects; -using Microsoft.Extensions.Logging; +namespace NetDaemon.HassModel.Internal; -namespace NetDaemon.HassModel.Internal +/// +/// Wraps an Observable so all subscribers can be unsubscribed by disposing +/// +internal sealed class ScopedObservable : IObservable, IDisposable { - /// - /// Wraps an Observable so all subscribers can be unsubscribed by disposing - /// - internal sealed class ScopedObservable : IObservable, IDisposable - { - private readonly IDisposable _subscription; - private readonly Subject _subject = new(); + private readonly IDisposable _subscription; + private readonly Subject _subject = new(); - public ScopedObservable(IObservable innerObservable) - { - _subscription = innerObservable.Subscribe(_subject); - } + public ScopedObservable(IObservable innerObservable) + { + _subscription = innerObservable.Subscribe(_subject); + } - public IDisposable Subscribe(IObserver observer) => _subject.Subscribe(observer); + public IDisposable Subscribe(IObserver observer) => _subject.Subscribe(observer); - public void Dispose() - { - // When disposed unsubscribe from inner observable - // this will make all subscribers of our Subject stop receiving events - _subscription.Dispose(); - _subject.Dispose(); - } + public void Dispose() + { + // When disposed unsubscribe from inner observable + // this will make all subscribers of our Subject stop receiving events + _subscription.Dispose(); + _subject.Dispose(); } -} - +} \ No newline at end of file diff --git a/src/HassModel/NetDeamon.HassModel/NetDaemon.HassModel.csproj b/src/HassModel/NetDeamon.HassModel/NetDaemon.HassModel.csproj index acd08e222..61b10c09b 100644 --- a/src/HassModel/NetDeamon.HassModel/NetDaemon.HassModel.csproj +++ b/src/HassModel/NetDeamon.HassModel/NetDaemon.HassModel.csproj @@ -37,6 +37,9 @@ + + + ..\..\..\.linting\roslynator.ruleset diff --git a/src/HassModel/NetDeamon.HassModel/Common/ObservableExtensions.cs b/src/HassModel/NetDeamon.HassModel/ObservableExtensions.cs similarity index 94% rename from src/HassModel/NetDeamon.HassModel/Common/ObservableExtensions.cs rename to src/HassModel/NetDeamon.HassModel/ObservableExtensions.cs index 7230a47d9..36117e0e5 100644 --- a/src/HassModel/NetDeamon.HassModel/Common/ObservableExtensions.cs +++ b/src/HassModel/NetDeamon.HassModel/ObservableExtensions.cs @@ -1,9 +1,4 @@ -using System; -using System.Reactive.Linq; -using System.Threading.Tasks; -using Microsoft.Extensions.Logging; - -namespace NetDaemon.HassModel.Common; +namespace NetDaemon.HassModel; /// /// Adds async and concurrent extensions on observables diff --git a/src/HassModel/NetDeamon.HassModel/ServiceTarget.cs b/src/HassModel/NetDeamon.HassModel/ServiceTarget.cs new file mode 100644 index 000000000..9c6a4d102 --- /dev/null +++ b/src/HassModel/NetDeamon.HassModel/ServiceTarget.cs @@ -0,0 +1,52 @@ +namespace NetDaemon.HassModel.Entities; + +/// +/// Target for a service call +/// +public class ServiceTarget +{ + /// + /// Creates a new ServiceTarget from an EntityId + /// + /// The Id of teh entity + /// A new ServiceTarget + public static ServiceTarget FromEntity(string entityId) => + new() { EntityIds = new[] { entityId } }; + + /// + /// Creates a new ServiceTarget from a list of EntityIds + /// + /// The Ids of entities + /// A new ServiceTarget + public static ServiceTarget FromEntities(IEnumerable entityIds) => + new() { EntityIds = entityIds.ToArray() }; + + /// + /// Creates a new ServiceTarget from EntityIds + /// + /// The Ids of entities + /// A new ServiceTarget + public static ServiceTarget FromEntities(params string[] entityIds) => + new() { EntityIds = entityIds.ToArray() }; + + /// + /// Creates a new empty ServiceTarget + /// + public ServiceTarget() + { } + + /// + /// IDs of entities to invoke a service on + /// + public IReadOnlyCollection? EntityIds { get; init; } + + /// + /// Ids of Devices to invoke a service on + /// + public IReadOnlyCollection? DeviceIds { get; init; } + + /// + /// Ids of Areas to invoke a service on + /// + public IReadOnlyCollection? AreaIds { get; init; } +} \ No newline at end of file diff --git a/src/Host/NetDaemon.Host.Default/Program.cs b/src/Host/NetDaemon.Host.Default/Program.cs index 9822308c4..74ee1954f 100644 --- a/src/Host/NetDaemon.Host.Default/Program.cs +++ b/src/Host/NetDaemon.Host.Default/Program.cs @@ -1,5 +1,4 @@ using System; -using System.Reflection; using System.Runtime.Loader; using Microsoft.Extensions.Hosting; using NetDaemon.AppModel; diff --git a/src/Runtime/NetDaemon.Runtime.Tests/Fixtures/LocalApp.cs b/src/Runtime/NetDaemon.Runtime.Tests/Fixtures/LocalApp.cs index 422ab73e9..2e08f2aae 100644 --- a/src/Runtime/NetDaemon.Runtime.Tests/Fixtures/LocalApp.cs +++ b/src/Runtime/NetDaemon.Runtime.Tests/Fixtures/LocalApp.cs @@ -1,5 +1,5 @@ using NetDaemon.AppModel; -using NetDaemon.HassModel.Common; +using NetDaemon.HassModel; using NetDaemon.HassModel.Entities; namespace LocalApps; diff --git a/src/Runtime/NetDaemon.Runtime.Tests/GlobalUsings.cs b/src/Runtime/NetDaemon.Runtime.Tests/GlobalUsings.cs index e5626b35d..d1b7f7161 100644 --- a/src/Runtime/NetDaemon.Runtime.Tests/GlobalUsings.cs +++ b/src/Runtime/NetDaemon.Runtime.Tests/GlobalUsings.cs @@ -5,11 +5,11 @@ global using FluentAssertions; global using Moq; global using Xunit; -global using NetDaemon.Client.Common; -global using NetDaemon.Client.Common.HomeAssistant.Model; +global using NetDaemon.Client; +global using NetDaemon.Client.HomeAssistant.Model; global using NetDaemon.Client.Internal.Extensions; global using NetDaemon.Client.Internal.HomeAssistant.Commands; -global using NetDaemon.Client.Common.Settings; +global using NetDaemon.Client.Settings; using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("NetDaemon.Runtime.Tests")] diff --git a/src/Runtime/NetDaemon.Runtime.Tests/Helpers/NonQueuedObservableMock.cs b/src/Runtime/NetDaemon.Runtime.Tests/Helpers/NonQueuedObservableMock.cs index 78533dd42..a5b9ca460 100644 --- a/src/Runtime/NetDaemon.Runtime.Tests/Helpers/NonQueuedObservableMock.cs +++ b/src/Runtime/NetDaemon.Runtime.Tests/Helpers/NonQueuedObservableMock.cs @@ -1,5 +1,5 @@ using System.Reactive.Subjects; -using NetDaemon.HassModel.Common; +using NetDaemon.HassModel; using NetDaemon.Infrastructure.ObservableHelpers; namespace NetDaemon.Runtime.Tests.Helpers; diff --git a/src/Runtime/NetDaemon.Runtime.Tests/Internal/AppStateManagerTests.cs b/src/Runtime/NetDaemon.Runtime.Tests/Internal/AppStateManagerTests.cs index 63e2a2b9a..db49431f9 100644 --- a/src/Runtime/NetDaemon.Runtime.Tests/Internal/AppStateManagerTests.cs +++ b/src/Runtime/NetDaemon.Runtime.Tests/Internal/AppStateManagerTests.cs @@ -3,7 +3,7 @@ using Microsoft.Extensions.DependencyInjection; using NetDaemon.AppModel; using NetDaemon.Client.Internal.Exceptions; -using NetDaemon.HassModel.Common; +using NetDaemon.HassModel; using NetDaemon.Runtime.Internal; using NetDaemon.Runtime.Internal.Model; diff --git a/src/Runtime/NetDaemon.Runtime.Tests/Internal/NetDaemonRuntimeTests.cs b/src/Runtime/NetDaemon.Runtime.Tests/Internal/NetDaemonRuntimeTests.cs index f7262d939..d1e08ea63 100644 --- a/src/Runtime/NetDaemon.Runtime.Tests/Internal/NetDaemonRuntimeTests.cs +++ b/src/Runtime/NetDaemon.Runtime.Tests/Internal/NetDaemonRuntimeTests.cs @@ -2,7 +2,6 @@ using Microsoft.Extensions.DependencyInjection; using NetDaemon.AppModel; using NetDaemon.HassModel; -using NetDaemon.HassModel.Common; using NetDaemon.HassModel.Internal; using NetDaemon.Runtime.Internal; diff --git a/src/Runtime/NetDaemon.Runtime/GlobalUsings.cs b/src/Runtime/NetDaemon.Runtime/GlobalUsings.cs index 38b5480c4..69cb0b759 100644 --- a/src/Runtime/NetDaemon.Runtime/GlobalUsings.cs +++ b/src/Runtime/NetDaemon.Runtime/GlobalUsings.cs @@ -2,10 +2,10 @@ global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Options; global using Microsoft.Extensions.Hosting; -global using NetDaemon.Client.Common; -global using NetDaemon.Client.Common.Extensions; -global using NetDaemon.Client.Common.HomeAssistant.Extensions; -global using NetDaemon.Client.Common.Settings; +global using NetDaemon.Client; +global using NetDaemon.Client.Extensions; +global using NetDaemon.Client.HomeAssistant.Extensions; +global using NetDaemon.Client.Settings; using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("NetDaemon.Runtime.Tests")] diff --git a/src/Runtime/NetDaemon.Runtime/Internal/AppStateManager.cs b/src/Runtime/NetDaemon.Runtime/Internal/AppStateManager.cs index ac3cf09e5..4d0739e23 100644 --- a/src/Runtime/NetDaemon.Runtime/Internal/AppStateManager.cs +++ b/src/Runtime/NetDaemon.Runtime/Internal/AppStateManager.cs @@ -5,7 +5,7 @@ using System.Reactive.Linq; using System.Text; using NetDaemon.AppModel; -using NetDaemon.Client.Common.HomeAssistant.Model; +using NetDaemon.Client.HomeAssistant.Model; using NetDaemon.Client.Internal.Exceptions; namespace NetDaemon.Runtime.Internal; diff --git a/src/Runtime/NetDaemon.Runtime/Internal/Model/CreateInputBooleanHelperCommand.cs b/src/Runtime/NetDaemon.Runtime/Internal/Model/CreateInputBooleanHelperCommand.cs index ea471a5d5..d614646b7 100644 --- a/src/Runtime/NetDaemon.Runtime/Internal/Model/CreateInputBooleanHelperCommand.cs +++ b/src/Runtime/NetDaemon.Runtime/Internal/Model/CreateInputBooleanHelperCommand.cs @@ -1,5 +1,5 @@ using System.Text.Json.Serialization; -using NetDaemon.Client.Common.HomeAssistant.Model; +using NetDaemon.Client.HomeAssistant.Model; namespace NetDaemon.Runtime.Internal.Model; diff --git a/src/Runtime/NetDaemon.Runtime/Internal/NetDaemonRuntime.cs b/src/Runtime/NetDaemon.Runtime/Internal/NetDaemonRuntime.cs index 690d82dc2..6498de8c0 100644 --- a/src/Runtime/NetDaemon.Runtime/Internal/NetDaemonRuntime.cs +++ b/src/Runtime/NetDaemon.Runtime/Internal/NetDaemonRuntime.cs @@ -1,6 +1,6 @@ using System.Reactive.Linq; using NetDaemon.AppModel; -using NetDaemon.HassModel.Common; +using NetDaemon.HassModel; namespace NetDaemon.Runtime.Internal; diff --git a/tests/Integration/NetDaemon.Tests.Integration/BasicTest.cs b/tests/Integration/NetDaemon.Tests.Integration/BasicTest.cs index ccc8f2b2d..4603d18d2 100644 --- a/tests/Integration/NetDaemon.Tests.Integration/BasicTest.cs +++ b/tests/Integration/NetDaemon.Tests.Integration/BasicTest.cs @@ -4,7 +4,7 @@ using System.Threading.Tasks; using FluentAssertions; using NetDaemon.AppModel; -using NetDaemon.HassModel.Common; +using NetDaemon.HassModel; using NetDaemon.HassModel.Entities; using NetDaemon.Tests.Integration.Helpers; using Xunit; diff --git a/tests/Integration/NetDaemon.Tests.Integration/Helpers/TestFixture.cs b/tests/Integration/NetDaemon.Tests.Integration/Helpers/TestFixture.cs index fe09a0d0a..cbdfb4ccf 100644 --- a/tests/Integration/NetDaemon.Tests.Integration/Helpers/TestFixture.cs +++ b/tests/Integration/NetDaemon.Tests.Integration/Helpers/TestFixture.cs @@ -1,6 +1,6 @@ using System.Threading; using System.Threading.Tasks; -using NetDaemon.Client.Common; +using NetDaemon.Client; using Xunit; namespace NetDaemon.Tests.Integration.Helpers;