diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..e76fde3
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,4 @@
+[*.cs]
+
+# CS8600: Literál s hodnotou null nebo s možnou hodnotou null se převádí na typ, který nemůže mít hodnotu null.
+dotnet_diagnostic.CS8600.severity = silent
diff --git a/API_SequentMicrosystems.csproj b/API_SequentMicrosystems.csproj
new file mode 100644
index 0000000..47b1d5a
--- /dev/null
+++ b/API_SequentMicrosystems.csproj
@@ -0,0 +1,19 @@
+
+
+
+ net8.0
+ enable
+ enable
+ true
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/API_SequentMicrosystems.http b/API_SequentMicrosystems.http
new file mode 100644
index 0000000..e67ea87
--- /dev/null
+++ b/API_SequentMicrosystems.http
@@ -0,0 +1,6 @@
+@API_SequentMicrosystems_HostAddress = http://localhost:5242
+
+GET {{API_SequentMicrosystems_HostAddress}}/weatherforecast/
+Accept: application/json
+
+###
diff --git a/API_SequentMicrosystems.sln b/API_SequentMicrosystems.sln
new file mode 100644
index 0000000..da60ede
--- /dev/null
+++ b/API_SequentMicrosystems.sln
@@ -0,0 +1,36 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.8.34309.116
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "API_SequentMicrosystems", "API_SequentMicrosystems.csproj", "{357DFFA8-F19B-4D1D-91A3-590E8C526763}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Libs_SequentMicrosystems", "..\Libs_SequentMicrosystems\Libs_SequentMicrosystems.csproj", "{65BF0CBE-211E-44BD-85CB-ACA4303A5744}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D1EBA159-E66F-40B9-9CA4-771280C2D647}"
+ ProjectSection(SolutionItems) = preProject
+ .editorconfig = .editorconfig
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {357DFFA8-F19B-4D1D-91A3-590E8C526763}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {357DFFA8-F19B-4D1D-91A3-590E8C526763}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {357DFFA8-F19B-4D1D-91A3-590E8C526763}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {357DFFA8-F19B-4D1D-91A3-590E8C526763}.Release|Any CPU.Build.0 = Release|Any CPU
+ {65BF0CBE-211E-44BD-85CB-ACA4303A5744}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {65BF0CBE-211E-44BD-85CB-ACA4303A5744}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {65BF0CBE-211E-44BD-85CB-ACA4303A5744}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {65BF0CBE-211E-44BD-85CB-ACA4303A5744}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {0195FF77-403C-4F80-BEC9-1D24388A7E04}
+ EndGlobalSection
+EndGlobal
diff --git a/Controllers/PointsController.cs b/Controllers/PointsController.cs
new file mode 100644
index 0000000..e01a421
--- /dev/null
+++ b/Controllers/PointsController.cs
@@ -0,0 +1,101 @@
+using API_SequentMicrosystems.Models;
+using API_SequentMicrosystems.Services;
+using Microsoft.AspNetCore.Mvc;
+
+// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
+
+namespace API_SequentMicrosystems.Controllers
+{
+ [Route("points")]
+ [ApiController]
+ public class PointsController : ControllerBase
+ {
+ private PointsService _PointsService;
+
+ public PointsController(PointsService _PS)
+ {
+ _PointsService = _PS;
+ }
+
+ // GET: api/
+ ///
+ /// Get all saved points
+ ///
+ ///
+ [HttpGet]
+ public List Get()
+ {
+ return _PointsService.GetPoints();
+ }
+
+ // GET api//5
+ ///
+ /// Read points from first to specified number
+ ///
+ /// max readed points
+ ///
+ [HttpGet("{max}")]
+ public List Get(int max)
+ {
+ return _PointsService.GetPoints().Take(max).ToList();
+ }
+
+ // GET api//5/5
+ ///
+ /// Read points from and to specified points positions
+ ///
+ ///
+ ///
+ ///
+ [HttpGet("{max}/{start}")]
+ public List Get(int max, int start)
+ {
+ return _PointsService.GetPoints().Skip(start).Take(max).ToList();
+ }
+
+ //DELETE api/points
+ ///
+ /// Delete saved points
+ ///
+ [HttpDelete]
+ public void Delete()
+ {
+ _PointsService.DeletePoints();
+ }
+
+ //GET api/points/save
+ ///
+ /// Save new point
+ ///
+ [HttpGet("save")]
+ public void GetSave()
+ {
+ _PointsService.SavePoint();
+ }
+
+ //GET api/points/save/300
+ ///
+ /// Start timer to automatic saving points in specified interval
+ ///
+ ///
+ [HttpGet("save/{sec}")]
+ public void GetSaveSec(int sec)
+ {
+ //start autosave timer
+ }
+
+ //GET api/points/save
+ ///
+ /// Stop timer for automatic save points
+ ///
+ [HttpDelete("save")]
+ public void DeleteSaveSec()
+ {
+ //stop autosave timer
+ }
+
+
+
+
+ }
+}
diff --git a/Controllers/RTDDataAcquisitionController.cs b/Controllers/RTDDataAcquisitionController.cs
new file mode 100644
index 0000000..dd2721b
--- /dev/null
+++ b/Controllers/RTDDataAcquisitionController.cs
@@ -0,0 +1,98 @@
+using API_SequentMicrosystems.Services;
+using Microsoft.AspNetCore.Mvc;
+
+// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
+
+namespace API_SequentMicrosystems.Controllers
+{
+ [Route("RTDDA")]
+ [ApiController]
+ public class RTDDataAcquisitionController : ControllerBase
+ {
+ private RTDDAService _RTDDAservice;
+ public RTDDataAcquisitionController(RTDDAService serv)
+ {
+ _RTDDAservice = serv;
+ }
+
+ // GET: api/
+ ///
+ /// Read data from all configured cards
+ ///
+ ///
+ [HttpGet]
+ public SortedList Get()
+ {
+ return _RTDDAservice.ReadAllConfiguredCard();
+ }
+
+ // GET api//All
+ ///
+ /// Read data from All RTD cards
+ ///
+ ///
+ [HttpGet("All")]
+ public SortedList GetAll()
+ {
+ return _RTDDAservice.ReadAllCard();
+ }
+
+ // GET api//5
+ ///
+ /// Read data from specified card from stack
+ ///
+ ///
+ /// data from specified card
+ [HttpGet("{stack}")]
+ public float[] GetAll(byte stack)
+ {
+ return _RTDDAservice.ReadCard(stack);
+ }
+
+ //GET api/RTDDA/Names
+ ///
+ /// Get Configured Names of Chanels
+ ///
+ ///
+ [HttpGet("Names")]
+ public SortedList GetNames()
+ {
+ return _RTDDAservice.GetChanelsNames();
+ }
+
+ // POST api/
+ ///
+ /// Post configured names of chanels
+ ///
+ ///
+ [HttpPost("Names")]
+ public void PostNames([FromBody] SortedList data)
+ {
+ _RTDDAservice.SetChanelsNames(data);
+ }
+
+ //GET api/RTDDA/Names/Preconfigured
+ ///
+ /// Get preconfigured Names for chanels
+ ///
+ ///
+ [HttpGet("Names/Preconfigured")]
+ public List GetNamesPreconfigured()
+ {
+ return _RTDDAservice.GetPreconfiguratedChanelsNames();
+ }
+
+ //POST api/RTDDA/Names/Preconfigured
+ ///
+ /// Post preconfigured names for chanels
+ ///
+ ///
+ [HttpPost("Names/Preconfigured")]
+ public void PostNamesPreconfigured([FromBody] List data)
+ {
+ _RTDDAservice.SetPreconfiguratedChanelsNames(data);
+ }
+
+
+ }
+}
diff --git a/Models/CardsConfig.cs b/Models/CardsConfig.cs
new file mode 100644
index 0000000..0ddd48c
--- /dev/null
+++ b/Models/CardsConfig.cs
@@ -0,0 +1,12 @@
+namespace API_SequentMicrosystems.Models
+{
+ public class CardsConfig
+ {
+#pragma warning disable CS8618 // Pole, které nemůže být null, musí při ukončování konstruktoru obsahovat hodnotu, která není null. Zvažte možnost deklarovat ho jako pole s možnou hodnotou null.
+ public string ID { get; set; }
+ public string Name { get; set; }
+ public string ShortName { get; set; }
+ public string Levels { get; set; }
+ public string UpdateRateMsec { get; set; }
+ }
+}
diff --git a/Models/PointsModel.cs b/Models/PointsModel.cs
new file mode 100644
index 0000000..9e99336
--- /dev/null
+++ b/Models/PointsModel.cs
@@ -0,0 +1,18 @@
+namespace API_SequentMicrosystems.Models
+{
+ public class PointsModel
+ {
+ public DateTime Time { get; set; }
+ public SortedList RTDDA { get; set; }
+
+
+
+
+
+
+
+
+
+
+ }
+}
diff --git a/Program.cs b/Program.cs
new file mode 100644
index 0000000..0ff13ef
--- /dev/null
+++ b/Program.cs
@@ -0,0 +1,39 @@
+using API_SequentMicrosystems.Services;
+
+namespace API_SequentMicrosystems
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ var builder = WebApplication.CreateBuilder(args);
+
+ // Add services to the container.
+
+ builder.Services.AddControllers();
+
+ builder.Services.AddSingleton();
+
+ // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
+ builder.Services.AddEndpointsApiExplorer();
+ builder.Services.AddSwaggerGen();
+
+ var app = builder.Build();
+
+ // Configure the HTTP request pipeline.
+ if (true)//app.Environment.IsDevelopment())
+ {
+ app.UseSwagger();
+ app.UseSwaggerUI();
+ }
+
+ app.UseAuthorization();
+
+ app.Services.GetService();
+
+ app.MapControllers();
+
+ app.Run();
+ }
+ }
+}
diff --git a/Properties/launchSettings.json b/Properties/launchSettings.json
new file mode 100644
index 0000000..170db4c
--- /dev/null
+++ b/Properties/launchSettings.json
@@ -0,0 +1,31 @@
+{
+ "$schema": "http://json.schemastore.org/launchsettings.json",
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:58419",
+ "sslPort": 0
+ }
+ },
+ "profiles": {
+ "http": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "applicationUrl": "http://localhost:5242",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ }
+ }
+}
diff --git a/Services/PointsService.cs b/Services/PointsService.cs
new file mode 100644
index 0000000..ac7715c
--- /dev/null
+++ b/Services/PointsService.cs
@@ -0,0 +1,95 @@
+using API_SequentMicrosystems.Models;
+using Newtonsoft.Json;
+
+namespace API_SequentMicrosystems.Services
+{
+ public class PointsService
+ {
+
+
+ private RTDDAService _RTDDAService;
+
+ public PointsService(RTDDAService _RTDDAS)
+ {
+ if (!Directory.Exists("Points"))
+ Directory.CreateDirectory("Points");
+
+ _RTDDAService = _RTDDAS;
+
+ _points = LoadPoints();
+ }
+
+ private List _points;
+
+ ///
+ /// Load points from File
+ ///
+ ///
+ private List LoadPoints()
+ {
+ try
+ {
+ #pragma warning disable CS8603 // Může jít o vrácený odkaz null.
+ return JsonConvert.DeserializeObject>(File.ReadAllText("Points/SavedData.json"));
+ #pragma warning restore CS8603 // Může jít o vrácený odkaz null.
+ }
+ catch
+ {
+ return new();
+ }
+ }
+
+ ///
+ /// Save points to File
+ ///
+ private void SavePoints()
+ {
+ File.WriteAllText("Points/SavedData.json", JsonConvert.SerializeObject(_points));
+ }
+
+ ///
+ /// Get saved Points
+ ///
+ ///
+ public List GetPoints()
+ {
+ return _points;
+ }
+
+ ///
+ /// Delete Points
+ ///
+ public void DeletePoints()
+ {
+ _points = new();
+ SavePoints();
+ }
+
+ ///
+ /// Save data/status point
+ ///
+ public void SavePoint()
+ {
+ PointsModel pm = new PointsModel(); //initialize point object
+ pm.Time = DateTime.Now; //set time of point created
+ pm.RTDDA = _RTDDAService.ReadAllCard(); //save RTD data to point
+
+ _points.Add(pm); //add point to list
+ SavePoints(); //Save updated points
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+}
diff --git a/Services/RTDDataAcquisitionService.cs b/Services/RTDDataAcquisitionService.cs
new file mode 100644
index 0000000..ed68205
--- /dev/null
+++ b/Services/RTDDataAcquisitionService.cs
@@ -0,0 +1,206 @@
+using API_SequentMicrosystems.Models;
+using Libs_SequentMicrosystems;
+using Newtonsoft.Json;
+
+namespace API_SequentMicrosystems.Services
+{
+ public class RTDDAService
+ {
+ private RTDStackLevelReader _stackLevelReader = new RTDStackLevelReader();
+ public readonly List _stackLevels = new List();
+
+ public RTDDAService(IConfiguration configuration)
+ {
+ if (!Directory.Exists("RTDDA"))
+ Directory.CreateDirectory("RTDDA");
+
+ List cardsConfig = configuration.GetSection("Cards").Get>();
+ #pragma warning disable CS8604 // Může jít o argument s odkazem null.
+ CardsConfig config = cardsConfig.Where(x => x.ID == "0").First();
+ #pragma warning restore CS8604 // Může jít o argument s odkazem null.
+ foreach (char c in config.Levels.ToCharArray())
+ {
+ try
+ {
+ _stackLevels.Add(byte.Parse(c.ToString()));
+ }
+ catch
+ {
+ Console.WriteLine($"Char {c} is not convertable to byte");
+ }
+ }
+
+ ChanelsNames = LoadChanelsNames(); //ChanelsNames
+ PreconfiguredChanelsNames = LoadPreconfiguredChanelsNames(); //ChanelsPreconfiguredNames
+ }
+
+ ///
+ /// Read data from all RTD cards
+ ///
+ /// data from all RTD cards
+ public SortedList ReadAllCard()
+ {
+ SortedList data = new SortedList();
+
+ 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");
+ }
+
+ }
+
+ return data; //return data
+ }
+
+ ///
+ /// Read data from all configured cards
+ ///
+ /// Data from all configuredd Cards
+ public SortedList ReadAllConfiguredCard()
+ {
+ SortedList data = new SortedList();
+
+ for (byte i = 0; i < 8; i++) //loop for read all stack levels
+ {
+ if (_stackLevels.Contains(i))
+ {
+ try
+ {
+ data.Add(i, ReadCard(i)); //read stack level
+ }
+ catch
+ {
+ Console.WriteLine($"RTD stack {i} is not available");
+ }
+ }
+ }
+
+ return data; //return data
+ }
+
+ ///
+ /// Read data from specified card
+ ///
+ /// stack level ID
+ /// Data of selected stack card
+ public float[] ReadCard(byte stack)
+ {
+ try
+ {
+ return _stackLevelReader.GetStack(stack); //return data from specified card
+ }
+ catch
+ {
+ return new float[0]; //if card read get error, return empty array
+ }
+ }
+
+
+ #region ChanelsName
+ private SortedList ChanelsNames;
+
+ ///
+ /// Load Chanels Names from file
+ ///
+ ///
+ private SortedList LoadChanelsNames()
+ {
+ try
+ {
+ #pragma warning disable CS8603 // Může jít o vrácený odkaz null.
+ return JsonConvert.DeserializeObject>(File.ReadAllText("RTDDA/Names.json"));
+ #pragma warning restore CS8603 // Může jít o vrácený odkaz null.
+ }
+ catch
+ {
+ return new();
+ }
+ }
+
+ ///
+ /// Save ChanelsNames to FIle
+ ///
+ private void SaveChanelsNames()
+ {
+ File.WriteAllText("RTDDA/Names.json", JsonConvert.SerializeObject(ChanelsNames));
+ }
+
+ ///
+ /// Get CHanelsNames
+ ///
+ ///
+ public SortedList GetChanelsNames()
+ {
+ return ChanelsNames;
+ }
+
+ ///
+ /// Save Chanels Names
+ ///
+ ///
+ public void SetChanelsNames(SortedList ChN)
+ {
+ ChanelsNames = ChN;
+ SaveChanelsNames();
+ }
+
+ #endregion
+
+ #region PreconfiguredChanelsNames
+ private List PreconfiguredChanelsNames;
+
+ ///
+ /// Load Preconfigurated Chanels Names from file
+ ///
+ ///
+ private List LoadPreconfiguredChanelsNames()
+ {
+ try
+ {
+ #pragma warning disable CS8603 // Může jít o vrácený odkaz null.
+ return JsonConvert.DeserializeObject>(File.ReadAllText("RTDDA/PNames.json"));
+ #pragma warning restore CS8603 // Může jít o vrácený odkaz null.
+ }
+ catch
+ {
+ return new();
+ }
+ }
+
+ ///
+ /// Save Preconfigurated chanels names to File
+ ///
+ private void SavePreconfiguratedChanelsNames()
+ {
+ File.WriteAllText("RTDDA/PNames.json", JsonConvert.SerializeObject(PreconfiguredChanelsNames));
+ }
+
+ ///
+ /// Get preconfigured chanels names
+ ///
+ ///
+ public List GetPreconfiguratedChanelsNames()
+ {
+ return PreconfiguredChanelsNames.ToList();
+ }
+
+ ///
+ /// Save Preconfigured ChanelsNames
+ ///
+ ///
+ public void SetPreconfiguratedChanelsNames(List ChN)
+ {
+ PreconfiguredChanelsNames = ChN;
+ SavePreconfiguratedChanelsNames();
+ }
+
+ #endregion
+
+ }
+}
diff --git a/appsettings.Development.json b/appsettings.Development.json
new file mode 100644
index 0000000..0c208ae
--- /dev/null
+++ b/appsettings.Development.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ }
+}
diff --git a/appsettings.json b/appsettings.json
new file mode 100644
index 0000000..f18bdf9
--- /dev/null
+++ b/appsettings.json
@@ -0,0 +1,18 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ },
+ "AllowedHosts": "*",
+ "Cards": [
+ {
+ "ID": "0",
+ "Name": "RTD Data Acquisition 8-Layer Stackable HAT for Raspberry Pi",
+ "ShortName": "RTDDA",
+ "Levels": "1",
+ "UpdateRateMsec": "1000"
+ }
+ ]
+}