Add support for RTD card and saving points with values for save

master
Jan Beníček 2023-11-25 19:00:12 +01:00
parent 85790996de
commit 90f682195e
8 changed files with 253 additions and 43 deletions

12
.config/dotnet-tools.json Normal file
View File

@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "8.0.0",
"commands": [
"dotnet-ef"
]
}
}
}

View File

@ -8,6 +8,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.0" />
<PackageReference Include="NetTopologySuite.IO.GeoJSON" Version="4.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>

View File

@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Mvc;
namespace API_SequentMicrosystems.Controllers
{
[Route("points")]
[Route("Points")]
[ApiController]
public class PointsController : ControllerBase
{
@ -25,7 +25,39 @@ namespace API_SequentMicrosystems.Controllers
[HttpGet]
public List<PointsModel> Get()
{
return _PointsService.GetPoints();
return _PointsService.GetPoints().Take(1000).ToList(); ;
}
// GET api/<PointsController>/5/5
/// <summary>
/// Read points from and to specified points positions
/// </summary>
/// <param name="limit">limit of returned points (Maximum 1000)</param>
/// <param name="start">id of start element</param>
/// <returns></returns>
[HttpGet("{start}/{limit}")]
public List<PointsModel> Get(int limit, int start)
{
if (limit > 1000)
limit = 1000;
return _PointsService.GetPoints(start, limit);
}
// POST api/<PointsController>/5
/// <summary>
/// Read points from and to specified points positions
/// </summary>
/// <param name="limit">limit of returned points (Maximum 1000)</param>
/// <param name="start">id of start element</param>
/// <returns></returns>
[HttpPost("{limit}")]
public List<PointsModel> Post(int limit, [FromBody] PointsModel pm)
{
if (limit > 1000)
limit = 1000;
return _PointsService.GetPoints(limit, pm);
}
// GET api/<PointsController>/5
@ -34,23 +66,10 @@ namespace API_SequentMicrosystems.Controllers
/// </summary>
/// <param name="max">max readed points</param>
/// <returns></returns>
[HttpGet("{max}")]
public List<PointsModel> Get(int max)
[HttpGet("Count")]
public int GetCount()
{
return _PointsService.GetPoints().Take(max).ToList();
}
// GET api/<PointsController>/5/5
/// <summary>
/// Read points from and to specified points positions
/// </summary>
/// <param name="max"></param>
/// <param name="start"></param>
/// <returns></returns>
[HttpGet("{max}/{start}")]
public List<PointsModel> Get(int max, int start)
{
return _PointsService.GetPoints().Skip(start).Take(max).ToList();
return _PointsService.GetPoints().Count;
}
//DELETE api/points
@ -78,20 +97,20 @@ namespace API_SequentMicrosystems.Controllers
/// Start timer to automatic saving points in specified interval
/// </summary>
/// <param name="sec"></param>
[HttpGet("save/{sec}")]
public void GetSaveSec(int sec)
[HttpGet("AutoSave/{msec}")]
public void GetSaveSec(int msec)
{
//start autosave timer
_PointsService.AutoSaveStart(msec);
}
//GET api/points/save
/// <summary>
/// Stop timer for automatic save points
/// </summary>
[HttpDelete("save")]
[HttpDelete("AutoSave")]
public void DeleteSaveSec()
{
//stop autosave timer
_PointsService.AutoSaveStop();
}

View File

@ -93,6 +93,23 @@ namespace API_SequentMicrosystems.Controllers
_RTDDAservice.SetPreconfiguratedChanelsNames(data);
}
//GET api/RTDDA/Calibration
/// <summary>
/// Get Calibration data
/// </summary>
/// <returns></returns>
[HttpGet("Calibration")]
public SortedList<byte, float[]> GetCalibration()
{
return _RTDDAservice.GetCalibrationData();
}
//POST api/RTDDA/Calibration
[HttpPost("Calibration")]
public void PostCalibration([FromBody] SortedList<byte, float[]> data)
{
_RTDDAservice.SetCalibrationData(data);
}
}
}

View File

@ -1,4 +1,6 @@
using API_SequentMicrosystems.Services;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace API_SequentMicrosystems
{
@ -10,9 +12,10 @@ namespace API_SequentMicrosystems
// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddControllers().AddNewtonsoftJson();
builder.Services.AddSingleton<RTDDAService>();
builder.Services.AddSingleton<PointsService>();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
@ -30,6 +33,7 @@ namespace API_SequentMicrosystems
app.UseAuthorization();
app.Services.GetService<RTDDAService>();
app.Services.GetService<PointsService>();
app.MapControllers();

View File

@ -1,21 +1,30 @@
using API_SequentMicrosystems.Models;
using Newtonsoft.Json;
using System.Timers;
namespace API_SequentMicrosystems.Services
{
public class PointsService
{
private System.Timers.Timer _SaveTimer;
private bool _SavePoints;
private System.Timers.Timer? _timer;
private RTDDAService _RTDDAService;
public PointsService(RTDDAService _RTDDAS)
public PointsService(IConfiguration conf, RTDDAService _RTDDAS)
{
if (!Directory.Exists("Points"))
Directory.CreateDirectory("Points");
_RTDDAService = _RTDDAS;
#pragma warning disable CS8604 // Může jít o argument s odkazem null.
_SaveTimer = new System.Timers.Timer(conf.GetValue<int>("PointsSaveToFileMinimumSec") * 1000);
#pragma warning restore CS8604 // Může jít o argument s odkazem null.
_SaveTimer.Elapsed += SaveTimerElapsed;
_SaveTimer.AutoReset = true;
_SaveTimer.Start();
_points = LoadPoints();
}
@ -44,7 +53,7 @@ namespace API_SequentMicrosystems.Services
/// </summary>
private void SavePoints()
{
File.WriteAllText("Points/SavedData.json", JsonConvert.SerializeObject(_points));
File.WriteAllText("Points/SavedData.json", JsonConvert.SerializeObject(_points.ToList()));
}
/// <summary>
@ -53,7 +62,39 @@ namespace API_SequentMicrosystems.Services
/// <returns></returns>
public List<PointsModel> GetPoints()
{
return _points;
return _points.ToList();
}
/// <summary>
/// Get points from start with limit
/// </summary>
/// <param name="limit">Limit of returned points</param>
/// <returns></returns>
public List<PointsModel> GetPoints(int limit)
{
return _points.Take(limit).ToList<PointsModel>();
}
/// <summary>
/// Get Points with start and count limit
/// </summary>
/// <param name="start">Start at this list position</param>
/// <param name="limit">Limit of returned points</param>
/// <returns></returns>
public List<PointsModel> GetPoints(int start, int limit)
{
return _points.Skip(start).Take(limit).ToList<PointsModel>();
}
/// <summary>
/// Get Points with start element and limit
/// </summary>
/// <param name="limit">Limit of returned points</param>
/// <param name="pm">Point from start reading</param>
/// <returns></returns>
public List<PointsModel> GetPoints(int limit, PointsModel pm)
{
return _points.Skip(_points.IndexOf(pm) + 1).Take(limit).ToList<PointsModel>();
}
/// <summary>
@ -75,18 +116,60 @@ namespace API_SequentMicrosystems.Services
pm.RTDDA = _RTDDAService.ReadAllCard(); //save RTD data to point
_points.Add(pm); //add point to list
SavePoints(); //Save updated points
_SavePoints = true;
}
/// <summary>
/// Start AutoSave points with specified delay
/// </summary>
/// <param name="msec"></param>
public void AutoSaveStart(int msec)
{
if (_timer != null && _timer.Enabled)
{
AutoSaveStop();
}
_timer = new System.Timers.Timer(msec);
_timer.AutoReset = true;
_timer.Elapsed += TimerElapsed;
_timer.Start();
}
/// <summary>
/// Stop AutoSaving points
/// </summary>
/// <returns></returns>
public int AutoSaveStop()
{
if (_timer == null)
return _points.Count;
_timer.Stop();
_timer.Close();
return _points.Count;
}
/// <summary>
/// TimerElapsed and saving point
/// </summary>
/// <param name="o"></param>
/// <param name="e"></param>
private void TimerElapsed(object? o, ElapsedEventArgs? e)
{
SavePoint();
}
private void SaveTimerElapsed(object? o, ElapsedEventArgs? e)
{
if (_SavePoints)
{
_SavePoints = false;
SavePoints();
}
}

View File

@ -32,6 +32,7 @@ namespace API_SequentMicrosystems.Services
ChanelsNames = LoadChanelsNames(); //ChanelsNames
PreconfiguredChanelsNames = LoadPreconfiguredChanelsNames(); //ChanelsPreconfiguredNames
CalibrationData = LoadCalibratioData();
}
/// <summary>
@ -44,15 +45,10 @@ namespace API_SequentMicrosystems.Services
for (byte i = 0; i < 8; i++) //loop for read all stack levels
{
try
{
data.Add(i, ReadCard(i)); //read stack level
}
catch
{
Console.WriteLine($"RTD stack {i} is not available");
}
float[] RD = ReadCard(i); //read stack level
if (RD.Length > 3)
data.Add(i, RD); //Add readed data to SortedList
}
return data; //return data
@ -93,7 +89,14 @@ namespace API_SequentMicrosystems.Services
{
try
{
return _stackLevelReader.GetStack(stack); //return data from specified card
float[] data = _stackLevelReader.GetStack(stack); //return data from specified card
for (byte i = 0;i < 8; i++)
{
data[i] += ReadCpecifiedChanelCalibration(stack, i);
}
return data;
}
catch
{
@ -101,7 +104,6 @@ namespace API_SequentMicrosystems.Services
}
}
#region ChanelsName
private SortedList<byte, string[]> ChanelsNames;
@ -153,6 +155,7 @@ namespace API_SequentMicrosystems.Services
#endregion
#region PreconfiguredChanelsNames
private List<string> PreconfiguredChanelsNames;
/// <summary>
@ -202,5 +205,74 @@ namespace API_SequentMicrosystems.Services
#endregion
#region Calibration
private SortedList<byte, float[]> CalibrationData;
/// <summary>
/// Load Calibration data from File
/// </summary>
/// <returns></returns>
private SortedList<byte, float[]> LoadCalibratioData()
{
try
{
#pragma warning disable CS8603 // Může jít o vrácený odkaz null.
return JsonConvert.DeserializeObject<SortedList<byte, float[]>>(File.ReadAllText("RTDDA/Calibration.json"));
#pragma warning restore CS8603 // Může jít o vrácený odkaz null.
}
catch
{
return new();
}
}
/// <summary>
/// Save Calibration data to File
/// </summary>
private void SaveCalibrationData()
{
File.WriteAllText("RTDDA/Calibration.json", JsonConvert.SerializeObject(CalibrationData));
}
/// <summary>
/// Get Calibration Data
/// </summary>
/// <returns></returns>
public SortedList<byte, float[]> GetCalibrationData()
{
return CalibrationData;
}
/// <summary>
/// Set new calibration Data
/// </summary>
/// <param name="CD"></param>
public void SetCalibrationData(SortedList<byte, float[]> CD)
{
CalibrationData = CD;
SaveCalibrationData();
}
/// <summary>
/// Get Calibration data of specific card chanel
/// </summary>
/// <param name="stack">Card stack position ID</param>
/// <param name="chanel">Chanel ID</param>
/// <returns>Calibration data of specific chanel</returns>
private float ReadCpecifiedChanelCalibration(byte stack, byte chanel)
{
if (!CalibrationData.ContainsKey(stack))
return 0;
if (CalibrationData[stack].Length < chanel)
return 0;
return CalibrationData[stack][chanel];
}
#endregion
}
}

View File

@ -6,6 +6,7 @@
}
},
"AllowedHosts": "*",
"PointsSaveToFileMinimumSec": "10",
"Cards": [
{
"ID": "0",