-
-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Prototype - Trigger subscriptions (#860)
* A first prototype of subscribe to triggers * Removed the dictionary * some changes * Draft of TriggerManager * add CAF * Simplified * Correct format * Removed special classes and updated testapp to use anonumous type * refactor and filter normal events on message id * fix test * fix warnings * rename * fix warning * relax CA on debug project * Added test for TriggerManager * small fix --------- Co-authored-by: Frank Bakker <[email protected]>
- Loading branch information
1 parent
b3dc9e4
commit 22e8e70
Showing
15 changed files
with
371 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 5 additions & 1 deletion
6
src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassEvent.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 6 additions & 0 deletions
6
src/Client/NetDaemon.HassClient/Common/HomeAssistant/Model/HassVariable.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace NetDaemon.Client.Common.HomeAssistant.Model; | ||
|
||
public record HassVariable | ||
{ | ||
[JsonPropertyName("trigger")] public JsonElement? TriggerElement { get; init; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
src/Client/NetDaemon.HassClient/Internal/HomeAssistant/Commands/SubscribeTriggerCommand.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
namespace NetDaemon.Client.Internal.HomeAssistant.Commands; | ||
|
||
internal record SubscribeTriggerCommand : CommandMessage | ||
{ | ||
public SubscribeTriggerCommand(object trigger) | ||
{ | ||
Type = "subscribe_trigger"; | ||
Trigger = trigger; | ||
} | ||
|
||
[JsonPropertyName("trigger")] | ||
public object Trigger { get; init; } | ||
} |
12 changes: 12 additions & 0 deletions
12
src/Client/NetDaemon.HassClient/Internal/HomeAssistant/Commands/UnsubscribeEventsCommand.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
namespace NetDaemon.Client.Internal.HomeAssistant.Commands; | ||
|
||
internal record UnsubscribeEventsCommand : CommandMessage | ||
{ | ||
public UnsubscribeEventsCommand(int subscriptionId) | ||
{ | ||
Type = "unsubscribe_events"; | ||
Subscription = subscriptionId; | ||
} | ||
|
||
[JsonPropertyName("subscription")] public int Subscription { get; init; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
117 changes: 117 additions & 0 deletions
117
src/HassModel/NetDaemon.HassModel.Tests/Internal/TriggerManagerTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
using System.Reactive.Subjects; | ||
using System.Text.Json; | ||
using System.Threading; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using NetDaemon.Client; | ||
using NetDaemon.Client.Common.HomeAssistant.Model; | ||
using NetDaemon.Client.HomeAssistant.Model; | ||
using NetDaemon.Client.Internal.HomeAssistant.Commands; | ||
using NetDaemon.HassModel.Tests.TestHelpers; | ||
|
||
namespace NetDaemon.HassModel.Tests.Internal; | ||
|
||
public class TriggerManagerTest | ||
{ | ||
private readonly ITriggerManager _triggerManager; | ||
|
||
private readonly Mock<IHomeAssistantConnection> _hassConnectionMock = new(); | ||
private readonly Subject<HassMessage> _messageSubject = new(); | ||
|
||
private int nextMessageId = 5; | ||
|
||
public TriggerManagerTest() | ||
{ | ||
_hassConnectionMock.Setup(m => m.SendCommandAndReturnHassMessageResponseAsync( | ||
It.IsAny<SubscribeTriggerCommand>(), It.IsAny<CancellationToken>())) | ||
.ReturnsAsync(() => new HassMessage { Id = nextMessageId }); | ||
|
||
_hassConnectionMock.Setup(m => m.SendCommandAndReturnHassMessageResponseAsync( | ||
It.IsAny<UnsubscribeEventsCommand>(), It.IsAny<CancellationToken>())) | ||
.ReturnsAsync(() => new HassMessage { Id = nextMessageId }); | ||
|
||
_hassConnectionMock | ||
.As<IHomeAssistantHassMessages>() | ||
.SetupGet(m => m.OnHassMessage) | ||
.Returns(_messageSubject); | ||
|
||
var provider = CreateServiceProvider(); | ||
_triggerManager = provider.GetRequiredService<ITriggerManager>(); | ||
} | ||
|
||
|
||
private ServiceProvider CreateServiceProvider() | ||
{ | ||
var serviceCollection = new ServiceCollection(); | ||
serviceCollection.AddLogging(); | ||
serviceCollection.AddScopedHaContext(); | ||
|
||
var haRunnerMock = new Mock<IHomeAssistantRunner>(); | ||
|
||
haRunnerMock.SetupGet(n => n.CurrentConnection).Returns(_hassConnectionMock.Object); | ||
serviceCollection.AddSingleton(_ => haRunnerMock.Object); | ||
|
||
var provider = serviceCollection.BuildServiceProvider(); | ||
|
||
return provider; | ||
} | ||
|
||
|
||
[Fact] | ||
public void RegisterTrigger() | ||
{ | ||
var incomingTriggersMock = _triggerManager.RegisterTrigger(new {}).SubscribeMock(); | ||
|
||
var message = new { }.AsJsonElement(); | ||
|
||
_messageSubject.OnNext(new HassMessage(){Id = nextMessageId, Event = new HassEvent(){Variables = new HassVariable() | ||
{TriggerElement = message }}}); | ||
|
||
// Assert | ||
incomingTriggersMock.Verify(e => e.OnNext(message)); | ||
} | ||
|
||
[Fact] | ||
public async void NoMoreTriggersAfterDispose() | ||
{ | ||
// Act | ||
var incomingTriggersMock = _triggerManager.RegisterTrigger(new {}).SubscribeMock(); | ||
|
||
await ((IAsyncDisposable)_triggerManager).DisposeAsync().ConfigureAwait(false); | ||
|
||
// Assert, Dispose should unsubscribe with HA AND stop any messages that do pass | ||
_hassConnectionMock.Verify(m => m.SendCommandAndReturnHassMessageResponseAsync( | ||
new UnsubscribeEventsCommand(nextMessageId), It.IsAny<CancellationToken>())); | ||
|
||
_messageSubject.OnNext(new HassMessage(){Id = nextMessageId, Event = new HassEvent(){Variables = new HassVariable() | ||
{TriggerElement = new JsonElement() }}}); | ||
|
||
incomingTriggersMock.VerifyNoOtherCalls(); | ||
} | ||
|
||
|
||
[Fact] | ||
public void RegisterTriggerCorrectMessagesPerSubscription() | ||
{ | ||
nextMessageId = 6; | ||
var incomingTriggersMock6 = _triggerManager.RegisterTrigger(new {}).SubscribeMock(); | ||
|
||
nextMessageId = 7; | ||
var incomingTriggersMock7 = _triggerManager.RegisterTrigger(new {}).SubscribeMock(); | ||
|
||
var message6 = new { tag = "six" }.AsJsonElement(); | ||
var message7 = new { tag = "seven" }.AsJsonElement(); | ||
|
||
// Assert | ||
_messageSubject.OnNext(new HassMessage{Id = 6, Event = new HassEvent(){Variables = new HassVariable() | ||
{TriggerElement = message6 }}}); | ||
|
||
|
||
_messageSubject.OnNext(new HassMessage{Id = 7, Event = new HassEvent(){Variables = new HassVariable() | ||
{TriggerElement = message7 }}}); | ||
|
||
incomingTriggersMock6.Verify(e => e.OnNext(message6), Times.Once); | ||
incomingTriggersMock7.Verify(e => e.OnNext(message7), Times.Once); | ||
} | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
namespace NetDaemon.HassModel; | ||
|
||
/// <summary> | ||
/// Enables the creation of triggers | ||
/// </summary> | ||
public interface ITriggerManager | ||
{ | ||
/// <summary> | ||
/// Registers a trigger in HA and returns an Observable with the events | ||
/// </summary> | ||
/// <param name="triggerParams">Input data for HA register_trigger command</param> | ||
/// <returns>IObservable with all events resulting from this trigger</returns> | ||
IObservable<JsonElement> RegisterTrigger(object triggerParams); | ||
} |
Oops, something went wrong.