53 Commits

Author SHA1 Message Date
marco.salvi 5d9f0e59df Componente detailOverview 2022-03-24 16:46:52 +01:00
Samuele Locatelli 4bfe039623 Update x gestione parametri con calcolo vario... 2022-03-23 20:07:29 +01:00
Samuele Locatelli 195f187ba8 Fix decodificatore lua x variabili calcolate (test in LUA) 2022-03-23 20:07:26 +01:00
Samuele Locatelli 3cebac853b update decoder x gestione decodifica preliminare parametri (manca DB) 2022-03-22 19:56:00 +01:00
Samuele Locatelli 42f01f14af update conf SIM x simulazione parametri 2022-03-22 19:55:47 +01:00
Samuele Locatelli 4e882ea3cb update conf code e aree REDIS salvataggio dati 2022-03-22 19:55:26 +01:00
Samuele Locatelli 3afe990365 cambio logica gestione display multi parameters 2022-03-22 19:54:26 +01:00
Samuele Locatelli 2ffa502538 modifica SIM x nuova gestione parametri (solo valore poi DECODER) 2022-03-21 19:24:53 +01:00
Samuele Locatelli 7e941aec34 conf costanti x allarmi/parametri gestiti 2022-03-21 19:24:44 +01:00
Samuele Locatelli e7c73cbce1 Inizio classe x gestione parametri come allarmi 2022-03-21 19:24:30 +01:00
Samuele Locatelli 6a8ad2604f Nuova modalità setup conf anche x SIM con metodi CORE 2022-03-21 18:51:26 +01:00
Samuele Locatelli a87fee41f5 Riordino lua script x DECODER 2022-03-21 18:51:03 +01:00
Samuele Locatelli 67c8e883fe pulizia conf non usati x DECODER 2022-03-21 18:50:46 +01:00
Samuele Locatelli 37ee6f5997 Modifica adapter x gestione config dei parametri da CORE 2022-03-21 18:50:33 +01:00
Samuele Locatelli 4f0e2d9aa5 Aggiunta classe e metodi gestione config in CORE 2022-03-21 18:50:22 +01:00
Samuele Locatelli ccd3ed8c45 Update layout generale pagine 2022-03-21 16:45:55 +01:00
Samuele Locatelli cbf72f2558 Allarmi: effettua sempre salvataggio su REDIS 2022-03-21 16:41:37 +01:00
Samuele Locatelli d41722f200 Fix decodifica allarmi ALL OK 2022-03-21 12:02:24 +01:00
Samuele Locatelli be7515b16c Merge tag 'FixDecoderAllarmi' into develop
Fix decoder x gestione allarmi
2022-03-21 10:29:03 +01:00
Samuele Locatelli 89fd608eef Merge branch 'release/FixDecoderAllarmi' 2022-03-21 10:28:45 +01:00
Samuele Locatelli cf310ab003 Aggiornamento gestioen DECODER x allarmi e check variazioni 2022-03-21 09:14:01 +01:00
Samuele Locatelli 5177f412de Update script LUA 2022-03-21 09:13:53 +01:00
Samuele Locatelli ccbb6fa644 Update gestione SIM e DECODER x allarmi (NON ancora OK) 2022-03-19 16:33:51 +01:00
Samuele Locatelli dd3491af16 Update formato pubblicazione allarmi da SIM: memAddr + valore 2022-03-19 11:40:34 +01:00
Samuele Locatelli 1403daffd6 Update SIM x gestione allarmi in BANK 2022-03-19 11:12:02 +01:00
Samuele Locatelli 1a9f6c810b Ok gestione allarmi configurati da setup iniziale redis su seconda area memoria 2022-03-19 10:54:49 +01:00
Samuele Locatelli a4841dd8bc OK mute/unmute via redis 2022-03-18 18:37:58 +01:00
Samuele Locatelli 76d25bc727 Inizio setup pagina dettaglio allarmi cons etup attivi/silenziati 2022-03-18 17:23:01 +01:00
Samuele Locatelli 1472c178b1 Update sim x alarm conf (da gestire) 2022-03-18 17:22:48 +01:00
Samuele Locatelli 731d8c6400 Aggiunta classe base gestione allarmi in CORE 2022-03-18 17:22:35 +01:00
Samuele Locatelli 998afbbd7e Abbozzato adapter con gestione lettura conf completa 2022-03-18 17:22:24 +01:00
Samuele Locatelli d2c0761f7b Fix warnings vari e semplificazione classe DB 2022-03-18 09:52:57 +01:00
Samuele Locatelli f2b24aa3ea Fix conf yaml 2022-03-18 09:38:24 +01:00
Samuele Locatelli 7023ef1609 Aggiunti step zip/upload 2022-03-18 09:37:06 +01:00
Samuele Locatelli 19cfeff468 Aggiunta step SIM/DECODER x release 2022-03-18 09:33:21 +01:00
Samuele Locatelli aa0f847aa3 altra opzione x pwd 2022-03-18 08:57:18 +01:00
Samuele Locatelli 0f32dc64bd cambio chaive x password 2022-03-18 08:55:59 +01:00
Samuele Locatelli 699e07e61f test alternative restore pack 2022-03-18 08:51:56 +01:00
Samuele Locatelli 9edb343d40 fix deploy IIS01/02/03 2022-03-18 08:24:38 +01:00
Samuele Locatelli 3a6dc1b08e Update yaml x nexus https 2022-03-18 08:22:39 +01:00
Samuele Locatelli 913d148545 Fix pagina visualizzazione allarmi 2022-03-18 08:13:05 +01:00
Samuele Locatelli 4ff531e435 update script x proxy nuget in dotnet publish 2022-03-18 08:12:43 +01:00
Samuele Locatelli 8eed5081c9 Merge tag 'UpdateAlarms' into develop
Update pagina Allarmi
2022-03-17 18:07:04 +01:00
Samuele Locatelli 5b40dd70f1 Merge branch 'release/UpdateAlarms' 2022-03-17 18:06:18 +01:00
Samuele Locatelli f2f733e6ee Ancora update pagina allarmi 2022-03-17 18:05:22 +01:00
Samuele Locatelli 7173e6e90a fix align e formattazione allarmi 2022-03-17 18:03:20 +01:00
Samuele Locatelli afda7d6221 Merge tag 'AutoRefreshAlarms' into develop
Auto refresh area allarmi
2022-03-17 15:24:29 +01:00
Samuele Locatelli 5587e9efca Merge branch 'release/AutoRefreshAlarms' 2022-03-17 15:24:21 +01:00
Samuele Locatelli 83634c7788 Update x autorefresh da DB degli ultimi allarmi 2022-03-17 15:23:59 +01:00
Samuele Locatelli e3c7cb356c Sistemato decoder: ora finalmente scrive sul DB... 2022-03-17 15:09:58 +01:00
Samuele Locatelli dfb2dd4c5c Merge branch 'feature/LuaPreliminaryTest' into develop 2022-03-17 13:14:05 +01:00
Samuele Locatelli 8e2a9634d1 Merge branch 'feature/LuaPreliminaryTest' into develop 2022-03-17 12:32:41 +01:00
Samuele Locatelli 06cd6ffa05 Merge branch 'develop' of https://gitlab.steamware.net/egalware/mapo-mono into develop 2022-03-16 16:21:33 +01:00
74 changed files with 3110 additions and 923 deletions
+120 -63
View File
@@ -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
+52
View File
@@ -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>
+281
View File
@@ -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}");
}
}
}
+35
View File
@@ -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"
}
}
}
}
+52
View File
@@ -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"
]
}
]
+125
View File
@@ -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"
}
]
+14
View File
@@ -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
+253
View File
@@ -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
}
}
+143
View File
@@ -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
}
}
+12 -5
View File
@@ -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";
+48
View File
@@ -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;
}
}
+4 -4
View File
@@ -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
+3
View File
@@ -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>
+48
View File
@@ -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;
}
}
}
}
-70
View File
@@ -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;
}
}
}
+93
View File
@@ -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
}
}
+3 -9
View File
@@ -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>
+159
View File
@@ -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
View File
@@ -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
{
+15 -3
View File
@@ -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
+5 -7
View File
@@ -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": {
-19
View File
@@ -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"
]
}
]
+73 -78
View File
@@ -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()
+84
View File
@@ -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()
+82
View File
@@ -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()
+1 -13
View File
@@ -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);
}
+181 -93
View File
@@ -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
}
}
+2 -2
View File
@@ -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
}
+6 -6
View File
@@ -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>
+2 -2
View File
@@ -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>
+7 -7
View File
@@ -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
}
-56
View File
@@ -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
View File
@@ -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 =>
+4 -9
View File
@@ -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
+8 -2
View File
@@ -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
View File
@@ -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));
+7
View File
@@ -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()
{
+2 -2
View File
@@ -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": {
+52
View File
@@ -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"
]
}
]
+125
View File
@@ -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"
}
]
+22 -7
View File
@@ -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"
}
]
+3 -2
View File
@@ -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
+13 -6
View File
@@ -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
{ }
+81
View File
@@ -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
}
}
+15 -36
View File
@@ -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>
+12 -2
View File
@@ -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();
}
}
}
+5 -11
View File
@@ -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
}
}
+28 -8
View File
@@ -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();
+68 -26
View File
@@ -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);
+2 -2
View File
@@ -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>
+3 -1
View File
@@ -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 {
+83 -74
View File
@@ -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>
+29 -1
View File
@@ -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
}
}
+3 -1
View File
@@ -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>
+3 -1
View File
@@ -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 {
+3 -1
View File
@@ -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 {
+1 -1
View File
@@ -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";
}
+3 -1
View File
@@ -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 {
+3 -1
View File
@@ -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>