Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 VerifyEntitySetState(string entityId, dynamic? state = null
{
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 VerifyEntitySetState(string entityId, dynamic? state = null
{
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