Skip to content

Commit 7d2e24e

Browse files
committed
Rework the entire live control stuff & module base to be more stable for future use
1 parent 82e463b commit 7d2e24e

29 files changed

+247
-166
lines changed

Desktop/Backend/BackendHubManager.cs

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
using System.Globalization;
1+
using System.Collections.Concurrent;
2+
using System.Globalization;
3+
using System.Reactive.Subjects;
24
using MudBlazor.Extensions;
35
using OpenShock.Desktop.Config;
46
using OpenShock.Desktop.Models;
7+
using OpenShock.Desktop.Models.BaseImpl;
8+
using OpenShock.Desktop.ModuleBase.Models;
59
using OpenShock.Desktop.Services;
610
using OpenShock.MinimalEvents;
711
using OpenShock.SDK.CSharp.Hub;
@@ -22,6 +26,10 @@ public sealed class BackendHubManager
2226

2327
public IAsyncMinimalEventObservable<LogEventArgs> OnRemoteControlledShocker => _onRemoteControlledShocker;
2428
private readonly AsyncMinimalEvent<LogEventArgs> _onRemoteControlledShocker = new();
29+
30+
public Subject<Guid?> OnHubStatusUpdated { get; } = new();
31+
32+
2533

2634
public BackendHubManager(ILogger<BackendHubManager> logger,
2735
ConfigManager configManager,
@@ -31,21 +39,53 @@ public BackendHubManager(ILogger<BackendHubManager> logger,
3139
_configManager = configManager;
3240
_openShockHubClient = openShockHubClient;
3341
_openShockApi = openShockApi;
34-
35-
_openShockHubClient.OnWelcome.SubscribeAsync(s =>
36-
{
37-
_liveConnectionId = s;
38-
return Task.CompletedTask;
39-
}).AsTask().Wait();
4042

43+
_openShockHubClient.OnWelcome.SubscribeAsync(Welcome).AsTask().Wait();;
4144
_openShockHubClient.OnLog.SubscribeAsync(RemoteActivateShockers).AsTask().Wait();
4245
_openShockHubClient.OnHubUpdate.SubscribeAsync(DeviceUpdate).AsTask().Wait();
46+
47+
_openShockHubClient.OnHubStatus.SubscribeAsync(HubStatus).AsTask().Wait();
4348
}
4449

45-
private async Task DeviceUpdate(HubUpdateEventArgs hubUpdateEventArgs)
50+
private Task Welcome(string connectionId)
4651
{
47-
_logger.LogDebug("Device update received {DeviceId} {UpdateType}", hubUpdateEventArgs.HubId, hubUpdateEventArgs.UpdateType);
48-
52+
_liveConnectionId = connectionId;
53+
_openShockApi.HubStates.Clear();
54+
55+
OnHubStatusUpdated.OnNext(null);
56+
return Task.CompletedTask;
57+
}
58+
59+
private Task HubStatus(IReadOnlyList<HubOnlineState> states)
60+
{
61+
_logger.LogDebug("Hub status update received {Count} hubs", states.Count);
62+
63+
foreach (var state in states)
64+
{
65+
_openShockApi.HubStates[state.Device] = new HubStatus
66+
{
67+
Online = state.Online
68+
};
69+
_logger.LogDebug("Hub {HubId} is now {Online}", state.Device, state.Online ? "online" : "offline");
70+
}
71+
72+
OnHubStatusUpdated.OnNext(null);
73+
return Task.CompletedTask;
74+
}
75+
76+
private async Task DeviceUpdate(HubUpdateEventArgs update)
77+
{
78+
if (update.UpdateType is not HubUpdateType.Created)
79+
{
80+
if(_openShockApi.Hubs.Value.All(x => x.Id != update.HubId))
81+
{
82+
_logger.LogDebug("Hub update received for none of our hubs {HubId} {Type}, ignoring", update.HubId, update.UpdateType);
83+
return;
84+
}
85+
}
86+
87+
_logger.LogDebug("Device update received {DeviceId} {UpdateType}", update.HubId, update.UpdateType);
88+
4989
await _openShockApi.RefreshHubs();
5090
}
5191

Desktop/Backend/OpenShockApi.cs

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
using System.Collections.Immutable;
2-
using OneOf;
3-
using OneOf.Types;
1+
using System.Collections.Concurrent;
2+
using System.Collections.Immutable;
43
using OpenShock.Desktop.Config;
5-
using OpenShock.Desktop.ModuleBase.Models;
4+
using OpenShock.Desktop.Models.BaseImpl;
5+
using OpenShock.Desktop.ModuleBase.StableInterfaces;
66
using OpenShock.Desktop.Utils;
77
using OpenShock.SDK.CSharp;
8-
using OpenShock.SDK.CSharp.Models;
9-
using OpenShock.SDK.CSharp.Utils;
108

119
namespace OpenShock.Desktop.Backend;
1210

@@ -37,7 +35,8 @@ public void SetupApiClient()
3735
});
3836
}
3937

40-
public ObservableVariable<ImmutableArray<OpenShockHub>> Hubs { get; } = new(ImmutableArray<OpenShockHub>.Empty);
38+
public ObservableVariable<IReadOnlyList<IOpenShockHub>> Hubs { get; } = new(ImmutableArray<OpenShockHub>.Empty);
39+
public ConcurrentDictionary<Guid, HubStatus> HubStates { get; } = new();
4140

4241
public async Task RefreshHubs()
4342
{
@@ -50,7 +49,7 @@ public async Task RefreshHubs()
5049

5150
response.Switch(success =>
5251
{
53-
Hubs.Value = [..success.Value.Select(SdkDtoMappings.ToSdkHub)];
52+
Hubs.Value = [..success.Value.Select(x => x.ToSdkHub(this))];
5453

5554
// re-populate config with previous data if present, this also deletes any shockers that are no longer present
5655
var shockerList = new Dictionary<Guid, OpenShockConf.ShockerConf>();
@@ -82,18 +81,5 @@ public void Logout()
8281
{
8382
Hubs.Value = ImmutableArray<OpenShockHub>.Empty;
8483
}
85-
86-
public
87-
Task<OneOf<Success<LcgResponse>, NotFound, DeviceOffline, UnauthenticatedError>>
88-
GetDeviceGateway(Guid deviceId, CancellationToken cancellationToken = default)
89-
{
90-
if (Client == null)
91-
{
92-
_logger.LogError("Client is not initialized!");
93-
throw new Exception("Client is not initialized!");
94-
}
95-
96-
return Client.GetDeviceGateway(deviceId, cancellationToken);
97-
}
9884

9985
}

Desktop/Desktop.csproj

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@
3737
</PropertyGroup>
3838

3939
<ItemGroup Condition="'$(Configuration)' == 'Debug-Windows' Or '$(Configuration)' == 'Release-Windows'">
40-
<PackageReference Include="Microsoft.Maui.Controls" Version="9.0.70" />
41-
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="9.0.70" />
42-
<PackageReference Update="Microsoft.AspNetCore.Components.WebView.Maui" Version="9.0.70" />
43-
<PackageReference Update="Microsoft.AspNetCore.Components.Web" Version="9.0.5" />
40+
<PackageReference Include="Microsoft.Maui.Controls" Version="9.0.80" />
41+
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="9.0.80" />
42+
<PackageReference Update="Microsoft.AspNetCore.Components.WebView.Maui" Version="9.0.80" />
43+
<PackageReference Update="Microsoft.AspNetCore.Components.Web" Version="9.0.6" />
4444
</ItemGroup>
4545

4646
<PropertyGroup Condition="'$(Configuration)' == 'Debug-Photino' Or '$(Configuration)' == 'Release-Photino'">
@@ -61,23 +61,23 @@
6161
</PropertyGroup>
6262

6363
<ItemGroup>
64-
<PackageReference Include="AspNetCore.SassCompiler" Version="1.89.0" />
64+
<PackageReference Include="AspNetCore.SassCompiler" Version="1.89.2" />
6565
<PackageReference Include="CommandLineParser" Version="2.9.1"/>
6666
<PackageReference Include="dnlib" Version="4.5.0" />
67-
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.0.5" />
68-
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.5" />
69-
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.5" />
70-
<PackageReference Include="MudBlazor" Version="8.7.0" />
67+
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.0.6" />
68+
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.6" />
69+
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.6" />
70+
<PackageReference Include="MudBlazor" Version="8.8.0" />
7171
<PackageReference Include="Semver" Version="3.0.0" />
7272
<PackageReference Include="Serilog" Version="4.3.0" />
73-
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.5" />
73+
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.6" />
7474
<PackageReference Include="Serilog.Extensions.Hosting" Version="9.0.0" />
75-
<PackageReference Include="Serilog.Extensions.Logging" Version="9.0.1" />
75+
<PackageReference Include="Serilog.Extensions.Logging" Version="9.0.2" />
7676
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
7777
<PackageReference Include="Serilog.Sinks.Debug" Version="3.0.0" />
78-
<PackageReference Include="OpenShock.SDK.CSharp" Version="0.0.35" />
79-
<PackageReference Include="OpenShock.SDK.CSharp.Hub" Version="0.0.35" />
80-
<PackageReference Include="OpenShock.SDK.CSharp.Live" Version="0.0.35" />
78+
<PackageReference Include="OpenShock.SDK.CSharp" Version="0.0.37" />
79+
<PackageReference Include="OpenShock.SDK.CSharp.Hub" Version="0.0.37" />
80+
<PackageReference Include="OpenShock.SDK.CSharp.Live" Version="0.0.37" />
8181
<PackageReference Include="System.Reactive" Version="6.0.1" />
8282
</ItemGroup>
8383

Desktop/Models/BaseImpl/HubStatus.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using OpenShock.Desktop.ModuleBase.StableInterfaces;
2+
3+
namespace OpenShock.Desktop.Models.BaseImpl;
4+
5+
public sealed class HubStatus : IHubStatus
6+
{
7+
public bool Online { get; set; } = false;
8+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using OpenShock.Desktop.ModuleBase.StableInterfaces;
2+
3+
namespace OpenShock.Desktop.Models.BaseImpl;
4+
5+
public sealed class OpenShockHub : OpenShockHubBase, IOpenShockHub
6+
{
7+
public required IReadOnlyList<IOpenShockShocker> Shockers { get; init; }
8+
public IHubStatus Status => GetStatus();
9+
10+
public required Func<HubStatus> GetStatus { get; init; }
11+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using OpenShock.Desktop.ModuleBase.StableInterfaces;
2+
3+
namespace OpenShock.Desktop.Models.BaseImpl;
4+
5+
public class OpenShockHubBase : IOpenShockHubBase
6+
{
7+
public required Guid Id { get; init; }
8+
public required string Name { get; init; }
9+
public required DateTime CreatedOn { get; init; }
10+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using OpenShock.Desktop.ModuleBase.StableInterfaces;
2+
3+
namespace OpenShock.Desktop.Models.BaseImpl;
4+
5+
public sealed class OpenShockHubWithToken : OpenShockHubBase, IOpenShockHubWithToken
6+
{
7+
public string? Token { get; init; }
8+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using OpenShock.Desktop.ModuleBase.Models;
2+
using OpenShock.Desktop.ModuleBase.StableInterfaces;
3+
4+
namespace OpenShock.Desktop.Models.BaseImpl;
5+
6+
public sealed class OpenShockShocker : IOpenShockShocker
7+
{
8+
public required Guid Id { get; init; }
9+
public required ushort RfId { get; init; }
10+
public required ShockerModelType Model { get; init; }
11+
public required string Name { get; init; }
12+
public required bool IsPaused { get; init; }
13+
public required DateTime CreatedOn { get; init; }
14+
}

Desktop/ModuleManager/Implementation/OpenShockApiWrapper.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
using OneOf;
22
using OneOf.Types;
33
using OpenShock.Desktop.Backend;
4+
using OpenShock.Desktop.Models.BaseImpl;
45
using OpenShock.Desktop.ModuleBase.Api;
5-
using OpenShock.Desktop.ModuleBase.Models;
6+
using OpenShock.Desktop.ModuleBase.StableInterfaces;
67

78
namespace OpenShock.Desktop.ModuleManager.Implementation;
89

@@ -15,16 +16,16 @@ public OpenShockApiWrapper(OpenShockApi openShockApi)
1516
_openShockApi = openShockApi;
1617
}
1718

18-
public async Task<OneOf<Success<OpenShockHubWithToken>, NotFound, UnauthenticatedError>> GetHub(Guid hubId, CancellationToken cancellationToken = default)
19+
public async Task<OneOf<Success<IOpenShockHubWithToken>, NotFound, UnauthenticatedError>> GetHub(Guid hubId, CancellationToken cancellationToken = default)
1920
{
2021
if (_openShockApi.Client == null) return new UnauthenticatedError();
2122

22-
var result = await _openShockApi.Client.GetDevice(hubId, cancellationToken);
23+
var result = await _openShockApi.Client.GetHub(hubId, cancellationToken);
2324

24-
return result.Match<OneOf<Success<OpenShockHubWithToken>, NotFound, UnauthenticatedError>>(success =>
25+
return result.Match<OneOf<Success<IOpenShockHubWithToken>, NotFound, UnauthenticatedError>>(success =>
2526
{
2627
var hub = success.Value;
27-
return new Success<OpenShockHubWithToken>(new OpenShockHubWithToken()
28+
return new Success<IOpenShockHubWithToken>(new OpenShockHubWithToken()
2829
{
2930
Id = hub.Id,
3031
Name = hub.Name,

Desktop/ModuleManager/Implementation/OpenShockControl.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Immutable;
22
using OpenShock.Desktop.Backend;
3+
using OpenShock.Desktop.Models.BaseImpl;
34
using OpenShock.Desktop.ModuleBase.Api;
45
using OpenShock.Desktop.ModuleBase.Models;
56
using OpenShock.Desktop.Services;

0 commit comments

Comments
 (0)