Added Client Synchronization function

master
Jan Beníček 2024-01-17 06:34:15 +01:00
parent 347348c81c
commit 8b62c82a15
9 changed files with 353 additions and 6 deletions

View File

@ -24,6 +24,11 @@
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Saved Points <span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Saved Points
</NavLink> </NavLink>
</div> </div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="Sync">
<span class="bi gg-sync" aria-hidden="true"></span> Sync Data
</NavLink>
</div>
</nav> </nav>
</div> </div>

View File

@ -6,6 +6,7 @@
@inject PointsService _PointsService @inject PointsService _PointsService
@inject RTD8TMService _RTD8TMService @inject RTD8TMService _RTD8TMService
@inject SyncService _SyncService
@inject NavigationManager Navigator @inject NavigationManager Navigator
@ -28,7 +29,7 @@
protected override void OnInitialized() protected override void OnInitialized()
{ {
//_RTD8TMService.SetAddress("http://10.250.251.131/"); //_RTD8TMService.SetAddress("http://10.250.251.131/");
_RTD8TMService.SetAddress(Navigator.BaseUri); _SyncService.SetAddress(Navigator.BaseUri);
} }

View File

@ -8,6 +8,7 @@
@inject NavigationManager Navigator @inject NavigationManager Navigator
@inject RTD8TMService _RTD8TMService @inject RTD8TMService _RTD8TMService
@inject PointsService _PointsService @inject PointsService _PointsService
@inject SyncService _SyncService
<PageTitle>Temperature</PageTitle> <PageTitle>Temperature</PageTitle>
@ -104,7 +105,7 @@
protected override void OnInitialized() protected override void OnInitialized()
{ {
//_RTD8TMService.SetAddress("http://10.250.251.131/"); //_RTD8TMService.SetAddress("http://10.250.251.131/");
_RTD8TMService.SetAddress(Navigator.BaseUri); _SyncService.SetAddress(Navigator.BaseUri);
_RTD8TMService.EventUpdateValues += UpdateView; _RTD8TMService.EventUpdateValues += UpdateView;
} }

View File

@ -2,17 +2,21 @@
@using UI_SequentMicrosystems.Services @using UI_SequentMicrosystems.Services
@inject NavigationManager Navigator @inject NavigationManager Navigator
@inject RTD8TMService _RTD8TMService @inject SyncService _SyncService
<PageTitle>Welcome</PageTitle> <PageTitle>Welcome</PageTitle>
<div class="text-center row"> <div class="text-center row">
<div class="h6 col-3"><strong>TesDevice App V1.1</strong></div> <div class="h6 col-3">TesDevice App V1.2</div>
<div class="col">Added Clients Synchronization</div>
</div>
<div class="text-center row">
<div class="h6 col-3">TesDevice App V1.1</div>
<div class="col">Added Automatic points Saving, Calibration and Calculating RTDCard values change in last 3O minutes in saved points</div> <div class="col">Added Automatic points Saving, Calibration and Calculating RTDCard values change in last 3O minutes in saved points</div>
</div> </div>
<div class="text-center row"> <div class="text-center row">
<div class="h6 col-3">TesDevice App V1.O</div> <div class="h6 col-3">TesDevice App V1.O</div>
<div class="col">Firt Fully function Build --> Reading RTD cards, RTD Graph, Points Saving and exporting as csv</div> <div class="col">First Fully function Build --> Reading RTD cards, RTD Graph, Points Saving and exporting as csv</div>
</div> </div>
@ -24,7 +28,7 @@
protected override void OnInitialized() protected override void OnInitialized()
{ {
//_RTD8TMService.SetAddress("http://10.250.251.131/"); //_RTD8TMService.SetAddress("http://10.250.251.131/");
_RTD8TMService.SetAddress(Navigator.BaseUri); _SyncService.SetAddress(Navigator.BaseUri);

97
Pages/SyncPage.razor Normal file
View File

@ -0,0 +1,97 @@
@page "/Sync"
@using UI_SequentMicrosystems.Services
@using UI_SequentMicrosystems.Models
@inject SyncService _SyncService
@inject NavigationManager Navigator
<PageTitle>Clients Sync</PageTitle>
<div class="text-white h6 text-center">
This ClientID: <strong>@_SyncService.GetClientID()</strong>
</div>
@if (SelectedSyncClientID != null)
{
<div class="row">
<div class="col-6">
<select class="form-select bg-dark text-white" aria-label="Default select example" @onchange="((x) =>
{
ClientSelected(x.Value.ToString());
})">
@if (SelectedSyncClientID == null && SelectedSyncClientID == "")
{
<option selected value="-1">Select Sync Client ID</option>
}
else
{
<option value="-1">Select Sync Client ID</option>
}
@foreach (string id in _SyncService.GetClientsIDs())
{
<option value="@id">@id</option>
}
</select>
</div>
@if (SelectedSyncClientID != null && SelectedSyncClientID != "")
{
<div class="col-xs-12 col-md-2 align-self-center">
<button class="btn btn-dark text-white no-border" @onclick="(() => _SyncService.SendClientSyncRequest(SelectedSyncClientID))">Synchronize With selected Client</button>
</div>
}
</div>
}
@code {
private string SelectedSyncClientID { get; set; }
protected override async void OnInitialized()
{
//_RTD8TMService.SetAddress("http://10.250.251.131/");
_SyncService.SetAddress(Navigator.BaseUri);
SelectedSyncClientID = await _SyncService.GetSelectedSyncClient();
_SyncService.EventUpdateClientsIDs += UpdateView;
}
private async void ClientSelected(string select)
{
Console.WriteLine($"SyncPage:ClientSelected Selected ID: {select}");
if (select == "-1")
{
SelectedSyncClientID = "";
await _SyncService.SendClientSyncRequest("");
}
else
{
SelectedSyncClientID = select;
await _SyncService.SendClientSyncRequest(select);
}
}
public async Task UpdateView(object? o, bool b)
{
await InvokeAsync(() =>
{
StateHasChanged();
});
}
}

View File

@ -18,6 +18,7 @@ namespace UI_SequentMicrosystems
builder.Services.AddSingleton<RTD8TMService>(); builder.Services.AddSingleton<RTD8TMService>();
builder.Services.AddSingleton<PointsService>(); builder.Services.AddSingleton<PointsService>();
builder.Services.AddSingleton<SyncService>();
await builder.Build().RunAsync(); await builder.Build().RunAsync();
} }

View File

@ -72,6 +72,22 @@ namespace UI_SequentMicrosystems.Services
return _PointsModel; return _PointsModel;
} }
/// <summary>
/// Set Points (used by sync)
/// </summary>
/// <param name="points"></param>
public async void SetPoints(PointsModel points)
{
_PointsModel = points;
PointsCount = _PointsModel.RTD8TM.Keys.Count;
if (EventUpdateTopBar != null)
{
await EventUpdateTopBar.Invoke(this, true);
}
}
/// <summary> /// <summary>
/// Get points Count /// Get points Count
/// </summary> /// </summary>

View File

@ -46,6 +46,9 @@ namespace UI_SequentMicrosystems.Services
GetChanelsNames(); GetChanelsNames();
GetValueTypes(); GetValueTypes();
GetCalibrations(); GetCalibrations();
} }
/// <summary> /// <summary>
@ -435,6 +438,24 @@ namespace UI_SequentMicrosystems.Services
return 0; return 0;
} }
/// <summary>
/// Get all Chart Data
/// </summary>
/// <returns></returns>
public SortedList<byte, List<List<RTD8TMPointModel>>> GetAllChartData()
{
return GraphData;
}
/// <summary>
/// Set Chart Data (used by syncservice)
/// </summary>
/// <param name="data"></param>
public void SetChartData(SortedList<byte, List<List<RTD8TMPointModel>>> data)
{
GraphData = data;
}
//Values Types //Values Types
/// <summary> /// <summary>

201
Services/SyncService.cs Normal file
View File

@ -0,0 +1,201 @@
using Newtonsoft.Json;
using UI_SequentMicrosystems.Models;
using Wrapper_Api_SequentMicrosystems.SignalR;
namespace UI_SequentMicrosystems.Services
{
public class SyncService
{
private PointsService _pointsService { get; set; }
private RTD8TMService _RTD8TMService { get; set; }
private string? Address { get; set; }
private string ClientID { get; set; }
private string? SyncRequestedClientID { get; set; }
private Sync? SyncClient { get; set; }
private List<string> _SyncClients = new();
public delegate Task AsyncEventHandler<TEventArgs>(object? sender, TEventArgs? e);
public event AsyncEventHandler<bool>? EventUpdateClientsIDs;
public SyncService(PointsService pointsService, RTD8TMService rtD8TMService)
{
_pointsService = pointsService;
_RTD8TMService = rtD8TMService;
ClientID = CreateClientID();
Console.WriteLine($"SyncService:* Local Client ID: {ClientID}");
}
/// <summary>
/// Set api address
/// </summary>
/// <param name="address"></param>
public void SetAddress(string address)
{
if (Address == address) { return; }
Address = address;
_RTD8TMService.SetAddress(Address);
StartConnection();
}
/// <summary>
/// Create Random ClientID
/// </summary>
private string CreateClientID()
{
string id = "";
List<char> chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".ToCharArray().ToList();
for (int i = 0; i < 4; i++)
{
id += chars[Random.Shared.Next(0, chars.Count - 1)];
}
return id;
}
/// <summary>
/// Get this ClientID
/// </summary>
/// <returns></returns>
public string GetClientID()
{
return ClientID;
}
/// <summary>
/// Start connection to Server
/// </summary>
private async void StartConnection()
{
if (Address == null) { return; }
SyncClient = new(Address);
SyncClient.EventClientIDRequest += ClientIDRequestRequested;
SyncClient.EventClientsIDResponse += ClientIDRequestResponse;
SyncClient.EventClientSyncRequest += ClientSyncRequested;
SyncClient.EventClientRTD8TMChartSync += ClientRTD8TMSyncData;
SyncClient.EventClientPointsSync += ClientPointsyncData;
RequestClientsIds();
}
private async Task ClientIDRequestRequested(object? o, bool b)
{
if (SyncClient == null) { return; }
_SyncClients.Clear();
await SyncClient.SendClientsResponse(ClientID);
}
#pragma warning disable CS1998 // V této asynchronní metodě chybí operátory await a spustí se synchronně.
private async Task ClientIDRequestResponse(object? o, string? id)
{
if (id == null || id == ClientID) { return; }
Console.WriteLine($"SyncService:ClientIDRequestResponse clientID: {id}");
_SyncClients.Add(id);
if (EventUpdateClientsIDs != null)
{
await EventUpdateClientsIDs.Invoke(this, true);
}
}
private async Task ClientSyncRequested(object? o, string? id)
{
if (SyncClient == null || id == null || id != ClientID) { return; }
await SyncClient.SendClientsPoints(ClientID, JsonConvert.SerializeObject(_pointsService.GetPoints()));
await SyncClient.SendClientsRTD8TMChart(ClientID, JsonConvert.SerializeObject(_RTD8TMService.GetAllChartData()));
}
private async Task ClientRTD8TMSyncData(object? o, string? id, string data)
{
if (data == null || id == null || id != SyncRequestedClientID) { return; }
_RTD8TMService.SetChartData(JsonConvert.DeserializeObject<SortedList<byte, List<List<RTD8TMPointModel>>>>(data));
}
private async Task ClientPointsyncData(object? o, string? id, string data)
{
if (data == null || id == null || id != SyncRequestedClientID) { return; }
_pointsService.SetPoints(JsonConvert.DeserializeObject<PointsModel>(data));
}
/// <summary>
/// Request Other Clients IDs
/// </summary>
public async void RequestClientsIds()
{
await SyncClient.SendClientsRequest();
}
/// <summary>
/// Get Clients IDs
/// </summary>
/// <returns></returns>
public List<string> GetClientsIDs()
{
Console.WriteLine($"SyncService:GetClientsIDs {JsonConvert.SerializeObject(_SyncClients.ToList())}");
return _SyncClients.ToList();
}
/// <summary>
/// Request Clients Sync
/// </summary>
/// <param name="ClientID">ID of client from sync requested</param>
/// <returns></returns>
public async Task SendClientSyncRequest(string ClientID)
{
if (SyncClient == null) { return; }
SyncRequestedClientID = ClientID;
if (SyncRequestedClientID == "")
{
return;
}
await SyncClient.SendClientSyncRequest(ClientID);
if (EventUpdateClientsIDs != null)
{
await EventUpdateClientsIDs.Invoke(this, true);
}
}
/// <summary>
/// Get selected Sync Client
/// </summary>
/// <returns></returns>
public async Task<string> GetSelectedSyncClient()
{
if (SyncRequestedClientID == null || SyncRequestedClientID == "")
{
return "";
}
else
{
return SyncRequestedClientID;
}
}
}
}