Sicherung
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace FSI.BT.IR.Plc.Settings.Log.Data
|
||||
{
|
||||
public class ApplicationDbContext : DbContext
|
||||
{
|
||||
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
|
||||
: base(options)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public DbSet<Models.Plc> Plcs { get; set; }
|
||||
|
||||
public DbSet<Models.Parameter> Parameters { get; set; }
|
||||
|
||||
public DbSet<Models.Logging> Logging { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Worker">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UserSecretsId>dotnet-FSI.BT.IR.Plc.Settings.Log-e9497254-26a2-42a8-a589-93cc70d1a108</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.10" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.10">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
|
||||
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.14" />
|
||||
<PackageReference Include="Sharp7" Version="1.1.84" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Data\Migrations\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Update="config.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
151
worker/FSI.BT.IR.Plc.Settings.Log/Migrations/20241017110209_InitialCreate.Designer.cs
generated
Normal file
151
worker/FSI.BT.IR.Plc.Settings.Log/Migrations/20241017110209_InitialCreate.Designer.cs
generated
Normal file
@@ -0,0 +1,151 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using FSI.BT.IR.Plc.Settings.Log.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace FSI.BT.IR.Plc.Settings.Log.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
[Migration("20241017110209_InitialCreate")]
|
||||
partial class InitialCreate
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.10");
|
||||
|
||||
modelBuilder.Entity("FSI.BT.IR.Plc.Settings.Log.Models.Logging", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ParameterId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("Timestamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ParameterId");
|
||||
|
||||
b.ToTable("Logging");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("FSI.BT.IR.Plc.Settings.Log.Models.Parameter", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("Created")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("DataType")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("DbNo")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("DbSize")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("DbStart")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("DefaultValue")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("PlcId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("Updated")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("PlcId");
|
||||
|
||||
b.ToTable("Parameters");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("FSI.BT.IR.Plc.Settings.Log.Models.Plc", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("Created")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("IpAdress")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Rack")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Slot")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("Updated")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Plcs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("FSI.BT.IR.Plc.Settings.Log.Models.Logging", b =>
|
||||
{
|
||||
b.HasOne("FSI.BT.IR.Plc.Settings.Log.Models.Parameter", "Parameter")
|
||||
.WithMany()
|
||||
.HasForeignKey("ParameterId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Parameter");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("FSI.BT.IR.Plc.Settings.Log.Models.Parameter", b =>
|
||||
{
|
||||
b.HasOne("FSI.BT.IR.Plc.Settings.Log.Models.Plc", "Plc")
|
||||
.WithMany()
|
||||
.HasForeignKey("PlcId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Plc");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace FSI.BT.IR.Plc.Settings.Log.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class InitialCreate : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Plcs",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Name = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Description = table.Column<string>(type: "TEXT", nullable: false),
|
||||
IpAdress = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Rack = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Slot = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Created = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||
Updated = table.Column<DateTime>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Plcs", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Parameters",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Name = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Description = table.Column<string>(type: "TEXT", nullable: false),
|
||||
PlcId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
DbNo = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
DbStart = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
DbSize = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
DataType = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
DefaultValue = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Created = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||
Updated = table.Column<DateTime>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Parameters", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Parameters_Plcs_PlcId",
|
||||
column: x => x.PlcId,
|
||||
principalTable: "Plcs",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Logging",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
ParameterId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Value = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Timestamp = table.Column<DateTime>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Logging", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Logging_Parameters_ParameterId",
|
||||
column: x => x.ParameterId,
|
||||
principalTable: "Parameters",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Logging_ParameterId",
|
||||
table: "Logging",
|
||||
column: "ParameterId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Parameters_PlcId",
|
||||
table: "Parameters",
|
||||
column: "PlcId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Logging");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Parameters");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Plcs");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using FSI.BT.IR.Plc.Settings.Log.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace FSI.BT.IR.Plc.Settings.Log.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
partial class ApplicationDbContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.10");
|
||||
|
||||
modelBuilder.Entity("FSI.BT.IR.Plc.Settings.Log.Models.Logging", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ParameterId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("Timestamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ParameterId");
|
||||
|
||||
b.ToTable("Logging");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("FSI.BT.IR.Plc.Settings.Log.Models.Parameter", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("Created")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("DataType")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("DbNo")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("DbSize")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("DbStart")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("DefaultValue")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("PlcId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("Updated")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("PlcId");
|
||||
|
||||
b.ToTable("Parameters");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("FSI.BT.IR.Plc.Settings.Log.Models.Plc", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("Created")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("IpAdress")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Rack")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Slot")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("Updated")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Plcs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("FSI.BT.IR.Plc.Settings.Log.Models.Logging", b =>
|
||||
{
|
||||
b.HasOne("FSI.BT.IR.Plc.Settings.Log.Models.Parameter", "Parameter")
|
||||
.WithMany()
|
||||
.HasForeignKey("ParameterId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Parameter");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("FSI.BT.IR.Plc.Settings.Log.Models.Parameter", b =>
|
||||
{
|
||||
b.HasOne("FSI.BT.IR.Plc.Settings.Log.Models.Plc", "Plc")
|
||||
.WithMany()
|
||||
.HasForeignKey("PlcId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Plc");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
19
worker/FSI.BT.IR.Plc.Settings.Log/Models/DataType.cs
Normal file
19
worker/FSI.BT.IR.Plc.Settings.Log/Models/DataType.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FSI.BT.IR.Plc.Settings.Log.Models
|
||||
{
|
||||
public enum DataType
|
||||
{
|
||||
[Display(Name = "INT")]
|
||||
Int = 1,
|
||||
[Display(Name = "DINT")]
|
||||
DInt,
|
||||
[Display(Name = "REAL")]
|
||||
Real,
|
||||
}
|
||||
}
|
||||
25
worker/FSI.BT.IR.Plc.Settings.Log/Models/Logging.cs
Normal file
25
worker/FSI.BT.IR.Plc.Settings.Log/Models/Logging.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FSI.BT.IR.Plc.Settings.Log.Models
|
||||
{
|
||||
public class Logging
|
||||
{
|
||||
[Key]
|
||||
public int Id { get; set; }
|
||||
|
||||
public Parameter Parameter { get; set; }
|
||||
|
||||
[ForeignKey(nameof(Parameter.Id))]
|
||||
public int ParameterId { get; set; }
|
||||
|
||||
public string Value { get; set; }
|
||||
|
||||
public DateTime Timestamp { get; set; } = DateTime.Now;
|
||||
}
|
||||
}
|
||||
37
worker/FSI.BT.IR.Plc.Settings.Log/Models/Parameter.cs
Normal file
37
worker/FSI.BT.IR.Plc.Settings.Log/Models/Parameter.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FSI.BT.IR.Plc.Settings.Log.Models
|
||||
{
|
||||
public class Parameter
|
||||
{
|
||||
[Key]
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Description { get; set; }
|
||||
|
||||
public Plc Plc { get; set; }
|
||||
|
||||
[ForeignKey(nameof(Plc.Id))]
|
||||
public int PlcId { get; set; }
|
||||
|
||||
public int DbNo { get; set; }
|
||||
|
||||
public int DbStart { get; set; }
|
||||
|
||||
public int DbSize { get; set; }
|
||||
|
||||
public DataType DataType { get; set; }
|
||||
|
||||
public string DefaultValue { get; set; }
|
||||
|
||||
public DateTime Created { get; set; } = DateTime.Now;
|
||||
|
||||
public DateTime Updated { get; set; } = DateTime.Now;
|
||||
}
|
||||
}
|
||||
28
worker/FSI.BT.IR.Plc.Settings.Log/Models/Plc.cs
Normal file
28
worker/FSI.BT.IR.Plc.Settings.Log/Models/Plc.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FSI.BT.IR.Plc.Settings.Log.Models
|
||||
{
|
||||
public class Plc
|
||||
{
|
||||
[Key]
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Description { get; set; }
|
||||
|
||||
public string IpAdress { get; set; }
|
||||
|
||||
public int Rack { get; set; }
|
||||
|
||||
public int Slot { get; set; }
|
||||
|
||||
public DateTime Created { get; set; } = DateTime.Now;
|
||||
|
||||
public DateTime Updated { get; set; } = DateTime.Now;
|
||||
}
|
||||
}
|
||||
18
worker/FSI.BT.IR.Plc.Settings.Log/Program.cs
Normal file
18
worker/FSI.BT.IR.Plc.Settings.Log/Program.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using FSI.BT.IR.Plc.Settings.Log;
|
||||
using FSI.BT.IR.Plc.Settings.Log.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using static FSI.BT.IR.Plc.Settings.Log.Settings.Context;
|
||||
|
||||
var builder = Host.CreateApplicationBuilder(args);
|
||||
|
||||
builder.Services.AddHostedService<Worker>();
|
||||
builder.Services.AddSingleton<ISettings, FSI.BT.IR.Plc.Settings.Log.Settings.AppContext>();
|
||||
|
||||
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
|
||||
builder.Services.AddDbContext<ApplicationDbContext>(options =>
|
||||
options.UseSqlite(connectionString));
|
||||
|
||||
|
||||
|
||||
var host = builder.Build();
|
||||
host.Run();
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"profiles": {
|
||||
"FSI.BT.IR.Plc.Settings.Log": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"environmentVariables": {
|
||||
"DOTNET_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
68
worker/FSI.BT.IR.Plc.Settings.Log/Settings/AppContext.cs
Normal file
68
worker/FSI.BT.IR.Plc.Settings.Log/Settings/AppContext.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using static FSI.BT.IR.Plc.Settings.Log.Settings.Context;
|
||||
|
||||
namespace FSI.BT.IR.Plc.Settings.Log.Settings
|
||||
{
|
||||
|
||||
public class AppContext : ISettings
|
||||
{
|
||||
private Cfg _cfg;
|
||||
|
||||
public AppContext()
|
||||
{
|
||||
LoadSettings();
|
||||
LoadCfg();
|
||||
}
|
||||
|
||||
private void LoadSettings()
|
||||
{
|
||||
var values = new ConfigurationBuilder()
|
||||
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||
.Build();
|
||||
|
||||
Settings = values.Get<Context.Settings>();
|
||||
}
|
||||
|
||||
private void LoadCfg()
|
||||
{
|
||||
var values = new ConfigurationBuilder()
|
||||
.AddJsonFile("config.json", optional: true, reloadOnChange: true)
|
||||
.Build();
|
||||
|
||||
Cfg = values.Get<Context.Cfg>();
|
||||
|
||||
Action onChange = () =>
|
||||
{
|
||||
Cfg = values.Get<Context.Cfg>();
|
||||
};
|
||||
|
||||
ChangeToken.OnChange(() => values.GetReloadToken(), onChange);
|
||||
}
|
||||
|
||||
public Context.Settings Settings { get; set; }
|
||||
|
||||
public Cfg Cfg
|
||||
{
|
||||
get { return _cfg; }
|
||||
set
|
||||
{
|
||||
_cfg = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void RaisePropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
// Null means no subscribers to the event
|
||||
var handler = PropertyChanged;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
}
|
||||
}
|
||||
139
worker/FSI.BT.IR.Plc.Settings.Log/Settings/Context.cs
Normal file
139
worker/FSI.BT.IR.Plc.Settings.Log/Settings/Context.cs
Normal file
@@ -0,0 +1,139 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FSI.BT.IR.Plc.Settings.Log.Settings
|
||||
{
|
||||
public class Context
|
||||
{
|
||||
public interface ISettings : INotifyPropertyChanged
|
||||
{
|
||||
/// <summary>
|
||||
/// Daten von appsettings.json
|
||||
/// </summary>
|
||||
public Settings Settings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Daten von config.json
|
||||
/// </summary>
|
||||
public Cfg Cfg { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Daten von appsettings.json
|
||||
/// </summary>
|
||||
public record Settings
|
||||
{
|
||||
/// <summary>
|
||||
/// Versions-Informationen
|
||||
/// </summary>
|
||||
public Version Version { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Build-Informationen
|
||||
/// </summary>
|
||||
public Build Build { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Logging-Einstellungen
|
||||
/// </summary>
|
||||
public Logging Logging { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Versions-Informationen
|
||||
/// </summary>
|
||||
public record Version
|
||||
{
|
||||
/// <summary>
|
||||
/// Haupt-Versionsnummer
|
||||
/// </summary>
|
||||
public uint Major { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Unter-Versionsnummer
|
||||
/// </summary>
|
||||
public uint Minor { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Patch/Hotfix
|
||||
/// </summary>
|
||||
public uint Patch { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// optinoale Versionsinformationen
|
||||
/// </summary>
|
||||
public string? Optional { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// gibt die Versions-Nummer zurück
|
||||
/// </summary>
|
||||
/// <returns>Versionsnummer</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return Major.ToString() + "." + Minor.ToString() + "." + Patch.ToString() + ((Optional == string.Empty || Optional == null) ? "" : "-" + Optional);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build-Informationen
|
||||
/// </summary>
|
||||
public record Build
|
||||
{
|
||||
/// <summary>
|
||||
/// Ersteller
|
||||
/// </summary>
|
||||
public string Creator { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Organisation
|
||||
/// </summary>
|
||||
public string Organization { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Erstellungsjahr
|
||||
/// </summary>
|
||||
public int CreationYear { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Beschreibung
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
}
|
||||
|
||||
public class Logging
|
||||
{
|
||||
public Loglevel LogLevel { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logging-Einstellungen
|
||||
/// </summary>
|
||||
public class Loglevel
|
||||
{
|
||||
public string Default { get; set; }
|
||||
|
||||
[ConfigurationKeyName("Microsoft.Hosting.Lifetime")]
|
||||
public string MicrosoftHostingLifetime { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Daten von config.json
|
||||
/// </summary>
|
||||
public record Cfg
|
||||
{
|
||||
/// <summary>
|
||||
/// Update Intevall in ms
|
||||
/// </summary>
|
||||
public int UpdateIntervall { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Clean intevall in days
|
||||
/// </summary>
|
||||
public int CleanIntevall { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
184
worker/FSI.BT.IR.Plc.Settings.Log/Worker.cs
Normal file
184
worker/FSI.BT.IR.Plc.Settings.Log/Worker.cs
Normal file
@@ -0,0 +1,184 @@
|
||||
using FSI.BT.IR.Plc.Settings.Log.Data;
|
||||
using FSI.BT.IR.Plc.Settings.Log.Models;
|
||||
using FSI.BT.IR.Plc.Settings.Log.Settings;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||
using NLog;
|
||||
using Sharp7;
|
||||
using System.Data.Common;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Security.AccessControl;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading;
|
||||
using System.Xml.Linq;
|
||||
using static FSI.BT.IR.Plc.Settings.Log.Settings.Context;
|
||||
|
||||
namespace FSI.BT.IR.Plc.Settings.Log
|
||||
{
|
||||
public class Worker : BackgroundService
|
||||
{
|
||||
private Logger _log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private ISettings _settings;
|
||||
private IServiceProvider _serviceProvider;
|
||||
private ApplicationDbContext _context;
|
||||
|
||||
public Worker(ISettings settings, IServiceProvider serviceProvider)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Standard Taks
|
||||
/// </summary>
|
||||
/// <param name="stoppingToken"></param>
|
||||
/// <returns></returns>
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
_context = scope.ServiceProvider.GetService<ApplicationDbContext>();
|
||||
|
||||
DateTime oldDate = DateTime.Now;
|
||||
|
||||
var plc = new S7Client(); // SPS-Verbindung
|
||||
List<Models.Parameter> parameters;
|
||||
List<Models.Logging> loggs;
|
||||
byte[] buffer;
|
||||
string value = string.Empty;
|
||||
Models.Logging logFirstEntry;
|
||||
|
||||
parameters = _context.Parameters.Include(x => x.Plc).ToList(); // Parameter auslesen
|
||||
loggs = _context.Logging.Include(x => x.Parameter).OrderByDescending(x => x.Timestamp).ToList(); // Logging auslesen
|
||||
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
if (oldDate.Date != DateTime.Now)
|
||||
{
|
||||
_log.Debug("Neuer Tag.");
|
||||
CleanLoggTable();
|
||||
}
|
||||
|
||||
parameters = _context.Parameters.ToList();
|
||||
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
value = string.Empty;
|
||||
logFirstEntry = new();
|
||||
buffer = new byte[parameter.DbSize];
|
||||
|
||||
try
|
||||
{
|
||||
// Verbindung mit SPS-Aufbauen
|
||||
var connectionRslt = plc.ConnectTo(parameter.Plc.IpAdress, parameter.Plc.Rack, parameter.Plc.Slot);
|
||||
|
||||
// Verbindungsstatus <20>berpr<70>fen
|
||||
if (connectionRslt == 0) // Verbindung i.O.
|
||||
{
|
||||
_log.Debug(parameter.Plc.Name + " Verbindung hergestellt.");
|
||||
}
|
||||
else // Verbindung n.i.O.
|
||||
{
|
||||
_log.Error(parameter.Plc.Name + " Verbindung nicht hergestellt.");
|
||||
_log.Error(parameter.Plc.Name + " Fehler: " + plc.ErrorText(connectionRslt));
|
||||
// await Task.Delay(UpdateIntervall, cancellationToken); // Warten bis zum n<>chsten Verbindungsversuch (Zeiten aus config.json)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_log.Error(parameter.Plc.Name + " " + ex.Message);
|
||||
}
|
||||
|
||||
plc.DBRead(parameter.DbNo, parameter.DbStart, parameter.DbSize, buffer); // Wert aus SPS auslesen
|
||||
|
||||
plc.Disconnect(); // Verbindung zur SPS trennen
|
||||
_log.Debug(parameter.Plc.Name + " Verbindung getrennt.");
|
||||
|
||||
value = GetStringOfValue(buffer, parameter); // Value in Sting, in Abh<62>nigkeit des Datentyps, wandeln
|
||||
_log.Debug(parameter.Name + ": Wert " + value + " wurde ausgelesen" +
|
||||
"");
|
||||
logFirstEntry = loggs.Where(x => x.ParameterId == parameter.Id).FirstOrDefault();
|
||||
|
||||
|
||||
if (logFirstEntry == null || !value.Equals(logFirstEntry.Value))
|
||||
{
|
||||
Models.Logging logging = new Models.Logging();
|
||||
logging.Value = value;
|
||||
logging.Parameter = parameter;
|
||||
|
||||
_context.Logging.Add(logging);
|
||||
_context.SaveChanges();
|
||||
|
||||
loggs = _context.Logging.OrderByDescending(x => x.Timestamp).ToList();
|
||||
}
|
||||
|
||||
_log.Debug(parameter.Plc.Name + " Start Task-Wartezeit");
|
||||
try
|
||||
{
|
||||
await Task.Delay(_settings.Cfg.UpdateIntervall, stoppingToken); // Warten bis zum n<>chsten Verbindungsversuch (Zeiten aus config.json)
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_log.Error(parameter.Plc.Name + " " + ex.Message);
|
||||
}
|
||||
_log.Debug(parameter.Plc.Name + " Ende Task-Wartezeit");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CleanLoggTable()
|
||||
{
|
||||
List<Models.Parameter> parameters = _context.Parameters.ToList();
|
||||
List<Models.Logging> loggs;
|
||||
int span;
|
||||
int cntDel = 0;
|
||||
|
||||
_log.Debug("Datenbereinigung gestartet");
|
||||
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
loggs = _context.Logging.Where(x => x.ParameterId == parameter.Id).OrderByDescending(x => x.Timestamp).ToList();
|
||||
|
||||
if (loggs != null && loggs.Count > 1)
|
||||
{
|
||||
for (int i = 1; i < loggs.Count; i++)
|
||||
{
|
||||
span = Math.Abs(loggs[i].Timestamp.Subtract(DateTime.Now).Days);
|
||||
if (span > _settings.Cfg.CleanIntevall)
|
||||
{
|
||||
_context.Logging.Remove(loggs[i]);
|
||||
cntDel++;
|
||||
_log.Debug("Logg mit der ID: " + loggs[i].Id + " wird gel<65>scht.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_context.SaveChanges();
|
||||
_log.Info("Datenbereinigung beendet - es wurden " + cntDel.ToString() +" Datens<6E>tze gel<65>scht");
|
||||
}
|
||||
|
||||
private string GetStringOfValue(byte[] buffer, Models.Parameter parameter)
|
||||
{
|
||||
// Wert nach Datentyp konvertieren
|
||||
switch (parameter.DataType)
|
||||
{
|
||||
case DataType.Int: // Integer
|
||||
return S7.GetIntAt(buffer, 0).ToString();
|
||||
|
||||
case DataType.DInt: // double Integer
|
||||
return S7.GetDIntAt(buffer, 0).ToString();
|
||||
|
||||
case DataType.Real: // Real
|
||||
return S7.GetRealAt(buffer, 0).ToString();
|
||||
|
||||
default:
|
||||
return string.Empty;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
}
|
||||
}
|
||||
23
worker/FSI.BT.IR.Plc.Settings.Log/appsettings.json
Normal file
23
worker/FSI.BT.IR.Plc.Settings.Log/appsettings.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"ConnectionStrings": {
|
||||
"DefaultConnection": "Data Source=d:\\WebApplication.db"
|
||||
},
|
||||
"Version": {
|
||||
"Major": 0,
|
||||
"Minor": 0,
|
||||
"Patch": 0,
|
||||
"Optional": "alpha"
|
||||
},
|
||||
"Build": {
|
||||
"Creator": "Stephan Maier",
|
||||
"Organization": "Fondium Singen GmbH",
|
||||
"CreationYear": "2024",
|
||||
"Description": ""
|
||||
},
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
}
|
||||
}
|
||||
5
worker/FSI.BT.IR.Plc.Settings.Log/config.json
Normal file
5
worker/FSI.BT.IR.Plc.Settings.Log/config.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"UpdateIntervall": "1000",
|
||||
"CleanIntervall" : "2"
|
||||
|
||||
}
|
||||
36
worker/FSI.BT.IR.Plc.Settings.Log/nlog.config
Normal file
36
worker/FSI.BT.IR.Plc.Settings.Log/nlog.config
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
autoReload="true"
|
||||
throwExceptions="false">
|
||||
|
||||
<variable name="appName" value="FSI.BT.IR.Plc.Settings.Log" />
|
||||
|
||||
<!-- the targets to write to -->
|
||||
<targets>
|
||||
<!-- write logs to file -->
|
||||
<target xsi:type="File"
|
||||
name="logfile"
|
||||
fileName="d:/logs/${appName}/${appName}.log"
|
||||
archiveFileName ="d:/logs/${appName}/{#}_${appName}.log"
|
||||
archiveNumbering ="Date" archiveEvery="Day"
|
||||
archiveDateFormat="yyyyMMdd"/>
|
||||
|
||||
<target name="viewer"
|
||||
xsi:type="NLogViewer"
|
||||
includeSourceInfo="true"
|
||||
address="udp://FDESINB0166:9999"/>
|
||||
|
||||
</targets>
|
||||
|
||||
<!-- rules to map from logger name to target -->
|
||||
<rules>
|
||||
<logger name="*"
|
||||
minlevel="Trace"
|
||||
writeTo="logfile,logconsole,console" />
|
||||
|
||||
<logger name="*"
|
||||
minlevel="Debug"
|
||||
writeTo="viewer" />
|
||||
</rules>
|
||||
</nlog>
|
||||
Reference in New Issue
Block a user