Skip to content

Commit 32c098b

Browse files
authored
Refresh state areas when devices or areas updated (#110)
* Refresh state areas when devices or areas updated * Also refresh all from server too
1 parent 9a51647 commit 32c098b

File tree

5 files changed

+49
-33
lines changed

5 files changed

+49
-33
lines changed

src/App/NetDaemon.App/NetDaemon.App.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
</PropertyGroup>
2424

2525
<ItemGroup>
26-
<PackageReference Include="JoySoftware.HassClient" Version="0.3.1-alpha" />
26+
<PackageReference Include="JoySoftware.HassClient" Version="0.3.2-alpha" />
2727
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="3.1.3" />
2828
</ItemGroup>
2929

src/Daemon/NetDaemon.Daemon/Daemon/NetDaemonHost.cs

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ public ICamera Cameras(INetDaemonApp app, Func<IEntityProperties, bool> func)
213213
/// <param name="cancellationToken"></param>
214214
public async Task Run(string host, short port, bool ssl, string token, CancellationToken cancellationToken)
215215
{
216+
_cancelToken = cancellationToken;
217+
216218
string? hassioToken = Environment.GetEnvironmentVariable("HASSIO_TOKEN");
217219

218220
if (_hassClient == null)
@@ -228,7 +230,7 @@ public async Task Run(string host, short port, bool ssl, string token, Cancellat
228230
{
229231
// We are running as hassio add-on
230232
connectResult = await _hassClient.ConnectAsync(new Uri("ws://supervisor/core/websocket"),
231-
hassioToken, true).ConfigureAwait(false);
233+
hassioToken, false).ConfigureAwait(false);
232234
}
233235
else
234236
{
@@ -244,35 +246,9 @@ public async Task Run(string host, short port, bool ssl, string token, Cancellat
244246
// Setup TTS
245247
Task handleTextToSpeechMessagesTask = HandleTextToSpeechMessages(cancellationToken);
246248

247-
await _hassClient.SubscribeToEvents().ConfigureAwait(false);
249+
await RefreshInternalStatesAndSetArea().ConfigureAwait(false);
248250

249-
foreach (var device in await _hassClient.GetDevices().ConfigureAwait(false))
250-
{
251-
if (device is object && device.Id is object)
252-
_hassDevices[device.Id] = device;
253-
}
254-
foreach (var area in await _hassClient.GetAreas().ConfigureAwait(false))
255-
{
256-
if (area is object && area.Id is object)
257-
_hassAreas[area.Id] = area;
258-
}
259-
foreach (var entity in await _hassClient.GetEntities().ConfigureAwait(false))
260-
{
261-
if (entity is object && entity.EntityId is object)
262-
_hassEntities[entity.EntityId] = entity;
263-
}
264-
265-
var initialStates = _hassClient.States.Values.Select(n => n.ToDaemonEntityState())
266-
.ToDictionary(n => n.EntityId);
267-
268-
269-
270-
foreach (var key in initialStates.Keys)
271-
{
272-
var state = initialStates[key];
273-
state.Area = GetAreaForEntityId(state.EntityId);
274-
InternalState[key] = state;
275-
}
251+
await _hassClient.SubscribeToEvents().ConfigureAwait(false);
276252

277253
Connected = true;
278254

@@ -309,6 +285,36 @@ public async Task Run(string host, short port, bool ssl, string token, Cancellat
309285
}
310286
}
311287

288+
internal async Task RefreshInternalStatesAndSetArea()
289+
{
290+
foreach (var device in await _hassClient.GetDevices().ConfigureAwait(false))
291+
{
292+
if (device is object && device.Id is object)
293+
_hassDevices[device.Id] = device;
294+
}
295+
foreach (var area in await _hassClient.GetAreas().ConfigureAwait(false))
296+
{
297+
if (area is object && area.Id is object)
298+
_hassAreas[area.Id] = area;
299+
}
300+
foreach (var entity in await _hassClient.GetEntities().ConfigureAwait(false))
301+
{
302+
if (entity is object && entity.EntityId is object)
303+
_hassEntities[entity.EntityId] = entity;
304+
}
305+
var hassStates = await _hassClient.GetAllStates(_cancelToken).ConfigureAwait(false);
306+
var initialStates = hassStates.Select(n => n.ToDaemonEntityState())
307+
.ToDictionary(n => n.EntityId);
308+
309+
InternalState.Clear();
310+
foreach (var key in initialStates.Keys)
311+
{
312+
var state = initialStates[key];
313+
state.Area = GetAreaForEntityId(state.EntityId);
314+
InternalState[key] = state;
315+
}
316+
}
317+
312318
internal string? GetAreaForEntityId(string entityId)
313319
{
314320
HassEntity? entity;
@@ -352,6 +358,7 @@ public async Task Run(string host, short port, bool ssl, string token, Cancellat
352358
if (result != null)
353359
{
354360
EntityState entityState = result.ToDaemonEntityState();
361+
entityState.Area = GetAreaForEntityId(entityState.EntityId);
355362
InternalState[entityState.EntityId] = entityState;
356363
return entityState;
357364
}
@@ -472,6 +479,10 @@ protected virtual async Task HandleNewEvent(HassEvent hassEvent, CancellationTok
472479
throw;
473480
}
474481
}
482+
else if (hassEvent.EventType == "device_registry_updated" || hassEvent.EventType == "area_registry_updated")
483+
{
484+
await RefreshInternalStatesAndSetArea().ConfigureAwait(false);
485+
}
475486
else
476487
{
477488
try
@@ -553,6 +564,7 @@ private async Task HandleTextToSpeechMessages(CancellationToken cancellationToke
553564
}
554565

555566
private IDictionary<string, object> _dataCache = new Dictionary<string, object>();
567+
private CancellationToken _cancelToken;
556568

557569
// Internal for test
558570
internal readonly ConcurrentDictionary<string, HassDevice> _hassDevices =

src/Daemon/NetDaemon.Daemon/NetDaemon.Daemon.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
</PropertyGroup>
2222
<ItemGroup>
23-
<PackageReference Include="JoySoftware.HassClient" Version="0.3.1-alpha" />
23+
<PackageReference Include="JoySoftware.HassClient" Version="0.3.2-alpha" />
2424
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.3" />
2525
</ItemGroup>
2626
<ItemGroup>

src/DaemonRunner/DaemonRunner/DaemonRunner.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
</PropertyGroup>
2323
<ItemGroup>
24-
<PackageReference Include="JoySoftware.HassClient" Version="0.3.1-alpha" />
24+
<PackageReference Include="JoySoftware.HassClient" Version="0.3.2-alpha" />
2525
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.5.0" />
2626
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.3" />
2727
<PackageReference Include="YamlDotNet" Version="8.1.1" />

tests/NetDaemon.Daemon.Tests/HassClientMock.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,14 @@ public HassClientMock()
2929
Setup(x => x.ConnectAsync(It.IsAny<string>(), It.IsAny<short>(), It.IsAny<bool>(),
3030
It.IsAny<string>(), It.IsAny<bool>()))
3131
.ReturnsAsync(true);
32-
SetupGet(x => x.States).Returns(FakeStates);
3332

3433
SetupDefaultStates();
3534

35+
SetupGet(x => x.States).Returns(FakeStates);
36+
37+
Setup(x => x.GetAllStates(It.IsAny<CancellationToken>()))
38+
.ReturnsAsync(() => { return (IEnumerable<HassState>)FakeStates.Values; });
39+
3640
Setup(x => x.ReadEventAsync())
3741
.ReturnsAsync(() => { return FakeEvents.TryDequeue(out var ev) ? ev : null; });
3842

0 commit comments

Comments
 (0)