From 2aca03ed95bc8ea419784e1540bb1399836138c3 Mon Sep 17 00:00:00 2001 From: "Georgy.Khatuncev" Date: Sun, 23 Mar 2025 04:24:35 +0500 Subject: [PATCH] Add config, combine generator and api, add swagger. --- .gitignore | 215 ++++++++++ APICycleVDP.sln | 6 - APICycleVDP/.config/dotnet-tools.json | 13 + APICycleVDP/APICycleVDP.csproj | 10 +- APICycleVDP/Controller/CyclesController.cs | 71 ---- APICycleVDP/Controllers/CyclesController.cs | 48 +++ APICycleVDP/DB/DbContext.cs | 12 + .../TableCycle.cs => APICycleVDP/DB/TCycle.cs | 13 +- APICycleVDP/Program.cs | 80 +++- .../PublishProfiles/FolderProfile.pubxml | 21 + APICycleVDP/Properties/launchSettings.json | 4 +- APICycleVDP/Services/VdpCyclesGen.cs | 377 ++++++++++++++++++ APICycleVDP/appsettings.Development.json | 15 +- APICycleVDP/appsettings.json | 7 +- DbCycleVDP/DbFurnace.cs | 24 -- GenCycleVDP/GenCycle.cs | 151 ------- GenCycleVDP/GenCycleVDP.csproj | 19 - GenCycleVDP/Program.cs | 53 --- GenCycleVDP/Resources/CycleStatus.cs | 20 - GenCycleVDP/Resources/GenData.cs | 131 ------ 20 files changed, 779 insertions(+), 511 deletions(-) create mode 100644 .gitignore create mode 100644 APICycleVDP/.config/dotnet-tools.json delete mode 100644 APICycleVDP/Controller/CyclesController.cs create mode 100644 APICycleVDP/Controllers/CyclesController.cs create mode 100644 APICycleVDP/DB/DbContext.cs rename DbCycleVDP/TableCycle.cs => APICycleVDP/DB/TCycle.cs (57%) create mode 100644 APICycleVDP/Properties/PublishProfiles/FolderProfile.pubxml create mode 100644 APICycleVDP/Services/VdpCyclesGen.cs delete mode 100644 DbCycleVDP/DbFurnace.cs delete mode 100644 GenCycleVDP/GenCycle.cs delete mode 100644 GenCycleVDP/GenCycleVDP.csproj delete mode 100644 GenCycleVDP/Program.cs delete mode 100644 GenCycleVDP/Resources/CycleStatus.cs delete mode 100644 GenCycleVDP/Resources/GenData.cs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..48c6589 --- /dev/null +++ b/.gitignore @@ -0,0 +1,215 @@ + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results +[Dd]ebug/ +[Rr]elease/ +x64/ +[Bb]in/ +[Oo]bj/ +# build folder is nowadays used for build scripts and should not be ignored +#build/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.scc + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +*.ncrunch* +.*crunch*.local.xml + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ +\!publish/ + +# Publish Web Output +*.Publish.xml + +# Windows Azure Build Output +csx +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.[Pp]ublish.xml +*.pfx +*.publishsettings +modulesbin/ +tempbin/ + +# EPiServer Site file (VPP) +AppData/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# vim +*.txt~ +*.swp +*.swo + +# Temp files when opening LibreOffice on ubuntu +.~lock.* + +# svn +.svn + +# CVS - Source Control +**/CVS/ + +# Remainings from resolving conflicts in Source Control +*.orig + +# SQL Server files +**/App_Data/*.mdf +**/App_Data/*.ldf +**/App_Data/*.sdf + + +#LightSwitch generated files +GeneratedArtifacts/ +_Pvt_Extensions/ +ModelManifest.xml + +# ========================= +# Windows detritus +# ========================= + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# OS generated files # +Icon? + +# Mac desktop service store files +.DS_Store + +# SASS Compiler cache +.sass-cache + +# Visual Studio 2014 CTP +**/*.sln.ide + +# Visual Studio temp something +.vs/ + +# dotnet stuff +project.lock.json + +# VS 2015+ +*.vc.vc.opendb +*.vc.db + +# Rider +.idea/ + +# Visual Studio Code +.vscode/ + +# Output folder used by Webpack or other FE stuff +**/node_modules/* +**/wwwroot/* + +# SpecFlow specific +*.feature.cs +*.feature.xlsx.* +*.Specs_*.html + +# UWP Projects +AppPackages/ diff --git a/APICycleVDP.sln b/APICycleVDP.sln index 2329781..1f0e449 100644 --- a/APICycleVDP.sln +++ b/APICycleVDP.sln @@ -5,8 +5,6 @@ VisualStudioVersion = 17.11.35303.130 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "APICycleVDP", "APICycleVDP\APICycleVDP.csproj", "{EE827F72-C902-4E67-B4E7-A1B869310349}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GenCycleVDP", "GenCycleVDP\GenCycleVDP.csproj", "{CEFFBDBE-DDBA-421D-80FA-A730914A5BDD}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -17,10 +15,6 @@ Global {EE827F72-C902-4E67-B4E7-A1B869310349}.Debug|Any CPU.Build.0 = Debug|Any CPU {EE827F72-C902-4E67-B4E7-A1B869310349}.Release|Any CPU.ActiveCfg = Release|Any CPU {EE827F72-C902-4E67-B4E7-A1B869310349}.Release|Any CPU.Build.0 = Release|Any CPU - {CEFFBDBE-DDBA-421D-80FA-A730914A5BDD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CEFFBDBE-DDBA-421D-80FA-A730914A5BDD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CEFFBDBE-DDBA-421D-80FA-A730914A5BDD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CEFFBDBE-DDBA-421D-80FA-A730914A5BDD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/APICycleVDP/.config/dotnet-tools.json b/APICycleVDP/.config/dotnet-tools.json new file mode 100644 index 0000000..9fab42f --- /dev/null +++ b/APICycleVDP/.config/dotnet-tools.json @@ -0,0 +1,13 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "dotnet-ef": { + "version": "8.0.8", + "commands": [ + "dotnet-ef" + ], + "rollForward": false + } + } +} \ No newline at end of file diff --git a/APICycleVDP/APICycleVDP.csproj b/APICycleVDP/APICycleVDP.csproj index 64687dd..d9f14f0 100644 --- a/APICycleVDP/APICycleVDP.csproj +++ b/APICycleVDP/APICycleVDP.csproj @@ -3,17 +3,13 @@ net8.0 enable - enable + disable - - - - - - + + diff --git a/APICycleVDP/Controller/CyclesController.cs b/APICycleVDP/Controller/CyclesController.cs deleted file mode 100644 index cdc7db2..0000000 --- a/APICycleVDP/Controller/CyclesController.cs +++ /dev/null @@ -1,71 +0,0 @@ -using Microsoft.AspNetCore.Cors; -using Microsoft.AspNetCore.Mvc; -using Newtonsoft.Json.Linq; -using DbCycleVDP; - -namespace APICycleVDP.Controller -{ - [EnableCors("All")] - public class CyclesController : ControllerBase - { - [HttpPost] - public ActionResult CurrCycles() - { - var result = new JObject - { - ["currTime"] = DateTime.Now - }; - - var tasks = new List>(); - //var v = new DB.WorkDB(); - for (var i = 1; i <= 48; i++) - tasks.Add(WorkDB.GetCycle(i)); - - var arr = new JArray(); - for (var i = 0; i < tasks.Count; i++) - { - var tmp = tasks[i].GetAwaiter().GetResult(); - if (tmp != null) - { - var t = new JObject(); - t["vdp"] = tmp.NumVdp; - t["cycle"] = tmp.NumCycle; - t["factStart"] = tmp.FactStart; - t["factEnd"] = tmp.FactEnd; - t["thinkEnd"] = tmp.ThinkEnd; - arr.Add(t); - } - } - result["data"] = arr; - - return Content(result.ToString(), "application/json"); - } - } - - - public static class WorkDB - { - async public static Task GetCycle(int vdp) - { - var result = new TableCycle(); - await Task.Run(() => - { - try - { - using var db = new DbFurnace(); - var tmp = (from u in db.Cycles - where - u.NumVdp == vdp - orderby u.FactStart descending - select u).FirstOrDefault(); - result = tmp; - } - catch (Exception e) - { - Console.WriteLine(e.Message); - } - }); - return result; - } - } -} diff --git a/APICycleVDP/Controllers/CyclesController.cs b/APICycleVDP/Controllers/CyclesController.cs new file mode 100644 index 0000000..20278d2 --- /dev/null +++ b/APICycleVDP/Controllers/CyclesController.cs @@ -0,0 +1,48 @@ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Threading.Tasks; +using System.Collections.Generic; +using System.Linq; +using Microsoft.EntityFrameworkCore; +using APICycleVDP.DB; + +namespace APICycleVDP.Controllers +{ + [ApiController] + [Route("cycles")] + public class CyclesController(DbVdpContext context) : ControllerBase + { + private readonly DbVdpContext _context = context; + + [HttpPost("current")] + public async Task CurrCycles() + { + var result = new + { + currTime = DateTime.UtcNow, + data = new List() + }; + + var cycles = _context.Cycles + .GroupBy(x => x.NumVdp) + .Select(x => x.OrderByDescending(x => x.FactStart).FirstOrDefault()); + + foreach (var cycle in cycles) + { + if (cycle != null) + { + result.data.Add(new + { + vdp = cycle.NumVdp, + cycle = cycle.NumCycle, + factStart = cycle.FactStart.ToUniversalTime(), + factEnd = cycle.FactEnd.ToUniversalTime(), + thinkEnd = cycle.ThinkEnd.ToUniversalTime() + }); + } + } + + return Ok(result); + } + } +} diff --git a/APICycleVDP/DB/DbContext.cs b/APICycleVDP/DB/DbContext.cs new file mode 100644 index 0000000..1029456 --- /dev/null +++ b/APICycleVDP/DB/DbContext.cs @@ -0,0 +1,12 @@ +using System; +using Microsoft.EntityFrameworkCore; + +namespace APICycleVDP.DB +{ + public class DbVdpContext(DbContextOptions options) : DbContext(options) + { + public DbSet Cycles { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) {} + } +} diff --git a/DbCycleVDP/TableCycle.cs b/APICycleVDP/DB/TCycle.cs similarity index 57% rename from DbCycleVDP/TableCycle.cs rename to APICycleVDP/DB/TCycle.cs index 7246b25..185cb4b 100644 --- a/DbCycleVDP/TableCycle.cs +++ b/APICycleVDP/DB/TCycle.cs @@ -2,22 +2,17 @@ using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations; -namespace DbCycleVDP +namespace APICycleVDP.DB { [Table("Cycles")] - public class TableCycle + public class Cycle { - [Column("idCycle"), Required, Key] - public int IdCycle { get; set; } - [Column("numVdp")] + [Key] + public int Id { get; set; } public int NumVdp { get; set; } - [Column("numCycle")] public int NumCycle { get; set; } - [Column("factStart")] public DateTime FactStart { get; set; } - [Column("thinkEnd")] public DateTime ThinkEnd { get; set; } - [Column("factEnd")] public DateTime FactEnd { get; set; } } } diff --git a/APICycleVDP/Program.cs b/APICycleVDP/Program.cs index 5758fa3..8a2c118 100644 --- a/APICycleVDP/Program.cs +++ b/APICycleVDP/Program.cs @@ -1,22 +1,72 @@ -var builder = WebApplication.CreateBuilder(args); +using APICycleVDP.DB; +using APICycleVDP.Services; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using System; -builder.Services.AddControllers(); -builder.Services.AddCors(options => +namespace APICycleVDP { - options.AddPolicy("AllowAllOrigins", - builder => + public class Program + { + public static void Main(string[] args) { - builder.AllowAnyOrigin() - .AllowAnyMethod() - .AllowAnyHeader(); - }); -}); + var builder = WebApplication.CreateBuilder(args); + builder.WebHost.UseKestrel(); -var app = builder.Build(); + //Add context DB + builder.Services.AddDbContext(options => + options.UseMySql(builder.Configuration.GetConnectionString("MySql"), + new MySqlServerVersion(new Version(8, 4, 3)))); -app.UseCors("AllowAllOrigins"); + builder.Services.AddCors(options => + { + options.AddDefaultPolicy( + policy => + { + policy.AllowAnyOrigin(); + policy.AllowAnyHeader(); + policy.AllowAnyMethod(); + }); + }); -app.MapControllerRoute(name: "CurrCycles", pattern: "/currcycles", - defaults: new { controller = "Cycles", action = "CurrCycles" }); + builder.Services.AddControllers(); -app.Run(); \ No newline at end of file + var useGenCycles = bool.TryParse(builder.Configuration["UseGenCycles"], out bool resConfBool) && resConfBool; + builder.Services.AddHostedService(); + + var useSwagger = bool.TryParse(builder.Configuration["UseSwagger"], out resConfBool) && resConfBool; + if (useSwagger) + { + builder.Services.AddEndpointsApiExplorer(); + builder.Services.AddSwaggerGen(); + } + + var app = builder.Build(); + + using (var scope = app.Services.CreateScope()) + { + var dbContext = scope.ServiceProvider.GetRequiredService(); + dbContext.Database.EnsureCreated(); + } + + if (useSwagger) + { + app.UseSwagger(); + app.UseSwaggerUI(options => + { + options.SwaggerEndpoint("/swagger/v1/swagger.json", "v1"); + //options.RoutePrefix = string.Empty; + }); + } + + app.UseCors(); + + app.UseAuthorization(); + app.MapControllers(); + app.Run(); + } + } +} \ No newline at end of file diff --git a/APICycleVDP/Properties/PublishProfiles/FolderProfile.pubxml b/APICycleVDP/Properties/PublishProfiles/FolderProfile.pubxml new file mode 100644 index 0000000..9eaff5f --- /dev/null +++ b/APICycleVDP/Properties/PublishProfiles/FolderProfile.pubxml @@ -0,0 +1,21 @@ + + + + + true + false + true + Release + Any CPU + FileSystem + !publish\ + FileSystem + <_TargetId>Folder + + net8.0 + ee827f72-c902-4e67-b4e7-a1b869310349 + false + + \ No newline at end of file diff --git a/APICycleVDP/Properties/launchSettings.json b/APICycleVDP/Properties/launchSettings.json index b9148c3..284c910 100644 --- a/APICycleVDP/Properties/launchSettings.json +++ b/APICycleVDP/Properties/launchSettings.json @@ -12,9 +12,7 @@ "http": { "commandName": "Project", "dotnetRunMessages": true, - "launchBrowser": true, - "launchUrl": "currcycles", - "applicationUrl": "http://localhost:65041", + "launchBrowser": false, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/APICycleVDP/Services/VdpCyclesGen.cs b/APICycleVDP/Services/VdpCyclesGen.cs new file mode 100644 index 0000000..f938624 --- /dev/null +++ b/APICycleVDP/Services/VdpCyclesGen.cs @@ -0,0 +1,377 @@ +using APICycleVDP.DB; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace APICycleVDP.Services +{ + public class VdpCyclesGen(IServiceScopeFactory serviceScopeFactory) : BackgroundService + { + private readonly IServiceScopeFactory _serviceScopeFactory = serviceScopeFactory; + private readonly List _tasks = []; + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + Console.WriteLine("Gen: Start cycles."); + + for (var i = 1; i <= 48; i++) + { + var task = new GenCycle(i, _serviceScopeFactory); + task.Start(); + _tasks.Add(task); + } + + while (!stoppingToken.IsCancellationRequested) + { + try + { + await Task.Delay(TimeSpan.FromMinutes(10), stoppingToken); + } + catch (TaskCanceledException) + { + Console.WriteLine("Gen: Cycle cancelled."); + continue; + } + for (var i = 0; i < _tasks.Count; i++) + { + if (i % 10 == 0 && i != 0) + Console.WriteLine(); + Console.Write(_tasks[i].GetStatus() + "|"); + } + Console.WriteLine(); + } + + foreach (var task in _tasks) + { + task.Stop(); + } + } + } + + internal class GenCycle(int vdp, IServiceScopeFactory serviceScopeFactory) + { + private readonly int _vdp = vdp; + private readonly IServiceScopeFactory _serviceScopeFactory = serviceScopeFactory; + private DbVdpContext? _db; + + private CycleStatus _currCycle = CycleStatus.EndTechCycle; + private DateTime _factStart = DateTime.Now; + private DateTime _factEnd = DateTime.Now; + private DateTime _thinkEnd = DateTime.Now; + + private readonly CancellationTokenSource _cts = new(); + private Task _taskCycle = Task.CompletedTask; + + public void Start() + { + _taskCycle = Cycle(_cts.Token); + } + public void Stop() + { + _cts.Cancel(); + _taskCycle.Wait(); + } + + async public Task Cycle(CancellationToken token) + { + using var scope = _serviceScopeFactory.CreateScope(); + _db = scope.ServiceProvider.GetRequiredService(); + while (!token.IsCancellationRequested) + { + if (GetCurrCycle()) //Can get info form DB. + { + if (DateTime.Now >= _factEnd) + { + GetNextCycle(); + GetTimeStart(); + GetTimeThinkEnd(); + GetTimeFactEnd(); + while (!SaveToDB()) + { + Console.WriteLine("Gen: VDP " + _vdp.ToString("D2") + ": Can't connect to DB."); + try + { + await Task.Delay(5000, token); + } + catch (TaskCanceledException) + { + Console.WriteLine("Gen: VDP " + _vdp.ToString("D2") + ": Main cycle cancelled."); + return; + } + } + } + } + else //It's new Cycle. + { + GetTimeStart(); + GetTimeThinkEnd(); + GetTimeFactEnd(); + while (!SaveToDB()) + { + Console.WriteLine("Gen: VDP " + _vdp.ToString("D2") + ": Can't connect to DB."); + try + { + await Task.Delay(5000, token); + } + catch (TaskCanceledException) + { + Console.WriteLine("Gen: VDP " + _vdp.ToString("D2") + ": Main cycle cancelled."); + return; + } + } + } + + while (!token.IsCancellationRequested && (DateTime.Now < _factEnd)) + { + var secAwait = (_factEnd - DateTime.Now).TotalSeconds; + secAwait = secAwait >= 5 ? 5 : secAwait; + try + { + await Task.Delay(Convert.ToInt32(Math.Ceiling(secAwait)) * 1000, token); + } + catch (TaskCanceledException) + { + Console.WriteLine("Gen: VDP " + _vdp.ToString("D2") + ": Main cycle cancelled."); + return; + } + } + } + Console.WriteLine("Gen: VDP " + _vdp.ToString("D2") + ": Main cycle cancelled."); + return; + } + + public bool GetCurrCycle() + { + if (_db == null) + { + return false; + } + try + { + var tmp = _db.Cycles + .Where(x => x.NumVdp == _vdp) + .OrderByDescending(x => x.FactStart) + .FirstOrDefault(); + if (tmp == null) + { + _currCycle = CycleStatus.EndTechCycle; + return false; + } + _currCycle = Enum.IsDefined(typeof(CycleStatus), tmp.NumCycle) + ? (CycleStatus)tmp.NumCycle + : CycleStatus.EndTechCycle; + _factStart = tmp.FactStart; + _factEnd = tmp.FactEnd; + } + catch (Exception e) + { + Console.WriteLine(e.Message); + return false; + } + return true; + } + public void GetNextCycle() + { + _currCycle = GenData.GetNextCycle(_currCycle); + } + public void GetTimeStart() + { + _factStart = _factEnd; + } + public void GetTimeThinkEnd() + { + _thinkEnd = _factStart.AddMinutes(GenData.GetDuration(_currCycle)); + } + public void GetTimeFactEnd() + { + _factEnd = _thinkEnd.AddSeconds(GenData.GetDeviation(_currCycle)); + } + public bool SaveToDB() + { + if (_db == null) + { + return false; + } + try + { + //Clear DB + var oldCycles = _db.Cycles + .Where(x => x.NumVdp == _vdp && x.FactEnd < DateTime.Now.AddMonths(-1)); + if (oldCycles.Any()) + { + _db.Cycles.RemoveRange(oldCycles); + } + + //Save parameter + _db.Cycles.Add(new Cycle() + { + NumVdp = _vdp, + NumCycle = (int)_currCycle, + FactStart = _factStart, + FactEnd = _factEnd, + ThinkEnd = _thinkEnd + }); + _db.SaveChanges(); + } + catch (Exception e) + { + Console.WriteLine("Gen: " + e.Message); + return false; + } + return true; + } + + public string GetStatus() + { + return _vdp.ToString("D2") + "-" + _currCycle.ToString(); + } + } + + internal static class GenData + { + private static readonly Random random = new(); + private static readonly Dictionary NextState, int Duration, (int min, int offset))> genDataMap = new() + { + { + CycleStatus.EndTechCycle, + (() => random.Next(100) < 50 + ? CycleStatus.VacForMeltingScarp + : CycleStatus.VacForWelding, + 15, + (7 * 60, 5 * 60)) + }, + { + CycleStatus.LoadUnload, + (() => CycleStatus.VacForWelding, + 15, + (3 * 60, 2 * 60)) + }, + { + CycleStatus.VacForWelding, + (() => CycleStatus.Welding, + 10, + (11 * 60, 1 * 60)) + }, + { + CycleStatus.Welding, + (() => CycleStatus.CoolingWelding, + 13, + (4 * 60, 3 * 60)) + }, + { + CycleStatus.CoolingWelding, + (() => CycleStatus.CheckWelding, + 7, + (4 * 60, 3 * 60)) + }, + { + CycleStatus.CheckWelding, + (() => random.Next(100) < 20 + ? CycleStatus.Welding + : CycleStatus.VacForMelting, + 5, + (7 * 60, 2 * 60)) + }, + { + CycleStatus.VacForMelting, + (() => CycleStatus.DilutionVat, + 10, + (11 * 60, 1 * 60)) + }, + { + CycleStatus.DilutionVat, + (() => CycleStatus.Melting, + 5, + (2 * 60, 1 * 60)) + }, + { + CycleStatus.Melting, + (() => CycleStatus.BringShrinkageCavity, + 60, + (40 * 60, 30 * 60)) + }, + { + CycleStatus.BringShrinkageCavity, + (() => CycleStatus.CoolingIngot, + 15, + (5 * 60, 3 * 60)) + }, + { + CycleStatus.CoolingIngot, + (() => CycleStatus.EndTechCycle, + 30, + (20 * 60, 10 * 60)) + }, + { + CycleStatus.VacForMeltingScarp, + (() => CycleStatus.MeltingScarp, + 10, + (11 * 60, 1 * 60)) + }, + { + CycleStatus.MeltingScarp, + (() => CycleStatus.CoolingMeltingScarp, + 20, + (4 * 60, 3 * 60)) + }, + { + CycleStatus.CoolingMeltingScarp, + (() => CycleStatus.LoadUnload, + 15, + (4 * 60, 3 * 60)) + }, + }; + + public static CycleStatus GetNextCycle(CycleStatus currCycle) + { + CycleStatus nextCycle = CycleStatus.EndTechCycle; + if (genDataMap.TryGetValue(currCycle, out var data)) + { + nextCycle = data.NextState(); + } + return nextCycle; + } + + public static int GetDuration(CycleStatus currCycle) + { + int duration = 15; + if (genDataMap.TryGetValue(currCycle, out var data)) + { + duration = data.Duration; + } + return duration; + } + + public static int GetDeviation(CycleStatus currCycle) + { + int deviation = random.Next(7 * 60) - (5 * 60); + if (genDataMap.TryGetValue(currCycle, out var data)) + { + deviation = random.Next(data.Item3.min) - data.Item3.offset; + } + return deviation; + } + } + + public enum CycleStatus : int + { + EndTechCycle = 0, + LoadUnload = 1, + VacForWelding = 2, + Welding = 5, + CoolingWelding = 6, + CheckWelding = 7, + VacForMelting = 8, + DilutionVat = 9, + Melting = 10, + BringShrinkageCavity = 11, + CoolingIngot = 12, + VacForMeltingScarp = 14, + MeltingScarp = 15, + CoolingMeltingScarp = 16 + } +} diff --git a/APICycleVDP/appsettings.Development.json b/APICycleVDP/appsettings.Development.json index 0c208ae..3cc8835 100644 --- a/APICycleVDP/appsettings.Development.json +++ b/APICycleVDP/appsettings.Development.json @@ -1,8 +1,21 @@ { + "Kestrel": { + "Endpoints": { + "UnixSocket": { + "Url": "http://127.0.0.1:5000" + } + } + }, + "ConnectionStrings": { + "MySql": "Server=khatuncev.ru;Port=64100;database=VDPCycles;user=ApiVdp;password=Fs*Zy@j0/PXPu5_t;" + }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } - } + }, + "AllowedHosts": "*", + "UseSwagger": true, + "useGenCycles": true } diff --git a/APICycleVDP/appsettings.json b/APICycleVDP/appsettings.json index 1f4780f..cf39575 100644 --- a/APICycleVDP/appsettings.json +++ b/APICycleVDP/appsettings.json @@ -6,11 +6,16 @@ } } }, + "ConnectionStrings": { + "MySql": "Server=/var/sock/mysqld.sock;database=VDPCycles;user=ApiVdp;password=Fs*Zy@j0/PXPu5_t;" + }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, - "AllowedHosts": "*" + "AllowedHosts": "*", + "UseSwagger": false, + "useGenCycles": true } diff --git a/DbCycleVDP/DbFurnace.cs b/DbCycleVDP/DbFurnace.cs deleted file mode 100644 index 8941433..0000000 --- a/DbCycleVDP/DbFurnace.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore; - -namespace DbCycleVDP -{ - public class DbFurnace : DbContext - { - public DbSet Cycles { get; set; } - public DbFurnace() - { - Database.EnsureCreated(); - } - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { -// optionsBuilder.UseMySql("server=127.0.0.1;user=diplom;password=diplom;database=VDPCycles;", new MySqlServerVersion(new Version(8, 0))); - optionsBuilder.UseMySql("server=37.79.216.218;user=mytest;password=mytest;database=VDPCycles;", new MySqlServerVersion(new Version(8, 0))); - } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - - } - } -} diff --git a/GenCycleVDP/GenCycle.cs b/GenCycleVDP/GenCycle.cs deleted file mode 100644 index d0486e6..0000000 --- a/GenCycleVDP/GenCycle.cs +++ /dev/null @@ -1,151 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using GenCycleVDP.Resources; -using DbCycleVDP; - -namespace GenCycleVDP -{ - internal class GenCycle(int vdp) - { - private readonly int vdp = vdp; - - private CycleStatus currCycle = CycleStatus.EndTechCycle; - private DateTime factStart = DateTime.Now; - private DateTime factEnd = DateTime.Now; - private DateTime thinkEnd = DateTime.Now; - - private bool cycle = false; - private Task taskCycle = Task.CompletedTask; - - public void Start() - { - cycle = true; - taskCycle = this.Cycle(); - } - public void Stop() - { - cycle = false; - taskCycle.Wait(); - } - - async public Task Cycle() - { - while (cycle) - { - if (GetCurrCycle()) //Can get info form DB. - { - if (DateTime.Now >= factEnd) - { - GetNextCycle(); - GetTimeStart(); - GetTimeThinkEnd(); - GetTimeFactEnd(); - while (!SaveToDB()) - { - Console.WriteLine("VDP " + vdp.ToString("D2") + ": Can't connect to DB."); - await Task.Delay(5000); - } - } - } - else //It's new Cycle. - { - GetTimeStart(); - GetTimeThinkEnd(); - GetTimeFactEnd(); - while (!SaveToDB()) - { - Console.WriteLine("VDP " + vdp.ToString("D2") + ": Can't connect to DB."); - await Task.Delay(5000); - } - } - - while (cycle && (DateTime.Now < factEnd)) - { - var secAwait = (factEnd - DateTime.Now).TotalSeconds; - if (secAwait >= 5) - { - await Task.Delay(5000); - } - else - { - await Task.Delay(Convert.ToInt32(Math.Ceiling(secAwait)) * 1000); - } - } - } - } - - public bool GetCurrCycle() - { - try - { - using var db = new DbFurnace(); - var tmp = (from u in db.Cycles - where - u.NumVdp == vdp - orderby u.FactStart descending - select u).FirstOrDefault(); - if (tmp == null) - { - currCycle = CycleStatus.EndTechCycle; - return false; - } - currCycle = Enum.IsDefined(typeof(CycleStatus), tmp.NumCycle) - ? (CycleStatus)tmp.NumCycle - : CycleStatus.EndTechCycle; - factStart = tmp.FactStart; - factEnd = tmp.FactEnd; - } - catch (Exception e) - { - Console.WriteLine(e.Message); - return false; - } - return true; - } - public void GetNextCycle() - { - currCycle = GenData.GetNextCycle(currCycle); - } - public void GetTimeStart() - { - factStart = factEnd; - } - public void GetTimeThinkEnd() - { - thinkEnd = factStart.AddMinutes(GenData.GetDuration(currCycle)); - } - public void GetTimeFactEnd() - { - factEnd = thinkEnd.AddSeconds(GenData.GetDeviation(currCycle)); - } - public bool SaveToDB() - { - try - { - using var db = new DbFurnace(); - var tmp = new TableCycle() - { - NumVdp = vdp, - NumCycle = (int)currCycle, - FactStart = factStart, - FactEnd = factEnd, - ThinkEnd = thinkEnd - }; - db.Cycles.Add(tmp); - db.SaveChanges(); - } - catch (Exception e) - { - Console.WriteLine(e.Message); - return false; - } - return true; - } - - public string GetStatus() - { - return vdp.ToString("D2") + "-" + currCycle.ToString(); - } - } -} diff --git a/GenCycleVDP/GenCycleVDP.csproj b/GenCycleVDP/GenCycleVDP.csproj deleted file mode 100644 index 4902e2e..0000000 --- a/GenCycleVDP/GenCycleVDP.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - Exe - net8.0 - disable - enable - - - - - - - - - - - - diff --git a/GenCycleVDP/Program.cs b/GenCycleVDP/Program.cs deleted file mode 100644 index 864eaa9..0000000 --- a/GenCycleVDP/Program.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace GenCycleVDP -{ - internal class Program - { - private static bool isExiting = false; - private static List tasks = []; - - static void Main(string[] args) - { - for (var i = 1; i <= 48; i++) - { - var a = new GenCycle(i); - a.Start(); - tasks.Add(a); - } - - int count = 0; - while (!isExiting) - { - if (count > 600) - { - for (var i = 0; i < tasks.Count; i++) - { - if (i % 10 == 0 && i != 0) - Console.WriteLine(); - Console.Write(tasks[i].GetStatus() + "|"); - } - Console.WriteLine(); - count = 0; - } - else - { - count++; - } - Task.Delay(1000).Wait(); - } - foreach(var furance in tasks) - { - furance.Stop(); - } - } - - private static void OnExit(object sender, ConsoleCancelEventArgs e) - { - isExiting = true; - e.Cancel = true; - } - } -} diff --git a/GenCycleVDP/Resources/CycleStatus.cs b/GenCycleVDP/Resources/CycleStatus.cs deleted file mode 100644 index aea3eaa..0000000 --- a/GenCycleVDP/Resources/CycleStatus.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace GenCycleVDP.Resources -{ - public enum CycleStatus : int - { - EndTechCycle = 0, - LoadUnload = 1, - VacForWelding = 2, - Welding = 5, - CoolingWelding = 6, - CheckWelding = 7, - VacForMelting = 8, - DilutionVat = 9, - Melting = 10, - BringShrinkageCavity = 11, - CoolingIngot = 12, - VacForMeltingScarp = 14, - MeltingScarp = 15, - CoolingMeltingScarp = 16 - } -} diff --git a/GenCycleVDP/Resources/GenData.cs b/GenCycleVDP/Resources/GenData.cs deleted file mode 100644 index b7c047f..0000000 --- a/GenCycleVDP/Resources/GenData.cs +++ /dev/null @@ -1,131 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace GenCycleVDP.Resources -{ - internal static class GenData - { - private static readonly Random random = new(); - private static readonly Dictionary NextState, int Duration, (int min, int offset))> genDataMap = new() - { - { - CycleStatus.EndTechCycle, - (() => random.Next(100) < 50 - ? CycleStatus.VacForMeltingScarp - : CycleStatus.VacForWelding, - 15, - (7 * 60, 5 * 60)) - }, - { - CycleStatus.LoadUnload, - (() => CycleStatus.VacForWelding, - 15, - (3 * 60, 2 * 60)) - }, - { - CycleStatus.VacForWelding, - (() => CycleStatus.Welding, - 10, - (11 * 60, 1 * 60)) - }, - { - CycleStatus.Welding, - (() => CycleStatus.CoolingWelding, - 13, - (4 * 60, 3 * 60)) - }, - { - CycleStatus.CoolingWelding, - (() => CycleStatus.CheckWelding, - 7, - (4 * 60, 3 * 60)) - }, - { - CycleStatus.CheckWelding, - (() => random.Next(100) < 20 - ? CycleStatus.Welding - : CycleStatus.VacForMelting, - 5, - (7 * 60, 2 * 60)) - }, - { - CycleStatus.VacForMelting, - (() => CycleStatus.DilutionVat, - 10, - (11 * 60, 1 * 60)) - }, - { - CycleStatus.DilutionVat, - (() => CycleStatus.Melting, - 5, - (2 * 60, 1 * 60)) - }, - { - CycleStatus.Melting, - (() => CycleStatus.BringShrinkageCavity, - 60, - (40 * 60, 30 * 60)) - }, - { - CycleStatus.BringShrinkageCavity, - (() => CycleStatus.CoolingIngot, - 15, - (5 * 60, 3 * 60)) - }, - { - CycleStatus.CoolingIngot, - (() => CycleStatus.EndTechCycle, - 30, - (20 * 60, 10 * 60)) - }, - { - CycleStatus.VacForMeltingScarp, - (() => CycleStatus.MeltingScarp, - 10, - (11 * 60, 1 * 60)) - }, - { - CycleStatus.MeltingScarp, - (() => CycleStatus.CoolingMeltingScarp, - 20, - (4 * 60, 3 * 60)) - }, - { - CycleStatus.CoolingMeltingScarp, - (() => CycleStatus.LoadUnload, - 15, - (4 * 60, 3 * 60)) - }, - }; - - public static CycleStatus GetNextCycle(CycleStatus currCycle) - { - CycleStatus nextCycle = CycleStatus.EndTechCycle; - if(genDataMap.TryGetValue(currCycle, out var data)) - { - nextCycle = data.NextState(); - } - return nextCycle; - } - - public static int GetDuration(CycleStatus currCycle) - { - int duration = 15; - if (genDataMap.TryGetValue(currCycle, out var data)) - { - duration = data.Duration; - } - return duration; - } - - public static int GetDeviation(CycleStatus currCycle) - { - int deviation = random.Next(7 * 60) - (5 * 60); - if (genDataMap.TryGetValue(currCycle, out var data)) - { - deviation = random.Next(data.Item3.min) - data.Item3.offset; - } - return deviation; - } - } -}