UI_SequentMicrosystems-RPI/Services/RTD8TMService.cs

566 lines
16 KiB
C#
Raw Normal View History

using System.Threading.Channels;
using System.Timers;
2023-12-17 17:09:39 +00:00
using UI_SequentMicrosystems.Components;
2023-12-16 07:59:53 +00:00
using UI_SequentMicrosystems.Models;
using Wrapper_Api_SequentMicrosystems.RTD8TM;
namespace UI_SequentMicrosystems.Services
{
public class RTD8TMService
{
private SortedList<byte, string[]> ChanelNames = new SortedList<byte, string[]>();
private SortedList<byte, float[]> ActualValues = new SortedList<byte, float[]>();
private SortedList<byte, byte[]> ValuesType = new SortedList<byte, byte[]>();
private SortedList<byte, float[]> Calibrations = new SortedList<byte, float[]>();
public SortedList<byte, List<List<RTD8TMPointModel>>> GraphData = new();
public SortedList<byte, List<List<RTD8TMPointModel>>> GraphFiltered = new();
2023-12-16 07:59:53 +00:00
private byte GraphDataCounterCount = 10;
2023-12-17 17:09:39 +00:00
private byte GraphDataCounter = 9;
2023-12-16 07:59:53 +00:00
private string? Address { get; set; }
private RTD8TM _RTD8TM = new RTD8TM();
private System.Timers.Timer _timer = new(1000);
public delegate Task AsyncEventHandler<TEventArgs>(object? sender, TEventArgs? e);
public event AsyncEventHandler<bool>? EventUpdateValues;
2023-12-17 17:09:39 +00:00
public event AsyncEventHandler<bool>? EventUpdateGraph;
2023-12-16 07:59:53 +00:00
public RTD8TMService()
{
_timer.AutoReset = true;
_timer.Elapsed += TimerElapsed;
_timer.Start();
}
//Main Parameters Work
/// <summary>
/// Set Device Address
/// </summary>
/// <param name="address">Address [Base url] (http://1.2.3.4)</param>
public void SetAddress(string address)
{
Address = address;
GetChanelsNames();
GetValueTypes();
GetCalibrations();
2023-12-16 07:59:53 +00:00
}
/// <summary>
/// Get used device Address
/// </summary>
/// <returns>Address or empty string</returns>
public string GetAddress()
{
if (Address == null)
{
return "";
}
else
{
return Address;
}
}
//Actual Data
2023-12-16 07:59:53 +00:00
/// <summary>
/// Read Actual values from Device
/// </summary>
private async void GetActualValues()
2023-12-16 07:59:53 +00:00
{
if (Address == null) { return; }
2023-12-16 07:59:53 +00:00
ActualValues = await _RTD8TM.Get(Address);
foreach (byte stack in ActualValues.Keys)
{
if (Calibrations.ContainsKey(stack))
{
for (byte chanel = 0; chanel < 8; chanel++)
{
ActualValues[stack][chanel] += Calibrations[stack][chanel];
}
}
}
2023-12-16 07:59:53 +00:00
if (GraphDataCounter >= GraphDataCounterCount)
{
GraphDataCounter = 0;
2023-12-17 17:09:39 +00:00
ReadChartData();
if (EventUpdateGraph != null)
{
await EventUpdateGraph.Invoke(this, true);
}
2023-12-16 07:59:53 +00:00
}
else
{
GraphDataCounter++;
}
}
2023-12-16 07:59:53 +00:00
/// <summary>
/// Request for actual data
/// </summary>
/// <returns></returns>
public SortedList<byte, float[]> GetActualData()
{
return ActualValues;
2023-12-16 07:59:53 +00:00
}
/// <summary>
/// Get actual data Value
/// </summary>
/// <param name="stack">Stack ID</param>
/// <param name="chanel">Chanel ID</param>
/// <returns>Measure Resistance</returns>
public float GetActualData(byte stack, byte chanel)
{
if (ActualValues.ContainsKey(stack))
{
return ActualValues[stack][chanel];
}
else
{
return 0;
}
}
//ChanelsNames
2023-12-16 07:59:53 +00:00
/// <summary>
/// Read configured chanels Names from Device
/// </summary>
public async void GetChanelsNames()
{
if (Address == null) return;
ChanelNames = await _RTD8TM.GetNames(Address);
AutoUpdateChanelsName();
}
/// <summary>
/// Set new Chanels Names
/// </summary>
/// <param name="names">chanels names sorted list</param>
#pragma warning disable CS1998 // V této asynchronní metodě chybí operátory await a spustí se synchronně.
public async Task SetChanelsNames()
2023-12-16 07:59:53 +00:00
#pragma warning restore CS1998 // V této asynchronní metodě chybí operátory await a spustí se synchronně.
{
if (Address == null)
return;
_RTD8TM.PostNames(Address, ChanelNames);
}
/// <summary>
/// Update Chanels Names for not null loading names
/// </summary>
private void AutoUpdateChanelsName()
{
if (ActualValues.Count <= 0)
return;
foreach (byte key in ActualValues.Keys)
{
if (!ChanelNames.ContainsKey(key))
{
ChanelNames.Add(key, new string[8]);
}
2023-12-16 07:59:53 +00:00
for (int i = 0; i < 8; i++)
{
if (ChanelNames[key][i] == null)
{
ChanelNames[key][i] = "----------";
}
}
}
}
/// <summary>
/// Get chanel names
/// </summary>
/// <returns>Chanels names object</returns>
public SortedList<byte, string[]> GetChanelNames()
{
return ChanelNames;
}
/// <summary>
/// Set chanel Name
/// </summary>
/// <param name="stack">Stack ID</param>
/// <param name="chanel">Chanel ID</param>
/// <param name="name">New Name</param>
public void SetChanelNames(byte stack, byte chanel, string name)
{
if (!ChanelNames.ContainsKey(stack))
{
ChanelNames.Add(stack, new string[8]);
}
ChanelNames[stack][chanel] = name;
}
/// <summary>
/// Read chanel name
/// </summary>
/// <param name="stack">Stack ID</param>
/// <param name="chanel">Chanel ID</param>
/// <returns>Chanel name</returns>
public string GetChanelName(byte stack, byte chanel)
{
if (ChanelNames.ContainsKey(stack))
{
return ChanelNames[stack][chanel];
}
else
{
return "----------";
}
}
2023-12-16 07:59:53 +00:00
/// <summary>
/// Clear chanels Names to default
/// </summary>
public void ClearChanelNames()
{
ChanelNames.Clear();
AutoUpdateChanelsName();
}
//Timer
private async void TimerElapsed(object? o, ElapsedEventArgs? e)
2023-12-16 07:59:53 +00:00
{
GetActualValues();
AutoUpdateChanelsName();
if (EventUpdateValues != null)
{
await EventUpdateValues.Invoke(this, true);
}
2023-12-16 07:59:53 +00:00
}
//Graph Data
2023-12-16 07:59:53 +00:00
2023-12-17 17:09:39 +00:00
/// <summary>
/// Get Chart data
/// </summary>
public void ReadChartData()
{
DateTime time = DateTime.Now;
foreach (byte stack in ActualValues.Keys)
{
if (!GraphData.ContainsKey(stack))
{
GraphData.Add(stack, new());
for (int chanel = 0; chanel < 8; chanel++)
{
GraphData[stack].Add(new());
}
}
for (byte chanel = 0; chanel < 8; chanel++)
{
GraphData[stack][chanel].Add(new RTD8TMPointModel() { Value = ActualValues[stack][chanel], Time = time });
2023-12-17 17:09:39 +00:00
}
}
GetFilteredChartData();
2023-12-17 17:09:39 +00:00
}
/// <summary>
/// Get data for graph visualize
/// </summary>
2023-12-17 17:09:39 +00:00
/// <returns>saved chart chanel Data</returns>
public List<RTD8TMPointModel> GetChartData(byte StackID, byte Chanel)
{
if (!GraphFiltered.ContainsKey(StackID))
2023-12-17 17:09:39 +00:00
{
return new List<RTD8TMPointModel>();
2023-12-17 17:09:39 +00:00
}
List<RTD8TMPointModel> RecalculatedData = new();
byte chanelRecalcTo = GetValueType(StackID, Chanel);
foreach (RTD8TMPointModel point in GraphFiltered[StackID][Chanel])
{
RTD8TMPointModel recalculated = new() { Time = point.Time, Value = new RTD8TMChanelComponent().RecalculateValues(point.Value, chanelRecalcTo) };
RecalculatedData.Add(recalculated);
}
return RecalculatedData;
}
/// <summary>
/// Clear data from Graph
/// </summary>
2023-12-17 17:09:39 +00:00
public void ClearChart()
{
GraphData.Clear();
}
2023-12-16 07:59:53 +00:00
private void GetFilteredChartData()
{
foreach ( byte stack in GraphData.Keys)
{
int pointsCount = GraphData[stack][0].Count;
int counter = 0;
if (pointsCount < 100)
{
GraphFiltered = GraphData;
}
else if (pointsCount > 100 && pointsCount < 500) // one from five
{
GraphFiltered = new();
GraphFiltered.Add(stack, new());
for (int chanel = 0; chanel < 8; chanel++)
{
GraphFiltered[stack].Add(new());
foreach (RTD8TMPointModel GraphPoint in GraphData[stack][chanel])
{
if (counter > 3)
{
GraphFiltered[stack][chanel].Add(GraphPoint);
counter = 0;
}
else
{
counter++;
}
}
}
}
else if (pointsCount > 500 && pointsCount < 1000) // one from ten
{
GraphFiltered = new();
GraphFiltered.Add(stack, new());
for (int chanel = 0; chanel < 8; chanel++)
{
GraphFiltered[stack].Add(new());
foreach (RTD8TMPointModel GraphPoint in GraphData[stack][chanel])
{
if (counter > 8)
{
GraphFiltered[stack][chanel].Add(GraphPoint);
counter = 0;
}
else
{
counter++;
}
}
}
}
else if (pointsCount > 1000 && pointsCount < 1500) // one from fifteen
{
GraphFiltered = new();
GraphFiltered.Add(stack, new());
2023-12-16 07:59:53 +00:00
for (int chanel = 0; chanel < 8; chanel++)
{
GraphFiltered[stack].Add(new());
foreach (RTD8TMPointModel GraphPoint in GraphData[stack][chanel])
{
if (counter > 13)
{
GraphFiltered[stack][chanel].Add(GraphPoint);
counter = 0;
}
else
{
counter++;
}
}
}
}
else if (pointsCount > 1500) // one from twenty
{
GraphFiltered = new();
GraphFiltered.Add(stack, new());
for (int chanel = 0; chanel < 8; chanel++)
{
GraphFiltered[stack].Add(new());
foreach (RTD8TMPointModel GraphPoint in GraphData[stack][chanel])
{
if (counter > 18)
{
GraphFiltered[stack][chanel].Add(GraphPoint);
counter = 0;
}
else
{
counter++;
}
}
}
}
//případně další
}
}
public int CountFilteredChartData()
{
foreach (byte stack in GraphFiltered.Keys)
{
return GraphFiltered[stack][0].Count;
}
return 0;
}
public int CountChartData()
{
foreach (byte stack in GraphData.Keys)
{
return GraphData[stack][0].Count;
}
return 0;
}
2023-12-16 07:59:53 +00:00
//Values Types
/// <summary>
/// Set Value Type identifier
/// </summary>
/// <param name="StackID">Stack ID</param>
/// <param name="ChanelID">Chanel ID</param>
/// <param name="Type">Value Type</param>
public void SetValueType(byte StackID, byte ChanelID, byte Type)
{
if (!ValuesType.ContainsKey(StackID))
{
ValuesType.Add(StackID, new byte[8]);
}
ValuesType[StackID][ChanelID] = Type;
}
/// <summary>
/// Get Value Type
/// </summary>
/// <param name="StackID">Stack ID</param>
/// <param name="ChanelID">Chanel ID</param>
/// <returns>Value Type</returns>
public byte GetValueType(byte StackID, byte ChanelID)
{
if (ValuesType.ContainsKey(StackID))
{
return ValuesType[StackID][ChanelID];
}
else
{
return 0;
}
}
/// <summary>
/// Get ValueTypes From API
/// </summary>
public async void GetValueTypes()
{
if (Address == null) { return; }
ValuesType = await _RTD8TM.GetValueTypes(Address);
}
/// <summary>
/// Post ValueTypes to API
/// </summary>
public void PostValueTypes()
{
if (Address == null) { return; }
_RTD8TM.PostValueTypes(Address, ValuesType);
}
public void ClearValueTypes()
{
ValuesType.Clear();
}
//calibrations
/// <summary>
/// Read Calibrations from API
/// </summary>
private async void GetCalibrations()
{
if (Address == null) { return; }
Calibrations = await _RTD8TM.GetCalibration(Address);
foreach (byte stack in ActualValues.Keys)
{
if (!Calibrations.ContainsKey(stack))
{
Calibrations.Add(stack, new float[8]);
}
}
}
/// <summary>
/// Post calibrations to API
/// </summary>
public void PostCalibrations()
{
if (Address == null) { return; }
_RTD8TM.PostCalibration(Address, Calibrations);
}
/// <summary>
/// Get calibration of specific chanel
/// </summary>
/// <param name="stack"></param>
/// <param name="chanel"></param>
/// <returns></returns>
public float GetCalibration(byte stack, byte chanel)
{
if (Calibrations.ContainsKey(stack))
{
return Calibrations[stack][chanel];
}
else
{
return 0;
}
}
/// <summary>
/// Set chanel Calibration Change
/// </summary>
/// <param name="stack"></param>
/// <param name="chanel"></param>
/// <param name="value"></param>
public void SetCalibration(byte stack, byte chanel, float value)
{
if (!Calibrations.ContainsKey(stack))
{
Calibrations.Add(stack, new float[8]);
}
Calibrations[stack][chanel] = value;
}
2023-12-16 07:59:53 +00:00
}
}