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> </PropertyGroup>
<ItemGroup> <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="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup> </ItemGroup>

View File

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

View File

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

View File

@ -1,21 +1,30 @@
using API_SequentMicrosystems.Models; using API_SequentMicrosystems.Models;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.Timers;
namespace API_SequentMicrosystems.Services namespace API_SequentMicrosystems.Services
{ {
public class PointsService public class PointsService
{ {
private System.Timers.Timer _SaveTimer;
private bool _SavePoints;
private System.Timers.Timer? _timer;
private RTDDAService _RTDDAService; private RTDDAService _RTDDAService;
public PointsService(RTDDAService _RTDDAS) public PointsService(IConfiguration conf, RTDDAService _RTDDAS)
{ {
if (!Directory.Exists("Points")) if (!Directory.Exists("Points"))
Directory.CreateDirectory("Points"); Directory.CreateDirectory("Points");
_RTDDAService = _RTDDAS; _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(); _points = LoadPoints();
} }
@ -44,7 +53,7 @@ namespace API_SequentMicrosystems.Services
/// </summary> /// </summary>
private void SavePoints() private void SavePoints()
{ {
File.WriteAllText("Points/SavedData.json", JsonConvert.SerializeObject(_points)); File.WriteAllText("Points/SavedData.json", JsonConvert.SerializeObject(_points.ToList()));
} }
/// <summary> /// <summary>
@ -53,7 +62,39 @@ namespace API_SequentMicrosystems.Services
/// <returns></returns> /// <returns></returns>
public List<PointsModel> GetPoints() 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> /// <summary>
@ -75,18 +116,60 @@ namespace API_SequentMicrosystems.Services
pm.RTDDA = _RTDDAService.ReadAllCard(); //save RTD data to point pm.RTDDA = _RTDDAService.ReadAllCard(); //save RTD data to point
_points.Add(pm); //add point to list _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 ChanelsNames = LoadChanelsNames(); //ChanelsNames
PreconfiguredChanelsNames = LoadPreconfiguredChanelsNames(); //ChanelsPreconfiguredNames PreconfiguredChanelsNames = LoadPreconfiguredChanelsNames(); //ChanelsPreconfiguredNames
CalibrationData = LoadCalibratioData();
} }
/// <summary> /// <summary>
@ -44,15 +45,10 @@ namespace API_SequentMicrosystems.Services
for (byte i = 0; i < 8; i++) //loop for read all stack levels for (byte i = 0; i < 8; i++) //loop for read all stack levels
{ {
try float[] RD = ReadCard(i); //read stack level
{
data.Add(i, ReadCard(i)); //read stack level
}
catch
{
Console.WriteLine($"RTD stack {i} is not available");
}
if (RD.Length > 3)
data.Add(i, RD); //Add readed data to SortedList
} }
return data; //return data return data; //return data
@ -93,7 +89,14 @@ namespace API_SequentMicrosystems.Services
{ {
try 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 catch
{ {
@ -101,7 +104,6 @@ namespace API_SequentMicrosystems.Services
} }
} }
#region ChanelsName #region ChanelsName
private SortedList<byte, string[]> ChanelsNames; private SortedList<byte, string[]> ChanelsNames;
@ -153,6 +155,7 @@ namespace API_SequentMicrosystems.Services
#endregion #endregion
#region PreconfiguredChanelsNames #region PreconfiguredChanelsNames
private List<string> PreconfiguredChanelsNames; private List<string> PreconfiguredChanelsNames;
/// <summary> /// <summary>
@ -202,5 +205,74 @@ namespace API_SequentMicrosystems.Services
#endregion #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": "*", "AllowedHosts": "*",
"PointsSaveToFileMinimumSec": "10",
"Cards": [ "Cards": [
{ {
"ID": "0", "ID": "0",