Compare commits
53 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5d9f0e59df | |||
| 4bfe039623 | |||
| 195f187ba8 | |||
| 3cebac853b | |||
| 42f01f14af | |||
| 4e882ea3cb | |||
| 3afe990365 | |||
| 2ffa502538 | |||
| 7e941aec34 | |||
| e7c73cbce1 | |||
| 6a8ad2604f | |||
| a87fee41f5 | |||
| 67c8e883fe | |||
| 37ee6f5997 | |||
| 4f0e2d9aa5 | |||
| ccd3ed8c45 | |||
| cbf72f2558 | |||
| d41722f200 | |||
| be7515b16c | |||
| 89fd608eef | |||
| cf310ab003 | |||
| 5177f412de | |||
| ccbb6fa644 | |||
| dd3491af16 | |||
| 1403daffd6 | |||
| 1a9f6c810b | |||
| a4841dd8bc | |||
| 76d25bc727 | |||
| 1472c178b1 | |||
| 731d8c6400 | |||
| 998afbbd7e | |||
| d2c0761f7b | |||
| f2b24aa3ea | |||
| 7023ef1609 | |||
| 19cfeff468 | |||
| aa0f847aa3 | |||
| 0f32dc64bd | |||
| 699e07e61f | |||
| 9edb343d40 | |||
| 3a6dc1b08e | |||
| 913d148545 | |||
| 4ff531e435 | |||
| 8eed5081c9 | |||
| 5b40dd70f1 | |||
| f2f733e6ee | |||
| 7173e6e90a | |||
| afda7d6221 | |||
| 5587e9efca | |||
| 83634c7788 | |||
| e3c7cb356c | |||
| dfb2dd4c5c | |||
| 8e2a9634d1 | |||
| 06cd6ffa05 |
+120
-63
@@ -7,12 +7,65 @@ variables:
|
||||
- |
|
||||
$hasSource = C:\Tools\nuget.exe sources list | find "`"Steamware Nexus`"" /C
|
||||
if ($hasSource -eq 0) {
|
||||
C:\Tools\nuget.exe sources Add -Name "`"Steamware Nexus`"" -Source http://nexus.steamware.net/repository/nuget-group -username "`"nugetUser`"" -password "`"viaDante16`""
|
||||
C:\Tools\nuget.exe sources Add -Name "`"Steamware Nexus`"" -Source https://nexus.steamware.net/repository/nuget-group -username "`"nugetUser`"" -password "`"viaDante16`"" -StorePasswordInClearText
|
||||
} else {
|
||||
C:\Tools\nuget.exe sources Update -Name "`"Steamware Nexus`"" -Source http://nexus.steamware.net/repository/nuget-group -username "`"nugetUser`"" -password "`"viaDante16`""
|
||||
C:\Tools\nuget.exe sources Update -Name "`"Steamware Nexus`"" -Source https://nexus.steamware.net/repository/nuget-group -username "`"nugetUser`"" -password "`"viaDante16`"" -StorePasswordInClearText
|
||||
}
|
||||
echo $hasSource
|
||||
|
||||
# helper creazione hash files x IIS
|
||||
.hashBuild: &hashBuild
|
||||
- |
|
||||
$Target = "$env:APP_NAME\Releases\" + $CI_COMMIT_BRANCH + "\" + $env:APP_NAME + ".zip"
|
||||
$MD5 = Get-FileHash $Target -Algorithm MD5
|
||||
$SHA1 = Get-FileHash $Target -Algorithm SHA1
|
||||
New-Item $Target".md5"
|
||||
New-Item $Target".sha1"
|
||||
$MD5.Hash | Set-Content -Path $Target".md5"
|
||||
$SHA1.Hash | Set-Content -Path $Target".sha1"
|
||||
|
||||
echo "Created HASH files for $Target"
|
||||
|
||||
# helper x send su NEXUS x pack
|
||||
.nexusUpload: &nexusUpload
|
||||
- |
|
||||
Set-Alias mCurl C:\Windows\system32\curl.exe
|
||||
$currentDate = get-date -format yyMM;
|
||||
$currentTime = get-date -format ddHH;
|
||||
$fileVers = $env:APP_NAME + "\Resources\VersNum.txt"
|
||||
$VersNumb = Get-Content $fileVers
|
||||
echo "Curr Version: $VersNumb"
|
||||
if($CI_COMMIT_BRANCH -eq "main")
|
||||
{
|
||||
$version = "stable"
|
||||
}
|
||||
else
|
||||
{
|
||||
$version = "unstable"
|
||||
}
|
||||
$File2Send = Get-ChildItem("$env:APP_NAME\Releases\" + $CI_COMMIT_BRANCH + "\*")
|
||||
ForEach ($File in $File2Send) {
|
||||
$FileName = Split-Path $File -leaf
|
||||
mCurl -v -u GitLab:$NEXUS_PASSWD --upload-file $File https://nexus.steamware.net/repository/SWS/$env:NEXUS_PATH/$version/LAST/$FileName
|
||||
mCurl -v -u GitLab:$NEXUS_PASSWD --upload-file $File https://nexus.steamware.net/repository/SWS/$env:NEXUS_PATH/$version/ARCHIVE/$VersNumb/$FileName
|
||||
echo "mCurl -v -u GitLab:$NEXUS_PASSWD --upload-file $File https://nexus.steamware.net/repository/SWS/$env:NEXUS_PATH/$version/LAST/$FileName"
|
||||
}
|
||||
mCurl -v -u GitLab:$NEXUS_PASSWD --upload-file "$env:APP_NAME\Resources\manifest.xml" https://nexus.steamware.net/repository/SWS/$env:NEXUS_PATH/$version/LAST/manifest.xml
|
||||
mCurl -v -u GitLab:$NEXUS_PASSWD --upload-file "$env:APP_NAME\Resources\ChangeLog.html" https://nexus.steamware.net/repository/SWS/$env:NEXUS_PATH/$version/LAST/ChangeLog.html
|
||||
|
||||
# helper creazione files zip
|
||||
.zipper: &zipper
|
||||
- |
|
||||
$7zipPath = $env:ProgramFiles+"\7-Zip\7z.exe"
|
||||
if (-not (Test-Path -Path $7zipPath -PathType Leaf)) {
|
||||
throw "7 zip file '$7zipPath' not found"
|
||||
}
|
||||
Set-Alias 7zip $7zipPath
|
||||
$Target = "$env:APP_NAME\Releases\" + $CI_COMMIT_BRANCH + "\" + $env:APP_NAME + ".zip"
|
||||
$Source = "$env:APP_NAME\bin\publish\net6.0\*"
|
||||
7zip a -tzip $Target $Source -xr!DATA
|
||||
echo "called ZIP $Source --> $Target"
|
||||
|
||||
stages:
|
||||
- build
|
||||
- staging
|
||||
@@ -37,55 +90,73 @@ SIM:build:
|
||||
before_script:
|
||||
- *nuget-fix
|
||||
- dotnet restore MP.MONO.ALL.sln
|
||||
script:
|
||||
script:
|
||||
- dotnet build MP.MONO.SIM/MP.MONO.SIM.csproj
|
||||
|
||||
DECODER:build:
|
||||
stage: build
|
||||
tags:
|
||||
- win
|
||||
before_script:
|
||||
- *nuget-fix
|
||||
- dotnet restore MP.MONO.ALL.sln
|
||||
script:
|
||||
- dotnet build MP.MONO.DECODER/MP.MONO.DECODER.csproj
|
||||
|
||||
# UI:staging:
|
||||
# stage: staging
|
||||
# tags:
|
||||
# - win
|
||||
# only:
|
||||
# - develop
|
||||
# needs: ["UI:build"]
|
||||
# script:
|
||||
# - dotnet publish -p:PublishProfile=IIS01.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true MP.MONO.UI/MP.MONO.UI.csproj
|
||||
UI:staging:
|
||||
stage: staging
|
||||
tags:
|
||||
- win
|
||||
only:
|
||||
- develop
|
||||
needs: ["UI:build"]
|
||||
script:
|
||||
- dotnet publish -p:PublishProfile=IIS01.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true MP.MONO.UI/MP.MONO.UI.csproj
|
||||
|
||||
# SIM:staging:
|
||||
# stage: staging
|
||||
# tags:
|
||||
# - win
|
||||
# only:
|
||||
# - develop
|
||||
# needs: ["SIM:build"]
|
||||
# script:
|
||||
# - dotnet publish -p:PublishProfile=IIS01.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true MP.MONO.SIM/MP.MONO.SIM.csproj
|
||||
|
||||
|
||||
# UI:deploy:
|
||||
# stage: deploy
|
||||
# tags:
|
||||
# - win
|
||||
# only:
|
||||
# - main
|
||||
# needs: ["UI:build"]
|
||||
# script:
|
||||
# # IIS 02
|
||||
# - dotnet publish -p:PublishProfile=IIS02.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true MP.MONO.UI/MP.MONO.UI.csproj
|
||||
# # IIS DEV
|
||||
# - dotnet publish -p:PublishProfile=IIS03.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true MP.MONO.UI/MP.MONO.UI.csproj
|
||||
|
||||
# SIM:deploy:
|
||||
# stage: deploy
|
||||
# tags:
|
||||
# - win
|
||||
# only:
|
||||
# - main
|
||||
# needs: ["SIM:build"]
|
||||
# script:
|
||||
# # IIS 02
|
||||
# - dotnet publish -p:PublishProfile=IIS02.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true MP.MONO.SIM/MP.MONO.SIM.csproj
|
||||
# # IIS DEV
|
||||
# - dotnet publish -p:PublishProfile=IIS03.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true MP.MONO.SIM/MP.MONO.SIM.csproj
|
||||
UI:deploy:
|
||||
stage: deploy
|
||||
tags:
|
||||
- win
|
||||
only:
|
||||
- main
|
||||
needs: ["UI:build"]
|
||||
script:
|
||||
# IIS 02
|
||||
- dotnet publish -p:PublishProfile=IIS02.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true MP.MONO.UI/MP.MONO.UI.csproj
|
||||
# IIS DEV
|
||||
- dotnet publish -p:PublishProfile=IIS03.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true MP.MONO.UI/MP.MONO.UI.csproj
|
||||
|
||||
SIM:release:
|
||||
stage: release
|
||||
tags:
|
||||
- win
|
||||
only:
|
||||
- main
|
||||
variables:
|
||||
APP_NAME: MP.MONO.SIM
|
||||
needs: ["SIM:build"]
|
||||
script:
|
||||
# - dotnet build MP.MONO.SIM/MP.MONO.SIM.csproj
|
||||
- dotnet publish -p:PublishProfile=SingleFileX86.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release MP.MONO.SIM/MP.MONO.SIM.csproj
|
||||
- *zipper
|
||||
- *hashBuild
|
||||
- *nexusUpload
|
||||
|
||||
DECODER:release:
|
||||
stage: release
|
||||
tags:
|
||||
- win
|
||||
only:
|
||||
- main
|
||||
variables:
|
||||
APP_NAME: MP.MONO.DECODER
|
||||
needs: ["DECODER:build"]
|
||||
script:
|
||||
# - dotnet build MP.MONO.DECODER/MP.MONO.DECODER.csproj
|
||||
- dotnet publish -p:PublishProfile=SingleFileX86.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release MP.MONO.DECODER/MP.MONO.DECODER.csproj
|
||||
- *zipper
|
||||
- *hashBuild
|
||||
- *nexusUpload
|
||||
|
||||
# UI:release:
|
||||
# stage: release
|
||||
@@ -101,18 +172,4 @@ SIM:build:
|
||||
# - publish/
|
||||
# script:
|
||||
# - dotnet publish -c Release -o ./publish MP.MONO.UI/MP.MONO.UI.csproj
|
||||
|
||||
# SIM:release:
|
||||
# stage: release
|
||||
# tags:
|
||||
# - win
|
||||
# only:
|
||||
# - main
|
||||
# except:
|
||||
# - branches
|
||||
# needs: ["SIM:build"]
|
||||
# artifacts:
|
||||
# paths:
|
||||
# - publish/
|
||||
# script:
|
||||
# - dotnet publish -c Release -o ./publish MP.MONO.SIM/MP.MONO.SIM.csproj
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="appsettings.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="appsettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="NLog" Version="4.7.14" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.5.43" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MP.MONO.Core\MP.MONO.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="conf\ModeList.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="conf\AlarmList.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="conf\ParamList.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="conf\StatusList.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,281 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using MP.MONO.Core;
|
||||
using MP.MONO.Core.CONF;
|
||||
using MP.MONO.Core.DTO;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using StackExchange.Redis;
|
||||
|
||||
// init parte config, vedere https://blog.hildenco.com/2020/05/configuration-in-net-core-console.html
|
||||
var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
|
||||
var builder = new ConfigurationBuilder()
|
||||
.AddJsonFile($"appsettings.json", true, true)
|
||||
.AddJsonFile($"appsettings.{env}.json", true, true)
|
||||
.AddEnvironmentVariables();
|
||||
var config = builder.Build();
|
||||
|
||||
// imposto variabili di base
|
||||
string lineSep = "---------------------------------------------";
|
||||
string redisConf = config.GetConnectionString("Redis");
|
||||
string confPath = Path.Combine(Directory.GetCurrentDirectory(), "conf");
|
||||
#if false
|
||||
string alarmSimMode = config.GetValue<string>("AlarmSimMode");
|
||||
#endif
|
||||
Logger Log = LogManager.GetCurrentClassLogger();
|
||||
Random rand = new Random();
|
||||
List<MachineStatus>? statusList = new List<MachineStatus>();
|
||||
List<MachineMode>? modeList = new List<MachineMode>();
|
||||
|
||||
// fix numero minimo dei thread pool x evitare collasso chiamate redis
|
||||
ThreadPool.SetMinThreads(10, 10);
|
||||
|
||||
Dictionary<string, int> LogSimulator = new Dictionary<string, int>();
|
||||
Dictionary<string, DateTime> LastSend = new Dictionary<string, DateTime>();
|
||||
DateTime lastLog = DateTime.Now.AddMinutes(-1);
|
||||
bool verboseLog = false;
|
||||
bool logWriting = false;
|
||||
|
||||
logInfo(lineSep, true, true);
|
||||
logInfo($"Starting Machine ADAPTER", true, true);
|
||||
logInfo($"Redis server param: {redisConf.Substring(0, 20)}...", false, true);
|
||||
logInfo(lineSep, true, true);
|
||||
logInfo("", true, true);
|
||||
logInfo("Running - press CTRL-C to stop SIM", false, true);
|
||||
logInfo("", false, true);
|
||||
|
||||
// Setup REDIS
|
||||
ConnectionMultiplexer.SetFeatureFlag("preventthreadtheft", true);
|
||||
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(redisConf);
|
||||
ISubscriber sub = redis.GetSubscriber();
|
||||
IDatabase? redisDb = redis.GetDatabase();
|
||||
|
||||
// salvo configurazioni in redis
|
||||
setupConf();
|
||||
|
||||
#if false
|
||||
var currSimGen = new Simulator(confPath, modeList.Count, statusList.Count);
|
||||
|
||||
// preparo la lista dei contatori invio...
|
||||
LogSimulator.Add(Constants.ACT_LOG_M_QUEUE, 0);
|
||||
LogSimulator.Add(Constants.ALARM_M_QUEUE, 0);
|
||||
LogSimulator.Add(Constants.EVENT_LOG_M_QUEUE, 0);
|
||||
LogSimulator.Add(Constants.PARAMS_M_QUEUE, 0);
|
||||
LogSimulator.Add(Constants.PROD_M_QUEUE, 0);
|
||||
LogSimulator.Add(Constants.MACH_STATS_M_QUEUE, 0);
|
||||
LogSimulator.Add(Constants.MAINT_STATS_M_QUEUE, 0);
|
||||
LogSimulator.Add(Constants.TOOLS_M_QUEUE, 0);
|
||||
|
||||
// avvio tutti i thread...
|
||||
Thread threadStatus = new Thread(simStatus);
|
||||
Thread threadAlarms = new Thread(simAlarms);
|
||||
Thread threadParams = new Thread(simParameters);
|
||||
Thread threadProd = new Thread(simProd);
|
||||
Thread threadMachStat = new Thread(simMachStat);
|
||||
Thread threadMaint = new Thread(simMaint);
|
||||
Thread threadTools = new Thread(simTools);
|
||||
Thread threadEvHistory = new Thread(simEvents);
|
||||
Thread threadActLog = new Thread(simActivityLog);
|
||||
|
||||
threadStatus.Start();
|
||||
threadAlarms.Start();
|
||||
threadParams.Start();
|
||||
threadProd.Start();
|
||||
threadMachStat.Start();
|
||||
threadMaint.Start();
|
||||
threadTools.Start();
|
||||
threadEvHistory.Start();
|
||||
threadActLog.Start();
|
||||
#endif
|
||||
|
||||
// Ciclo infinito x attesa chiusura con CTRL-C
|
||||
do
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
} while (true);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// verifica esistenza file oppure lo crea...
|
||||
/// </summary>
|
||||
void checkFilePresent(string filePath)
|
||||
{
|
||||
// verific presenza file log...
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
File.WriteAllText(filePath, $"{filePath} created!");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setup e salvataggio redis delle conf (es modi/stati)
|
||||
/// </summary>
|
||||
void setupConf()
|
||||
{
|
||||
#if false
|
||||
// leggo e salvo conf stati
|
||||
string fullPath = Path.Combine(confPath, "StatusList.json");
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
List<MachineStatus>? statusList = JsonConvert.DeserializeObject<List<MachineStatus>>(rawData);
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.STATUS_CONF_KEY, JsonConvert.SerializeObject(statusList));
|
||||
}
|
||||
}
|
||||
|
||||
// leggo e salvo conf modi
|
||||
fullPath = Path.Combine(confPath, "ModeList.json");
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
var localObj = JsonConvert.DeserializeObject<List<MachineMode>>(rawData);
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.MODE_CONF_KEY, JsonConvert.SerializeObject(localObj));
|
||||
}
|
||||
}
|
||||
|
||||
// leggo e salvo conf allarmi
|
||||
fullPath = Path.Combine(confPath, "AlarmList.json");
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
var localObj = JsonConvert.DeserializeObject<List<BaseAlarmConf>>(rawData);
|
||||
if (localObj != null)
|
||||
{
|
||||
// sistemo allarmi
|
||||
foreach (var item in localObj)
|
||||
{
|
||||
item.setupData();
|
||||
// loggo
|
||||
logInfo($"Decodifica aree alarmMap: {item.description} | {item.memAddr} x {item.size} byte | {item.messages.Count} messaggi allarme", true, true);
|
||||
}
|
||||
}
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.ALARMS_CONF_KEY, JsonConvert.SerializeObject(localObj));
|
||||
}
|
||||
}
|
||||
|
||||
// leggo e salvo conf parametri
|
||||
fullPath = Path.Combine(confPath, "ParamList.json");
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
var localObj = JsonConvert.DeserializeObject<List<DisplayDataDTO>>(rawData);
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.PARAMS_CONF_KEY, JsonConvert.SerializeObject(localObj));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ConfigManager configManager = new ConfigManager(redisConf, confPath);
|
||||
_ = configManager.getAlarmsConf();
|
||||
_ = configManager.getMachineModeConf();
|
||||
_ = configManager.getMachineStatusConf();
|
||||
_ = configManager.getParamsConf();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua log INFO su file e se richiesto su console
|
||||
/// </summary>
|
||||
void logInfo(string msg, bool log2file = true, bool log2console = false)
|
||||
{
|
||||
if (log2console)
|
||||
{
|
||||
Console.WriteLine(msg);
|
||||
}
|
||||
if (log2file)
|
||||
{
|
||||
Log.Info(msg);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Effettua log ERROR su file e se richiesto su console
|
||||
/// </summary>
|
||||
void logError(string msg, bool log2file = true, bool log2console = false)
|
||||
{
|
||||
if (log2console)
|
||||
{
|
||||
Console.WriteLine(msg);
|
||||
}
|
||||
if (log2file)
|
||||
{
|
||||
Log.Error(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void saveAndSendMessage(string memKey, string value, string notifyChannel, string message)
|
||||
{
|
||||
// effettuo la scrittura nell'area di memoria indicata SE passato intervallo minimo
|
||||
bool doSend = true;
|
||||
if (LastSend.ContainsKey(memKey))
|
||||
{
|
||||
if (DateTime.Now.Subtract(LastSend[memKey]).TotalSeconds < 60)
|
||||
{
|
||||
doSend = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LastSend.Add(memKey, DateTime.Now);
|
||||
}
|
||||
if (doSend)
|
||||
{
|
||||
redisDb.StringSetAsync(memKey, value);
|
||||
LastSend[memKey] = DateTime.Now;
|
||||
logInfo($"Redis Cache Key: {memKey}");
|
||||
}
|
||||
//redisDb.SetAdd(memKey, value);
|
||||
|
||||
// invio notifica tramite il canale richiesto
|
||||
sub.Publish(notifyChannel, message);
|
||||
if (verboseLog)
|
||||
{
|
||||
logInfo($"[{notifyChannel}] key: {memKey} | val: {value} | message: {message}");
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!logWriting)
|
||||
{
|
||||
if (LogSimulator.ContainsKey(notifyChannel))
|
||||
{
|
||||
LogSimulator[notifyChannel]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogSimulator.Add(notifyChannel, 1);
|
||||
}
|
||||
logWriting = true;
|
||||
// vedo se loggare...
|
||||
DateTime adesso = DateTime.Now;
|
||||
if (adesso.Subtract(lastLog).TotalSeconds > 15)
|
||||
{
|
||||
lastLog = adesso;
|
||||
logInfo(lineSep);
|
||||
|
||||
// lavoro su copia...
|
||||
var LogSimulatorCopy = new Dictionary<string, int>(LogSimulator);
|
||||
foreach (var item in LogSimulatorCopy)
|
||||
{
|
||||
logInfo($"Redis mQueue {item.Key,-20}{item.Value,12}");
|
||||
}
|
||||
logInfo(lineSep);
|
||||
}
|
||||
logWriting = false;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logError($"ERROR{Environment.NewLine}{ex}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"ConnectionStrings": {
|
||||
"Redis": "nkcredis.steamware.net:6379,DefaultDatabase=7,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false,password=nkc.password",
|
||||
"AuthConnection": "Server=localhost;port=3306;database=GWMS;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
|
||||
"DefaultConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
|
||||
"AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Egalware_24068!;sslmode=None;",
|
||||
"MP.MONO.Data": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;"
|
||||
},
|
||||
"DbConfig": {
|
||||
"Server": "10.74.82.230",
|
||||
"nKey": "MONO",
|
||||
"sKey": "Calcium0xide-CaO"
|
||||
},
|
||||
"MachineId": 1,
|
||||
"maxRecord": 15,
|
||||
"ExternalProviders": {
|
||||
"MailKit": {
|
||||
"SMTP": {
|
||||
"Address": "smtp.gmail.com",
|
||||
"Port": "465",
|
||||
"Account": "steamwarebot@gmail.com",
|
||||
"Password": "drmfsls16",
|
||||
"SenderEmail": "steamwarebot@gmail.com",
|
||||
"SenderName": "Steamware Email BOT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
[
|
||||
{
|
||||
"description": "General Alarm",
|
||||
"tipoMem": "DInt",
|
||||
"memAddr": "40901",
|
||||
"index": 901,
|
||||
"size": 2,
|
||||
"messages": [
|
||||
"Alarm 001",
|
||||
"Alarm 002",
|
||||
"Alarm 003",
|
||||
"Alarm 004",
|
||||
"Alarm 005",
|
||||
"Alarm 006",
|
||||
"Alarm 007",
|
||||
"Alarm 008",
|
||||
"Alarm 009",
|
||||
"Alarm 010",
|
||||
"Alarm 011",
|
||||
"Alarm 012",
|
||||
"##Alarm 013",
|
||||
"##Alarm 014",
|
||||
"##Alarm 015",
|
||||
"##Alarm 016"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Secondary Alarm",
|
||||
"tipoMem": "DInt",
|
||||
"memAddr": "40907",
|
||||
"index": 907,
|
||||
"size": 2,
|
||||
"messages": [
|
||||
"Warning 001",
|
||||
"Warning 002",
|
||||
"Warning 003",
|
||||
"Warning 004",
|
||||
"Warning 005",
|
||||
"Warning 006",
|
||||
"Warning 007",
|
||||
"Warning 008",
|
||||
"##Warning 009",
|
||||
"##Warning 010",
|
||||
"##Warning 011",
|
||||
"##Warning 012",
|
||||
"Warning 013",
|
||||
"Warning 014",
|
||||
"Warning 015",
|
||||
"Warning 016"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,125 @@
|
||||
[
|
||||
{
|
||||
"Order": 3,
|
||||
"Type": "SPEED-5000-10000",
|
||||
"Title": "SPEED",
|
||||
"Value": "4000",
|
||||
"ValueNum": 4000,
|
||||
"MinVal": 1000,
|
||||
"MaxVal": 10000,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-gauge-high",
|
||||
"SamplePeriod": 180,
|
||||
"VcFunc": "MEDIAN"
|
||||
},
|
||||
{
|
||||
"Order": 2,
|
||||
"Type": "FEED-3000-5000",
|
||||
"Title": "FEED",
|
||||
"Value": "2500",
|
||||
"ValueNum": 2500,
|
||||
"MinVal": 1000,
|
||||
"MaxVal": 5000,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-gauge-high",
|
||||
"SamplePeriod": 180,
|
||||
"VcFunc": "MEDIAN"
|
||||
},
|
||||
{
|
||||
"Order": 1,
|
||||
"Type": "LOAD",
|
||||
"Title": "SPINDLE LOAD",
|
||||
"Value": "30",
|
||||
"ValueNum": 30,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt",
|
||||
"SamplePeriod": 180,
|
||||
"VcFunc": "MEDIAN"
|
||||
},
|
||||
{
|
||||
"Order": 4,
|
||||
"Type": "POS",
|
||||
"Title": "X POS",
|
||||
"Value": "1500",
|
||||
"ValueNum": 1500,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 5000,
|
||||
"DisplFormat": "N2",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"CssIcon": "fa-solid fa-ruler-horizontal",
|
||||
"SamplePeriod": 180,
|
||||
"VcFunc": "MEDIAN"
|
||||
},
|
||||
{
|
||||
"Order": 5,
|
||||
"Type": "POS",
|
||||
"Title": "Y POS",
|
||||
"Value": "5000",
|
||||
"ValueNum": 5000,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10000,
|
||||
"DisplFormat": "N2",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"CssIcon": "fa-solid fa-ruler-horizontal",
|
||||
"SamplePeriod": 180,
|
||||
"VcFunc": "MEDIAN"
|
||||
},
|
||||
{
|
||||
"Order": 6,
|
||||
"Type": "POS",
|
||||
"Title": "Z POS",
|
||||
"Value": "-1500",
|
||||
"ValueNum": -1500,
|
||||
"MinVal": -3000,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "N2",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"CssIcon": "fa-solid fa-ruler-horizontal",
|
||||
"SamplePeriod": 180,
|
||||
"VcFunc": "MEDIAN"
|
||||
},
|
||||
{
|
||||
"Order": 7,
|
||||
"Type": "POS",
|
||||
"Title": "A POS",
|
||||
"Value": "150",
|
||||
"ValueNum": 150,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 360,
|
||||
"DisplFormat": "N3",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"CssIcon": "fa-solid fa-rotate-right",
|
||||
"SamplePeriod": 180,
|
||||
"VcFunc": "MEDIAN"
|
||||
},
|
||||
{
|
||||
"Order": 8,
|
||||
"Type": "POS",
|
||||
"Title": "B POS",
|
||||
"Value": "150",
|
||||
"ValueNum": 150,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 360,
|
||||
"DisplFormat": "N3",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"CssIcon": "fa-solid fa-rotate-right",
|
||||
"SamplePeriod": 180,
|
||||
"VcFunc": "MEDIAN"
|
||||
}
|
||||
]
|
||||
@@ -15,6 +15,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP.MONO.DECODER", "MP.MONO.
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP.MONO.ANALYZER", "MP.MONO.ANALYZER\MP.MONO.ANALYZER.csproj", "{4C9BEAED-1A33-41A7-B9D6-7C173A43FDB8}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP.MONO.ADAPTER", "MP.MONO.ADAPTER\MP.MONO.ADAPTER.csproj", "{873736BA-CDB6-4CE5-A340-6D904C11C07C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -97,6 +99,18 @@ Global
|
||||
{4C9BEAED-1A33-41A7-B9D6-7C173A43FDB8}.Release|x64.Build.0 = Release|x64
|
||||
{4C9BEAED-1A33-41A7-B9D6-7C173A43FDB8}.Release|x86.ActiveCfg = Release|x86
|
||||
{4C9BEAED-1A33-41A7-B9D6-7C173A43FDB8}.Release|x86.Build.0 = Release|x86
|
||||
{873736BA-CDB6-4CE5-A340-6D904C11C07C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{873736BA-CDB6-4CE5-A340-6D904C11C07C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{873736BA-CDB6-4CE5-A340-6D904C11C07C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{873736BA-CDB6-4CE5-A340-6D904C11C07C}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{873736BA-CDB6-4CE5-A340-6D904C11C07C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{873736BA-CDB6-4CE5-A340-6D904C11C07C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{873736BA-CDB6-4CE5-A340-6D904C11C07C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{873736BA-CDB6-4CE5-A340-6D904C11C07C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{873736BA-CDB6-4CE5-A340-6D904C11C07C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{873736BA-CDB6-4CE5-A340-6D904C11C07C}.Release|x64.Build.0 = Release|Any CPU
|
||||
{873736BA-CDB6-4CE5-A340-6D904C11C07C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{873736BA-CDB6-4CE5-A340-6D904C11C07C}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -0,0 +1,253 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using static MP.MONO.Core.Enums;
|
||||
|
||||
namespace MP.MONO.Core.CONF
|
||||
{
|
||||
/// <summary>
|
||||
/// Classe gestione configurazione parametri di base x allarmi
|
||||
/// </summary>
|
||||
public class BaseAlarmConf
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Segnaposto impiegato x disabilitare gli allarmi (sempre)
|
||||
/// </summary>
|
||||
public string disableMark { get; set; } = "##";
|
||||
|
||||
/// <summary>
|
||||
/// Elenco dei contatori blink x gestione caso fronte salita/discesa segnale che blinka
|
||||
/// </summary>
|
||||
public int[] alarmsBlinkCounter { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// BitMask 16bit (1 = valido, 0 = filtro) degli allarmi silenziati (salvato in redis) come valore da sottrarre x check
|
||||
/// </summary>
|
||||
public uint[] silenceMask { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// BitMask 16bit (1 = valido, 0 = filtro) degli allarmi DISABILITATI (se iniziano per [disableMark]) come valore da sottrarre x check
|
||||
/// </summary>
|
||||
public uint[] disableMask { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Array dei valori allarme correnti
|
||||
/// </summary>
|
||||
public uint[] alarmsState { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// valore di partenza x un segnale di blink in caso di fine variazione (fronte discesa)
|
||||
/// </summary>
|
||||
public int blinkDownVal { get; set; } = 4;
|
||||
|
||||
/// <summary>
|
||||
/// valore di partenza x un segnale di blink in caso di inizio variazione (fronte salita)
|
||||
/// </summary>
|
||||
public int blinkUpVal { get; set; } = 3;
|
||||
|
||||
/// <summary>
|
||||
/// Descrizione area allarmi
|
||||
/// </summary>
|
||||
public string description { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Indice nell'area di memoria (da valore iniziale = 0)
|
||||
/// </summary>
|
||||
public int index { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Nome "assoluto" della posizione nell'area di memoria (anche diverso da indice)
|
||||
/// </summary>
|
||||
public string memAddr { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Elenco allarmi configurati x la bitmap
|
||||
/// </summary>
|
||||
public List<string> messages { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Dictionary calcolato allarmi
|
||||
/// </summary>
|
||||
public Dictionary<int, string> messagesMap //{ get; set; } = new Dictionary<int, string>();
|
||||
{
|
||||
get
|
||||
{
|
||||
Dictionary<int, string> map = new Dictionary<int, string>();
|
||||
if (messages != null)
|
||||
{
|
||||
foreach (var item in messages)
|
||||
{
|
||||
map.Add(map.Count + 1, item);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
public bool isSilenced(int messIndex)
|
||||
{
|
||||
//decremento: è base 1 mi serve base 0...
|
||||
messIndex--;
|
||||
bool answ = false;
|
||||
int bank = (messIndex) / 16;
|
||||
if (silenceMask != null && silenceMask.Length >= bank)
|
||||
{
|
||||
var testVal = 1 << messIndex;
|
||||
answ = !((silenceMask[bank] & testVal) == testVal);
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Size in byte
|
||||
/// </summary>
|
||||
public int size { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Tipo di dato
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public plcDataType tipoMem { get; set; } = plcDataType.Boolean;
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Calcola il filtro da condizione blink (ovvero maschera per valori indicati blinking)
|
||||
/// </summary>
|
||||
/// <param name="num"></param>
|
||||
/// <returns></returns>
|
||||
public uint blinkFilter(int num)
|
||||
{
|
||||
uint answ = 0;
|
||||
int idx = 16 * num;
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
if (alarmsBlinkCounter[idx + i] > 0)
|
||||
{
|
||||
answ += (uint)1 << i;
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua update dei contatori blink per gestire i segnali alternati sul fronte di salita/discesa
|
||||
/// </summary>
|
||||
/// <param name="num"></param>
|
||||
/// <param name="newStatus"></param>
|
||||
public void checkBlinkCounter(int num, uint newStatus)
|
||||
{
|
||||
// calcola la maschera di variazione da valore precedente
|
||||
var variations = newStatus ^ alarmsState[num];
|
||||
// ciclo sui 16 bit...
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
// controllo se è variato
|
||||
if ((variations & (1 << i)) == (1 << i))
|
||||
{
|
||||
// se il valore nuovo è 1 --> è in fronte salita
|
||||
if ((newStatus & (1 << i)) == (1 << i))
|
||||
{
|
||||
// cambio SOLO SE il valore blink è zero...
|
||||
if (alarmsBlinkCounter[num * 16 + i] == 0)
|
||||
{
|
||||
alarmsBlinkCounter[num * 16 + i] = blinkUpVal;
|
||||
}
|
||||
}
|
||||
// altrimenti se è fronte discesa
|
||||
else
|
||||
{
|
||||
// cambio SOLO SE il valore blink è zero...
|
||||
if (alarmsBlinkCounter[num * 16 + i] == 0)
|
||||
{
|
||||
alarmsBlinkCounter[num * 16 + i] = blinkDownVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// decremento contatori blink
|
||||
int idx = 0;
|
||||
foreach (var item in alarmsBlinkCounter)
|
||||
{
|
||||
alarmsBlinkCounter[idx] = item > 0 ? item - 1 : item;
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Confronta un valore di stato allarme con lo stato precedentemente salvato considerando blink/veto
|
||||
/// </summary>
|
||||
/// <param name="num">Numero/indice del banco di allarme (uint16)</param>
|
||||
/// <param name="newValue">Valore (bitmap) allarmi come uint16</param>
|
||||
/// <returns></returns>
|
||||
public bool isChanged(int num, uint newValue)
|
||||
{
|
||||
// per prima cosa controllo valori RAW
|
||||
bool answ = !alarmsState[num].Equals(newValue);
|
||||
if (answ)
|
||||
{
|
||||
// controllo valori filtrati x silenziamento temporaneo o definitivo (sottraendo BITMASK dai valori di filtro)
|
||||
answ = ((alarmsState[num] & disableMask[num] & silenceMask[num]) != (newValue & disableMask[num] & silenceMask[num]));
|
||||
// se fossero ancora differenti controllo ulteriore mask dato il counter dei blink:
|
||||
if (answ)
|
||||
{
|
||||
var blinkFilt = blinkFilter(num);
|
||||
answ = ((alarmsState[num] & (disableMask[num] & silenceMask[num] & ~blinkFilt)) != (newValue & (disableMask[num] & silenceMask[num] & ~blinkFilt)));
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inizializzazione classe con valori calcolati: attenzione si aspetta banchi da 32 bit...
|
||||
/// </summary>
|
||||
public void setupData()
|
||||
{
|
||||
// inizializzo vettore valore allarmi x banco int16
|
||||
alarmsState = new uint[size / 2];
|
||||
disableMask = new uint[size / 2];
|
||||
silenceMask = new uint[size / 2];
|
||||
|
||||
// una volta inizializzata la classe di base sistemo vettori allarmi disabilitati ed il contatore blink dei fronti di discesa
|
||||
alarmsBlinkCounter = new int[messages.Count];
|
||||
int idx = 0;
|
||||
int bank = 0;
|
||||
foreach (var item in messages)
|
||||
{
|
||||
if (item.StartsWith(disableMark))
|
||||
{
|
||||
alarmsBlinkCounter[idx] = -999;
|
||||
}
|
||||
else
|
||||
{
|
||||
alarmsBlinkCounter[idx] = 1;
|
||||
disableMask[bank] += (uint)1 << idx;
|
||||
}
|
||||
silenceMask[bank] += (uint)1 << idx;
|
||||
idx++;
|
||||
// sistemo bank/indice
|
||||
if (idx > 15)
|
||||
{
|
||||
bank++;
|
||||
idx = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Imposta il valore dello status attuale allarme impostando eventuale valore blink x le variazioni
|
||||
/// </summary>
|
||||
/// <param name="num"></param>
|
||||
/// <param name="newStatus"></param>
|
||||
public void updStatusVal(int num, uint newStatus)
|
||||
{
|
||||
// salvo nuovo valore
|
||||
alarmsState[num] = newStatus;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
using MP.MONO.Core.CONF;
|
||||
using MP.MONO.Core.DTO;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace MP.MONO.Core
|
||||
{
|
||||
public class ConfigManager
|
||||
{
|
||||
#region Private Fields
|
||||
|
||||
private Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
protected string confPath = "";
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Public Constructors
|
||||
|
||||
public ConfigManager(string redisConf, string confDirPath)
|
||||
{
|
||||
confPath = confDirPath;
|
||||
ConnectionMultiplexer.SetFeatureFlag("preventthreadtheft", true);
|
||||
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(redisConf);
|
||||
redisDb = redis.GetDatabase();
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
protected IDatabase redisDb { get; set; } = null!;
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public List<BaseAlarmConf> getAlarmsConf()
|
||||
{
|
||||
List<BaseAlarmConf>? currConf = null;
|
||||
// leggo e salvo conf stati
|
||||
string fullPath = Path.Combine(confPath, "AlarmList.json");
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
currConf = JsonConvert.DeserializeObject<List<BaseAlarmConf>>(rawData);
|
||||
if (currConf != null)
|
||||
{
|
||||
// sistemo allarmi
|
||||
foreach (var item in currConf)
|
||||
{
|
||||
item.setupData();
|
||||
// loggo
|
||||
Log.Info($"Decodifica aree alarmMap: {item.description} | {item.memAddr} x {item.size} byte | {item.messages.Count} messaggi allarme", true, true);
|
||||
}
|
||||
}
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.ALARMS_CONF_KEY, JsonConvert.SerializeObject(currConf));
|
||||
}
|
||||
}
|
||||
if (currConf == null)
|
||||
{
|
||||
currConf = new List<BaseAlarmConf>();
|
||||
}
|
||||
return currConf;
|
||||
}
|
||||
|
||||
public List<MachineMode> getMachineModeConf()
|
||||
{
|
||||
List<MachineMode>? currConf = null;
|
||||
// leggo e salvo conf stati
|
||||
string fullPath = Path.Combine(confPath, "ModeList.json");
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
currConf = JsonConvert.DeserializeObject<List<MachineMode>>(rawData);
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.MODE_CONF_KEY, JsonConvert.SerializeObject(currConf));
|
||||
}
|
||||
}
|
||||
if (currConf == null)
|
||||
{
|
||||
currConf = new List<MachineMode>();
|
||||
}
|
||||
return currConf;
|
||||
}
|
||||
|
||||
public List<MachineStatus> getMachineStatusConf()
|
||||
{
|
||||
List<MachineStatus>? currConf = null;
|
||||
// leggo e salvo conf stati
|
||||
string fullPath = Path.Combine(confPath, "StatusList.json");
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
currConf = JsonConvert.DeserializeObject<List<MachineStatus>>(rawData);
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.STATUS_CONF_KEY, JsonConvert.SerializeObject(currConf));
|
||||
}
|
||||
}
|
||||
if (currConf == null)
|
||||
{
|
||||
currConf = new List<MachineStatus>();
|
||||
}
|
||||
return currConf;
|
||||
}
|
||||
|
||||
public List<DisplayDataDTO> getParamsConf()
|
||||
{
|
||||
List<DisplayDataDTO>? currConf = null;
|
||||
// leggo e salvo conf stati
|
||||
string fullPath = Path.Combine(confPath, "ParamList.json");
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
currConf = JsonConvert.DeserializeObject<List<DisplayDataDTO>>(rawData);
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.PARAMS_CONF_KEY, JsonConvert.SerializeObject(currConf));
|
||||
}
|
||||
}
|
||||
if (currConf == null)
|
||||
{
|
||||
currConf = new List<DisplayDataDTO>();
|
||||
}
|
||||
return currConf;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
}
|
||||
@@ -23,27 +23,34 @@ namespace MP.MONO.Core
|
||||
// Configurazioni
|
||||
public static readonly string STATUS_CONF_KEY = $"{BASE_HASH}:Conf:Status";
|
||||
public static readonly string MODE_CONF_KEY = $"{BASE_HASH}:Conf:Mode";
|
||||
public static readonly string ALARMS_CONF_KEY = $"{BASE_HASH}:Conf:Alarms";
|
||||
public static readonly string PARAMS_CONF_KEY = $"{BASE_HASH}:Conf:Params";
|
||||
|
||||
// Dati correnti
|
||||
// settings utente
|
||||
public static readonly string ALARMS_SETT_KEY = $"{BASE_HASH}:Settings:Alarms";
|
||||
|
||||
// REDIS KEY Dati correnti
|
||||
public static readonly string ACT_LOG_CURR_KEY = $"{BASE_HASH}:Current:ActivityLog";
|
||||
public static readonly string ALARM_ACT_KEY = $"{BASE_HASH}:Current:AlarmsVal";
|
||||
public static readonly string ALARM_CURR_KEY = $"{BASE_HASH}:Current:Alarms";
|
||||
public static readonly string EVENT_LOG_CURR_KEY = $"{BASE_HASH}:Current:EventsLog";
|
||||
public static readonly string MACH_STATS_CURR_KEY = $"{BASE_HASH}:Current:MachStats";
|
||||
public static readonly string MAINT_STATS_CURR_KEY = $"{BASE_HASH}:Current:Maintenance";
|
||||
public static readonly string PARAMS_CURR_KEY = $"{BASE_HASH}:Current:Parameters";
|
||||
public static readonly string PARAMS_ACT_KEY = $"{BASE_HASH}:Current:ParamsVal";
|
||||
public static readonly string PARAMS_CURR_KEY = $"{BASE_HASH}:Current:Params";
|
||||
public static readonly string PROD_CURR_KEY = $"{BASE_HASH}:Current:Production";
|
||||
public static readonly string STATUS_CURR_KEY = $"{BASE_HASH}:Current:Status";
|
||||
public static readonly string TOOLS_CURR_KEY = $"{BASE_HASH}:Current:Tools";
|
||||
|
||||
// Canali messaggi REDIS
|
||||
// REDIS Channels messaggi
|
||||
public static readonly string ACT_LOG_M_QUEUE = $"ActivityLog";
|
||||
public static readonly string ALARM_ACT_VAL = $"AlarmsActVal";
|
||||
public static readonly string ALARM_ACT_QUEUE = $"AlarmsActVal";
|
||||
public static readonly string ALARM_M_QUEUE = $"Alarms";
|
||||
public static readonly string EVENT_LOG_M_QUEUE = $"EventsLog";
|
||||
public static readonly string MACH_STATS_M_QUEUE = $"MachStats";
|
||||
public static readonly string MAINT_STATS_M_QUEUE = $"Maintenance";
|
||||
public static readonly string PARAMS_M_QUEUE = $"Parameters";
|
||||
public static readonly string PARAMS_ACT_QUEUE = $"ParamsActVal";
|
||||
public static readonly string PARAMS_M_QUEUE = $"Params";
|
||||
public static readonly string PROD_M_QUEUE = $"Production";
|
||||
public static readonly string STATUS_M_QUEUE = $"Status";
|
||||
public static readonly string TOOLS_M_QUEUE = $"Tools";
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static MP.MONO.Core.Enums;
|
||||
|
||||
// <Auto-Generated>
|
||||
// This is here so CodeMaid doesn't reorganize this document
|
||||
@@ -11,18 +12,65 @@ namespace MP.MONO.Core.DTO
|
||||
{
|
||||
public class DisplayDataDTO
|
||||
{
|
||||
/// <summary>
|
||||
/// Display Order
|
||||
/// </summary>
|
||||
public int Order { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// Data Type
|
||||
/// </summary>
|
||||
public string Type { get; set; } = "";
|
||||
/// <summary>
|
||||
/// Title/Name
|
||||
/// </summary>
|
||||
public string Title { get; set; } = "";
|
||||
/// <summary>
|
||||
/// Value (string format)
|
||||
/// </summary>
|
||||
public string Value { get; set; } = "";
|
||||
/// <summary>
|
||||
/// Value (number)
|
||||
/// </summary>
|
||||
public double ValueNum { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// Display format
|
||||
/// </summary>
|
||||
public string DisplFormat { get; set; } = "N0";
|
||||
/// <summary>
|
||||
/// Min Value permitted
|
||||
/// </summary>
|
||||
public double MinVal { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// Max Value permitted
|
||||
/// </summary>
|
||||
public double MaxVal { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// Define if is numeric
|
||||
/// </summary>
|
||||
public bool IsNumeric { get; set; } = false;
|
||||
/// <summary>
|
||||
/// Enabled for plotting
|
||||
/// </summary>
|
||||
public bool EnablePlot { get; set; } = true;
|
||||
/// <summary>
|
||||
/// Enable percent BAR display
|
||||
/// </summary>
|
||||
public bool ShowBar { get; set; } = false;
|
||||
/// <summary>
|
||||
/// Enable GAUGE display
|
||||
/// </summary>
|
||||
public bool ShowGauge { get; set; } = false;
|
||||
/// <summary>
|
||||
/// CSS Icon (ex: Fontawesome 6)
|
||||
/// </summary>
|
||||
public string CssIcon { get; set; } = "";
|
||||
/// <summary>
|
||||
/// Sample period for DB recording of min/Avg/MAX data (seconds)
|
||||
/// </summary>
|
||||
public double SamplePeriod { get; set; } = 60 * 3;
|
||||
/// <summary>
|
||||
/// Tipo di trasformazione VC da applicare ai dati al momento del raggiungimento del periodo di acquisizione
|
||||
/// </summary>
|
||||
public VC_func VcFunc { get; set; } = VC_func.POINT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,9 +170,9 @@
|
||||
AVG,
|
||||
|
||||
/// <summary>
|
||||
/// Valore massimo del periodo
|
||||
/// Calcolo MEDIANA
|
||||
/// </summary>
|
||||
MAX,
|
||||
MEDIAN,
|
||||
|
||||
/// <summary>
|
||||
/// Valore minimo del periodo
|
||||
@@ -180,9 +180,9 @@
|
||||
MIN,
|
||||
|
||||
/// <summary>
|
||||
/// Calcolo MEDIANA
|
||||
/// Valore massimo del periodo
|
||||
/// </summary>
|
||||
MEDIAN
|
||||
MAX
|
||||
}
|
||||
|
||||
#endregion Public Enums
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MathNet.Numerics" Version="4.15.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="NLog" Version="4.7.14" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.5.43" />
|
||||
<PackageReference Include="System.Collections" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
using static MP.MONO.Core.Enums;
|
||||
|
||||
namespace MP.MONO.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Configurazione per Variabili Casuali
|
||||
/// </summary>
|
||||
public class VCData
|
||||
{
|
||||
#region Public Fields
|
||||
|
||||
/// <summary>
|
||||
/// DataOra inizio periodo di elaborazione x determinare periodo massimo
|
||||
/// </summary>
|
||||
public DateTime DTStart;
|
||||
|
||||
#endregion Public Fields
|
||||
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Array dati per calcolo
|
||||
/// </summary>
|
||||
public List<double> dataArray { get; set; } = new List<double>();
|
||||
|
||||
/// <summary>
|
||||
/// Tipologia di funzione da applicare
|
||||
/// </summary>
|
||||
public VC_func Funzione { get; set; } = VC_func.POINT;
|
||||
|
||||
/// <summary>
|
||||
/// Periodo di riferimento in secondi (da aggiungere a DTStart x determinare scadenza x elaborazione)
|
||||
/// </summary>
|
||||
public double Period { get; set; } = 60.0;
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
public bool isElapsed
|
||||
{
|
||||
get
|
||||
{
|
||||
bool answ = false;
|
||||
answ = DTStart.AddSeconds(Period) <= DateTime.Now;
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
using NLog;
|
||||
using NLua;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MP.MONO.DECODER
|
||||
{
|
||||
public class AlarmManager
|
||||
{
|
||||
protected List<string> AlarmList = new List<string>();
|
||||
List<int> currAlarmStatus = new List<int>();
|
||||
protected static Lua state = new Lua();
|
||||
protected static string luaPath = "";
|
||||
public static string alarmStatus = "";
|
||||
public static bool valueChanged = false;
|
||||
protected static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public AlarmManager()
|
||||
{
|
||||
// !!!FIXME TODO
|
||||
|
||||
// fare vero setup da file... x ora è fake
|
||||
for (int i = 1; i < 9; i++)
|
||||
{
|
||||
AlarmList.Add($"Allarme{i:00}");
|
||||
}
|
||||
currAlarmStatus.Add(0);
|
||||
|
||||
// preparo variabile x avvisare script che il modo è da NLua
|
||||
luaPath = Path.Combine(Directory.GetCurrentDirectory(), "lua", "AlarmDecoder.lua");
|
||||
state.DoString(" callMode = 'NLua' ");
|
||||
state["alarmList"] = AlarmList;
|
||||
state["numAlarm"] = AlarmList.Count;
|
||||
|
||||
// initi 0/0
|
||||
state["lastVal"] = 0;
|
||||
state["currVal"] = 0;
|
||||
|
||||
Log.Info("AlarmManager OK");
|
||||
Console.WriteLine("AlarmManager OK");
|
||||
}
|
||||
|
||||
public static List<string> processData(int newStatus)
|
||||
{
|
||||
List<string> answ = new List<string>();
|
||||
// invio dati aggiornati a LUA
|
||||
state["currVal"] = newStatus;
|
||||
// FIXME TODO!!! fare invio banco allarmi correnti (SE fossero + banchi da config)
|
||||
state.DoFile(luaPath);
|
||||
alarmStatus = state.GetString("alarmStatus");
|
||||
bool.TryParse(state.GetString("valueChanged"), out valueChanged);
|
||||
if (valueChanged)
|
||||
{
|
||||
Log.Trace($"Changed: {valueChanged}");
|
||||
Log.Trace(alarmStatus);
|
||||
|
||||
LuaTable tabActive = state.GetTable("alarmListActive");
|
||||
List<string> activeList = new List<string>();
|
||||
foreach (var allarme in tabActive.Values)
|
||||
{
|
||||
answ.Add($"{allarme}");
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
using NLog;
|
||||
using NLua;
|
||||
|
||||
namespace MP.MONO.DECODER
|
||||
{
|
||||
public class AlarmsManager
|
||||
{
|
||||
#region Protected Fields
|
||||
|
||||
protected static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
protected static string luaPath = "";
|
||||
protected static Lua state = new Lua();
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Public Fields
|
||||
|
||||
public static string alarmStatus = "";
|
||||
public static bool valueChanged = false;
|
||||
|
||||
#endregion Public Fields
|
||||
|
||||
#region Public Constructors
|
||||
|
||||
public AlarmsManager()
|
||||
{
|
||||
// preparo variabile x avvisare script che il modo è da NLua
|
||||
luaPath = Path.Combine(Directory.GetCurrentDirectory(), "lua", "AlarmDecoder.lua");
|
||||
|
||||
#if false
|
||||
state.DoString(" callMode = 'NLua' ");
|
||||
// initi 0/0
|
||||
state.DoString(" lastVal = 0 ");
|
||||
state.DoString(" currVal = 0 ");
|
||||
#endif
|
||||
state["callMode"] = "NLua";
|
||||
state["lastVal"] = 0;
|
||||
state["currVal"] = 0;
|
||||
|
||||
Log.Info("AlarmsManager OK");
|
||||
Console.WriteLine("AlarmsManager OK");
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Funzione chiamata LUA x calcolo status allarmi
|
||||
/// </summary>
|
||||
/// <param name="prefix"></param>
|
||||
/// <param name="alarmList"></param>
|
||||
/// <param name="muteMask"></param>
|
||||
/// <param name="disableMask"></param>
|
||||
/// <param name="lastVal"></param>
|
||||
/// <param name="currVal"></param>
|
||||
/// <returns></returns>
|
||||
public static List<string> processData(string prefix, List<string> alarmList, uint muteMask, uint disableMask, uint lastVal, ref uint currVal)
|
||||
{
|
||||
state["prefix"] = prefix;
|
||||
state["alarmList"] = alarmList;
|
||||
state["numAlarm"] = alarmList.Count;
|
||||
state["muteMask"] = muteMask;
|
||||
state["disableMask"] = disableMask;
|
||||
|
||||
List<string> answ = new List<string>();
|
||||
// invio dati aggiornati a LUA
|
||||
state["lastVal"] = lastVal;
|
||||
state["currVal"] = currVal;
|
||||
|
||||
state.DoFile(luaPath);
|
||||
alarmStatus = state.GetString("alarmStatus");
|
||||
// recupero NUOVO valore (filtrato) attuale da salvare
|
||||
currVal = (uint)state.GetNumber("lastVal");
|
||||
bool.TryParse(state.GetString("valueChanged"), out valueChanged);
|
||||
if (valueChanged)
|
||||
{
|
||||
Log.Trace($"Changed: {valueChanged}");
|
||||
Log.Trace(alarmStatus);
|
||||
|
||||
LuaTable tabActive = state.GetTable("alarmListActive");
|
||||
List<string> activeList = new List<string>();
|
||||
foreach (var allarme in tabActive.Values)
|
||||
{
|
||||
answ.Add($"{allarme}");
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
}
|
||||
@@ -32,15 +32,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="conf\AlarmConf.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="conf\ConfMode.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="conf\ConfStatus.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="logs\.placeholder.file">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
@@ -53,6 +44,9 @@
|
||||
<None Update="logs\stdout.log">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="lua\ParamsDecoder.lua">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="lua\mobdebug.lua">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
using MP.MONO.Core;
|
||||
using MP.MONO.Core.DTO;
|
||||
using MP.MONO.Data.DbModels;
|
||||
using NLog;
|
||||
using NLua;
|
||||
|
||||
namespace MP.MONO.DECODER
|
||||
{
|
||||
public class ParamsManager
|
||||
{
|
||||
#region Private Fields
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario dei valori accumulati sulle variabili
|
||||
/// </summary>
|
||||
private Dictionary<string, VCData> ParamsAccumulator = new Dictionary<string, VCData>();
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
protected static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
protected static string luaPath = "";
|
||||
protected static Lua state = new Lua();
|
||||
protected List<string> AlarmList = new List<string>();
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Public Fields
|
||||
|
||||
public static string alarmStatus = "";
|
||||
public static bool valueChanged = false;
|
||||
|
||||
#endregion Public Fields
|
||||
|
||||
#region Public Constructors
|
||||
|
||||
public ParamsManager()
|
||||
{
|
||||
// preparo variabile x avvisare script che il modo è da NLua
|
||||
luaPath = Path.Combine(Directory.GetCurrentDirectory(), "lua", "ParamsDecoder.lua");
|
||||
|
||||
state["callMode"] = "NLua";
|
||||
state["lastVal"] = 0;
|
||||
state["currVal"] = 0;
|
||||
|
||||
Log.Info("ParamsManager OK");
|
||||
Console.WriteLine("ParamsManager OK");
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Funzione chiamata LUA x calcolo degli eventuali parametri con periodi "scaduti"
|
||||
/// </summary>
|
||||
/// <param name="paramsList"></param>
|
||||
/// <param name="redisParamConf"></param>
|
||||
/// <returns></returns>
|
||||
public List<DataLogModel> processData(Dictionary<string, double> paramsList, List<DisplayDataDTO> redisParamConf)
|
||||
{
|
||||
List<DataLogModel> answ = new List<DataLogModel>();
|
||||
DateTime adesso = DateTime.Now;
|
||||
|
||||
// vado ad "accumulare i dati" a quelli presenti...
|
||||
foreach (var item in paramsList)
|
||||
{
|
||||
var currParam = redisParamConf.FirstOrDefault(x => x.Title == item.Key);
|
||||
// cerco nelle variabili accomulatori...
|
||||
if (!ParamsAccumulator.ContainsKey(item.Key))
|
||||
{
|
||||
if (currParam != null)
|
||||
{
|
||||
var dataList = new List<double>();
|
||||
dataList.Add(item.Value);
|
||||
VCData newSet = new VCData()
|
||||
{
|
||||
dataArray = dataList,
|
||||
DTStart = adesso,
|
||||
Funzione = currParam.VcFunc,
|
||||
Period = currParam.SamplePeriod
|
||||
};
|
||||
// se non ci fosse creo
|
||||
ParamsAccumulator.Add(item.Key, newSet);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// altrimenti aggiungo
|
||||
ParamsAccumulator[item.Key].dataArray.Add(item.Value);
|
||||
}
|
||||
|
||||
// effettuo verifiche scadenza
|
||||
if (ParamsAccumulator.ContainsKey(item.Key))
|
||||
{
|
||||
if (ParamsAccumulator[item.Key].isElapsed)
|
||||
{
|
||||
// se scaduto --> mando a LUA x calcolo
|
||||
|
||||
// FIXME TODO
|
||||
var calcVal = ParamsAccumulator[item.Key].dataArray.FirstOrDefault();
|
||||
#if false
|
||||
// processing LUA del calcolo dei dati "scaduti"
|
||||
//state["prefix"] = prefix;
|
||||
//state["alarmList"] = alarmList;
|
||||
//state["numAlarm"] = alarmList.Count;
|
||||
//state["muteMask"] = muteMask;
|
||||
//state["disableMask"] = disableMask;
|
||||
|
||||
// invio dati aggiornati a LUA
|
||||
state["lastVal"] = lastVal;
|
||||
state["currVal"] = currVal;
|
||||
|
||||
state.DoFile(luaPath);
|
||||
alarmStatus = state.GetString("alarmStatus");
|
||||
// recupero NUOVO valore (filtrato) attuale da salvare
|
||||
currVal = (uint)state.GetNumber("lastVal");
|
||||
bool.TryParse(state.GetString("valueChanged"), out valueChanged);
|
||||
if (valueChanged)
|
||||
{
|
||||
Log.Trace($"Changed: {valueChanged}");
|
||||
Log.Trace(alarmStatus);
|
||||
|
||||
LuaTable tabActive = state.GetTable("alarmListActive");
|
||||
List<string> activeList = new List<string>();
|
||||
foreach (var allarme in tabActive.Values)
|
||||
{
|
||||
answ.Add($"{allarme}");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// aggiungo alla lista finale...
|
||||
var dbRecord = new DataLogModel()
|
||||
{
|
||||
DtRif = adesso,
|
||||
FluxType = item.Key,
|
||||
MachineId = 1,
|
||||
ValNum = calcVal,
|
||||
ValStr = $"{calcVal:N3}"
|
||||
|
||||
};
|
||||
answ.Add(dbRecord);
|
||||
|
||||
// elimino dai valori accumulati...
|
||||
ParamsAccumulator.Remove(item.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return answ;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
}
|
||||
+212
-221
@@ -1,14 +1,15 @@
|
||||
using NLua;
|
||||
using MP.MONO.DECODER;
|
||||
using MP.MONO.Data;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using MP.MONO.Core;
|
||||
using StackExchange.Redis;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Newtonsoft.Json;
|
||||
using MP.MONO.Core.CONF;
|
||||
using MP.MONO.Core.DTO;
|
||||
using MP.MONO.Data;
|
||||
using MP.MONO.Data.Controllers;
|
||||
using NLog;
|
||||
using MP.MONO.Data.DbModels;
|
||||
using MP.MONO.DECODER;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using NLua;
|
||||
using StackExchange.Redis;
|
||||
|
||||
// See https://aka.ms/new-console-template for more information
|
||||
|
||||
@@ -33,15 +34,27 @@ Console.WriteLine(lineSep);
|
||||
Console.WriteLine("");
|
||||
|
||||
// init DB
|
||||
// init info x DB
|
||||
string dbServerAddr = config["DbConfig:Server"];
|
||||
string nKey = config["DbConfig:nKey"];
|
||||
string sKey = config["DbConfig:sKey"];
|
||||
DbConfig.InitDb(dbServerAddr, nKey, sKey);
|
||||
// inizializzo il DB e creo (se necessario) l'utente
|
||||
DbConfig.CheckUser(nKey, sKey);
|
||||
// verifico se serve applicazione migrazioni
|
||||
DbConfig.ExecMigrationMain();
|
||||
//DbConfig.ExecMigrationIdentity();
|
||||
|
||||
// altri parametri per check vari
|
||||
string connStringDB = DbConfig.CONNECTION_STRING;
|
||||
MpDbController dbController = null!;
|
||||
string connStr = config.GetConnectionString("MP.MONO.Data");
|
||||
if (string.IsNullOrEmpty(connStr))
|
||||
if (string.IsNullOrEmpty(connStringDB))
|
||||
{
|
||||
Log.Error("ConnString empty!");
|
||||
}
|
||||
else
|
||||
{
|
||||
dbController = new MpDbController(config);
|
||||
dbController = new MpDbController();
|
||||
Log.Info("DbController OK");
|
||||
Console.WriteLine("DbController OK");
|
||||
}
|
||||
@@ -51,15 +64,75 @@ int MachineId = 1;
|
||||
int.TryParse(config.GetValue<string>("MachineId"), out MachineId);
|
||||
|
||||
// init oggetti REDIS + messagePipe...
|
||||
ConnectionMultiplexer.SetFeatureFlag("preventthreadtheft", true);
|
||||
ConnectionMultiplexer redisConn = ConnectionMultiplexer.Connect(config.GetConnectionString("Redis"));
|
||||
MessagePipe alarmPipe = new MessagePipe(redisConn, Constants.ALARM_M_QUEUE);
|
||||
MessagePipe alarmValPipe = new MessagePipe(redisConn, Constants.ALARM_ACT_VAL);
|
||||
alarmValPipe.EA_NewMessage += AlarmValPipe_EA_NewMessage;
|
||||
IDatabase? redisDb = redisConn.GetDatabase();
|
||||
|
||||
// preparo oggetti da configurare
|
||||
List<BaseAlarmConf>? alarmsConf = new List<BaseAlarmConf>();
|
||||
List<MachineMode>? machineModeConf = new List<MachineMode>();
|
||||
List<MachineStatus>? machineStatusConf = new List<MachineStatus>();
|
||||
// gestione configurazioni da redis
|
||||
setupConf();
|
||||
|
||||
/* --------------------------------
|
||||
* Setup Gestione ALLARMI
|
||||
* --------------------------------*/
|
||||
// init classe gestione allarmi con LUA
|
||||
AlarmManager alarmMan = new AlarmManager();
|
||||
void AlarmValPipe_EA_NewMessage(object? sender, EventArgs e)
|
||||
AlarmsManager alarmsMan = new AlarmsManager();
|
||||
// inizializzo gestione messagePipe da Redis x allarmi
|
||||
MessagePipe alarmsPipe = new MessagePipe(redisConn, Constants.ALARM_M_QUEUE);
|
||||
MessagePipe alarmsValPipe = new MessagePipe(redisConn, Constants.ALARM_ACT_QUEUE);
|
||||
// registro gestione eventi
|
||||
alarmsValPipe.EA_NewMessage += AlarmsValPipe_EA_NewMessage;
|
||||
|
||||
/* --------------------------------
|
||||
* Setup Gestione Parametri
|
||||
* --------------------------------*/
|
||||
ParamsManager paramMan = new ParamsManager();
|
||||
// inizializzo gestione messagePipe da Redis x allarmi
|
||||
MessagePipe paramsPipe = new MessagePipe(redisConn, Constants.PARAMS_M_QUEUE);
|
||||
MessagePipe paramsValPipe = new MessagePipe(redisConn, Constants.PARAMS_ACT_QUEUE);
|
||||
// registro gestione eventi
|
||||
paramsValPipe.EA_NewMessage += ParamsValPipe_EA_NewMessage;
|
||||
|
||||
|
||||
/* --------------------------------
|
||||
* Funzioni / metodi accessori
|
||||
* --------------------------------*/
|
||||
/// <summary>
|
||||
/// Recupero da redis le conf (es modi,stati,allarmi)
|
||||
/// </summary>
|
||||
void setupConf()
|
||||
{
|
||||
// recupero valori e deserializzo
|
||||
string rawData = "";
|
||||
|
||||
// machine conf
|
||||
rawData = redisDb.StringGet(Constants.STATUS_CONF_KEY);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
machineStatusConf = JsonConvert.DeserializeObject<List<MachineStatus>>(rawData);
|
||||
}
|
||||
|
||||
// machine mode
|
||||
rawData = redisDb.StringGet(Constants.MODE_CONF_KEY);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
machineModeConf = JsonConvert.DeserializeObject<List<MachineMode>>(rawData);
|
||||
}
|
||||
|
||||
// allarmi, versione base...
|
||||
rawData = redisDb.StringGet(Constants.ALARMS_CONF_KEY);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
alarmsConf = JsonConvert.DeserializeObject<List<BaseAlarmConf>>(rawData);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Gestione evento ricezione messaggi allarmi
|
||||
/// </summary>
|
||||
void AlarmsValPipe_EA_NewMessage(object? sender, EventArgs e)
|
||||
{
|
||||
PubSubEventArgs currArgs = (PubSubEventArgs)e;
|
||||
// conversione on-the-fly List<string> --> allarmi
|
||||
@@ -67,237 +140,155 @@ void AlarmValPipe_EA_NewMessage(object? sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var alarmList = JsonConvert.DeserializeObject<List<int>>(currArgs.newMessage);
|
||||
// verifico codici allarmi ricevuti
|
||||
var alarmList = JsonConvert.DeserializeObject<Dictionary<string, uint>>(currArgs.newMessage);
|
||||
if (alarmList != null)
|
||||
{
|
||||
// variabili accessorie
|
||||
List<string> activeAlarmList = new List<string>();
|
||||
List<AlarmLogModel> alarmLogList = new List<AlarmLogModel>();
|
||||
foreach (var bankVal in alarmList)
|
||||
|
||||
// rileggo da REDIS la conf attuale allarmi da area ALARMS_SETT_KEY, altrimenti uso quella letta inizialmente da conf base
|
||||
List<BaseAlarmConf>? currAlarmsConf = new List<BaseAlarmConf>();
|
||||
string rawData = redisDb.StringGet(Constants.ALARMS_SETT_KEY);
|
||||
// se trovati uso questi...
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
var bankAlarmList = AlarmManager.processData(bankVal);
|
||||
// aggiungo...
|
||||
activeAlarmList.AddRange(bankAlarmList);
|
||||
// preparo OBJ x DB
|
||||
AlarmLogModel newAlarm = new AlarmLogModel()
|
||||
currAlarmsConf = JsonConvert.DeserializeObject<List<BaseAlarmConf>>(rawData);
|
||||
}
|
||||
// altrimenti uso quelli di default inizialmente letti
|
||||
else
|
||||
{
|
||||
currAlarmsConf = alarmsConf;
|
||||
}
|
||||
if (currAlarmsConf != null)
|
||||
{
|
||||
// ciclo x ogni bank di allarmi configurato
|
||||
foreach (var alarmData in currAlarmsConf)
|
||||
{
|
||||
MachineId = MachineId,
|
||||
DtRif = DateTime.Now,
|
||||
MemAddress = "SIM.DB",
|
||||
Index = 0,
|
||||
Status = (uint)bankVal,
|
||||
ValDecoded = activeAlarmList.Count > 0 ? JsonConvert.SerializeObject(activeAlarmList) : "All OK"
|
||||
};
|
||||
alarmLogList.Add(newAlarm);
|
||||
}
|
||||
// serializzo...
|
||||
string serAlarms = "All OK";
|
||||
if (activeAlarmList.Count > 0)
|
||||
{
|
||||
serAlarms= JsonConvert.SerializeObject(activeAlarmList);
|
||||
// recupero valore allarme
|
||||
var bankVal = alarmList.FirstOrDefault(x => x.Key == alarmData.memAddr);
|
||||
uint actVal = !string.IsNullOrEmpty(bankVal.Key) ? bankVal.Value : 0;
|
||||
// valutare se dividere in 2 da 16... FIXME TODO
|
||||
var bankAlarmList = AlarmsManager.processData(alarmData.memAddr, alarmData.messages, alarmData.silenceMask[0], alarmData.disableMask[0], alarmData.alarmsState[0], ref actVal);
|
||||
// salvo nuovo valore in oggetto...
|
||||
if (alarmData.alarmsState[0] != actVal)
|
||||
{
|
||||
alarmData.alarmsState[0] = actVal;
|
||||
// aggiungo...
|
||||
activeAlarmList.AddRange(bankAlarmList);
|
||||
|
||||
AlarmLogModel newAlarm = new AlarmLogModel()
|
||||
{
|
||||
MachineId = MachineId,
|
||||
DtRif = DateTime.Now,
|
||||
MemAddress = bankVal.Key,
|
||||
Index = alarmData != null ? alarmData.index : 0,
|
||||
Status = alarmData != null ? (uint)bankVal.Value & alarmData.silenceMask[0] & alarmData.disableMask[0] : (uint)bankVal.Value,
|
||||
ValDecoded = bankAlarmList.Count > 0 ? string.Join(", ", bankAlarmList) : "All OK"
|
||||
};
|
||||
alarmLogList.Add(newAlarm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// salvo status aggiornato allarme...
|
||||
redisDb.StringSet(Constants.ALARMS_SETT_KEY, JsonConvert.SerializeObject(currAlarmsConf));
|
||||
|
||||
// serializzo l'elenco allarmi...
|
||||
string serAlarms = "[]";
|
||||
serAlarms = JsonConvert.SerializeObject(activeAlarmList);
|
||||
// invio sulla message pipeline corretta TUTTI gli allarmi serializzati
|
||||
alarmPipe.sendMessage(serAlarms);
|
||||
alarmsPipe.saveAndSendMessage(Constants.ALARM_CURR_KEY, serAlarms);
|
||||
if (dbController != null)
|
||||
{
|
||||
// salvo sul DB
|
||||
_ = dbController.AlarmLogInsertMany(alarmLogList).Result;
|
||||
|
||||
#if false
|
||||
// salvo nel DB lo stato dei bank di allarme
|
||||
foreach (var dbItem in alarmLogList)
|
||||
{
|
||||
_ = dbController.AlarmLogInsert(dbItem).Result;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione in AlarmsValPipe_EA_NewMessage:{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Lua state;
|
||||
state = new Lua();
|
||||
// preparo variabile x avvisare script che il modo è da NLua
|
||||
state.DoString(" callMode = 'NLua' ");
|
||||
|
||||
int numTest = 0;
|
||||
if (numTest == 1)
|
||||
/// <summary>
|
||||
/// Gestione evento ricezione messaggi parametri
|
||||
/// </summary>
|
||||
void ParamsValPipe_EA_NewMessage(object? sender, EventArgs e)
|
||||
{
|
||||
// inserisco dati in LUA...
|
||||
List<string> alarmList = new List<string>();
|
||||
string alarmStatus = "";
|
||||
bool valueChanged = false;
|
||||
string luaPath = Path.Combine(Directory.GetCurrentDirectory(), "lua", "AlarmDecoder.lua");
|
||||
state.NewTable("alarmListTable");
|
||||
LuaTable tabA = state.GetTable("alarmListTable");
|
||||
|
||||
// aggiorno valori
|
||||
alarmList = new List<string>() { "Allarme01", "Allarme02", "##Allarme03", "Allarme04", "##Allarme05", "Allarme06", "Allarme07", "Allarme08" };
|
||||
state["alarmList"] = alarmList;
|
||||
state["numAlarm"] = alarmList.Count;
|
||||
|
||||
//state.DoString(@"
|
||||
//function setupAlarms()
|
||||
// for i = numAlarm,1, -1
|
||||
// do
|
||||
// alarmListTable[i] = alarmList[i-1]
|
||||
// end
|
||||
//end
|
||||
//");
|
||||
//var scriptFunc = state["setupAlarms"] as LuaFunction;
|
||||
//var res2 = scriptFunc.Call();
|
||||
|
||||
// eseguo
|
||||
state["lastVal"] = 0;
|
||||
state["currVal"] = 3;
|
||||
state.DoFile(luaPath);
|
||||
alarmStatus = state.GetString("alarmStatus");
|
||||
bool.TryParse(state.GetString("valueChanged"), out valueChanged);
|
||||
Console.WriteLine($"Changed: {valueChanged}");
|
||||
Console.WriteLine(alarmStatus);
|
||||
//tabA = state.GetTable("alarmListActive");
|
||||
//foreach (var item in tabA.Values)
|
||||
//{
|
||||
// Console.WriteLine(item);
|
||||
//}
|
||||
Thread.Sleep(800);
|
||||
|
||||
state["currVal"] = 7;
|
||||
state.DoFile(luaPath);
|
||||
alarmStatus = state.GetString("alarmStatus");
|
||||
bool.TryParse(state.GetString("valueChanged"), out valueChanged);
|
||||
Console.WriteLine($"Changed: {valueChanged}");
|
||||
Console.WriteLine(alarmStatus);
|
||||
//tabA = state.GetTable("alarmListActive");
|
||||
//foreach (var item in tabA.Values)
|
||||
//{
|
||||
// Console.WriteLine(item);
|
||||
//}
|
||||
Thread.Sleep(800);
|
||||
|
||||
state["currVal"] = 15;
|
||||
state.DoFile(luaPath);
|
||||
alarmStatus = state.GetString("alarmStatus");
|
||||
bool.TryParse(state.GetString("valueChanged"), out valueChanged);
|
||||
Console.WriteLine($"Changed: {valueChanged}");
|
||||
Console.WriteLine(alarmStatus);
|
||||
//tabA = state.GetTable("alarmListActive");
|
||||
//foreach (var item in tabA.Values)
|
||||
//{
|
||||
// Console.WriteLine(item);
|
||||
//}
|
||||
|
||||
Thread.Sleep(800);
|
||||
|
||||
state["currVal"] = 0;
|
||||
state.DoFile(luaPath);
|
||||
alarmStatus = state.GetString("alarmStatus");
|
||||
bool.TryParse(state.GetString("valueChanged"), out valueChanged);
|
||||
Console.WriteLine($"Changed: {valueChanged}");
|
||||
Console.WriteLine(alarmStatus);
|
||||
//tabA = state.GetTable("alarmListActive");
|
||||
//foreach (var item in tabA.Values)
|
||||
//{
|
||||
// Console.WriteLine(item);
|
||||
//}
|
||||
|
||||
//state.DoString("a={b={c=2}}");
|
||||
//LuaTable tabA = state.GetTable("a");
|
||||
//LuaTable tabB = state.GetTable("a.b");
|
||||
//state.DoString(" print(a) ");
|
||||
|
||||
//foreach (var item in tabB)
|
||||
//{
|
||||
// Console.WriteLine(item);
|
||||
//}
|
||||
//tabA = state.GetTable("alarmListActive");
|
||||
//foreach (var item in tabA.Values)
|
||||
//{
|
||||
// Console.WriteLine(item);
|
||||
//}
|
||||
|
||||
|
||||
}
|
||||
else if (numTest == 2)
|
||||
{
|
||||
static double Compute(double x)
|
||||
PubSubEventArgs currArgs = (PubSubEventArgs)e;
|
||||
// conversione on-the-fly Dictionary<string,int> --> parametri valorizzati (tra quelli configurati)
|
||||
if (!string.IsNullOrEmpty(currArgs.newMessage))
|
||||
{
|
||||
return x * (x - 1);
|
||||
try
|
||||
{
|
||||
// verifico codici ricevuti
|
||||
var paramsList = JsonConvert.DeserializeObject<Dictionary<string, double>>(currArgs.newMessage);
|
||||
if (paramsList != null)
|
||||
{
|
||||
// recupero elenco parametri salvati in redis...
|
||||
List<DisplayDataDTO>? redisParamConf = new List<DisplayDataDTO>();
|
||||
List<DisplayDataDTO> updatedParams = new List<DisplayDataDTO>();
|
||||
string rawData = redisDb.StringGet(Constants.PARAMS_CONF_KEY);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
redisParamConf = JsonConvert.DeserializeObject<List<DisplayDataDTO>>(rawData);
|
||||
// se ho i parametri...
|
||||
if (redisParamConf != null)
|
||||
{
|
||||
// ciclo x ogni valore ricevuto da message service...
|
||||
foreach (var item in paramsList)
|
||||
{
|
||||
// cerco il parametro corrispondente...
|
||||
var currParam = redisParamConf.FirstOrDefault(x => x.Title == item.Key);
|
||||
if (currParam != null)
|
||||
{
|
||||
currParam.ValueNum = item.Value;
|
||||
currParam.Value = $"{item.Value.ToString(currParam.DisplFormat)}";
|
||||
// aggiungo a lista...
|
||||
updatedParams.Add(currParam);
|
||||
}
|
||||
}
|
||||
if (dbController != null)
|
||||
{
|
||||
// verifico x ogni parametro se sia completato il periodo di campionamento...
|
||||
var params2save = paramMan.processData(paramsList, redisParamConf);
|
||||
if (params2save.Count > 0)
|
||||
{
|
||||
// salvo sul DB
|
||||
_ = dbController.DataLogInsertMany(params2save).Result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// invio sulla message pipeline corretta TUTTI i parametri aggiornati serializzati
|
||||
string updRawVal = JsonConvert.SerializeObject(redisParamConf);
|
||||
paramsPipe.saveAndSendMessage(Constants.PARAMS_CURR_KEY, updRawVal);
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione in ParamsValPipe_EA_NewMessage:{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
var myobj = new MyClass();
|
||||
myobj.IntegerProperty = 17;
|
||||
state["var1"] = "someValue";
|
||||
state["obj"] = myobj;
|
||||
state["compute"] = new Func<double, double>(Compute);
|
||||
// Will print "output: someValue"
|
||||
state.DoString(" print('output: ' .. var1) ");
|
||||
// Will print 18
|
||||
state.DoString(" print(obj.IntegerProperty + 1) ");
|
||||
// Will print "Doing something: hello"
|
||||
state.DoString(" obj:DoSomething('hello') ");
|
||||
state.DoString(" obj:SaveData('redis:key:name','{John = 320, Mary = 340, Bob = 880, Rob = 860}') ");
|
||||
|
||||
state.DoString("a={b={c=2}}");
|
||||
LuaTable tabA = state.GetTable("a");
|
||||
LuaTable tabB = state.GetTable("a.b");
|
||||
state.DoString(" print(a) ");
|
||||
foreach (var item in tabA)
|
||||
{
|
||||
Console.WriteLine(item);
|
||||
}
|
||||
|
||||
foreach (var item in tabB)
|
||||
{
|
||||
Console.WriteLine(item);
|
||||
}
|
||||
|
||||
|
||||
// Will print "-0.1875"
|
||||
state.DoString(" print(compute(0.25)) ");
|
||||
// Reading values back
|
||||
state.DoString(" x = compute(0.75) ");
|
||||
state.DoString(" y = 2.0 * (obj.IntegerProperty * x) ");
|
||||
|
||||
double x = state.GetNumber("x");
|
||||
double y = state.GetNumber("y");
|
||||
// Will print: x = -0.1875, y = -6.375
|
||||
Console.WriteLine($"x = {x}, y = {y}");
|
||||
|
||||
double val = 12.0;
|
||||
state["x"] = val; // Create a global value 'x'
|
||||
var resRaw = state.DoString("return 10 + x*(5 + 2)")[0];
|
||||
double res = 0;
|
||||
double.TryParse($"{resRaw}", out res);
|
||||
Console.WriteLine($"{res}");
|
||||
|
||||
|
||||
|
||||
state.DoString("y = 10 + x*(4 + 2)");
|
||||
var rawState = state["y"]; // Retrieve the value of y
|
||||
double y2 = 0;
|
||||
double.TryParse($"{rawState}", out y2);
|
||||
Console.WriteLine($"{y2}");
|
||||
|
||||
state.DoString(@"
|
||||
function ScriptFunc (val1, val2)
|
||||
if val1 > val2 then
|
||||
return val1 + 1
|
||||
else
|
||||
return val2 - 1
|
||||
end
|
||||
end
|
||||
");
|
||||
var scriptFunc = state["ScriptFunc"] as LuaFunction;
|
||||
var res2 = (long)scriptFunc.Call(3, 9).First();
|
||||
Console.WriteLine($"risultato script: {res2}");
|
||||
// LuaFunction.Call will also return a array of objects, since a Lua function
|
||||
// can return multiple values
|
||||
|
||||
}
|
||||
else if (numTest == 99)
|
||||
{
|
||||
string luaPath = Path.Combine(Directory.GetCurrentDirectory(), "lua", "prova.lua");
|
||||
state.DoFile(luaPath);
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------
|
||||
* MAIN
|
||||
* --------------------------------*/
|
||||
|
||||
// Ciclo infinito x attesa chiusura con CTRL-C
|
||||
do
|
||||
{
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
Per installare il simulatore come servizio impiegare nssm come gestore servizio.
|
||||
-------------------------------
|
||||
- SDK
|
||||
-------------------------------
|
||||
|
||||
IN particolare installare con
|
||||
Va installato pacchetto dotnet core hosting (che installa anche i runtime di dotnetcore)
|
||||
choco install dotnet-windowshosting
|
||||
|
||||
nssm.exe install MP-MONO-SIM
|
||||
|
||||
(Se non bastasse bisogna installare prima SDK dotnet core choco install dotnet-6.0-sdk)
|
||||
|
||||
-------------------------------
|
||||
- SERVIZIO
|
||||
-------------------------------
|
||||
|
||||
Per installare il DECODER come servizio impiegare nssm come gestore servizio. In particolare installare con
|
||||
|
||||
nssm.exe install MP-MONO-SIM
|
||||
|
||||
@@ -10,17 +10,15 @@
|
||||
"Redis": "nkcredis.steamware.net:6379,DefaultDatabase=7,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false,password=nkc.password",
|
||||
"AuthConnection": "Server=localhost;port=3306;database=GWMS;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
|
||||
"DefaultConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
|
||||
//"AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Egalware_24068!;sslmode=None;",
|
||||
//"MP.MONO.Data": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;"
|
||||
"AdminConnection": "Server=10.74.82.230;port=3306;database=MAPO.MONO;user=steamware;pwd=Egalware_24068!;sslmode=None;",
|
||||
"MP.MONO.Data": "Server=10.74.82.230;port=3306;database=MAPO.MONO;user=MONO;pwd=MPMONO_secret_pwd;sslmode=None;"
|
||||
"AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Egalware_24068!;sslmode=None;",
|
||||
"MP.MONO.Data": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;"
|
||||
},
|
||||
"DbConfig": {
|
||||
"Server": "localhost",
|
||||
"Server": "10.74.82.230",
|
||||
"nKey": "MONO",
|
||||
"sKey": "M3T@n0-CH4"
|
||||
"sKey": "Calcium0xide-CaO"
|
||||
},
|
||||
"MachineId": 1,
|
||||
"MachineId": 1,
|
||||
"maxRecord": 15,
|
||||
"ExternalProviders": {
|
||||
"MailKit": {
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "Allarmi SIM",
|
||||
"tipoMem": "Boolean",
|
||||
"memAddr": "DB0.DBB0",
|
||||
"index": 10,
|
||||
"size": 2,
|
||||
"messages": [
|
||||
"Allarme 01",
|
||||
"Allarme 02",
|
||||
"Allarme 03",
|
||||
"Allarme 04",
|
||||
"Allarme 05",
|
||||
"Allarme 06",
|
||||
"Allarme 07",
|
||||
"Allarme 08"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -2,38 +2,42 @@
|
||||
Procedura decodifica Allarmi:
|
||||
|
||||
Variabili IN:
|
||||
- alarmList(array/tabella) (elenco allarmi gestiti a bitmap, se ## = silenziati)
|
||||
- currVal(INT) stato corrente
|
||||
- lastVal(INT) ultimo stato (oppure 0) - opzionale
|
||||
- muteMap(INT) valore BITMASK x silenziamento allarmi (xFF default = tutto attivo, ogni bit a 0 è silenziato) - opzionale
|
||||
- alarmList(array): elenco allarmi gestiti a bitmap, se ## = silenziati
|
||||
- currVal(INT): stato corrente
|
||||
- lastVal(INT): ultimo stato (oppure 0)
|
||||
- muteMask(INT): valore disableMask x silenziamento allarmi (xFF default = tutto attivo, ogni bit a 0 è silenziato) - opzionale
|
||||
|
||||
Variabili OUT:
|
||||
- alarmStatus (stirng con status finale risultato allarmi attivi)
|
||||
|
||||
Viene calcolato internamente la bitmask dall'elenco allarmi
|
||||
- alarmStatus: string con status finale risultato allarmi attivi
|
||||
-----------------------------------------------------]]
|
||||
|
||||
-- ricezione da codice tab status allarmi, attenzione da C# è 0 based, qui è 1 based --> fix costruzione tabella
|
||||
|
||||
-- variabile semaforo callMode (locali o remote da NLua)
|
||||
callMode = callMode or ''
|
||||
currVal = currVal or 0
|
||||
lastVal = lastVal or 0
|
||||
muteMap = muteMap or 0Xff
|
||||
bitMask = bitMask or 0x00
|
||||
valueChanged = false
|
||||
callMode = callMode or ''
|
||||
currVal = currVal or 0
|
||||
lastVal = lastVal or 0
|
||||
muteMask = muteMask or 0XFF
|
||||
disableMask = disableMask or 0xFF
|
||||
valueChanged = false
|
||||
prefix = prefix or 'AREA'
|
||||
|
||||
-- se non è da NLua inizializzo variabili accessorie
|
||||
local function checkInit()
|
||||
if(callMode ~= 'NLua') then
|
||||
alarmList = {"##Allarme01", "Allarme02", "Allarme03", "##Allarme04", "Allarme05", "Allarme06", "Allarme07", "##Allarme08"}
|
||||
numAlarm = #alarmList
|
||||
-- valori status da testare
|
||||
lastVal = 0
|
||||
currVal = 255
|
||||
end
|
||||
if (callMode ~= 'NLua') then
|
||||
alarmList = {"Allarme01", "Allarme02", "Allarme03", "Allarme04", "Allarme05", "Allarme06", "Allarme07",
|
||||
"Allarme08", "##Allarme09", "##Allarme10", "##Allarme11", "##Allarme12", "##Allarme13",
|
||||
"##Allarme14", "##Allarme15", "##Allarme16"}
|
||||
numAlarm = #alarmList
|
||||
-- valori status da testare
|
||||
lastVal = 0
|
||||
currVal = 1403
|
||||
disableMask = 0xFF
|
||||
muteMask = 0xFF3F
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function testBit(testVal, i)
|
||||
local answ=0
|
||||
local idx=2^(i-1)
|
||||
@@ -43,12 +47,12 @@ local function testBit(testVal, i)
|
||||
end
|
||||
|
||||
local function valMask(testVal)
|
||||
return testVal & bitMask
|
||||
return testVal & disableMask & muteMask
|
||||
end
|
||||
|
||||
local function setupTable()
|
||||
if numAlarm > 0 and alarmList[0] ~= nil then
|
||||
bitMask = 0
|
||||
--disableMask = 0
|
||||
for i = numAlarm,1, -1 do
|
||||
alarmListTable[i] = alarmList[i-1]
|
||||
end
|
||||
@@ -56,82 +60,73 @@ local function setupTable()
|
||||
alarmListTable = alarmList
|
||||
end
|
||||
end
|
||||
-- calcolo maschera...
|
||||
local function setupBitMask()
|
||||
for i = 1, numAlarm,1 do
|
||||
if(string.sub(alarmListTable[i],0,2)~='##') then
|
||||
bitMask = bitMask + 2^(i-1)
|
||||
end
|
||||
end
|
||||
bitMask = math.tointeger(bitMask)
|
||||
end
|
||||
|
||||
|
||||
-- confronto lastVal e currVal
|
||||
local function checkVariation()
|
||||
valueChanged = valMask(lastVal) ~= valMask(currVal)
|
||||
if(callMode ~= 'NLua') then
|
||||
if(valueChanged) then
|
||||
print('LastVal: '.. lastVal .. ' | CurrVal: '.. currVal .. ' || LastValMask: '.. valMask(lastVal) .. ' | CurrValMask: '.. valMask(currVal))
|
||||
else
|
||||
print('UNCHANGED | LastValMask: '.. valMask(lastVal) .. ' | CurrValMask: '.. valMask(currVal))
|
||||
valueChanged = valMask(lastVal) ~= valMask(currVal)
|
||||
if (callMode ~= 'NLua') then
|
||||
if (valueChanged) then
|
||||
print('LastVal: ' .. lastVal .. ' | CurrVal: ' .. currVal .. ' || LastValMask: ' .. valMask(lastVal) .. ' | CurrValMask: ' .. valMask(currVal))
|
||||
else
|
||||
print('UNCHANGED | LastValMask: ' .. valMask(lastVal) .. ' | CurrValMask: ' .. valMask(currVal))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- salva nuovo valore corrente (post mask)
|
||||
lastVal = valMask(currVal)
|
||||
|
||||
-- salva nuovo valore corrente (post mask)
|
||||
lastVal = valMask(currVal)
|
||||
end
|
||||
|
||||
|
||||
local function checkActiveAlarms()
|
||||
local hasAlarms = 0
|
||||
for i = 1, numAlarm do
|
||||
bTest = testBit(valMask(currVal),i)
|
||||
if(bTest) then
|
||||
alarmListActive[#alarmListActive+1]=string.format("%03d",i) ..' - '.. alarmListTable[i]
|
||||
hasAlarms = 1
|
||||
local hasAlarms = 0
|
||||
for i = 1, numAlarm do
|
||||
bTest = testBit(lastVal, i)
|
||||
--bTest = testBit(valMask(currVal), i)
|
||||
if (bTest) then
|
||||
alarmListActive[#alarmListActive + 1] = '[' .. prefix .. '.' .. string.format("%02d", i) .. '] ' .. alarmListTable[i]
|
||||
hasAlarms = 1
|
||||
end
|
||||
end
|
||||
end
|
||||
-- ordino allarmi...
|
||||
if(hasAlarms==1) then
|
||||
table.sort(alarmListActive)
|
||||
end
|
||||
end
|
||||
|
||||
local function calcStatusVar()
|
||||
for k, v in pairs(alarmListActive) do
|
||||
alarmStatus = alarmStatus .. v .. ' | '
|
||||
end
|
||||
|
||||
if(#alarmStatus == 0) then
|
||||
alarmStatus = 'All OK'
|
||||
else
|
||||
if(#alarmStatus > 3) then
|
||||
alarmStatus = string.sub(alarmStatus, 0, #alarmStatus -3)
|
||||
-- ordino allarmi...
|
||||
if (hasAlarms == 1) then
|
||||
table.sort(alarmListActive)
|
||||
end
|
||||
end
|
||||
local function calcStatusVar()
|
||||
for k, v in pairs(alarmListActive) do
|
||||
alarmStatus = alarmStatus .. v .. ' | '
|
||||
end
|
||||
|
||||
if (#alarmStatus == 0) then
|
||||
alarmStatus = 'All OK'
|
||||
else
|
||||
if (#alarmStatus > 3) then
|
||||
alarmStatus = string.sub(alarmStatus, 0, #alarmStatus - 3)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function displayTestInfo()
|
||||
if(callMode ~= 'NLua') then
|
||||
print('muteMap: '.. muteMap .. ' | bitMask: '.. bitMask)
|
||||
print(alarmStatus)
|
||||
--print('------------------------------')
|
||||
--for i,val in pairs(alarmListTable) do
|
||||
-- print("AL"..i.." | "..val)
|
||||
--end
|
||||
end
|
||||
if (callMode ~= 'NLua') then
|
||||
print('muteMask: ' .. muteMask .. ' | disableMask: ' .. disableMask)
|
||||
print(alarmStatus)
|
||||
-- print('------------------------------')
|
||||
-- for i,val in pairs(alarmListTable) do
|
||||
-- print("AL"..i.." | "..val)
|
||||
-- end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- MAIN
|
||||
alarmListTable = {}
|
||||
alarmListTable = {}
|
||||
alarmListActive = {}
|
||||
alarmStatus = ""
|
||||
alarmStatus = ""
|
||||
|
||||
checkInit()
|
||||
setupTable()
|
||||
setupBitMask()
|
||||
|
||||
checkVariation()
|
||||
checkActiveAlarms()
|
||||
calcStatusVar()
|
||||
calcStatusVar()
|
||||
displayTestInfo()
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
--[[---------------------------------------------------
|
||||
Procedura calcolo statistiche parametri:
|
||||
|
||||
Variabili IN:
|
||||
- vcFunct(string): tipo di processing da effettuare tra [POINT/AVG/MEDIAN/MIN/MAX]
|
||||
- valList(<double>): elenco VALORI double da processare
|
||||
|
||||
Variabili OUT:
|
||||
- calcVal(double): valore calcolato finale
|
||||
-----------------------------------------------------]]
|
||||
|
||||
|
||||
-- Per eventuale debug
|
||||
local ZBS = "c:/ZeroBraneStudio"
|
||||
if not package.path:find(ZBS,1,true) then
|
||||
package.path = ZBS .. "/lualibs/?/?.lua;" .. ZBS .. "/lualibs/?.lua;" .. package.path
|
||||
package.cpath = ZBS .. "/bin/?.dll;" .. ZBS .. "/bin/clibs53/?.dll;" .. package.cpath
|
||||
end
|
||||
|
||||
-- variabile semaforo callMode (locali o remote da NLua)
|
||||
callMode = callMode or ''
|
||||
vcFunct = vcFunct or ''
|
||||
valList = valList or {}
|
||||
calcVal = 0
|
||||
calcOk = false
|
||||
|
||||
-- se non è da NLua inizializzo variabili accessorie
|
||||
local function checkInit()
|
||||
if (callMode ~= 'NLua') then
|
||||
-- imposto valori test
|
||||
valList = { 4.0, 5.0, 3.0, 6.0, 1.0, 2.0 }
|
||||
vcFunct = 'MIN'
|
||||
--POINT AVG MEDIAN MIN MAX
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function doCalc()
|
||||
if(#valList>0) then
|
||||
-- verifica il tipo di richiesta
|
||||
if(vcFunct == 'AVG') then
|
||||
s = 0
|
||||
for i,v in ipairs(valList) do
|
||||
s = s + v
|
||||
end
|
||||
calcVal = s / #valList
|
||||
elseif(vcFunct == 'POINT') then
|
||||
calcVal = valList[#valList]
|
||||
elseif(vcFunct == 'MEDIAN') then
|
||||
table.sort(valList)
|
||||
calcVal = valList[#valList/2]
|
||||
elseif(vcFunct == 'MIN') then
|
||||
table.sort(valList)
|
||||
calcVal = valList[1]
|
||||
elseif(vcFunct == 'MAX') then
|
||||
table.sort(valList)
|
||||
calcVal = valList[#valList]
|
||||
end
|
||||
calcOk = true
|
||||
else
|
||||
calcVal = 0
|
||||
calcOk = false
|
||||
end
|
||||
end
|
||||
|
||||
local function displayTestInfo()
|
||||
if (callMode ~= 'NLua') then
|
||||
print('------------------------------')
|
||||
print('calcOk: ' .. tostring(calcOk))
|
||||
print('vcFunct: ' .. vcFunct)
|
||||
for i,val in pairs(valList) do
|
||||
print("v_"..i.." | "..val)
|
||||
end
|
||||
print('calcVal: ' .. calcVal)
|
||||
print('------------------------------')
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- MAIN
|
||||
|
||||
checkInit()
|
||||
doCalc()
|
||||
displayTestInfo()
|
||||
@@ -0,0 +1,82 @@
|
||||
--[[---------------------------------------------------
|
||||
Procedura calcolo statistiche parametri:
|
||||
|
||||
Variabili IN:
|
||||
- vcFunct(string): tipo di processing da effettuare tra [POINT/AVG/MEDIAN/MIN/MAX]
|
||||
- valList(<double>): elenco VALORI double da processare
|
||||
|
||||
Variabili OUT:
|
||||
- calcVal(double): valore calcolato finale
|
||||
-----------------------------------------------------]]
|
||||
|
||||
|
||||
-- Per eventuale debug
|
||||
local ZBS = "c:/ZeroBraneStudio"
|
||||
if not package.path:find(ZBS,1,true) then
|
||||
package.path = ZBS .. "/lualibs/?/?.lua;" .. ZBS .. "/lualibs/?.lua;" .. package.path
|
||||
package.cpath = ZBS .. "/bin/?.dll;" .. ZBS .. "/bin/clibs53/?.dll;" .. package.cpath
|
||||
end
|
||||
|
||||
-- variabile semaforo callMode (locali o remote da NLua)
|
||||
callMode = callMode or ''
|
||||
vcFunct = vcFunct or ''
|
||||
valList = valList or {}
|
||||
calcVal = 0
|
||||
calcOk = false
|
||||
|
||||
-- se non è da NLua inizializzo variabili accessorie
|
||||
local function checkInit()
|
||||
if (callMode ~= 'NLua') then
|
||||
-- imposto valori test
|
||||
valList = { 4.0, 5.0, 3.0, 6.0, 1.0, 2.0 }
|
||||
vcFunct = 'MAX'
|
||||
--POINT AVG MEDIAN MIN MAX
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function doCalc()
|
||||
if(#valList>0) then
|
||||
-- verifica il tipo di richiesta
|
||||
if(vcFunct == 'AVG') then
|
||||
s = 0
|
||||
for i,v in ipairs(valList) do
|
||||
s = s + v
|
||||
end
|
||||
calcVal = s / #valList
|
||||
elseif(vcFunct == 'POINT') then
|
||||
calcVal = valList[#valList]
|
||||
elseif(vcFunct == 'MEDIAN') then
|
||||
table.sort(valList)
|
||||
calcVal = valList[#valList/2]
|
||||
elseif(vcFunct == 'MIN') then
|
||||
calcVal = math.min(valList)
|
||||
elseif(vcFunct == 'MAX') then
|
||||
calcVal = math.max(valList)
|
||||
end
|
||||
calcOk = true
|
||||
else
|
||||
calcVal = 0
|
||||
calcOk = false
|
||||
end
|
||||
end
|
||||
|
||||
local function displayTestInfo()
|
||||
if (callMode ~= 'NLua') then
|
||||
print('------------------------------')
|
||||
print('calcOk: ' .. tostring(calcOk))
|
||||
print('vcFunct: ' .. vcFunct)
|
||||
for i,val in pairs(valList) do
|
||||
print("v_"..i.." | "..val)
|
||||
end
|
||||
print('calcVal: ' .. calcVal)
|
||||
print('------------------------------')
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- MAIN
|
||||
|
||||
checkInit()
|
||||
doCalc()
|
||||
displayTestInfo()
|
||||
@@ -17,8 +17,6 @@ namespace MP.MONO.Data
|
||||
{
|
||||
#region Private Fields
|
||||
|
||||
private IConfiguration _configuration;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Public Constructors
|
||||
@@ -27,14 +25,6 @@ namespace MP.MONO.Data
|
||||
{
|
||||
}
|
||||
|
||||
public AdminContext(IConfiguration configuration)
|
||||
{
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
public AdminContext(DbContextOptions<AdminContext> options) : base(options)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
@@ -43,7 +33,7 @@ namespace MP.MONO.Data
|
||||
/// <summary>
|
||||
/// User management
|
||||
/// </summary>
|
||||
public DbSet<UserPriv> UserList { get; set; }
|
||||
public DbSet<UserPriv> UserList { get; set; } = null!;
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
@@ -60,8 +50,6 @@ namespace MP.MONO.Data
|
||||
string connString = DbConfig.ADMIN_CONNECTION_STRING;
|
||||
if (!optionsBuilder.IsConfigured)
|
||||
{
|
||||
//connString = _configuration.GetConnectionString("GWMS.Data");
|
||||
//connString = "Server=localhost;port=3306;database=GWMS;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;";
|
||||
var serverVersion = ServerVersion.AutoDetect(connString);
|
||||
optionsBuilder.UseMySql(connString, serverVersion);
|
||||
}
|
||||
|
||||
@@ -1,32 +1,26 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using MP.MONO.Core;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using MP.MONO.Core.DTO;
|
||||
using MP.MONO.Data.DbModels;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MP.MONO.Data.Controllers
|
||||
{
|
||||
public class MpDbController : IDisposable
|
||||
{
|
||||
private static IConfiguration _configuration;
|
||||
#region Private Fields
|
||||
|
||||
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public MpDbController(IConfiguration configuration)
|
||||
{
|
||||
_configuration = configuration;
|
||||
}
|
||||
#endregion Private Fields
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Clear database context
|
||||
//Log.Info("Dispose di GWMSController");
|
||||
}
|
||||
#region Public Constructors
|
||||
|
||||
public MpDbController()
|
||||
{ }
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Recupero elenco allarmi (ultimi datop "skip")
|
||||
@@ -38,7 +32,7 @@ namespace MP.MONO.Data.Controllers
|
||||
public List<AlarmLogModel> AlarmLogGetFilt(int MachineId, int skipRec, int numRec)
|
||||
{
|
||||
List<AlarmLogModel> dbResult = new List<AlarmLogModel>();
|
||||
using (MapoMonoContext localDbCtx = new MapoMonoContext(_configuration))
|
||||
using (MapoMonoContext localDbCtx = new MapoMonoContext())
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -67,7 +61,7 @@ namespace MP.MONO.Data.Controllers
|
||||
public async Task<bool> AlarmLogInsert(AlarmLogModel newItem)
|
||||
{
|
||||
bool fatto = false;
|
||||
using (MapoMonoContext localDbCtx = new MapoMonoContext(_configuration))
|
||||
using (MapoMonoContext localDbCtx = new MapoMonoContext())
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -85,27 +79,150 @@ namespace MP.MONO.Data.Controllers
|
||||
return fatto;
|
||||
}
|
||||
|
||||
public ProductionDTO MachineGetProd()
|
||||
/// <summary>
|
||||
/// Inserimento di un record AlarmLog
|
||||
/// </summary>
|
||||
/// <param name="newItems">Lista Record da inserire (senza ID...)</param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> AlarmLogInsertMany(List<AlarmLogModel> newItems)
|
||||
{
|
||||
// !!!FIXME TODO... è fake...
|
||||
|
||||
Random rand = new Random();
|
||||
int stdCycle = 5;
|
||||
|
||||
ProductionDTO currMachDto = new ProductionDTO()
|
||||
bool fatto = false;
|
||||
using (MapoMonoContext localDbCtx = new MapoMonoContext())
|
||||
{
|
||||
Order = "ODL Test",
|
||||
ItemCode = "ART.0000123",
|
||||
ProgName = "P000012",
|
||||
CurrQty = DateTime.Now.Minute + rand.Next(1, 40),
|
||||
OrderQty = 100,
|
||||
CycleTimeMin = rand.NextDouble() * stdCycle,
|
||||
Message = "...simulated data..."
|
||||
};
|
||||
try
|
||||
{
|
||||
await localDbCtx
|
||||
.DbSetAlarmLog
|
||||
.AddRangeAsync(newItems);
|
||||
await localDbCtx.SaveChangesAsync();
|
||||
fatto = true;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione durante AlarmLogInsert{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return fatto;
|
||||
}
|
||||
|
||||
Task.Delay(400).Wait();
|
||||
/// <summary>
|
||||
/// Recupero record DataLog data condizione filtro
|
||||
/// </summary>
|
||||
/// <param name="MachineId"></param>
|
||||
/// <param name="FluxType"></param>
|
||||
/// <param name="skipRec"></param>
|
||||
/// <param name="numRec"></param>
|
||||
/// <returns></returns>
|
||||
public List<DataLogModel> DataLogGetFilt(int MachineId, string FluxType, int skipRec, int numRec)
|
||||
{
|
||||
List<DataLogModel> dbResult = new List<DataLogModel>();
|
||||
using (MapoMonoContext localDbCtx = new MapoMonoContext())
|
||||
{
|
||||
try
|
||||
{
|
||||
dbResult = localDbCtx
|
||||
.DbSetDataLog
|
||||
.Where(x => x.MachineId == MachineId && x.FluxType == FluxType)
|
||||
.Include(m => m.MachineNav)
|
||||
.OrderByDescending(x => x.DataLogId)
|
||||
.Skip(skipRec)
|
||||
.Take(numRec)
|
||||
.ToList();
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione durante DataLogGetFilt{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
return currMachDto;
|
||||
/// <summary>
|
||||
/// Inserimento di un SET di record DataLog (post aggregazione base VC)
|
||||
/// </summary>
|
||||
/// <param name="newItems">Lista Record da inserire (senza ID...)</param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> DataLogInsertMany(List<DataLogModel> newItems)
|
||||
{
|
||||
bool fatto = false;
|
||||
using (MapoMonoContext localDbCtx = new MapoMonoContext())
|
||||
{
|
||||
try
|
||||
{
|
||||
await localDbCtx
|
||||
.DbSetDataLog
|
||||
.AddRangeAsync(newItems);
|
||||
await localDbCtx.SaveChangesAsync();
|
||||
fatto = true;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione durante DataLogInsert{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return fatto;
|
||||
}
|
||||
/// <summary>
|
||||
/// Recupero record DataStAg (aggregati) data condizione filtro
|
||||
/// </summary>
|
||||
/// <param name="MachineId"></param>
|
||||
/// <param name="FluxType"></param>
|
||||
/// <param name="skipRec"></param>
|
||||
/// <param name="numRec"></param>
|
||||
/// <returns></returns>
|
||||
public List<DataStAgModel> DataStAgGetFilt(int MachineId, string FluxType, int skipRec, int numRec)
|
||||
{
|
||||
List<DataStAgModel> dbResult = new List<DataStAgModel>();
|
||||
using (MapoMonoContext localDbCtx = new MapoMonoContext())
|
||||
{
|
||||
try
|
||||
{
|
||||
dbResult = localDbCtx
|
||||
.DbSetDataStAg
|
||||
.Where(x => x.MachineId == MachineId && x.FluxType == FluxType)
|
||||
.Include(m => m.MachineNav)
|
||||
.OrderByDescending(x => x.DataStAgId)
|
||||
.Skip(skipRec)
|
||||
.Take(numRec)
|
||||
.ToList();
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione durante DataLogGetFilt{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return dbResult;
|
||||
}
|
||||
/// <summary>
|
||||
/// Inserimento di un record DataStAg (aggregati) - creati da ANALYZER che effettua compattazione
|
||||
/// </summary>
|
||||
/// <param name="newItem">Record da inserire (senza ID...)</param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> DataStAgInsert(DataStAgModel newItem)
|
||||
{
|
||||
bool fatto = false;
|
||||
using (MapoMonoContext localDbCtx = new MapoMonoContext())
|
||||
{
|
||||
try
|
||||
{
|
||||
localDbCtx
|
||||
.DbSetDataStAg
|
||||
.Add(newItem);
|
||||
await localDbCtx.SaveChangesAsync();
|
||||
fatto = true;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione durante DataStAgInsert{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return fatto;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Clear database context
|
||||
//Log.Info("Dispose di GWMSController");
|
||||
}
|
||||
|
||||
public List<DisplayDataDTO> MachineGetDisplay()
|
||||
@@ -115,58 +232,6 @@ namespace MP.MONO.Data.Controllers
|
||||
// !!!FIXME TODO... è fake...
|
||||
|
||||
Random rand = new Random();
|
||||
int stdCycle = 5;
|
||||
|
||||
#if false
|
||||
var currVal = rand.NextDouble();
|
||||
DisplayDataDTO displ01 = new DisplayDataDTO()
|
||||
{
|
||||
Order = 0,
|
||||
Title = "OEE",
|
||||
ValueNum = currVal,
|
||||
IsNumeric = true,
|
||||
Value = currVal.ToString("P1"),
|
||||
Type = "OEE-75-90"
|
||||
};
|
||||
answ.Add(displ01);
|
||||
|
||||
currVal = rand.NextDouble();
|
||||
DisplayDataDTO displ02 = new DisplayDataDTO()
|
||||
{
|
||||
Order = 0,
|
||||
Title = "Avail",
|
||||
ValueNum = currVal,
|
||||
IsNumeric = true,
|
||||
Value = currVal.ToString("P1"),
|
||||
Type = "AVAIL-50-80"
|
||||
};
|
||||
answ.Add(displ02);
|
||||
|
||||
currVal = rand.NextDouble();
|
||||
DisplayDataDTO displ03 = new DisplayDataDTO()
|
||||
{
|
||||
Order = 0,
|
||||
Title = "Order fulfill",
|
||||
ValueNum = currVal,
|
||||
IsNumeric = true,
|
||||
Value = currVal.ToString("P1"),
|
||||
Type = "ORDER"
|
||||
};
|
||||
answ.Add(displ03);
|
||||
|
||||
double minTCiclo = stdCycle * rand.NextDouble();
|
||||
TimeSpan durTCycle = TimeSpan.FromMinutes(minTCiclo);
|
||||
DisplayDataDTO displ04 = new DisplayDataDTO()
|
||||
{
|
||||
Order = 0,
|
||||
Title = "Cycle time",
|
||||
ValueNum = 0,
|
||||
IsNumeric = false,
|
||||
Value = $"{durTCycle.Hours:00}:{durTCycle.Minutes:00}:{durTCycle.Seconds:00}",
|
||||
Type = "TCycle"
|
||||
};
|
||||
answ.Add(displ04);
|
||||
#endif
|
||||
double currVal = 0;
|
||||
currVal = rand.Next(10, 120) * 100;
|
||||
DisplayDataDTO displ01 = new DisplayDataDTO()
|
||||
@@ -204,7 +269,7 @@ namespace MP.MONO.Data.Controllers
|
||||
};
|
||||
answ.Add(displ03);
|
||||
|
||||
currVal = rand.NextDouble() *5000;
|
||||
currVal = rand.NextDouble() * 5000;
|
||||
DisplayDataDTO displ04 = new DisplayDataDTO()
|
||||
{
|
||||
Order = 0,
|
||||
@@ -240,11 +305,34 @@ namespace MP.MONO.Data.Controllers
|
||||
};
|
||||
answ.Add(displ06);
|
||||
|
||||
|
||||
Task.Delay(200).Wait();
|
||||
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public ProductionDTO MachineGetProd()
|
||||
{
|
||||
// !!!FIXME TODO... è fake...
|
||||
|
||||
Random rand = new Random();
|
||||
int stdCycle = 5;
|
||||
|
||||
ProductionDTO currMachDto = new ProductionDTO()
|
||||
{
|
||||
Order = "ODL Test",
|
||||
ItemCode = "ART.0000123",
|
||||
ProgName = "P000012",
|
||||
CurrQty = DateTime.Now.Minute + rand.Next(1, 40),
|
||||
OrderQty = 100,
|
||||
CycleTimeMin = rand.NextDouble() * stdCycle,
|
||||
Message = "...simulated data..."
|
||||
};
|
||||
|
||||
Task.Delay(400).Wait();
|
||||
|
||||
return currMachDto;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
}
|
||||
@@ -18,8 +18,8 @@ namespace MP.MONO.Data.DbModels
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
public int Count { get; set; }
|
||||
public string TableName { get; set; }
|
||||
public int Count { get; set; } = 0;
|
||||
public string TableName { get; set; } = "";
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
|
||||
@@ -16,15 +16,15 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MailKit" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="6.0.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.3">
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="6.0.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.3">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -29,9 +29,9 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="NLog" Version="4.7.13" />
|
||||
<PackageReference Include="NLog" Version="4.7.14" />
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="6.0.1" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.2.88" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.5.43" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -15,16 +15,16 @@ namespace MP.MONO.Data
|
||||
|
||||
#region Public Properties
|
||||
|
||||
public string Host_Address { get; set; }
|
||||
public string Host_Address { get; set; } = "";
|
||||
|
||||
public string Host_Password { get; set; }
|
||||
public int Host_Port { get; set; }
|
||||
public string Host_Password { get; set; } = "";
|
||||
public int Host_Port { get; set; } = 0;
|
||||
|
||||
public SecureSocketOptions Host_SecureSocketOptions { get; set; }
|
||||
public string Host_Username { get; set; }
|
||||
public string Sender_EMail { get; set; }
|
||||
public SecureSocketOptions Host_SecureSocketOptions { get; set; } = SecureSocketOptions.None;
|
||||
public string Host_Username { get; set; } = "";
|
||||
public string Sender_EMail { get; set; } = "";
|
||||
|
||||
public string Sender_Name { get; set; }
|
||||
public string Sender_Name { get; set; } = "";
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
|
||||
@@ -13,37 +13,16 @@ namespace MP.MONO.Data
|
||||
|
||||
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private IConfiguration _configuration;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Public Constructors
|
||||
|
||||
|
||||
public MapoMonoContext(IConfiguration configuration)
|
||||
{
|
||||
_configuration = configuration;
|
||||
}
|
||||
public MapoMonoContext()
|
||||
{
|
||||
//connString = "server=10.74.82.230;port=3306;database=MAPO.MONO;uid=steamware;pwd=Egalware_24068!;sslmode=None;";
|
||||
}
|
||||
|
||||
#if false
|
||||
|
||||
public MapoMonoContext(DbContextOptions<MapoMonoContext> options) : base(options)
|
||||
{
|
||||
try
|
||||
{
|
||||
// se non ci fosse... crea o migra!
|
||||
Database.Migrate();
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error(exc, "Exception during context initialization 02");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
@@ -103,35 +82,6 @@ namespace MP.MONO.Data
|
||||
/// </summary>
|
||||
public virtual DbSet<AlarmLogModel> DbSetAlarmLog { get; set; } = null!;
|
||||
|
||||
#if false
|
||||
|
||||
public virtual DbSet<RebootLogModel> DbRebootLog { get; set; }
|
||||
|
||||
public virtual DbSet<AlarmLogModel> DbSetAlarmLog { get; set; }
|
||||
|
||||
|
||||
public virtual DbSet<ItemModel> DbSetItems { get; set; }
|
||||
|
||||
|
||||
public virtual DbSet<ListValModel> DbSetListVal { get; set; }
|
||||
|
||||
public virtual DbSet<OrderModel> DbSetOrders { get; set; }
|
||||
|
||||
public virtual DbSet<ParamSendModel> DbSetParamSend { get; set; }
|
||||
|
||||
public virtual DbSet<ParamSetModel> DbSetParamSet { get; set; }
|
||||
|
||||
|
||||
|
||||
public virtual DbSet<PlantStatusModel> DbSetPlantStatus { get; set; }
|
||||
|
||||
public virtual DbSet<WeekPlanModel> DbSetPlantSupplWeekPlan { get; set; }
|
||||
|
||||
public virtual DbSet<SupplierModel> DbSetSupplier { get; set; }
|
||||
|
||||
public virtual DbSet<TransporterModel> DbSetTransporter { get; set; }
|
||||
#endif
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Private Methods
|
||||
@@ -153,12 +103,6 @@ namespace MP.MONO.Data
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
// se vuoto sistemo...
|
||||
if (string.IsNullOrEmpty(connString))
|
||||
{
|
||||
connString = "server=10.74.82.230;port=3306;database=MAPO.MONO;uid=steamware;pwd=Egalware_24068!;sslmode=None;";
|
||||
//connString = "server=localhost;port=3306;database=MAPO.MONO;uid=root;pwd=Egalware_24068!;sslmode=None;";
|
||||
}
|
||||
if (!optionsBuilder.IsConfigured)
|
||||
{
|
||||
var serverVersion = ServerVersion.AutoDetect(connString);
|
||||
|
||||
+69
-25
@@ -1,4 +1,5 @@
|
||||
using StackExchange.Redis;
|
||||
using NLog;
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace MP.MONO.Data
|
||||
{
|
||||
@@ -6,40 +7,51 @@ namespace MP.MONO.Data
|
||||
{
|
||||
#region Private Fields
|
||||
|
||||
private bool enableLog = false;
|
||||
#if false
|
||||
private DateTime LastSend = DateTime.Now.AddMinutes(-5);
|
||||
#endif
|
||||
private IConnectionMultiplexer redis;
|
||||
private bool enableConsoleLog = false;
|
||||
private IDatabase? redisDb;
|
||||
|
||||
#endregion Private Fields
|
||||
#endregion Private Fields
|
||||
|
||||
#region Public Constructors
|
||||
#region Protected Fields
|
||||
|
||||
protected static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Public Constructors
|
||||
|
||||
public MessagePipe(IConnectionMultiplexer redisConn, string channelName, bool enableLog = false)
|
||||
{
|
||||
_channel = channelName;
|
||||
redis = redisConn;
|
||||
enableConsoleLog = enableLog;
|
||||
redisDb = redis.GetDatabase();
|
||||
this.enableLog = enableLog;
|
||||
// aggiungo sottoscrittore
|
||||
setupSubscriber();
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Events
|
||||
#region Public Events
|
||||
|
||||
public event EventHandler EA_NewMessage = delegate { };
|
||||
|
||||
#endregion Public Events
|
||||
#endregion Public Events
|
||||
|
||||
#region Private Properties
|
||||
#region Private Properties
|
||||
|
||||
/// <summary>
|
||||
/// Canale associato al gestore pipeline messaggi
|
||||
/// </summary>
|
||||
private string _channel { get; set; } = "";
|
||||
|
||||
#endregion Private Properties
|
||||
#endregion Private Properties
|
||||
|
||||
#region Private Methods
|
||||
#region Private Methods
|
||||
|
||||
private void setupSubscriber()
|
||||
{
|
||||
@@ -47,11 +59,8 @@ namespace MP.MONO.Data
|
||||
//Subscribe to the channel named messages
|
||||
sub.Subscribe(_channel, (channel, message) =>
|
||||
{
|
||||
// Se abilitato Output messaggio ricevuto
|
||||
if (enableConsoleLog)
|
||||
{
|
||||
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] {message}");
|
||||
}
|
||||
Log.Info($"[{DateTime.Now:HH:mm:ss}] {message}");
|
||||
// messaggio
|
||||
PubSubEventArgs mea = new PubSubEventArgs(message);
|
||||
// se qualcuno ascolta sollevo evento nuovo valore...
|
||||
if (EA_NewMessage != null)
|
||||
@@ -59,12 +68,42 @@ namespace MP.MONO.Data
|
||||
EA_NewMessage(this, mea);
|
||||
}
|
||||
});
|
||||
Console.WriteLine($"Subscribed {_channel}");
|
||||
Log.Info($"Subscribed {_channel}");
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
#endregion Private Methods
|
||||
|
||||
#region Public Methods
|
||||
#region Public Methods
|
||||
|
||||
public bool saveAndSendMessage(string memKey, string message)
|
||||
{
|
||||
bool answ = false;
|
||||
// invio notifica tramite il canale richiesto
|
||||
answ = sendMessage(message);
|
||||
#if false
|
||||
// effettuo la scrittura nell'area di memoria indicata SE passato intervallo minimo
|
||||
bool doSend = true;
|
||||
if (DateTime.Now.Subtract(LastSend).TotalSeconds < 60)
|
||||
{
|
||||
doSend = false;
|
||||
}
|
||||
|
||||
if (doSend && redisDb != null)
|
||||
#endif
|
||||
|
||||
if (redisDb != null)
|
||||
{
|
||||
redisDb.StringSetAsync(memKey, message);
|
||||
#if false
|
||||
LastSend = DateTime.Now;
|
||||
#endif
|
||||
if (enableLog)
|
||||
{
|
||||
Log.Info($"Redis Cache Key: {memKey}");
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invio messaggio sul canale
|
||||
@@ -74,30 +113,35 @@ namespace MP.MONO.Data
|
||||
public bool sendMessage(string newMess)
|
||||
{
|
||||
bool answ = false;
|
||||
|
||||
ISubscriber sub = redis.GetSubscriber();
|
||||
sub.Publish(_channel, newMess);
|
||||
return answ;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
#endregion Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Invio messaggio sul canale + salvataggio in cache REDIS
|
||||
/// </summary>
|
||||
/// <param name="memKey">Chiave REDIS x salvare valore</param>
|
||||
/// <param name="message"></param>
|
||||
}
|
||||
|
||||
public class PubSubEventArgs : EventArgs
|
||||
{
|
||||
#region Public Constructors
|
||||
#region Public Constructors
|
||||
|
||||
public PubSubEventArgs(string messaggio)
|
||||
{
|
||||
this.newMessage = messaggio;
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Properties
|
||||
#region Public Properties
|
||||
|
||||
public string newMessage { get; set; } = "";
|
||||
|
||||
#endregion Public Properties
|
||||
#endregion Public Properties
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ namespace MP.MONO.Data.Migrations
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "6.0.3")
|
||||
.HasAnnotation("ProductVersion", "6.0.2")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||
|
||||
modelBuilder.Entity("MP.MONO.Data.DbModels.AlarmLogModel", b =>
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace MP.MONO.Data.Migrations
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "6.0.3")
|
||||
.HasAnnotation("ProductVersion", "6.0.2")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||
|
||||
modelBuilder.Entity("MP.MONO.Data.DbModels.AlarmLogModel", b =>
|
||||
|
||||
@@ -15,23 +15,18 @@ namespace MP.MONO.Data
|
||||
// se non ci fosse... crea o migra!
|
||||
Database.Migrate();
|
||||
}
|
||||
catch (Exception exc)
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
|
||||
public UserIdentityDbContext(DbContextOptions<UserIdentityDbContext> options)
|
||||
: base(options)
|
||||
public UserIdentityDbContext(DbContextOptions<UserIdentityDbContext> options) : base(options)
|
||||
{
|
||||
#if false
|
||||
// se non ci fosse... crea!
|
||||
Database.EnsureCreated();
|
||||
#endif
|
||||
try
|
||||
{
|
||||
// se non ci fosse... crea o migra!
|
||||
Database.Migrate();
|
||||
}
|
||||
catch (Exception exc)
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
|
||||
@@ -39,7 +34,7 @@ namespace MP.MONO.Data
|
||||
|
||||
#region Public Properties
|
||||
|
||||
public DbSet<TableCount> DbSetCounts { get; set; }
|
||||
public DbSet<TableCount> DbSetCounts { get; set; } = null!;
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
|
||||
@@ -44,7 +44,13 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="conf\ConfMode.json">
|
||||
<None Update="conf\AlarmList.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="conf\ModeList.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="conf\ParamList.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="conf\SimActLog.json">
|
||||
@@ -62,7 +68,7 @@
|
||||
<None Update="conf\SimMaint.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="conf\ConfStatus.json">
|
||||
<None Update="conf\StatusList.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="conf\SimProd.json">
|
||||
|
||||
+95
-42
@@ -3,6 +3,7 @@ using MachineSim;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using MP.MONO.Core;
|
||||
using MP.MONO.Core.CONF;
|
||||
using MP.MONO.Core.DTO;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using StackExchange.Redis;
|
||||
@@ -19,7 +20,6 @@ var config = builder.Build();
|
||||
string lineSep = "---------------------------------------------";
|
||||
string redisConf = config.GetConnectionString("Redis");
|
||||
string confPath = Path.Combine(Directory.GetCurrentDirectory(), "conf");
|
||||
string alarmSimMode = config.GetValue<string>("AlarmSimMode");
|
||||
Logger Log = LogManager.GetCurrentClassLogger();
|
||||
Random rand = new Random();
|
||||
List<MachineStatus>? statusList = new List<MachineStatus>();
|
||||
@@ -42,12 +42,17 @@ logInfo("", true, true);
|
||||
logInfo("Running - press CTRL-C to stop SIM", false, true);
|
||||
logInfo("", false, true);
|
||||
|
||||
//Create a connection
|
||||
// Setup REDIS
|
||||
ConnectionMultiplexer.SetFeatureFlag("preventthreadtheft", true);
|
||||
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(redisConf);
|
||||
ISubscriber sub = redis.GetSubscriber();
|
||||
IDatabase? redisDb = redis.GetDatabase();
|
||||
|
||||
// preparo oggetti da configurare
|
||||
List<BaseAlarmConf>? alarmsConf = new List<BaseAlarmConf>();
|
||||
List<MachineMode>? machineModeConf = new List<MachineMode>();
|
||||
List<MachineStatus>? machineStatusConf = new List<MachineStatus>();
|
||||
|
||||
// salvo configurazioni in redis
|
||||
setupConf();
|
||||
var currSimGen = new Simulator(confPath, modeList.Count, statusList.Count);
|
||||
@@ -99,30 +104,77 @@ void checkFilePresent(string filePath)
|
||||
/// </summary>
|
||||
void setupConf()
|
||||
{
|
||||
#if false
|
||||
// leggo e salvo conf stati
|
||||
string fullPath = Path.Combine(confPath, "ConfStatus.json");
|
||||
string fullPath = Path.Combine(confPath, "StatusList.json");
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
List<MachineStatus>? statusList = JsonConvert.DeserializeObject<List<MachineStatus>>(rawData);
|
||||
machineStatusConf = JsonConvert.DeserializeObject<List<MachineStatus>>(rawData);
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.STATUS_CONF_KEY, JsonConvert.SerializeObject(statusList));
|
||||
redisDb.StringSetAsync(Constants.STATUS_CONF_KEY, JsonConvert.SerializeObject(machineStatusConf));
|
||||
}
|
||||
}
|
||||
|
||||
// leggo e salvo conf modi
|
||||
fullPath = Path.Combine(confPath, "ConfMode.json");
|
||||
fullPath = Path.Combine(confPath, "ModeList.json");
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
var localObj = JsonConvert.DeserializeObject<List<MachineMode>>(rawData);
|
||||
machineModeConf = JsonConvert.DeserializeObject<List<MachineMode>>(rawData);
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.MODE_CONF_KEY, JsonConvert.SerializeObject(localObj));
|
||||
redisDb.StringSetAsync(Constants.MODE_CONF_KEY, JsonConvert.SerializeObject(machineModeConf));
|
||||
}
|
||||
}
|
||||
|
||||
// leggo e salvo conf allarmi
|
||||
fullPath = Path.Combine(confPath, "AlarmList.json");
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
alarmsConf = JsonConvert.DeserializeObject<List<BaseAlarmConf>>(rawData);
|
||||
if (alarmsConf != null)
|
||||
{
|
||||
// sistemo allarmi
|
||||
foreach (var item in alarmsConf)
|
||||
{
|
||||
item.setupData();
|
||||
// loggo
|
||||
logInfo($"Decodifica aree alarmMap: {item.description} | {item.memAddr} x {item.size} byte | {item.messages.Count} messaggi allarme", true, true);
|
||||
}
|
||||
}
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.ALARMS_CONF_KEY, JsonConvert.SerializeObject(alarmsConf));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// leggo e salvo conf parametri
|
||||
fullPath = Path.Combine(confPath, "ParamList.json");
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
var localObj = JsonConvert.DeserializeObject<List<DisplayDataDTO>>(rawData);
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.PARAMS_CONF_KEY, JsonConvert.SerializeObject(localObj));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ConfigManager configManager = new ConfigManager(redisConf, confPath);
|
||||
alarmsConf = configManager.getAlarmsConf();
|
||||
machineModeConf= configManager.getMachineModeConf();
|
||||
machineStatusConf = configManager.getMachineStatusConf();
|
||||
_ = configManager.getParamsConf();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -154,7 +206,7 @@ void logError(string msg, bool log2file = true, bool log2console = false)
|
||||
}
|
||||
}
|
||||
|
||||
void saveAndSendMessage(string memKey, string value, string notifyChannel, string message)
|
||||
void saveAndSendMessage(string memKey, string notifyChannel, string message)
|
||||
{
|
||||
// effettuo la scrittura nell'area di memoria indicata SE passato intervallo minimo
|
||||
bool doSend = true;
|
||||
@@ -171,17 +223,16 @@ void saveAndSendMessage(string memKey, string value, string notifyChannel, strin
|
||||
}
|
||||
if (doSend)
|
||||
{
|
||||
redisDb.StringSetAsync(memKey, value);
|
||||
redisDb.StringSetAsync(memKey, message);
|
||||
LastSend[memKey] = DateTime.Now;
|
||||
logInfo($"Redis Cache Key: {memKey}");
|
||||
}
|
||||
//redisDb.SetAdd(memKey, value);
|
||||
|
||||
// invio notifica tramite il canale richiesto
|
||||
sub.Publish(notifyChannel, message);
|
||||
if (verboseLog)
|
||||
{
|
||||
logInfo($"[{notifyChannel}] key: {memKey} | val: {value} | message: {message}");
|
||||
logInfo($"[{notifyChannel}] key: {memKey} | val/message: {message}");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -225,33 +276,26 @@ void saveAndSendMessage(string memKey, string value, string notifyChannel, strin
|
||||
|
||||
void simAlarms()
|
||||
{
|
||||
int minPeriod = 5000;
|
||||
int maxPeriod = 10000;
|
||||
int minPeriod = 3000;
|
||||
int maxPeriod = 9000;
|
||||
int percAllarmi = config.GetValue<int>("percAllarmi");
|
||||
|
||||
do
|
||||
{
|
||||
List<int> currAlarmsVal = new List<int>();
|
||||
List<string> activeAlarms = new List<string>();
|
||||
//int alarmCode = rand.Next(0, 255);
|
||||
int alarmCode = rand.Next(0, 160);
|
||||
// se >= 128 --> 0 (no alarm)
|
||||
alarmCode = alarmCode <= 127 ? alarmCode : 0;
|
||||
currAlarmsVal.Add(alarmCode);
|
||||
string rawDataVal = JsonConvert.SerializeObject(currAlarmsVal);
|
||||
saveAndSendMessage(Constants.ALARM_ACT_KEY, rawDataVal, Constants.ALARM_ACT_VAL, rawDataVal);
|
||||
if (alarmSimMode == "all")
|
||||
Dictionary<string, uint> currAlarmsVal = new Dictionary<string, uint>();
|
||||
uint alarmCode = 0;
|
||||
bool hasAlarm;
|
||||
// ciclo x numero banchi da config...
|
||||
foreach (var item in alarmsConf)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if ((alarmCode & (1 << i)) != 0)
|
||||
{
|
||||
activeAlarms.Add($"Alarm {i:000}");
|
||||
}
|
||||
}
|
||||
string rawData = JsonConvert.SerializeObject(activeAlarms);
|
||||
// decodifico allarme e lo trasformo in List<String> + List<int> di allarmi attivi...
|
||||
saveAndSendMessage(Constants.ALARM_CURR_KEY, rawData, Constants.ALARM_M_QUEUE, rawData);
|
||||
// limito allarmi al percAllarmi/100 dei casi
|
||||
hasAlarm = rand.Next(0, 100) <= percAllarmi;
|
||||
// allarme libero SE in condizione allarme
|
||||
alarmCode = hasAlarm ? (uint)rand.Next(0, 65535) : 0;
|
||||
currAlarmsVal.Add(item.memAddr, alarmCode);
|
||||
}
|
||||
string rawDataVal = JsonConvert.SerializeObject(currAlarmsVal);
|
||||
saveAndSendMessage(Constants.ALARM_ACT_KEY, Constants.ALARM_ACT_QUEUE, rawDataVal);
|
||||
// attesa random
|
||||
Thread.Sleep(rand.Next(minPeriod, maxPeriod));
|
||||
} while (true);
|
||||
@@ -264,9 +308,18 @@ void simParameters()
|
||||
|
||||
do
|
||||
{
|
||||
#if false
|
||||
// da eliminare quando gestita da decoder
|
||||
var newParams = currSimGen.getParameters();
|
||||
string rawData = JsonConvert.SerializeObject(newParams);
|
||||
saveAndSendMessage(Constants.PARAMS_CURR_KEY, rawData, Constants.PARAMS_M_QUEUE, rawData);
|
||||
saveAndSendMessage(Constants.PARAMS_CURR_KEY, Constants.PARAMS_M_QUEUE, rawData);
|
||||
#endif
|
||||
|
||||
// gestione SIM dictionary
|
||||
var paramDict = currSimGen.getParamsVal();
|
||||
string rawData = JsonConvert.SerializeObject(paramDict);
|
||||
saveAndSendMessage(Constants.PARAMS_ACT_KEY, Constants.PARAMS_ACT_QUEUE, rawData);
|
||||
|
||||
// attesa random
|
||||
Thread.Sleep(rand.Next(minPeriod, maxPeriod));
|
||||
} while (true);
|
||||
@@ -282,7 +335,7 @@ void simStatus()
|
||||
// recupero uno stato simulato
|
||||
var newStatus = currSimGen.getStatus();
|
||||
string rawData = JsonConvert.SerializeObject(newStatus);
|
||||
saveAndSendMessage(Constants.STATUS_CURR_KEY, rawData, Constants.STATUS_M_QUEUE, rawData);
|
||||
saveAndSendMessage(Constants.STATUS_CURR_KEY, Constants.STATUS_M_QUEUE, rawData);
|
||||
|
||||
// attesa random
|
||||
Thread.Sleep(rand.Next(minPeriod, maxPeriod));
|
||||
@@ -299,7 +352,7 @@ void simProd()
|
||||
// recupero uno stato simulato
|
||||
var newStatus = currSimGen.getProd();
|
||||
string rawData = JsonConvert.SerializeObject(newStatus);
|
||||
saveAndSendMessage(Constants.PROD_CURR_KEY, rawData, Constants.PROD_M_QUEUE, rawData);
|
||||
saveAndSendMessage(Constants.PROD_CURR_KEY, Constants.PROD_M_QUEUE, rawData);
|
||||
|
||||
// attesa random
|
||||
Thread.Sleep(rand.Next(minPeriod, maxPeriod));
|
||||
@@ -316,7 +369,7 @@ void simMachStat()
|
||||
// recupero uno stato simulato
|
||||
var newVal = currSimGen.getProdStats();
|
||||
string rawData = JsonConvert.SerializeObject(newVal);
|
||||
saveAndSendMessage(Constants.MACH_STATS_CURR_KEY, rawData, Constants.MACH_STATS_M_QUEUE, rawData);
|
||||
saveAndSendMessage(Constants.MACH_STATS_CURR_KEY, Constants.MACH_STATS_M_QUEUE, rawData);
|
||||
|
||||
// attesa random
|
||||
Thread.Sleep(rand.Next(minPeriod, maxPeriod));
|
||||
@@ -333,7 +386,7 @@ void simMaint()
|
||||
// recupero uno stato simulato
|
||||
var newVal = currSimGen.getMaint();
|
||||
string rawData = JsonConvert.SerializeObject(newVal);
|
||||
saveAndSendMessage(Constants.MAINT_STATS_CURR_KEY, rawData, Constants.MAINT_STATS_M_QUEUE, rawData);
|
||||
saveAndSendMessage(Constants.MAINT_STATS_CURR_KEY, Constants.MAINT_STATS_M_QUEUE, rawData);
|
||||
|
||||
// attesa random
|
||||
Thread.Sleep(rand.Next(minPeriod, maxPeriod));
|
||||
@@ -350,7 +403,7 @@ void simTools()
|
||||
// recupero uno stato simulato
|
||||
var newVal = currSimGen.getTools();
|
||||
string rawData = JsonConvert.SerializeObject(newVal);
|
||||
saveAndSendMessage(Constants.TOOLS_CURR_KEY, rawData, Constants.TOOLS_M_QUEUE, rawData);
|
||||
saveAndSendMessage(Constants.TOOLS_CURR_KEY, Constants.TOOLS_M_QUEUE, rawData);
|
||||
|
||||
// attesa random
|
||||
Thread.Sleep(rand.Next(minPeriod, maxPeriod));
|
||||
@@ -367,7 +420,7 @@ void simEvents()
|
||||
// recupero uno stato simulato
|
||||
var newVal = currSimGen.getEvents();
|
||||
string rawData = JsonConvert.SerializeObject(newVal);
|
||||
saveAndSendMessage(Constants.EVENT_LOG_CURR_KEY, rawData, Constants.EVENT_LOG_M_QUEUE, rawData);
|
||||
saveAndSendMessage(Constants.EVENT_LOG_CURR_KEY, Constants.EVENT_LOG_M_QUEUE, rawData);
|
||||
|
||||
// attesa random
|
||||
Thread.Sleep(rand.Next(minPeriod, maxPeriod));
|
||||
@@ -384,7 +437,7 @@ void simActivityLog()
|
||||
// recupero uno stato simulato
|
||||
var newVal = currSimGen.getActLog();
|
||||
string rawData = JsonConvert.SerializeObject(newVal);
|
||||
saveAndSendMessage(Constants.ACT_LOG_CURR_KEY, rawData, Constants.ACT_LOG_M_QUEUE, rawData);
|
||||
saveAndSendMessage(Constants.ACT_LOG_CURR_KEY, Constants.ACT_LOG_M_QUEUE, rawData);
|
||||
|
||||
// attesa random
|
||||
Thread.Sleep(rand.Next(minPeriod, maxPeriod));
|
||||
|
||||
@@ -198,6 +198,13 @@ namespace MachineSim
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
public Dictionary<string, double> getParamsVal()
|
||||
{
|
||||
Dictionary<string, double> answ = new Dictionary<string, double>();
|
||||
// genero a partire dall'elenco configurato da simulare...
|
||||
answ = currSimPar.ToDictionary(i => i.Title, i => simNext(i.ValueNum, i.MinVal, i.MaxVal, i.SimMean, i.SimStd));
|
||||
return answ;
|
||||
}
|
||||
|
||||
public ProductionDTO getProd()
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"ConnectionStrings": {
|
||||
"Redis": "nkcredis.steamware.net:6379,DefaultDatabase=7,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false,password=nkc.password",
|
||||
"Redis": "nkcredis.steamware.net:6379,DefaultDatabase=7,connectTimeout=30000,syncTimeout=30000,asyncTimeout=30000,abortConnect=false,ssl=false,password=nkc.password",
|
||||
"AuthConnection": "Server=localhost;port=3306;database=GWMS;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
|
||||
"DefaultConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
|
||||
"AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Egalware_24068!;sslmode=None;",
|
||||
@@ -18,8 +18,8 @@
|
||||
"nKey": "MONO",
|
||||
"sKey": "M3T@n0-CH4"
|
||||
},
|
||||
"AlarmSimMode": "numeric",
|
||||
"maxRecord": 15,
|
||||
"percAllarmi": 40,
|
||||
"ExternalProviders": {
|
||||
"MailKit": {
|
||||
"SMTP": {
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
[
|
||||
{
|
||||
"description": "General Alarm",
|
||||
"tipoMem": "DInt",
|
||||
"memAddr": "40901",
|
||||
"index": 901,
|
||||
"size": 2,
|
||||
"messages": [
|
||||
"Alarm 001",
|
||||
"Alarm 002",
|
||||
"Alarm 003",
|
||||
"Alarm 004",
|
||||
"Alarm 005",
|
||||
"Alarm 006",
|
||||
"Alarm 007",
|
||||
"Alarm 008",
|
||||
"##Alarm 009",
|
||||
"##Alarm 010",
|
||||
"##Alarm 011",
|
||||
"##Alarm 012",
|
||||
"##Alarm 013",
|
||||
"##Alarm 014",
|
||||
"##Alarm 015",
|
||||
"##Alarm 016"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Secondary Alarm",
|
||||
"tipoMem": "DInt",
|
||||
"memAddr": "40907",
|
||||
"index": 907,
|
||||
"size": 2,
|
||||
"messages": [
|
||||
"Warning 001",
|
||||
"Warning 002",
|
||||
"Warning 003",
|
||||
"Warning 004",
|
||||
"Warning 005",
|
||||
"Warning 006",
|
||||
"##Warning 007",
|
||||
"##Warning 008",
|
||||
"##Warning 009",
|
||||
"Warning 010",
|
||||
"Warning 011",
|
||||
"Warning 012",
|
||||
"Warning 013",
|
||||
"Warning 014",
|
||||
"Warning 015",
|
||||
"Warning 016"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,125 @@
|
||||
[
|
||||
{
|
||||
"Order": 3,
|
||||
"Type": "SPEED-5000-10000",
|
||||
"Title": "SPEED",
|
||||
"Value": "4000",
|
||||
"ValueNum": 4000,
|
||||
"MinVal": 1000,
|
||||
"MaxVal": 10000,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-gauge-high",
|
||||
"SamplePeriod": 180,
|
||||
"VcFunc": "MEDIAN"
|
||||
},
|
||||
{
|
||||
"Order": 2,
|
||||
"Type": "FEED-3000-5000",
|
||||
"Title": "FEED",
|
||||
"Value": "2500",
|
||||
"ValueNum": 2500,
|
||||
"MinVal": 1000,
|
||||
"MaxVal": 5000,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-gauge-high",
|
||||
"SamplePeriod": 180,
|
||||
"VcFunc": "MEDIAN"
|
||||
},
|
||||
{
|
||||
"Order": 1,
|
||||
"Type": "LOAD",
|
||||
"Title": "SPINDLE LOAD",
|
||||
"Value": "30",
|
||||
"ValueNum": 30,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt",
|
||||
"SamplePeriod": 180,
|
||||
"VcFunc": "MEDIAN"
|
||||
},
|
||||
{
|
||||
"Order": 4,
|
||||
"Type": "POS",
|
||||
"Title": "X POS",
|
||||
"Value": "1500",
|
||||
"ValueNum": 1500,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 5000,
|
||||
"DisplFormat": "N2",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"CssIcon": "fa-solid fa-ruler-horizontal",
|
||||
"SamplePeriod": 180,
|
||||
"VcFunc": "MEDIAN"
|
||||
},
|
||||
{
|
||||
"Order": 5,
|
||||
"Type": "POS",
|
||||
"Title": "Y POS",
|
||||
"Value": "5000",
|
||||
"ValueNum": 5000,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10000,
|
||||
"DisplFormat": "N2",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"CssIcon": "fa-solid fa-ruler-horizontal",
|
||||
"SamplePeriod": 180,
|
||||
"VcFunc": "MEDIAN"
|
||||
},
|
||||
{
|
||||
"Order": 6,
|
||||
"Type": "POS",
|
||||
"Title": "Z POS",
|
||||
"Value": "-1500",
|
||||
"ValueNum": -1500,
|
||||
"MinVal": -3000,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "N2",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"CssIcon": "fa-solid fa-ruler-horizontal",
|
||||
"SamplePeriod": 180,
|
||||
"VcFunc": "MEDIAN"
|
||||
},
|
||||
{
|
||||
"Order": 7,
|
||||
"Type": "POS",
|
||||
"Title": "A POS",
|
||||
"Value": "150",
|
||||
"ValueNum": 150,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 360,
|
||||
"DisplFormat": "N3",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"CssIcon": "fa-solid fa-rotate-right",
|
||||
"SamplePeriod": 180,
|
||||
"VcFunc": "MEDIAN"
|
||||
},
|
||||
{
|
||||
"Order": 8,
|
||||
"Type": "POS",
|
||||
"Title": "B POS",
|
||||
"Value": "150",
|
||||
"ValueNum": 150,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 360,
|
||||
"DisplFormat": "N3",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"CssIcon": "fa-solid fa-rotate-right",
|
||||
"SamplePeriod": 180,
|
||||
"VcFunc": "MEDIAN"
|
||||
}
|
||||
]
|
||||
@@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
"Order": 0,
|
||||
"Order": 3,
|
||||
"Type": "SPEED-5000-10000",
|
||||
"Title": "SPEED",
|
||||
"Value": "4000",
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
},
|
||||
{
|
||||
"Order": 0,
|
||||
"Order": 2,
|
||||
"Type": "FEED-3000-5000",
|
||||
"Title": "FEED",
|
||||
"Value": "2500",
|
||||
@@ -33,7 +33,7 @@
|
||||
"CssIcon": "fa-solid fa-gauge-high"
|
||||
},
|
||||
{
|
||||
"Order": 0,
|
||||
"Order": 1,
|
||||
"Type": "LOAD",
|
||||
"Title": "SPINDLE LOAD",
|
||||
"Value": "30",
|
||||
@@ -49,7 +49,7 @@
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 0,
|
||||
"Order": 4,
|
||||
"Type": "POS",
|
||||
"Title": "X POS",
|
||||
"Value": "1500",
|
||||
@@ -64,7 +64,7 @@
|
||||
"CssIcon": "fa-solid fa-ruler-horizontal"
|
||||
},
|
||||
{
|
||||
"Order": 0,
|
||||
"Order": 5,
|
||||
"Type": "POS",
|
||||
"Title": "Y POS",
|
||||
"Value": "5000",
|
||||
@@ -79,7 +79,7 @@
|
||||
"CssIcon": "fa-solid fa-ruler-horizontal"
|
||||
},
|
||||
{
|
||||
"Order": 0,
|
||||
"Order": 6,
|
||||
"Type": "POS",
|
||||
"Title": "Z POS",
|
||||
"Value": "-1500",
|
||||
@@ -94,7 +94,7 @@
|
||||
"CssIcon": "fa-solid fa-ruler-horizontal"
|
||||
},
|
||||
{
|
||||
"Order": 0,
|
||||
"Order": 7,
|
||||
"Type": "POS",
|
||||
"Title": "A POS",
|
||||
"Value": "150",
|
||||
@@ -107,5 +107,20 @@
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"CssIcon": "fa-solid fa-rotate-right"
|
||||
},
|
||||
{
|
||||
"Order": 8,
|
||||
"Type": "POS",
|
||||
"Title": "B POS",
|
||||
"Value": "150",
|
||||
"ValueNum": 150,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 360,
|
||||
"SimMean": 5,
|
||||
"SimStd": 2,
|
||||
"DisplFormat": "N3",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"CssIcon": "fa-solid fa-rotate-right"
|
||||
}
|
||||
]
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
@if (ListRecords != null && ListRecords.Count > 0)
|
||||
{
|
||||
<ul class="list-group">
|
||||
@* <ul class="list-group">
|
||||
@foreach (var item in ListRecords)
|
||||
{
|
||||
<li class="list-group-item list-group-item-action">
|
||||
@@ -18,7 +18,8 @@
|
||||
</div>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</ul>*@
|
||||
<DetailOverview></DetailOverview>
|
||||
|
||||
}
|
||||
else
|
||||
|
||||
@@ -23,6 +23,9 @@ namespace MP.MONO.UI.Components
|
||||
{
|
||||
public partial class AlarmsOverview
|
||||
{
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<int> messageReceived { get; set; }
|
||||
private List<DisplayDataDTO>? ListRecords { get; set; } = new List<DisplayDataDTO>();
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
@@ -39,13 +42,17 @@ namespace MP.MONO.UI.Components
|
||||
try
|
||||
{
|
||||
var alarmList = JsonConvert.DeserializeObject<List<string>>(currArgs.newMessage);
|
||||
ListRecords = alarmList.Select(x => new DisplayDataDTO()
|
||||
if (alarmList != null)
|
||||
{
|
||||
IsNumeric = false,
|
||||
Title = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss}",
|
||||
Value = x,
|
||||
Order = ListRecords == null ? 0 : ListRecords.Count
|
||||
}).ToList();
|
||||
ListRecords = alarmList.Select(x => new DisplayDataDTO()
|
||||
{
|
||||
IsNumeric = false,
|
||||
Title = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss}",
|
||||
Value = x,
|
||||
Order = ListRecords == null ? 0 : ListRecords.Count
|
||||
}).ToList();
|
||||
messageReceived.InvokeAsync(alarmList.Count);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
@using MP.MONO.Data
|
||||
@using MP.MONO.UI.Components
|
||||
@using MP.MONO.Core.DTO
|
||||
@using MP.MONO.UI.Data
|
||||
|
||||
@inject IJSRuntime JSRuntime
|
||||
@inject CurrentDataService MMDataService
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header bg-secondary text-light">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="p-2">
|
||||
<h5>Alarm Messages Setup</h5>
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<button class="btn btn-sm btn-primary" @onclick="() => resetAlarmSetup()" title="Reset Alarm Config"><i class="fa-solid fa-gear"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-3">
|
||||
@if (ListRecords == null)
|
||||
{
|
||||
<LoadingData></LoadingData>
|
||||
}
|
||||
else if (ListRecords.Count == 0)
|
||||
{
|
||||
<div class="alert alert-warning text-center h3">No record found</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<b>Alarm Bank</b>
|
||||
<ul class="list-group">
|
||||
@foreach (var item in ListRecords)
|
||||
{
|
||||
<li class="list-group-item list-group-item-action @cssActive(item.memAddr)" @onclick="() => raiseSelect(item)">
|
||||
@item.description
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
</div>
|
||||
<div class="col-9">
|
||||
@if (AlarmMap == null)
|
||||
{
|
||||
<div class="alert alert-warning text-center h3">Select Bank First</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-12 mb-2">
|
||||
<ul class="list-group">
|
||||
@foreach (var item in AlarmMap.messagesMap)
|
||||
{
|
||||
<li class="list-group-item list-group-item-action @cssSilenced(item.Key)" @onclick="() => toggleMute(item.Key)">
|
||||
<div>@item.Value</div>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<i>click to mute/unmute alarms</i>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="btn-group btn-group-sm">
|
||||
<button type="button" class="btn btn-primary">Alarm Enabled</button>
|
||||
<button type="button" class="btn btn-secondary">Alarm Disabled</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using MP.MONO.Core.CONF;
|
||||
|
||||
namespace MP.MONO.UI.Components
|
||||
{
|
||||
public partial class AlarmsSetup
|
||||
{
|
||||
#region Protected Fields
|
||||
|
||||
|
||||
protected List<BaseAlarmConf>? ListRecords = null;
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
protected BaseAlarmConf? AlarmMap { get; set; } = null;
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
protected string cssActive(string memAddr)
|
||||
{
|
||||
string answ = "";
|
||||
if (AlarmMap != null)
|
||||
{
|
||||
answ = AlarmMap.memAddr.Equals(memAddr) ? "bg-dark text-light" : "";
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
protected string cssSilenced(int messIndex)
|
||||
{
|
||||
string answ = "";
|
||||
if (AlarmMap != null)
|
||||
{
|
||||
answ = AlarmMap.isSilenced(messIndex) ? "bg-secondary text-light" : "bg-primary text-light";
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
protected async Task raiseSelect(BaseAlarmConf selBank)
|
||||
{
|
||||
AlarmMap = selBank;
|
||||
await Task.Delay(1);
|
||||
}
|
||||
|
||||
protected async Task ReloadData()
|
||||
{
|
||||
ListRecords = null;
|
||||
await Task.Delay(1);
|
||||
ListRecords = await MMDataService.getAlarmSetup();
|
||||
await Task.Delay(1);
|
||||
}
|
||||
|
||||
protected async Task resetAlarmSetup()
|
||||
|
||||
{
|
||||
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Reset Alarm Config: you are going to reset actual alarm configuration. Are you sure to proceed?"))
|
||||
return;
|
||||
await Task.Delay(1);
|
||||
var baseConf = await MMDataService.getAlarmConfig();
|
||||
await MMDataService.setAlarmSetup(baseConf);
|
||||
AlarmMap = null;
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
protected async Task toggleMute(int alarmIndex)
|
||||
{
|
||||
// base 1 --> base 0
|
||||
alarmIndex--;
|
||||
int bank = alarmIndex / 16;
|
||||
// calcolo inverso del valore richiesto
|
||||
if (ListRecords != null && AlarmMap != null)
|
||||
{
|
||||
AlarmMap.silenceMask[bank] = AlarmMap.silenceMask[bank] ^ (uint)(1 << alarmIndex);
|
||||
// sostituisco...
|
||||
var currObj = ListRecords.FirstOrDefault(x => x.memAddr == AlarmMap.memAddr);
|
||||
if (currObj != null)
|
||||
{
|
||||
currObj.silenceMask = AlarmMap.silenceMask;
|
||||
// salvo su redis...
|
||||
await MMDataService.setAlarmSetup(ListRecords);
|
||||
}
|
||||
}
|
||||
await Task.Delay(1);
|
||||
await ReloadData();
|
||||
await Task.Delay(1);
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
}
|
||||
}
|
||||
@@ -1,40 +1,20 @@
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-9 text-left">
|
||||
<div class="col-12 col-lg-8 text-left">
|
||||
<div class="row">
|
||||
<div class="col-12 small">
|
||||
@if (totalCount > 0)
|
||||
{
|
||||
<Pagination Class="mb-0">
|
||||
<PaginationItem>
|
||||
<PaginationLink Clicked="@HandlePaginationItemClick" Page="1">
|
||||
<i class="fas fa-angle-double-left"></i>
|
||||
</PaginationLink>
|
||||
</PaginationItem>
|
||||
<PaginationItem>
|
||||
<PaginationLink Clicked="@HandlePaginationItemClick" Page="@prevBlock.ToString()">
|
||||
<span aria-hidden="true"><i class="fas fa-angle-left"></i></span>
|
||||
</PaginationLink>
|
||||
</PaginationItem>
|
||||
<ul class="pagination pagination-sm mb-1">
|
||||
<li class="page-item"><button class="page-link" @onclick="() => PaginationItemClick(1)"><i class="fas fa-angle-double-left"></i></button></li>
|
||||
<li class="page-item"><button class="page-link" @onclick="() => PaginationItemClick(prevBlock)"><i class="fas fa-angle-left"></i></button></li>
|
||||
@for (int i = @startPage; i <= endPage; ++i)
|
||||
{
|
||||
var pageNum = i;
|
||||
<PaginationItem Active="@(currPage.Equals(pageNum))">
|
||||
<PaginationLink Clicked="@HandlePaginationItemClick" Page="@pageNum.ToString()">
|
||||
@pageNum
|
||||
</PaginationLink>
|
||||
</PaginationItem>
|
||||
<li class="page-item @cssActive(pageNum)"><button class="page-link" @onclick="() => PaginationItemClick(pageNum)">@pageNum</button></li>
|
||||
}
|
||||
<PaginationItem>
|
||||
<PaginationLink Clicked="@HandlePaginationItemClick" Page="@nextBlock.ToString()">
|
||||
<i class="fas fa-angle-right"></i>
|
||||
</PaginationLink>
|
||||
</PaginationItem>
|
||||
<PaginationItem>
|
||||
<PaginationLink Clicked="@HandlePaginationItemClick" Page="@LastPage.ToString()">
|
||||
<i class="fas fa-angle-double-right"></i>
|
||||
</PaginationLink>
|
||||
</PaginationItem>
|
||||
</Pagination>
|
||||
<li class="page-item"><button class="page-link" @onclick="() => PaginationItemClick(nextBlock)"><i class="fas fa-angle-right"></i></button></li>
|
||||
<li class="page-item"><button class="page-link" @onclick="() => PaginationItemClick(LastPage)"><i class="fas fa-angle-double-right"></i></button></li>
|
||||
</ul>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -42,26 +22,26 @@
|
||||
<div class="col-12 small">
|
||||
@if (showLoading)
|
||||
{
|
||||
<Progress>
|
||||
<ProgressBar Value="@percLoading" Striped="true" Animated="true" />
|
||||
</Progress>
|
||||
<div class="progress" style="height: 10px;">
|
||||
<div class="progress-bar progress-bar-striped progress-bar-animated" style="width:@percLoading%;"></div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-3">
|
||||
<div class="col-12 col-lg-4">
|
||||
<div class="d-flex">
|
||||
<div class="p-1 flex-fill text-right">
|
||||
<div class="p-1 flex-fill">
|
||||
@if (!showLoading)
|
||||
{
|
||||
<span>@totalCount records</span>
|
||||
}
|
||||
</div>
|
||||
<div class="p-1 flex-fill text-right small">
|
||||
<div class="p-1 small">
|
||||
@if (totalCount > 0)
|
||||
{
|
||||
<div class="input-group input-group-sm">
|
||||
<select @bind="@PageSize" class="form-control form-control-sm">
|
||||
<select @bind="@PageSize" class="form-select form-select-sm text-end">
|
||||
<option value="5">5</option>
|
||||
<option value="10">10</option>
|
||||
<option value="25">25</option>
|
||||
@@ -74,4 +54,3 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -162,9 +162,14 @@ namespace MP.MONO.UI.Components
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
protected void HandlePaginationItemClick(string page)
|
||||
protected string cssActive(int numPage)
|
||||
{
|
||||
currPage = int.Parse(page);
|
||||
string answ = "";
|
||||
if (numPage == currPage)
|
||||
{
|
||||
answ = "active";
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
@@ -172,6 +177,11 @@ namespace MP.MONO.UI.Components
|
||||
await Task.Run(() => showLoading = false);
|
||||
}
|
||||
|
||||
protected void PaginationItemClick(int page)
|
||||
{
|
||||
currPage = page;
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
@using MP.MONO.UI.Components
|
||||
@using MP.MONO.Core.DTO
|
||||
@using MP.MONO.UI.Data
|
||||
|
||||
@inject CurrentDataService MMDataService
|
||||
|
||||
@if (ListRecords != null && ListRecords.Count > 0)
|
||||
{
|
||||
<ul class="list-group">
|
||||
@foreach (var item in ListRecords)
|
||||
{
|
||||
<li class="list-group-item list-group-item-action">
|
||||
<div class="col-4">
|
||||
@if (!string.IsNullOrEmpty(item.CssIcon))
|
||||
{
|
||||
<div class="d-flex flex-column">
|
||||
<div class="small"><sup>@item.Title</sup></div>
|
||||
<div><i class="@item.CssIcon"></i></div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div>@item.Title</div>
|
||||
}
|
||||
</div>
|
||||
<div class="col-8 float-end">
|
||||
<div class="d-flex flex-column">
|
||||
<div class="d-flex flex-row-reverse"><h5 class="float-end"><b>@item.Value</b></h5></div>
|
||||
@if (item.ShowBar)
|
||||
{
|
||||
<div class="w-100">
|
||||
<div class="progress" style="height: 0.3rem;">
|
||||
<div class="progress-bar" role="progressbar" style="@percProgress(item.ValueNum, item.MinVal, item.MaxVal)" aria-valuenow="@item.ValueNum" aria-valuemin="@item.MinVal" aria-valuemax="@item.MaxVal"></div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using Microsoft.AspNetCore.Components.Forms;
|
||||
using Microsoft.AspNetCore.Components.Routing;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using Microsoft.AspNetCore.Components.Web.Virtualization;
|
||||
using Microsoft.JSInterop;
|
||||
using MP.MONO.UI;
|
||||
using MP.MONO.UI.Shared;
|
||||
using MP.MONO.UI.Components;
|
||||
using MP.MONO.Core.DTO;
|
||||
using MP.MONO.UI.Data;
|
||||
using Newtonsoft.Json;
|
||||
using MP.MONO.Data;
|
||||
|
||||
namespace MP.MONO.UI.Components
|
||||
{
|
||||
public partial class DetailOverview
|
||||
{
|
||||
private List<DisplayDataDTO>? ListRecords { get; set; } = null;
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await ReloadData();
|
||||
MMDataService.toolsPipe.EA_NewMessage += ToolsPipe_EA_NewMessage;
|
||||
}
|
||||
|
||||
private void ToolsPipe_EA_NewMessage(object? sender, EventArgs e)
|
||||
{
|
||||
PubSubEventArgs currArgs = (PubSubEventArgs)e;
|
||||
if (!string.IsNullOrEmpty(currArgs.newMessage))
|
||||
{
|
||||
try
|
||||
{
|
||||
ListRecords = JsonConvert.DeserializeObject<List<DisplayDataDTO>>(currArgs.newMessage);
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
InvokeAsync(() =>
|
||||
{
|
||||
StateHasChanged();
|
||||
});
|
||||
}
|
||||
|
||||
protected string percProgress(double num, double minVal, double maxVal)
|
||||
{
|
||||
string answ = "width: 0%;";
|
||||
double den = (maxVal - minVal) != 0 ? (maxVal - minVal) : 1;
|
||||
double ratio = ((double)num) / den;
|
||||
answ = $"width: {ratio:P0};";
|
||||
return answ;
|
||||
}
|
||||
protected async Task ReloadData()
|
||||
{
|
||||
ListRecords = await MMDataService.getTools();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,23 +16,17 @@ namespace MP.MONO.UI.Components
|
||||
#region Private Methods
|
||||
|
||||
[Parameter]
|
||||
public List<string> SelVal { get; set; } = new List<string>();
|
||||
|
||||
|
||||
public List<string> SelVal { get; set; } = new List<string>();
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<string> EC_SelValue { get; set; }
|
||||
|
||||
protected List<chartJsData.chartJsTSerie> LevelVal = new List<chartJsData.chartJsTSerie>();
|
||||
|
||||
protected string cssActive(string ParamName)
|
||||
{
|
||||
string answ = SelVal.Contains(ParamName) ? "bg-dark text-light": "";
|
||||
string answ = SelVal.Contains(ParamName) ? "bg-dark text-light" : "";
|
||||
return answ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void ParametersPipe_EA_NewMessage(object? sender, EventArgs e)
|
||||
{
|
||||
PubSubEventArgs currArgs = (PubSubEventArgs)e;
|
||||
@@ -82,10 +76,10 @@ namespace MP.MONO.UI.Components
|
||||
{
|
||||
SelVal.Add(SelectedValue);
|
||||
}
|
||||
|
||||
|
||||
EC_SelValue.InvokeAsync(SelectedValue);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
}
|
||||
}
|
||||
@@ -6,20 +6,40 @@
|
||||
|
||||
@if (ListRecords != null && ListRecords.Count > 0)
|
||||
{
|
||||
<ul class="list-group">
|
||||
@*<ul class="list-group">
|
||||
@foreach (var item in ListRecords)
|
||||
{
|
||||
<li class="list-group-item list-group-item-action">
|
||||
<div class="d-flex w-100 justify-content-between" title="order">
|
||||
<div>@item.Title</div>
|
||||
<div>
|
||||
<h5> <b>@item.Value</b></h5>
|
||||
<div class="col-4">
|
||||
@if (!string.IsNullOrEmpty(item.CssIcon))
|
||||
{
|
||||
<div class="d-flex flex-column">
|
||||
<div class="small"><sup>@item.Title</sup></div>
|
||||
<div><i class="@item.CssIcon"></i></div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div>@item.Title</div>
|
||||
}
|
||||
</div>
|
||||
<div class="col-8 float-end">
|
||||
<div class="d-flex flex-column">
|
||||
<div class="d-flex flex-row-reverse"><h5 class="float-end"><b>@item.Value</b></h5></div>
|
||||
@if (item.ShowBar)
|
||||
{
|
||||
<div class="w-100">
|
||||
<div class="progress" style="height: 0.3rem;">
|
||||
<div class="progress-bar" role="progressbar" style="@percProgress(item.ValueNum, item.MinVal, item.MaxVal)" aria-valuenow="@item.ValueNum" aria-valuemin="@item.MinVal" aria-valuemax="@item.MaxVal"></div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
|
||||
</ul>*@
|
||||
<DetailOverview></DetailOverview>
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -48,6 +48,14 @@ namespace MP.MONO.UI.Components
|
||||
});
|
||||
}
|
||||
|
||||
protected string percProgress(double num, double minVal, double maxVal)
|
||||
{
|
||||
string answ = "width: 0%;";
|
||||
double den = (maxVal - minVal) != 0 ? (maxVal - minVal) : 1;
|
||||
double ratio = ((double)num) / den;
|
||||
answ = $"width: {ratio:P0};";
|
||||
return answ;
|
||||
}
|
||||
protected async Task ReloadData()
|
||||
{
|
||||
ListRecords = await MMDataService.getTools();
|
||||
|
||||
@@ -15,8 +15,8 @@ namespace MP.MONO.UI.Data
|
||||
{
|
||||
#region Private Fields
|
||||
|
||||
private static IConfiguration _configuration;
|
||||
private static ILogger<CurrentDataService> _logger;
|
||||
private static IConfiguration _configuration = null!;
|
||||
private static ILogger<CurrentDataService> _logger = null!;
|
||||
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
/// <summary>
|
||||
@@ -37,7 +37,7 @@ namespace MP.MONO.UI.Data
|
||||
/// <summary>
|
||||
/// Controller dati da DB
|
||||
/// </summary>
|
||||
public static MpDbController dbController;
|
||||
public static MpDbController dbController = null!;
|
||||
|
||||
#endregion Public Fields
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace MP.MONO.UI.Data
|
||||
}
|
||||
else
|
||||
{
|
||||
dbController = new MpDbController(configuration);
|
||||
dbController = new MpDbController();
|
||||
_logger.LogInformation("DbController OK");
|
||||
}
|
||||
}
|
||||
@@ -110,8 +110,7 @@ namespace MP.MONO.UI.Data
|
||||
public async Task<List<DisplayDataDTO>> getActLog()
|
||||
{
|
||||
List<DisplayDataDTO>? dbResult = new List<DisplayDataDTO>();
|
||||
string cacheKey = Constants.ACT_LOG_CURR_KEY;
|
||||
string rawData = await redisDb.StringGetAsync(cacheKey);
|
||||
string rawData = await redisDb.StringGetAsync(Constants.ACT_LOG_CURR_KEY);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
dbResult = JsonConvert.DeserializeObject<List<DisplayDataDTO>>(rawData);
|
||||
@@ -126,8 +125,7 @@ namespace MP.MONO.UI.Data
|
||||
public async Task<List<string>> getAlarms()
|
||||
{
|
||||
List<string>? dbResult = new List<string>();
|
||||
string cacheKey = Constants.ALARM_CURR_KEY;
|
||||
string rawData = await redisDb.StringGetAsync(cacheKey);
|
||||
string rawData = await redisDb.StringGetAsync(Constants.ALARM_CURR_KEY);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
dbResult = JsonConvert.DeserializeObject<List<string>>(rawData);
|
||||
@@ -139,11 +137,63 @@ namespace MP.MONO.UI.Data
|
||||
return await Task.FromResult(dbResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Conf allarmi (da ADAPTER) senza valori silenziati da app
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<List<BaseAlarmConf>> getAlarmConfig()
|
||||
{
|
||||
List<BaseAlarmConf>? dbResult = new List<BaseAlarmConf>();
|
||||
string rawData = await redisDb.StringGetAsync(Constants.ALARMS_CONF_KEY);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
dbResult = JsonConvert.DeserializeObject<List<BaseAlarmConf>>(rawData);
|
||||
}
|
||||
if (dbResult == null)
|
||||
{
|
||||
dbResult = new List<BaseAlarmConf>();
|
||||
}
|
||||
return await Task.FromResult(dbResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Conf allarmi IMPOSTATA con valori silenziati
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<List<BaseAlarmConf>> getAlarmSetup()
|
||||
{
|
||||
List<BaseAlarmConf>? dbResult = new List<BaseAlarmConf>();
|
||||
string rawData = await redisDb.StringGetAsync(Constants.ALARMS_SETT_KEY);
|
||||
//se non avessi trovato valori cerco quelli di setup...
|
||||
if (string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
rawData = await redisDb.StringGetAsync(Constants.ALARMS_CONF_KEY);
|
||||
}
|
||||
// ora provo a deserializzare
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
dbResult = JsonConvert.DeserializeObject<List<BaseAlarmConf>>(rawData);
|
||||
}
|
||||
// altrimenti imposto vuoto
|
||||
if (dbResult == null)
|
||||
{
|
||||
dbResult = new List<BaseAlarmConf>();
|
||||
}
|
||||
return await Task.FromResult(dbResult);
|
||||
}
|
||||
|
||||
public async Task<bool> setAlarmSetup(List<BaseAlarmConf> alarmConf)
|
||||
{
|
||||
bool answ = false;
|
||||
string rawData = JsonConvert.SerializeObject(alarmConf);
|
||||
await redisDb.StringSetAsync(Constants.ALARMS_SETT_KEY, rawData);
|
||||
return await Task.FromResult(answ);
|
||||
}
|
||||
|
||||
public async Task<List<DisplayDataDTO>> getEventHist()
|
||||
{
|
||||
List<DisplayDataDTO>? dbResult = new List<DisplayDataDTO>();
|
||||
string cacheKey = Constants.EVENT_LOG_CURR_KEY;
|
||||
string rawData = await redisDb.StringGetAsync(cacheKey);
|
||||
string rawData = await redisDb.StringGetAsync(Constants.EVENT_LOG_CURR_KEY);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
dbResult = JsonConvert.DeserializeObject<List<DisplayDataDTO>>(rawData);
|
||||
@@ -158,8 +208,7 @@ namespace MP.MONO.UI.Data
|
||||
public async Task<List<DisplayDataDTO>> getMaintenance()
|
||||
{
|
||||
List<DisplayDataDTO>? dbResult = new List<DisplayDataDTO>();
|
||||
string cacheKey = Constants.MAINT_STATS_CURR_KEY;
|
||||
string rawData = await redisDb.StringGetAsync(cacheKey);
|
||||
string rawData = await redisDb.StringGetAsync(Constants.MAINT_STATS_CURR_KEY);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
dbResult = JsonConvert.DeserializeObject<List<DisplayDataDTO>>(rawData);
|
||||
@@ -174,8 +223,7 @@ namespace MP.MONO.UI.Data
|
||||
public async Task<List<MachineMode>> getModesList()
|
||||
{
|
||||
List<MachineMode>? dbResult = new List<MachineMode>();
|
||||
string cacheKey = Constants.MODE_CONF_KEY;
|
||||
string rawData = await redisDb.StringGetAsync(cacheKey);
|
||||
string rawData = await redisDb.StringGetAsync(Constants.MODE_CONF_KEY);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
dbResult = JsonConvert.DeserializeObject<List<MachineMode>>(rawData);
|
||||
@@ -190,8 +238,7 @@ namespace MP.MONO.UI.Data
|
||||
public async Task<List<DisplayDataDTO>> getParameters()
|
||||
{
|
||||
List<DisplayDataDTO>? dbResult = new List<DisplayDataDTO>();
|
||||
string cacheKey = Constants.PARAMS_CURR_KEY;
|
||||
string rawData = await redisDb.StringGetAsync(cacheKey);
|
||||
string rawData = await redisDb.StringGetAsync(Constants.PARAMS_CURR_KEY);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
dbResult = JsonConvert.DeserializeObject<List<DisplayDataDTO>>(rawData);
|
||||
@@ -206,8 +253,7 @@ namespace MP.MONO.UI.Data
|
||||
public async Task<ProductionDTO> getProd()
|
||||
{
|
||||
ProductionDTO? dbResult = new ProductionDTO();
|
||||
string cacheKey = Constants.PROD_CURR_KEY;
|
||||
string rawData = await redisDb.StringGetAsync(cacheKey);
|
||||
string rawData = await redisDb.StringGetAsync(Constants.PROD_CURR_KEY);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
dbResult = JsonConvert.DeserializeObject<ProductionDTO>(rawData);
|
||||
@@ -222,8 +268,7 @@ namespace MP.MONO.UI.Data
|
||||
public async Task<List<DisplayDataDTO>> getStats()
|
||||
{
|
||||
List<DisplayDataDTO>? dbResult = new List<DisplayDataDTO>();
|
||||
string cacheKey = Constants.MACH_STATS_CURR_KEY;
|
||||
string rawData = await redisDb.StringGetAsync(cacheKey);
|
||||
string rawData = await redisDb.StringGetAsync(Constants.MACH_STATS_CURR_KEY);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
dbResult = JsonConvert.DeserializeObject<List<DisplayDataDTO>>(rawData);
|
||||
@@ -238,8 +283,7 @@ namespace MP.MONO.UI.Data
|
||||
public async Task<MachineDTO> getStatus()
|
||||
{
|
||||
MachineDTO? dbResult = new MachineDTO();
|
||||
string cacheKey = Constants.STATUS_CURR_KEY;
|
||||
string rawData = await redisDb.StringGetAsync(cacheKey);
|
||||
string rawData = await redisDb.StringGetAsync(Constants.STATUS_CURR_KEY);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
dbResult = JsonConvert.DeserializeObject<MachineDTO>(rawData);
|
||||
@@ -254,8 +298,7 @@ namespace MP.MONO.UI.Data
|
||||
public async Task<List<MachineStatus>> getStatusList()
|
||||
{
|
||||
List<MachineStatus>? dbResult = new List<MachineStatus>();
|
||||
string cacheKey = Constants.STATUS_CONF_KEY;
|
||||
string rawData = await redisDb.StringGetAsync(cacheKey);
|
||||
string rawData = await redisDb.StringGetAsync(Constants.STATUS_CONF_KEY);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
dbResult = JsonConvert.DeserializeObject<List<MachineStatus>>(rawData);
|
||||
@@ -270,8 +313,7 @@ namespace MP.MONO.UI.Data
|
||||
public async Task<List<DisplayDataDTO>> getTools()
|
||||
{
|
||||
List<DisplayDataDTO>? dbResult = new List<DisplayDataDTO>();
|
||||
string cacheKey = Constants.TOOLS_CURR_KEY;
|
||||
string rawData = await redisDb.StringGetAsync(cacheKey);
|
||||
string rawData = await redisDb.StringGetAsync(Constants.TOOLS_CURR_KEY);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
dbResult = JsonConvert.DeserializeObject<List<DisplayDataDTO>>(rawData);
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Negotiate" Version="6.0.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.3">
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Negotiate" Version="6.0.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@page "/ActLog"
|
||||
|
||||
<div class="row">
|
||||
<div class="row m-2">
|
||||
<div class="col-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
@@ -11,6 +11,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-8">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
|
||||
@@ -10,111 +10,120 @@
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-6 col-lg-3 h3">
|
||||
<div class="col-12 col-md-6 col-lg-3">
|
||||
<h3>Alarms</h3>
|
||||
</div>
|
||||
<div class="col-12 col-md-6 col-lg-9 text-right">
|
||||
<div class="col-12 col-md-6 col-lg-9 float-end">
|
||||
<div class="d-flex flex-row-reverse">
|
||||
<div class="p-2">
|
||||
<div class="form-group mb-0">
|
||||
<Button id="btnReset" class="btn btn-info btn-sm btn-block" Clicked="DoRefresh" title="Reset Filter"><span class="oi oi-loop-circular"></span></Button>
|
||||
<button id="btnReset" class="btn btn-primary btn-sm btn-block" @onclick="() => ReloadData()" title="Reset Filter"><span class="oi oi-loop-circular"></span></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Max Record:</span>
|
||||
<span class="input-group-text">Last Records:</span>
|
||||
</div>
|
||||
<input class="form-control form-control-sm" @bind-value="@MaxRecord" title="Max number of record to show" />
|
||||
</div>
|
||||
</div>
|
||||
@*<div class="p-2">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">
|
||||
<span class="fas fa-gas-pump" aria-hidden="true"></span>
|
||||
</span>
|
||||
</div>
|
||||
<select @bind="@SelPlantId" class="form-control form-control-sm">
|
||||
<option value="0">--- Tutti ---</option>
|
||||
@if (PlantsList != null)
|
||||
{
|
||||
foreach (var item in PlantsList)
|
||||
{
|
||||
<option value="@item.PlantId">@item.PlantCode | @item.PlantDesc</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>*@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<h5>Current alarms</h5>
|
||||
<AlarmsOverview></AlarmsOverview>
|
||||
<div class="col-3">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="p-2">
|
||||
<h5>Current alarms</h5>
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<div class="form-check form-check-sm form-switch" title="Setup Alarms (mute/unmute)">
|
||||
<input class="form-check-input" type="checkbox" id="mySwitch" name="setupAlarms" value="@doSetup" unchecked @onclick="() => SetupAlarms()">
|
||||
<label class="form-check-label" for="mySwitch">Setup</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<AlarmsOverview messageReceived="() => reloadFromMessage()"></AlarmsOverview>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-8">
|
||||
@if (ListRecords == null)
|
||||
<div class="col-9">
|
||||
@if (doSetup)
|
||||
{
|
||||
<LoadingData></LoadingData>
|
||||
}
|
||||
else if (totalCount == 0)
|
||||
{
|
||||
<div class="alert alert-warning text-center display-4">No record found</div>
|
||||
<AlarmsSetup></AlarmsSetup>
|
||||
}
|
||||
else
|
||||
{
|
||||
<table class="table table-sm table-striped table-responsive-lg">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Data</th>
|
||||
<th>Ora</th>
|
||||
<th>Codice Area</th>
|
||||
<th class="text-right">Codice</th>
|
||||
<th class="text-right">Stato</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var record in ListRecords)
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5>Alarm History</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@if (ListRecords == null)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
@record.DtRif.ToString("ddd yyyy.MM.dd")
|
||||
</td>
|
||||
<td>
|
||||
@record.DtRif.ToString("HH:mm:ss")
|
||||
</td>
|
||||
<td><b>@record.MemAddress</b> / @record.Index</td>
|
||||
<td class="text-right">
|
||||
@record.Status
|
||||
</td>
|
||||
<td class="text-right">
|
||||
@if (record.Status == 0)
|
||||
{
|
||||
<span class="text-success">@record.ValDecoded <i class="fas fa-certificate"></i></span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="text-danger">@record.ValDecoded <i class="fas fa-exclamation-triangle"></i></span>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
<LoadingData></LoadingData>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
else if (totalCount == 0)
|
||||
{
|
||||
<div class="alert alert-warning text-center display-4">No record found</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<table class="table table-sm table-striped table-responsive-lg small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date - Time</th>
|
||||
<th>Memory Area</th>
|
||||
<th><div class="float-end">Code</div></th>
|
||||
<th><div class="float-end">Status</div></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var record in ListRecords)
|
||||
{
|
||||
<tr>
|
||||
<td class="text-nowrap">
|
||||
@record.DtRif.ToString("yyyy.MM.dd HH:mm:ss")
|
||||
</td>
|
||||
<td><b>@record.MemAddress</b> / @record.Index</td>
|
||||
<td>
|
||||
<div class="float-end">@record.Status</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="float-end">
|
||||
@if (record.Status == 0)
|
||||
{
|
||||
<span class="text-success">@record.ValDecoded <i class="fas fa-certificate"></i></span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="text-danger">@record.ValDecoded <i class="fas fa-exclamation-triangle"></i></span>
|
||||
}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
</div>
|
||||
<div class="card-footer py-0">
|
||||
<DataPager PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="totalCount" showLoading="isLoading" />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer p-1">
|
||||
<DataPager PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="totalCount" showLoading="isLoading" />
|
||||
</div>
|
||||
@*<div class="card-footer p-1">
|
||||
</div>*@
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace MP.MONO.UI.Pages
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
protected int _MaxRecord = 100;
|
||||
protected int _MaxRecord = 200;
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
@@ -109,13 +109,41 @@ namespace MP.MONO.UI.Pages
|
||||
{
|
||||
await ReloadData();
|
||||
}
|
||||
protected async Task reloadFromMessage()
|
||||
{
|
||||
isLoading = true;
|
||||
ListRecords = null;
|
||||
await Task.Delay(300);
|
||||
await ReloadData();
|
||||
await Task.Delay(1);
|
||||
await InvokeAsync(() =>
|
||||
{
|
||||
StateHasChanged();
|
||||
});
|
||||
}
|
||||
|
||||
protected async Task ReloadData()
|
||||
{
|
||||
isLoading = true;
|
||||
ListRecords = null;
|
||||
await Task.Delay(1);
|
||||
SearchRecords = await MMDataService.AlarmLogGetFilt(MachineId, 0, MaxRecord);
|
||||
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
|
||||
await Task.Delay(1);
|
||||
await Task.Delay(1);
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
protected bool doSetup = false;
|
||||
|
||||
protected async Task SetupAlarms()
|
||||
{
|
||||
await Task.Delay(1);
|
||||
doSetup = !doSetup;
|
||||
await Task.Delay(1);
|
||||
}
|
||||
|
||||
|
||||
#endregion Protected Methods
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
@page "/Events"
|
||||
|
||||
<div class="row">
|
||||
<div class="row m-2">
|
||||
<div class="col-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
@@ -11,6 +11,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-8">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@page "/MachStats"
|
||||
|
||||
<div class="row">
|
||||
<div class="row m-2">
|
||||
<div class="col-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
@@ -11,6 +11,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-8">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@page "/Maintenance"
|
||||
|
||||
<div class="row">
|
||||
<div class="row m-2">
|
||||
<div class="col-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
@@ -11,6 +11,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-8">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace MP.MONO.UI.Pages
|
||||
{
|
||||
string answ = "col-12";
|
||||
int numPar = selParams.Count;
|
||||
if (numPar > 4)
|
||||
if (numPar > 6)
|
||||
{
|
||||
answ = "col-4";
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@page "/Production"
|
||||
|
||||
<div class="row">
|
||||
<div class="row m-2">
|
||||
<div class="col-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
@@ -11,6 +11,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-8">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@page "/Tools"
|
||||
|
||||
<div class="row">
|
||||
<div class="row m-2">
|
||||
<div class="col-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
@@ -11,6 +11,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-8">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
|
||||
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<TimeStampOfAssociatedLegacyPublishXmlFile />
|
||||
<EncryptedPassword>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAARwa+h3SucUCk0+IZCHMQsgAAAAACAAAAAAADZgAAwAAAABAAAADOPMd3758qI/y/dA1hJlk6AAAAAASAAACgAAAAEAAAALjI1Q4A+Na1SHTbn2iY4kQYAAAA+8wgMcZ+vEOXhrpk/ei4H4gSz/lppCy4FAAAADEgX6TTl06NoYYCkrCN2gRN2gDO</EncryptedPassword>
|
||||
<History>True|2022-03-18T07:13:40.4364579Z;True|2022-03-10T18:22:15.7066492+01:00;</History>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
|
||||
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<TimeStampOfAssociatedLegacyPublishXmlFile />
|
||||
<EncryptedPassword>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAARwa+h3SucUCk0+IZCHMQsgAAAAACAAAAAAADZgAAwAAAABAAAADOPMd3758qI/y/dA1hJlk6AAAAAASAAACgAAAAEAAAALjI1Q4A+Na1SHTbn2iY4kQYAAAA+8wgMcZ+vEOXhrpk/ei4H4gSz/lppCy4FAAAADEgX6TTl06NoYYCkrCN2gRN2gDO</EncryptedPassword>
|
||||
<History>True|2022-03-18T07:13:40.4364579Z;True|2022-03-10T18:22:15.7066492+01:00;</History>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -14,7 +14,7 @@ by editing this MSBuild file. In order to learn more about this please visit htt
|
||||
<ExcludeApp_Data>false</ExcludeApp_Data>
|
||||
<ProjectGuid>6fb65850-c023-4986-9dff-770c4e582d60</ProjectGuid>
|
||||
<SelfContained>false</SelfContained>
|
||||
<MSDeployServiceURL>https://iis01.egalware.com:8172/MsDeploy.axd</MSDeployServiceURL>
|
||||
<MSDeployServiceURL>https://iis03.egalware.com:8172/MsDeploy.axd</MSDeployServiceURL>
|
||||
<DeployIisAppPath>Default Web Site/MP/MONO</DeployIisAppPath>
|
||||
<RemoteSitePhysicalPath />
|
||||
<SkipExtraFilesOnServer>true</SkipExtraFilesOnServer>
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
|
||||
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<TimeStampOfAssociatedLegacyPublishXmlFile />
|
||||
<EncryptedPassword>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAARwa+h3SucUCk0+IZCHMQsgAAAAACAAAAAAADZgAAwAAAABAAAADOPMd3758qI/y/dA1hJlk6AAAAAASAAACgAAAAEAAAALjI1Q4A+Na1SHTbn2iY4kQYAAAA+8wgMcZ+vEOXhrpk/ei4H4gSz/lppCy4FAAAADEgX6TTl06NoYYCkrCN2gRN2gDO</EncryptedPassword>
|
||||
<History>True|2022-03-18T07:13:40.4364579Z;True|2022-03-10T18:22:15.7066492+01:00;</History>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user