Přidejte soubory projektu.

master
Jan Beníček 2023-11-25 09:24:04 +01:00
parent 627613b499
commit 85790996de
14 changed files with 691 additions and 0 deletions

4
.editorconfig Normal file
View File

@ -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

View File

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Libs_SequentMicrosystems\Libs_SequentMicrosystems.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,6 @@
@API_SequentMicrosystems_HostAddress = http://localhost:5242
GET {{API_SequentMicrosystems_HostAddress}}/weatherforecast/
Accept: application/json
###

View File

@ -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

View File

@ -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/<PointsController>
/// <summary>
/// Get all saved points
/// </summary>
/// <returns></returns>
[HttpGet]
public List<PointsModel> Get()
{
return _PointsService.GetPoints();
}
// GET api/<PointsController>/5
/// <summary>
/// Read points from first to specified number
/// </summary>
/// <param name="max">max readed points</param>
/// <returns></returns>
[HttpGet("{max}")]
public List<PointsModel> Get(int max)
{
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();
}
//DELETE api/points
/// <summary>
/// Delete saved points
/// </summary>
[HttpDelete]
public void Delete()
{
_PointsService.DeletePoints();
}
//GET api/points/save
/// <summary>
/// Save new point
/// </summary>
[HttpGet("save")]
public void GetSave()
{
_PointsService.SavePoint();
}
//GET api/points/save/300
/// <summary>
/// Start timer to automatic saving points in specified interval
/// </summary>
/// <param name="sec"></param>
[HttpGet("save/{sec}")]
public void GetSaveSec(int sec)
{
//start autosave timer
}
//GET api/points/save
/// <summary>
/// Stop timer for automatic save points
/// </summary>
[HttpDelete("save")]
public void DeleteSaveSec()
{
//stop autosave timer
}
}
}

View File

@ -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/<RTDDataAcquisitionController>
/// <summary>
/// Read data from all configured cards
/// </summary>
/// <returns></returns>
[HttpGet]
public SortedList<byte, float[]> Get()
{
return _RTDDAservice.ReadAllConfiguredCard();
}
// GET api/<RTDDataAcquisitionController>/All
/// <summary>
/// Read data from All RTD cards
/// </summary>
/// <returns></returns>
[HttpGet("All")]
public SortedList<byte, float[]> GetAll()
{
return _RTDDAservice.ReadAllCard();
}
// GET api/<RTDDataAcquisitionController>/5
/// <summary>
/// Read data from specified card from stack
/// </summary>
/// <param name="stack"></param>
/// <returns>data from specified card</returns>
[HttpGet("{stack}")]
public float[] GetAll(byte stack)
{
return _RTDDAservice.ReadCard(stack);
}
//GET api/RTDDA/Names
/// <summary>
/// Get Configured Names of Chanels
/// </summary>
/// <returns></returns>
[HttpGet("Names")]
public SortedList<byte, string[]> GetNames()
{
return _RTDDAservice.GetChanelsNames();
}
// POST api/<RTDDataAcquisitionController>
/// <summary>
/// Post configured names of chanels
/// </summary>
/// <param name="data"></param>
[HttpPost("Names")]
public void PostNames([FromBody] SortedList<byte, string[]> data)
{
_RTDDAservice.SetChanelsNames(data);
}
//GET api/RTDDA/Names/Preconfigured
/// <summary>
/// Get preconfigured Names for chanels
/// </summary>
/// <returns></returns>
[HttpGet("Names/Preconfigured")]
public List<string> GetNamesPreconfigured()
{
return _RTDDAservice.GetPreconfiguratedChanelsNames();
}
//POST api/RTDDA/Names/Preconfigured
/// <summary>
/// Post preconfigured names for chanels
/// </summary>
/// <param name="data"></param>
[HttpPost("Names/Preconfigured")]
public void PostNamesPreconfigured([FromBody] List<string> data)
{
_RTDDAservice.SetPreconfiguratedChanelsNames(data);
}
}
}

12
Models/CardsConfig.cs Normal file
View File

@ -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; }
}
}

18
Models/PointsModel.cs Normal file
View File

@ -0,0 +1,18 @@
namespace API_SequentMicrosystems.Models
{
public class PointsModel
{
public DateTime Time { get; set; }
public SortedList<byte, float[]> RTDDA { get; set; }
}
}

39
Program.cs Normal file
View File

@ -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<RTDDAService>();
// 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<RTDDAService>();
app.MapControllers();
app.Run();
}
}
}

View File

@ -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"
}
}
}
}

95
Services/PointsService.cs Normal file
View File

@ -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<PointsModel> _points;
/// <summary>
/// Load points from File
/// </summary>
/// <returns></returns>
private List<PointsModel> LoadPoints()
{
try
{
#pragma warning disable CS8603 // Může jít o vrácený odkaz null.
return JsonConvert.DeserializeObject<List<PointsModel>>(File.ReadAllText("Points/SavedData.json"));
#pragma warning restore CS8603 // Může jít o vrácený odkaz null.
}
catch
{
return new();
}
}
/// <summary>
/// Save points to File
/// </summary>
private void SavePoints()
{
File.WriteAllText("Points/SavedData.json", JsonConvert.SerializeObject(_points));
}
/// <summary>
/// Get saved Points
/// </summary>
/// <returns></returns>
public List<PointsModel> GetPoints()
{
return _points;
}
/// <summary>
/// Delete Points
/// </summary>
public void DeletePoints()
{
_points = new();
SavePoints();
}
/// <summary>
/// Save data/status point
/// </summary>
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
}
}
}

View File

@ -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<byte> _stackLevels = new List<byte>();
public RTDDAService(IConfiguration configuration)
{
if (!Directory.Exists("RTDDA"))
Directory.CreateDirectory("RTDDA");
List<CardsConfig> cardsConfig = configuration.GetSection("Cards").Get<List<CardsConfig>>();
#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
}
/// <summary>
/// Read data from all RTD cards
/// </summary>
/// <returns>data from all RTD cards</returns>
public SortedList<byte, float[]> ReadAllCard()
{
SortedList<byte, float[]> data = new SortedList<byte, float[]>();
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
}
/// <summary>
/// Read data from all configured cards
/// </summary>
/// <returns>Data from all configuredd Cards</returns>
public SortedList<byte, float[]> ReadAllConfiguredCard()
{
SortedList<byte, float[]> data = new SortedList<byte, float[]>();
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
}
/// <summary>
/// Read data from specified card
/// </summary>
/// <param name="stack">stack level ID</param>
/// <returns>Data of selected stack card</returns>
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<byte, string[]> ChanelsNames;
/// <summary>
/// Load Chanels Names from file
/// </summary>
/// <returns></returns>
private SortedList<byte, string[]> LoadChanelsNames()
{
try
{
#pragma warning disable CS8603 // Může jít o vrácený odkaz null.
return JsonConvert.DeserializeObject<SortedList<byte, string[]>>(File.ReadAllText("RTDDA/Names.json"));
#pragma warning restore CS8603 // Může jít o vrácený odkaz null.
}
catch
{
return new();
}
}
/// <summary>
/// Save ChanelsNames to FIle
/// </summary>
private void SaveChanelsNames()
{
File.WriteAllText("RTDDA/Names.json", JsonConvert.SerializeObject(ChanelsNames));
}
/// <summary>
/// Get CHanelsNames
/// </summary>
/// <returns></returns>
public SortedList<byte, string[]> GetChanelsNames()
{
return ChanelsNames;
}
/// <summary>
/// Save Chanels Names
/// </summary>
/// <param name="ChN"></param>
public void SetChanelsNames(SortedList<byte, string[]> ChN)
{
ChanelsNames = ChN;
SaveChanelsNames();
}
#endregion
#region PreconfiguredChanelsNames
private List<string> PreconfiguredChanelsNames;
/// <summary>
/// Load Preconfigurated Chanels Names from file
/// </summary>
/// <returns></returns>
private List<string> LoadPreconfiguredChanelsNames()
{
try
{
#pragma warning disable CS8603 // Může jít o vrácený odkaz null.
return JsonConvert.DeserializeObject<List<string>>(File.ReadAllText("RTDDA/PNames.json"));
#pragma warning restore CS8603 // Může jít o vrácený odkaz null.
}
catch
{
return new();
}
}
/// <summary>
/// Save Preconfigurated chanels names to File
/// </summary>
private void SavePreconfiguratedChanelsNames()
{
File.WriteAllText("RTDDA/PNames.json", JsonConvert.SerializeObject(PreconfiguredChanelsNames));
}
/// <summary>
/// Get preconfigured chanels names
/// </summary>
/// <returns></returns>
public List<string> GetPreconfiguratedChanelsNames()
{
return PreconfiguredChanelsNames.ToList();
}
/// <summary>
/// Save Preconfigured ChanelsNames
/// </summary>
/// <param name="ChN"></param>
public void SetPreconfiguratedChanelsNames(List<string> ChN)
{
PreconfiguredChanelsNames = ChN;
SavePreconfiguratedChanelsNames();
}
#endregion
}
}

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

18
appsettings.json Normal file
View File

@ -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"
}
]
}