Skip to content

Commit

Permalink
Implement wait for response CallService
Browse files Browse the repository at this point in the history
  • Loading branch information
helto4real committed Jan 10, 2021
1 parent fb2a3dc commit 715a55a
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 19 deletions.
3 changes: 2 additions & 1 deletion src/App/NetDaemon.App/Common/INetDaemon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ public interface INetDaemon : INetDaemonCommon
/// <param name="domain">The domain of the service</param>
/// <param name="service">The service being called</param>
/// <param name="data">Any data that the service requires</param>
void CallService(string domain, string service, dynamic? data = null);
/// <param name="waitForResponse">Waits for Home Assistant to return result before returning</param>
void CallService(string domain, string service, dynamic? data = null, bool waitForResponse = false);

/// <summary>
/// Calls a service
Expand Down
3 changes: 2 additions & 1 deletion src/App/NetDaemon.App/Common/Reactive/INetDaemonReactive.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ public interface INetDaemonRxApp : INetDaemonAppBase, IRxEntity
/// <param name="domain">Domain of sevice</param>
/// <param name="service">Service name</param>
/// <param name="data">Data provided to service. Use anonomous type</param>
void CallService(string domain, string service, dynamic? data);
/// <param name="waitForResponse">Waits for Home Assistant to return result before returning</param>
void CallService(string domain, string service, dynamic? data, bool waitForResponse = false);

/// <summary>
/// Calls service in Home Assistant
Expand Down
6 changes: 2 additions & 4 deletions src/App/NetDaemon.App/Common/Reactive/NetDaemonRxApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,17 @@ protected NetDaemonRxApp()
Daemon?.State ?? new List<EntityState>();

/// <inheritdoc/>
public void CallService(string domain, string service, dynamic? data)
public void CallService(string domain, string service, dynamic? data, bool waitForResponse = false)
{
_ = Daemon ?? throw new NetDaemonNullReferenceException($"{nameof(Daemon)} cant be null!");
Daemon.CallService(domain, service, data);
Daemon.CallService(domain, service, data, waitForResponse);
}

/// <inheritdoc/>
public void Delay(TimeSpan timeout)
{
// We use Task.Delay instead of Thread.Sleep so we can stop timers on cancellation tokens
Task.Delay(timeout, _cancelTimers.Token).Wait(_cancelTimers.Token);
Logger.LogError("WE REACHED END OF DELAY!");
}

/// <inheritdoc/>
Expand All @@ -83,7 +82,6 @@ public void Delay(TimeSpan timeout, CancellationToken token)
using var combinedToken = CancellationTokenSource.CreateLinkedTokenSource(_cancelTimers.Token, token);
// We use Task.Delay instead of Thread.Sleep so we can stop timers on cancellation tokens
Task.Delay(timeout, combinedToken.Token).Wait(combinedToken.Token);
Logger.LogError("WE REACHED END OF DELAY2!");
}

/// <summary>
Expand Down
12 changes: 7 additions & 5 deletions src/App/NetDaemon.App/Common/Reactive/RxEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ public interface IRxEntityBase
/// </summary>
/// <param name="state">The state to set, primitives only</param>
/// <param name="attributes">The attributes to set. Use anonomous type</param>
void SetState(dynamic state, dynamic? attributes = null);
/// <param name="waitForResponse">Waits for Home Assistant to return result before returning</param>
void SetState(dynamic state, dynamic? attributes = null, bool waitForResponse = false);

/// <summary>
/// Toggles state on/off on entity
Expand Down Expand Up @@ -94,11 +95,11 @@ public RxEntity(INetDaemonRxApp daemon, IEnumerable<string> entityIds)
}

/// <inheritdoc/>
public void SetState(dynamic state, dynamic? attributes = null)
public void SetState(dynamic state, dynamic? attributes = null, bool waitForResponse = false)
{
foreach (var entityId in EntityIds)
{
DaemonRxApp.SetState(entityId, state, attributes);
DaemonRxApp.SetState(entityId, state, attributes, waitForResponse);
}
}

Expand All @@ -125,7 +126,8 @@ internal static string GetDomainFromEntity(string entity)
/// </summary>
/// <param name="service">Name of the service to call</param>
/// <param name="data">Data to provide</param>
public void CallService(string service, dynamic? data = null)
/// <param name="waitForResponse">Waits for Home Assistant to return result before returning</param>
public void CallService(string service, dynamic? data = null, bool waitForResponse = false)
{
if (EntityIds?.Any() != true)
return;
Expand Down Expand Up @@ -153,7 +155,7 @@ public void CallService(string service, dynamic? data = null)

serviceData["entity_id"] = entityId;

DaemonRxApp.CallService(domain, service, serviceData);
DaemonRxApp.CallService(domain, service, serviceData, waitForResponse);
}
}

Expand Down
13 changes: 10 additions & 3 deletions src/Daemon/NetDaemon.Daemon/Daemon/NetDaemonHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,12 +159,19 @@ public async Task<IEnumerable<HassServiceDomain>> GetAllServices()
return await _hassClient.GetServices().ConfigureAwait(false);
}

public void CallService(string domain, string service, dynamic? data = null)
public void CallService(string domain, string service, dynamic? data = null, bool waitForResponse = false)
{
_cancelToken.ThrowIfCancellationRequested();

if (!_serviceCallMessageChannel.Writer.TryWrite((domain, service, data)))
throw new NetDaemonException("Servicecall queue full!");
if (!waitForResponse)
{
if (!_serviceCallMessageChannel.Writer.TryWrite((domain, service, data)))
throw new NetDaemonException("Servicecall queue full!");
}
else
{
CallServiceAsync(domain, service, data, true).Result();
}
}

[SuppressMessage("", "CA1031")]
Expand Down
1 change: 1 addition & 0 deletions src/DevelopmentApps/apps/DebugApp/DebugApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public override void Initialize()
{
var uid = Guid.NewGuid();
RunEvery(TimeSpan.FromSeconds(5), () => Log("Hello developer! from instance {instanceId} - {id}", _instanceId, uid));
CallService("notify", "persistent_notification", new { message = "Hello", title = "Yay it works!" }, true);
}

[HomeAssistantServiceCall]
Expand Down
14 changes: 9 additions & 5 deletions src/Fakes/NetDaemon.Fakes/RxAppMock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ public void VerifyCallService(string? domain = null, string? service = null, dyn
domain ??= It.IsAny<string>();
service ??= It.IsAny<string>();
data ??= It.IsAny<object>();
Verify(x => x.CallService(domain, service, It.IsAny<object>()), t);
Verify(x => x.CallService(domain, service, It.IsAny<object>(), It.IsAny<bool>()), t);
}

/// <summary>
Expand Down Expand Up @@ -276,14 +276,16 @@ public void VerifyEntityToggle(string entityId, dynamic? attributes = null, Time
{
Verify(x => x.Entity(entityId).SetState(
(object)state,
(object)attributes),
(object)attributes,
It.IsAny<bool>()),
t);
}
else
{
Verify(x => x.Entity(entityId).SetState(
(object)state,
It.IsAny<object>()),
It.IsAny<object>(),
It.IsAny<bool>()),
t);
}
}
Expand All @@ -293,14 +295,16 @@ public void VerifyEntityToggle(string entityId, dynamic? attributes = null, Time
{
Verify(x => x.Entity(entityId).SetState(
It.IsAny<object>(),
(object)attributes),
(object)attributes,
It.IsAny<bool>()),
t);
}
else
{
Verify(x => x.Entity(entityId).SetState(
It.IsAny<object>(),
It.IsAny<object>()),
It.IsAny<object>(),
It.IsAny<bool>()),
t);
}
}
Expand Down

0 comments on commit 715a55a

Please sign in to comment.