Merge branch 'release/IobWinSQL_01'
This commit is contained in:
@@ -312,6 +312,19 @@ IOB-WIN-SIEMENS:build:
|
||||
script:
|
||||
- '& "$env:MSBUILD_PATH" "$env:APP_NAME\$env:APP_NAME.csproj" -target:Build /p:Configuration=Release /p:Platform="x86" /p:OutputPath=bin/ /nodeReuse:false /verbosity:minimal /m'
|
||||
|
||||
IOB-WIN-SQL:build:
|
||||
stage: build
|
||||
tags:
|
||||
- win
|
||||
variables:
|
||||
APP_NAME: IOB-WIN-SQL
|
||||
before_script:
|
||||
- *nuget-fix
|
||||
- '& "$env:NUGET_PATH" restore "$env:APP_NAME.sln" -verbosity quiet'
|
||||
- *version-fix
|
||||
script:
|
||||
- '& "$env:MSBUILD_PATH" "$env:APP_NAME\$env:APP_NAME.csproj" -target:Build /p:Configuration=Release /p:Platform="x86" /p:OutputPath=bin/ /nodeReuse:false /verbosity:minimal /m'
|
||||
|
||||
IOB-WIN-WPS:build:
|
||||
stage: build
|
||||
tags:
|
||||
@@ -566,6 +579,31 @@ IOB-WIN-SIEMENS:release:
|
||||
- *nexusUpload
|
||||
- *SendToVersionsLog
|
||||
|
||||
IOB-WIN-SQL:release:
|
||||
stage: release
|
||||
needs: ["IOB-WIN-SQL:build"]
|
||||
tags:
|
||||
- win
|
||||
variables:
|
||||
APP_NAME: IOB-WIN-SQL
|
||||
NEXUS_PATH: MAPO/IOB-WIN-SQL
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH == 'master'
|
||||
changes:
|
||||
- IOB-WIN-SQL/*
|
||||
when: always
|
||||
before_script:
|
||||
- *nuget-fix
|
||||
- '& "$env:NUGET_PATH" restore "$env:APP_NAME.sln" -verbosity quiet'
|
||||
- *version-fix
|
||||
- *cleanup-zip
|
||||
script:
|
||||
- '& "$env:MSBUILD_PATH" "$env:APP_NAME\$env:APP_NAME.csproj" -target:Build /p:Configuration=Release /p:Platform="x86" /p:OutputPath=bin/ /nodeReuse:false /verbosity:minimal /m'
|
||||
- *zipper
|
||||
- *hashBuild
|
||||
- *nexusUpload
|
||||
- *SendToVersionsLog
|
||||
|
||||
IOB-WIN-WPS:release:
|
||||
stage: release
|
||||
needs: ["IOB-WIN-WPS:build"]
|
||||
@@ -780,6 +818,26 @@ IOB-WIN-SIEMENS:docfx:
|
||||
- mv $env:APP_NAME/_site "docfx"
|
||||
- *DocReplica
|
||||
|
||||
IOB-WIN-SQL:docfx:
|
||||
stage: docfx
|
||||
needs: ["IOB-WIN-SQL:build"]
|
||||
tags:
|
||||
- win
|
||||
variables:
|
||||
APP_NAME: IOB-WIN-SQL
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH == 'master'
|
||||
changes:
|
||||
- IOB-WIN-SQL/*
|
||||
when: always
|
||||
before_script:
|
||||
- *nuget-fix
|
||||
- '& "$env:NUGET_PATH" restore "$env:APP_NAME.sln" -verbosity quiet'
|
||||
script:
|
||||
- docfx $env:APP_NAME/docfx.json
|
||||
- mv $env:APP_NAME/_site "docfx"
|
||||
- *DocReplica
|
||||
|
||||
IOB-WIN-WPS:docfx:
|
||||
stage: docfx
|
||||
needs: ["IOB-WIN-WPS:build"]
|
||||
|
||||
@@ -64,15 +64,10 @@ namespace IOB_WIN_NEXT
|
||||
btnStart.Enabled = true;
|
||||
break;
|
||||
|
||||
#if false
|
||||
case tipoAdapter.IcoelDb:
|
||||
iobObj = new IobSql.IcoelDb(this, IOBConf);
|
||||
btnStart.Enabled = true;
|
||||
break;
|
||||
|
||||
#if false
|
||||
case tipoAdapter.IcoelSoap:
|
||||
iobObj = new IobNet.IcoelSoap(this, IOBConf);
|
||||
btnStart.Enabled = true;
|
||||
break;
|
||||
#endif
|
||||
|
||||
@@ -95,22 +90,6 @@ namespace IOB_WIN_NEXT
|
||||
break;
|
||||
|
||||
#if false
|
||||
case tipoAdapter.REST:
|
||||
iobObj = new IobRest.Base(this, IOBConf);
|
||||
btnStart.Enabled = true;
|
||||
break;
|
||||
|
||||
case tipoAdapter.REST_CITIZEN:
|
||||
iobObj = new IobRest.Citizen(this, IOBConf);
|
||||
btnStart.Enabled = true;
|
||||
break;
|
||||
|
||||
case tipoAdapter.SOAP_GOMBA:
|
||||
iobObj = new IobSoap.Gomba(this, IOBConf);
|
||||
btnStart.Enabled = true;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case tipoAdapter.SQLSERVER_LANTEK:
|
||||
iobObj = new IobSql.SqlServLantek(this, IOBConf);
|
||||
btnStart.Enabled = true;
|
||||
@@ -119,7 +98,8 @@ namespace IOB_WIN_NEXT
|
||||
case tipoAdapter.SQLSERVER_PAMA:
|
||||
iobObj = new IobSql.SqlServPama(this, IOBConf);
|
||||
btnStart.Enabled = true;
|
||||
break;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case tipoAdapter.ND:
|
||||
default:
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
;Configurazione IOB-WIN
|
||||
[IOB]
|
||||
;Macchina TEST FTP simile a ultrasuoni Sonatest x IMI Remosa
|
||||
CNCTYPE=FTP
|
||||
PING_MS_TIMEOUT=500
|
||||
|
||||
[MACHINE]
|
||||
VENDOR=TEST_FTP
|
||||
MODEL=TRUESCALE_FTP
|
||||
|
||||
[CNC]
|
||||
IP=10.74.82.204
|
||||
PORT=21
|
||||
PING_IP=10.74.82.204
|
||||
GETPRGNAME=false
|
||||
|
||||
[SERVER]
|
||||
MPIP=http://10.74.82.218
|
||||
MPURL=/MP/IO
|
||||
CMDBASE=/IOB/input/
|
||||
CMDFLOG=/IOB/flog/
|
||||
CMDALIVE=/IOB
|
||||
CMDENABLED=/IOB/enabled/
|
||||
CMDADV1=?valore=
|
||||
CMDREBO=/sendReboot.aspx?idxMacchina=
|
||||
|
||||
[MEMORY]
|
||||
ADDR_READ=DB9999.DBB0
|
||||
ADDR_WRITE=DB9999.DBB0
|
||||
SIZE_READ=0
|
||||
SIZE_WRITE=0
|
||||
|
||||
|
||||
[BLINK]
|
||||
;MAX_COUNTER_BLINK = 30
|
||||
MAX_COUNTER_BLINK = 30
|
||||
BLINK_FILT=0
|
||||
|
||||
[OPTPAR]
|
||||
; imposto breve sennò non riesce a partire...
|
||||
WAIT_REC_MSEC = 1000
|
||||
; indica gestione folder ritorno dati ODL
|
||||
ODL_FOLDER = TRUE
|
||||
; gestione contapezzi
|
||||
PZCOUNT_MODE=NONE
|
||||
DISABLE_PZCOUNT=TRUE
|
||||
ENABLE_SEND_PZC_BLOCK=FALSE
|
||||
MIN_SEND_PZC_BLOCK=0
|
||||
MAX_SEND_PZC_BLOCK=100
|
||||
;errori verifica folder FTP MAX
|
||||
MAX_ERR_CHECK=10
|
||||
; gestione DynData
|
||||
ENABLE_DYN_DATA=TRUE
|
||||
FORCE_DYN_DATA=TRUE
|
||||
DISABLE_DYN_DATA=TRUE
|
||||
DISABLE_SEND_WDST=TRUE
|
||||
|
||||
; gestioni PING
|
||||
MAX_TRY_PING=3
|
||||
VETO_QUEUE_IN=4
|
||||
VETO_PING_SEC=4
|
||||
VETO_CHECKDIR_SEC=10
|
||||
MAX_ELAPSED_TIME_SEC=60
|
||||
|
||||
;VETO_SEND_SNAPSHOT=3
|
||||
POWEROFF_TIMEOUT_SEC=60
|
||||
|
||||
; conf parametri memoria READ/WRITE
|
||||
FTP_PARAM=FTP_SONATEST.json
|
||||
|
||||
[BRANCH]
|
||||
NAME=master
|
||||
|
||||
; Tags manuali
|
||||
[TAGS]
|
||||
Customer=SteamWare
|
||||
HostOS=WIN
|
||||
HostName=IOB-WIN-SIMULA
|
||||
HostAddr=10.74.82.76
|
||||
@@ -1,26 +0,0 @@
|
||||
{
|
||||
"ListTask": [
|
||||
{
|
||||
"ActionId": "FtpDownload",
|
||||
"ServerAddr": "egw-tscale-04",
|
||||
"ServerPort": 21,
|
||||
"ConnUser": "testftpuser",
|
||||
"ConnPasswd": "we4reFromB3rghem!",
|
||||
"RawCert": "",
|
||||
"SkipCert": true,
|
||||
"ReExecVeto": 90,
|
||||
"Note": "Sync periodico completo",
|
||||
"StepsList": [
|
||||
{
|
||||
"Id": "01",
|
||||
"Description": "Mirror Remote 2 Local Directory",
|
||||
"Action": "mirrorDirR2L",
|
||||
"ParamList": {
|
||||
"RemoteDir": "ftpdata/syncfolder",
|
||||
"LocalDir": "\\\\iis01\\W$\\Files"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
;Configurazione IOB-WIN
|
||||
[IOB]
|
||||
;Macchina controllo ultrasuoni Sonatest x IMI Remosa
|
||||
CNCTYPE=FTP
|
||||
PING_MS_TIMEOUT=500
|
||||
|
||||
[MACHINE]
|
||||
VENDOR=SONATEST
|
||||
MODEL=VEO
|
||||
|
||||
[CNC]
|
||||
IP=172.28.30.208
|
||||
PORT=21
|
||||
PING_IP=172.28.30.208
|
||||
GETPRGNAME=false
|
||||
|
||||
[SERVER]
|
||||
MPIP=http://192.168.0.110
|
||||
MPURL=/MP/IO
|
||||
CMDBASE=/IOB/input/
|
||||
CMDFLOG=/IOB/flog/
|
||||
CMDALIVE=/IOB
|
||||
CMDENABLED=/IOB/enabled/
|
||||
CMDADV1=?valore=
|
||||
CMDREBO=/sendReboot.aspx?idxMacchina=
|
||||
|
||||
[MEMORY]
|
||||
ADDR_READ=DB9999.DBB0
|
||||
ADDR_WRITE=DB9999.DBB0
|
||||
SIZE_READ=0
|
||||
SIZE_WRITE=0
|
||||
|
||||
|
||||
[BLINK]
|
||||
;MAX_COUNTER_BLINK = 30
|
||||
MAX_COUNTER_BLINK = 30
|
||||
BLINK_FILT=0
|
||||
|
||||
[OPTPAR]
|
||||
; imposto breve sennò non riesce a partire...
|
||||
WAIT_REC_MSEC = 1000
|
||||
; indica gestione folder ritorno dati ODL
|
||||
ODL_FOLDER = TRUE
|
||||
; gestione contapezzi
|
||||
PZCOUNT_MODE=NONE
|
||||
DISABLE_PZCOUNT=TRUE
|
||||
ENABLE_SEND_PZC_BLOCK=FALSE
|
||||
MIN_SEND_PZC_BLOCK=0
|
||||
MAX_SEND_PZC_BLOCK=100
|
||||
;errori verifica folder FTP MAX
|
||||
MAX_ERR_CHECK=10
|
||||
; gestione DynData
|
||||
ENABLE_DYN_DATA=TRUE
|
||||
FORCE_DYN_DATA=TRUE
|
||||
DISABLE_DYN_DATA=TRUE
|
||||
DISABLE_SEND_WDST=TRUE
|
||||
|
||||
; gestioni PING
|
||||
MAX_TRY_PING=3
|
||||
VETO_QUEUE_IN=5
|
||||
VETO_PING_SEC=5
|
||||
VETO_CHECKDIR_SEC=10
|
||||
MAX_ELAPSED_TIME_SEC=60
|
||||
|
||||
;VETO_SEND_SNAPSHOT=3
|
||||
POWEROFF_TIMEOUT_SEC=60
|
||||
|
||||
; conf parametri memoria READ/WRITE
|
||||
FTP_PARAM=IMI_SONATEST.json
|
||||
|
||||
[BRANCH]
|
||||
NAME=master
|
||||
|
||||
; Tags manuali
|
||||
[TAGS]
|
||||
Customer=IMI-Remosa
|
||||
HostOS=WIN
|
||||
HostName=MAPO-SRV-60
|
||||
HostAddr=192.168.0.12
|
||||
@@ -1,27 +0,0 @@
|
||||
{
|
||||
"ListTask": [
|
||||
{
|
||||
"ActionId": "FtpDownload",
|
||||
"ServerAddr": "172.28.30.208",
|
||||
"ServerPort": 21,
|
||||
"ConnUser": "ftpuser",
|
||||
"ConnPasswd": "SOnaTEst",
|
||||
"RawCert": "",
|
||||
"SkipCert": true,
|
||||
"ReExecVeto": 90,
|
||||
"Note": "Sync periodico completo",
|
||||
"StepsList": [
|
||||
{
|
||||
"Id": "01",
|
||||
"Description": "Mirror Remote 2 Local Directory",
|
||||
"Action": "mirrorDirR2L",
|
||||
"ParamList": {
|
||||
"RemoteDir": "internal/MES",
|
||||
"LocalDir": "\\\\308file\\shares\\QUAL\\Sonatest_Reports\\MES"
|
||||
}
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -103,15 +103,6 @@
|
||||
<Reference Include="EasyModbus, Version=5.6.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\EasyModbusTCP.5.6.0\lib\net40\EasyModbus.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="EgwProxy.Gomba, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\EgwProxy.Gomba.3.6.2309.1416\lib\EgwProxy.Gomba.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="EgwProxy.Icoel, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\EgwProxy.Icoel.3.6.2309.708\lib\EgwProxy.Icoel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="EgwProxy.Icoel.DataLayer, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\EgwProxy.Icoel.3.6.2309.708\lib\EgwProxy.Icoel.DataLayer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="EgwProxy.MultiCncLib, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\EgwProxy.MultiCncLib.3.6.2207.1211\lib\EgwProxy.MultiCncLib.dll</HintPath>
|
||||
</Reference>
|
||||
@@ -121,18 +112,12 @@
|
||||
<Reference Include="EgwProxy.OsaiCncLib.XmlSerializers, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\EgwProxy.OsaiCncLib.3.6.2205.2015\lib\EgwProxy.OsaiCncLib.XmlSerializers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="EgwProxy.SqlDb, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\EgwProxy.SqlDb.3.6.2303.1515\lib\EgwProxy.SqlDb.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\EntityFramework.6.5.1\lib\net45\EntityFramework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\EntityFramework.6.5.1\lib\net45\EntityFramework.SqlServer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="FluentFTP, Version=51.1.0.0, Culture=neutral, PublicKeyToken=f4af092b1d8df44f, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentFTP.51.1.0\lib\net462\FluentFTP.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="krcc, Version=0.0.0.0, Culture=neutral, processorArchitecture=x86">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>ExtLib\krcc.dll</HintPath>
|
||||
@@ -404,9 +389,6 @@
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="IobFile\IobFileSoitaab.cs" />
|
||||
<Compile Include="IobSql\SqlServLantek.cs" />
|
||||
<Compile Include="IobSql\SqlServPama.cs" />
|
||||
<Compile Include="IobSql\IcoelDb.cs" />
|
||||
<Compile Include="Iob\Mitsubishi.cs" />
|
||||
<Compile Include="MainFormNext.cs">
|
||||
<SubType>Form</SubType>
|
||||
@@ -666,9 +648,7 @@
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="IobNet\" />
|
||||
<Folder Include="IobRest\" />
|
||||
<Folder Include="IobSoap\" />
|
||||
<Folder Include="IobSql\" />
|
||||
<Folder Include="prog\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using EgwProxy.SqlDb.DbModels;
|
||||
#if false
|
||||
using EgwProxy.SqlDb.DbModels;
|
||||
#endif
|
||||
using IOB_UT_NEXT;
|
||||
using MapoSDK;
|
||||
using System;
|
||||
@@ -221,10 +223,12 @@ namespace IOB_WIN_NEXT.IobFile
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
#if false
|
||||
/// <summary>
|
||||
/// Stato di sync delle tab gestite
|
||||
/// </summary>
|
||||
protected List<SyncStateModel> elencoSyncState { get; set; } = new List<SyncStateModel>();
|
||||
protected List<SyncStateModel> elencoSyncState { get; set; } = new List<SyncStateModel>();
|
||||
#endif
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
|
||||
@@ -1,471 +0,0 @@
|
||||
using EgwProxy.Icoel;
|
||||
using EgwProxy.Icoel.SizerService;
|
||||
using IOB_UT_NEXT;
|
||||
using MapoSDK;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.NetworkInformation;
|
||||
|
||||
namespace IOB_WIN_NEXT.IobNet
|
||||
{
|
||||
/// <summary>
|
||||
/// Adapter specializzato per ICOEL e le chiamate tramite WS Soap al Sizer, con libreria EgwProxy.Icoel
|
||||
/// </summary>
|
||||
public class IcoelSoap : Iob.GenericNext
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Costruttore dell'IOB Icoel SOAP
|
||||
/// </summary>
|
||||
/// <param name="caller">AdapterForm chiamante</param>
|
||||
/// <param name="IOBConf">Configurazione IOB per avvio</param>
|
||||
public IcoelSoap(AdapterFormNext caller, IobConfiguration IOBConf) : base(caller, IOBConf)
|
||||
{
|
||||
/* --------------------------------------
|
||||
* todo's
|
||||
* --------------------------------------
|
||||
* - init obj comunicazione da conf e nuget
|
||||
* - test comunicazione
|
||||
* - estensione IOB come OPT_PAR di OVERRIDE (x inviare dati di un unico iOB da più IOB programs)
|
||||
* - gestione processCustomTaskLF
|
||||
* - x lettura dei 2 batch correnti (sx/dx)
|
||||
* - calcolo batch in corso/chiusi da date inizio/fine
|
||||
* - trasmettere a MP/IO risultato valutazioni
|
||||
* - gestione executeTasks
|
||||
* - task di invio batch configurato in coda
|
||||
* - task di recupero info anagrafiche (grower, variety, layout,...)
|
||||
* - contapezzi (SE ha senso con sizer oppure saltare)
|
||||
*/
|
||||
|
||||
IcoelSizer = new Connector(IOBConf.cncIpAddr, IOBConf.cncPort);
|
||||
lastPING = DateTime.Now.AddHours(-1);
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Implementazione custom esecuzione task specifici
|
||||
/// </summary>
|
||||
/// <param name="task2exe"></param>
|
||||
/// <returns></returns>
|
||||
public override Dictionary<string, string> executeTasks(Dictionary<string, string> task2exe)
|
||||
{
|
||||
/*---------------------------------------
|
||||
* fixme todo fare !!!
|
||||
* gestione execute task SPECIFICI x il sizer:
|
||||
* - recupero anagrafice variety/layout (attivi)
|
||||
* - recupero grower
|
||||
* - invio batch da accodare
|
||||
* - recupero dati da sizer (OVE disponibili)
|
||||
* - recupero batch corrente (modalità force/resync?)
|
||||
*
|
||||
*---------------------------------------*/
|
||||
|
||||
// Verificare il protocollo: dovrebbe togliere SOLO i task eseguiti...
|
||||
Dictionary<string, string> taskDone = new Dictionary<string, string>();
|
||||
if (task2exe != null)
|
||||
{
|
||||
// controllo se memMap != null...
|
||||
if (memMap != null)
|
||||
{
|
||||
bool taskOk = false;
|
||||
string taskVal = "";
|
||||
// cerco task specifici: se ho startSetup --> imposto bit DBB701.DBB0.4
|
||||
foreach (var item in task2exe)
|
||||
{
|
||||
taskOk = false;
|
||||
taskVal = "";
|
||||
// converto richiesta in enum...
|
||||
taskType tName = taskType.nihil;
|
||||
Enum.TryParse(item.Key, out tName);
|
||||
// controllo sulla KEY...
|
||||
switch (tName)
|
||||
{
|
||||
case taskType.setSupplier:
|
||||
|
||||
string cmdArgs = item.Value;
|
||||
taskVal = executeSetSupplier(cmdArgs);
|
||||
break;
|
||||
|
||||
case taskType.setParameter:
|
||||
// richiedo da URL i parametri WRITE da popolare
|
||||
lgInfo("Chiamata setParameter --> processMemWriteRequests");
|
||||
taskVal = processMemWriteRequests();
|
||||
// se restituiscce "" faccio altra prova...
|
||||
if (string.IsNullOrEmpty(taskVal))
|
||||
{
|
||||
// i parametri me li aspetto come stringa composta paramName|paramvalue
|
||||
if (item.Value.Contains("|"))
|
||||
{
|
||||
string[] paramsJob = item.Value.Split('|');
|
||||
taskVal = $"REQUEST SET PARAMETERS: {paramsJob[0]} --> {paramsJob[1]}";
|
||||
}
|
||||
else
|
||||
{
|
||||
taskVal = $"WRONG REQUEST FOR SET PARAMETERS: {item.Value} doesnt contain pipe for splitting key/value";
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
|
||||
lgInfo($"Chiamata senza processing: taskOk: {taskOk} | taskVal: {taskVal}");
|
||||
break;
|
||||
}
|
||||
// aggiungo task!
|
||||
taskDone.Add(item.Key, taskVal);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError($"Attenzione! memMap è nullo, non posso eseguire task2exe!");
|
||||
}
|
||||
}
|
||||
|
||||
return taskDone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero dati dinamici...
|
||||
/// </summary>
|
||||
public override Dictionary<string, string> getDynData()
|
||||
{
|
||||
// valore non presente in vers default... se gestito fare override
|
||||
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
||||
// recupero da libreria il dizionario dei performance parameters...
|
||||
perfParamDict = IcoelSizer.GetPerfMeters();
|
||||
lgTrace("SOAP: effettuata chiamata IcoelSizer.GetPerfMeters()");
|
||||
foreach (var item in perfParamDict)
|
||||
{
|
||||
saveValue(ref outVal, item.Key, item.Value);
|
||||
}
|
||||
// ora leggo i batch data
|
||||
batchDataDict = IcoelSizer.GetCurrBatchData();
|
||||
lgTrace("SOAP: effettuata chiamata IcoelSizer.GetCurrBatchData()");
|
||||
foreach (var item in batchDataDict)
|
||||
{
|
||||
saveValueString(ref outVal, item.Key, item.Value);
|
||||
}
|
||||
|
||||
lastReadPLC = DateTime.Now;
|
||||
return outVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua processing CUSTOM x Icoel:
|
||||
/// - recupera elenco batch delle 2 linee
|
||||
/// - invia al sistema
|
||||
/// </summary>
|
||||
public override void processCustomTaskLF()
|
||||
{
|
||||
lgInfo($"Richiesto processCustomTaskLF");
|
||||
var currBatch = IcoelSizer.GetCurrentBatch();
|
||||
lgTrace("SOAP: effettuata chiamata IcoelSizer.GetCurrentBatch()");
|
||||
if (currBatch != null)
|
||||
{
|
||||
// verifico se i batch siano variati... e quindi da inviare...
|
||||
bool doSend = (currBatchList == null || currBatchList.Count == 0);
|
||||
if (currBatch.Count > 0 && !doSend)
|
||||
{
|
||||
foreach (var item in currBatch)
|
||||
{
|
||||
// se variato ID è cambiato
|
||||
doSend = doSend || (currBatchList[item.Key].Id != item.Value.Id);
|
||||
}
|
||||
}
|
||||
// se devo inviare impacchetto dati
|
||||
if (doSend)
|
||||
{
|
||||
accodaRawData(rawTransfType.IcoelBatch, currBatch);
|
||||
currBatchList = currBatch;
|
||||
}
|
||||
}
|
||||
|
||||
lastReadPLC = DateTime.Now;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua lettura semafori principale <paramref name="currDispData">Parametri da
|
||||
/// aggiornare x display in form</paramref>
|
||||
/// </summary>
|
||||
public override void readSemafori(ref newDisplayData currDispData)
|
||||
{
|
||||
if (connectionOk)
|
||||
{
|
||||
B_input = 1;
|
||||
currDispData.semIn = Semaforo.SV;
|
||||
if (currBatchList == null)
|
||||
{
|
||||
// se nullo --> provo a leggere!
|
||||
var currBatch = IcoelSizer.GetCurrentBatch();
|
||||
lgTrace("SOAP: effettuata chiamata IcoelSizer.GetCurrentBatch()");
|
||||
if (currBatch != null)
|
||||
{
|
||||
currBatchList = currBatch;
|
||||
accodaRawData(rawTransfType.IcoelBatch, currBatch);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//se i perf parameters mi danno valire > 0 x quantità frutta...
|
||||
if (perfParamDict != null && perfParamDict.Count > 0)
|
||||
{
|
||||
if (perfParamDict.ContainsKey("VelFruttiMinuto"))
|
||||
{
|
||||
if (perfParamDict["VelFruttiMinuto"] > 0)
|
||||
{
|
||||
B_input += (1 << 1);
|
||||
}
|
||||
// metto manuale
|
||||
else
|
||||
{
|
||||
B_input += (1 << 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//usato altro criterio x stato verde da vel frutti minuto
|
||||
#if false
|
||||
// se ho batch NON chiusi (data = minValue) allora lavora
|
||||
if (currBatchList[1].EndTime == DateTime.MinValue || currBatchList[1].EndTime == DateTime.MinValue)
|
||||
{
|
||||
B_input = 3;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
// accodo NON emergenza
|
||||
B_input += (1 << 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
B_input = 0;
|
||||
currDispData.semIn = Semaforo.SR;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override connessione
|
||||
/// </summary>
|
||||
public override void tryConnect()
|
||||
{
|
||||
if (!connectionOk)
|
||||
{
|
||||
// controllo che il ping sia stato tentato almeno pingTestSec fa...
|
||||
if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec"))
|
||||
{
|
||||
if (verboseLog || periodicLog)
|
||||
{
|
||||
lgInfo("IcoelSoap: ConnKO - tryConnect");
|
||||
}
|
||||
// in primis salvo data ping...
|
||||
lastPING = DateTime.Now;
|
||||
// se passa il ping faccio il resto...
|
||||
if (testPingMachine == IPStatus.Success)
|
||||
{
|
||||
string szStatusConnection = "";
|
||||
try
|
||||
{
|
||||
// ora provo connessione...
|
||||
parentForm.commPlcActive = true;
|
||||
// recupero elenco batch... se != vuoto -_> connesso!
|
||||
var batchList = IcoelSizer.GetCurrentBatch();
|
||||
lgTrace("SOAP: effettuata chiamata IcoelSizer.GetCurrentBatch()");
|
||||
if (batchList != null && batchList.Count > 0)
|
||||
{
|
||||
lgInfo($"szStatusConnection IcoelSoap, recuperato elenco di {batchList.Count} batch");
|
||||
parentForm.commPlcActive = false;
|
||||
connectionOk = true;
|
||||
}
|
||||
// refresh stato connessione!!!
|
||||
if (connectionOk)
|
||||
{
|
||||
queueInEnabCurr = true;
|
||||
if (adpRunning)
|
||||
{
|
||||
lgInfo("Connessione OK");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError("Impossibile procedere, connessione mancante...");
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
lgFatal($"Errore nella connessione all'adapter IcoelSoap: {szStatusConnection}{Environment.NewLine}{exc}");
|
||||
connectionOk = false;
|
||||
lgInfo($"Eccezione in TryConnect, Adapter IcoelSoap NON running, pausa di {utils.CRI("waitRecMSec")} msec prima di ulteriori tentativi di riconnessione");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// loggo no risposta ping ...
|
||||
connectionOk = false;
|
||||
if (verboseLog || periodicLog)
|
||||
{
|
||||
lgInfo($"Attenzione: IcoelSoap controllo PING fallito per IP {cIobConf.cncPingAddr}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
needRefresh = true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void tryDisconnect()
|
||||
{
|
||||
// registro solo che è disconnesso
|
||||
connectionOk = false;
|
||||
queueInEnabCurr = false;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario dati Batch correnti
|
||||
/// </summary>
|
||||
protected Dictionary<string, string> batchDataDict { get; set; } = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// elenco dei BAtch correntemente caricati x testing variazione
|
||||
/// </summary>
|
||||
protected Dictionary<int, Batch> currBatchList { get; set; }
|
||||
|
||||
protected Connector IcoelSizer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario parametri correnti
|
||||
/// </summary>
|
||||
protected Dictionary<string, double> perfParamDict { get; set; } = new Dictionary<string, double>();
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Metodo da overridare x scrivere DAVVERO i parametri sul PLC
|
||||
/// </summary>
|
||||
/// <param name="updatedPar"></param>
|
||||
protected override void plcWriteParams(ref List<objItem> updatedPar)
|
||||
{
|
||||
foreach (var item in updatedPar)
|
||||
{
|
||||
// cerco se sia setSupplier
|
||||
if (item.uid == "setSupplier")
|
||||
{
|
||||
string reqVal = !string.IsNullOrEmpty(item.reqValue) ? item.reqValue : item.value;
|
||||
// chiamo
|
||||
var taskVal = executeSetSupplier(reqVal);
|
||||
bool fatto = taskVal.StartsWith("REQUEST");
|
||||
// se fatto --> aggiorno!
|
||||
if (fatto)
|
||||
{
|
||||
//item.value = item.reqValue;
|
||||
item.reqValue = "";
|
||||
item.lastRead = DateTime.Now;
|
||||
item.UM = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// recupera le variety ed i rispettivi layout e li invia al sistema MP/IO
|
||||
/// </summary>
|
||||
protected void refreshVarietyData()
|
||||
{
|
||||
///determina se recuperare SOLO varietà attive o tutte
|
||||
bool soloAttive = false;
|
||||
var varList = IcoelSizer.GetVarietyList(soloAttive);
|
||||
lgTrace("SOAP: effettuata chiamata IcoelSizer.GetVarietyList()");
|
||||
if (varList != null && varList.Length > 0)
|
||||
{
|
||||
var varietyData = IcoelSizer.GetLayoutForVarietyList(varList);
|
||||
lgTrace("SOAP: effettuata chiamata IcoelSizer.GetLayoutForVarietyList()");
|
||||
}
|
||||
|
||||
lastReadPLC = DateTime.Now;
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private string executeSetSupplier(string cmdArgs)
|
||||
{
|
||||
string taskVal;
|
||||
// loggo i parametri ricevuti da popolare
|
||||
lgInfo($"Chiamata setSupplier --> params payload: {cmdArgs}");
|
||||
// recupero batch corrente x preselezionare i dati guid layout/varietà...
|
||||
var currBatch = IcoelSizer.GetCurrentBatch();
|
||||
// recupero GUID x variety e layout di default
|
||||
var varGuid = currBatch[1].VarietyId;
|
||||
var layGuid = currBatch[1].LayoutId;
|
||||
// predispongo grower di default
|
||||
GrowerInfo GrowerData = new GrowerInfo();
|
||||
// le info sono una stringa separata da valore | di GrowerCode|GrowerName|varietyGuid|LayoutGuid;
|
||||
string[] reqParams = cmdArgs.Split('|');
|
||||
// se ho dati sistemo grower...
|
||||
if (reqParams.Length >= 2)
|
||||
{
|
||||
//GrowerData.GrowerCode = reqParams[0];
|
||||
//GrowerData.GrowerName = reqParams[1];
|
||||
// sistemo commenti
|
||||
var comments = new List<string>();
|
||||
comments.Add($"sent {DateTime.Now: yyyy.MM.dd HH:mm:ss}");
|
||||
comments.Add("Qty: no set");
|
||||
comments.Add("------------");
|
||||
//GrowerData.Comments = comments;
|
||||
|
||||
GrowerData = new GrowerInfo()
|
||||
{
|
||||
GrowerCode = reqParams[0],
|
||||
GrowerName = reqParams[1],
|
||||
Comments = comments
|
||||
};
|
||||
lgInfo($"Set grower data | GrowerCode: {GrowerData.GrowerCode} | GrowerName: {GrowerData.GrowerName}");
|
||||
}
|
||||
if (reqParams.Length >= 3)
|
||||
{
|
||||
Guid.TryParse(reqParams[2], out varGuid);
|
||||
lgInfo($"Set Variety data | VarGUID: {varGuid}");
|
||||
}
|
||||
if (reqParams.Length >= 4)
|
||||
{
|
||||
Guid.TryParse(reqParams[3], out layGuid);
|
||||
lgInfo($"Set Layout data | LayGUID: {layGuid}");
|
||||
}
|
||||
|
||||
// invio richiesta!!!
|
||||
IcoelSizer.EnqueueBatch(GrowerData, varGuid, layGuid);
|
||||
lgInfo($"Request sent!");
|
||||
|
||||
taskVal = $"REQUEST SET SUPPLIER | EnqueueBatch | GrowCode: {GrowerData.GrowerCode} | GrowName: {GrowerData.GrowerName} | Var: {varGuid} | Lay: {layGuid} ";
|
||||
// se restituiscce "" faccio altra prova...
|
||||
if (string.IsNullOrEmpty(taskVal))
|
||||
{
|
||||
// i parametri me li aspetto come stringa composta paramName|paramvalue
|
||||
if (cmdArgs.Contains("|"))
|
||||
{
|
||||
string[] paramsJob = cmdArgs.Split('|');
|
||||
taskVal = $"REQUEST SET PARAMETERS: {paramsJob[0]} --> {paramsJob[1]}";
|
||||
}
|
||||
else
|
||||
{
|
||||
taskVal = $"WRONG REQUEST FOR SET PARAMETERS: {cmdArgs} doesnt contain pipe for splitting key/value";
|
||||
}
|
||||
}
|
||||
|
||||
return taskVal;
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -1,633 +0,0 @@
|
||||
using IOB_UT_NEXT;
|
||||
using MapoSDK;
|
||||
using Newtonsoft.Json;
|
||||
using RestSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace IOB_WIN_NEXT.IobRest
|
||||
{
|
||||
/// <summary>
|
||||
/// Adapter base per sviluppo chiamate con servizi REST
|
||||
/// </summary>
|
||||
public class Base : Iob.GenericNext
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Costruttore dell'IOB Rest generico
|
||||
/// </summary>
|
||||
/// <param name="caller">AdapterForm chiamante</param>
|
||||
/// <param name="IOBConf">Configurazione IOB per avvio</param>
|
||||
public Base(AdapterFormNext caller, IobConfiguration IOBConf) : base(caller, IOBConf)
|
||||
{
|
||||
lgInfo($"Richiesto Adapter IobRest.Base con i parametri seguenti | ADDR: {IOBConf.cncIpAddr} | PORT: {IOBConf.cncPort}");
|
||||
lastPING = DateTime.Now.AddHours(-1);
|
||||
// predispongo configurazione specifica Rest...
|
||||
if (!string.IsNullOrEmpty(getOptPar("REST_CONF")))
|
||||
{
|
||||
setupRestConf(getOptPar("REST_CONF"));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Implementazione custom esecuzione task specifici
|
||||
/// </summary>
|
||||
/// <param name="task2exe"></param>
|
||||
/// <returns></returns>
|
||||
public override Dictionary<string, string> executeTasks(Dictionary<string, string> task2exe)
|
||||
{
|
||||
/*---------------------------------------
|
||||
* gestione execute task SPECIFICI x pesa:
|
||||
* - salva i parametri richiesta (RM, cod1..cod6)
|
||||
* - esegue metodo richiesta (IN/OUT)
|
||||
*---------------------------------------*/
|
||||
|
||||
// Verificare il protocollo: dovrebbe togliere SOLO i task eseguiti...
|
||||
Dictionary<string, string> taskDone = new Dictionary<string, string>();
|
||||
#if false
|
||||
if (task2exe != null)
|
||||
{
|
||||
lgTrace($"executeTasks: richiesta esecuzione {task2exe.Count} task");
|
||||
// controllo se memMap != null...
|
||||
if (memMap != null)
|
||||
{
|
||||
bool taskOk = false;
|
||||
string taskVal = "";
|
||||
// cerco task specifici: qui sono NON standard...
|
||||
foreach (var item in task2exe)
|
||||
{
|
||||
lgInfo($"TASK | {item.Key} --> {item.Value}");
|
||||
taskOk = false;
|
||||
taskVal = "";
|
||||
// converto richiesta in enum...
|
||||
taskType tName = taskType.nihil;
|
||||
Enum.TryParse(item.Key, out tName);
|
||||
// controllo sulla KEY...
|
||||
switch (tName)
|
||||
{
|
||||
case taskType.setParameter:
|
||||
// richiedo da URL i parametri WRITE da popolare
|
||||
lgInfo("Chiamata setParameter --> processMemWriteRequests");
|
||||
taskVal = processMemWriteRequests();
|
||||
// se restituiscce "" faccio altra prova...
|
||||
if (string.IsNullOrEmpty(taskVal))
|
||||
{
|
||||
// i parametri me li aspetto come stringa composta paramName|paramvalue
|
||||
if (item.Value.Contains("|"))
|
||||
{
|
||||
string[] paramsJob = item.Value.Split('|');
|
||||
taskVal = $"REQUEST SET PARAMETERS: {paramsJob[0]} --> {paramsJob[1]}";
|
||||
}
|
||||
else
|
||||
{
|
||||
taskVal = $"WRONG REQUEST FOR SET PARAMETERS: {item.Value} doesnt contain pipe for splitting key/value";
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
|
||||
lgInfo($"Chiamata senza processing: taskOk: {taskOk} | taskVal: {taskVal}");
|
||||
break;
|
||||
}
|
||||
// aggiungo task!
|
||||
taskDone.Add(item.Key, taskVal);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError($"Attenzione! memMap è nullo, non posso eseguire task2exe!");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return taskDone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero dati dinamici...
|
||||
/// </summary>
|
||||
public override Dictionary<string, string> getDynData()
|
||||
{
|
||||
// valore non presente in vers default... se gestito fare override
|
||||
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
||||
// indico esecuzione e proseguo
|
||||
lastReadPLC = DateTime.Now;
|
||||
return outVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua lettura semafori principale <paramref name="currDispData">Parametri da
|
||||
/// aggiornare x display in form</paramref>
|
||||
/// </summary>
|
||||
public override void readSemafori(ref newDisplayData currDispData)
|
||||
{
|
||||
DateTime adesso = DateTime.Now;
|
||||
lastReadPLC = adesso;
|
||||
// verifico non sia in veto invio iniziale...
|
||||
if (queueInEnabCurr)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (verboseLog)
|
||||
{
|
||||
lgInfo("inizio read semafori");
|
||||
}
|
||||
|
||||
currDispData.semIn = Semaforo.SV;
|
||||
// effettua refresh dati da leggere SPECIFICi x citizen...
|
||||
refreshData();
|
||||
// decodifica e gestione
|
||||
decodeToBaseBitmap(ref currDispData);
|
||||
// display
|
||||
reportRawInput(ref currDispData);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
currDispData.semIn = Semaforo.SR;
|
||||
lgError($"Eccezione in readSemafori:{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lgDebug($"[VETO readSemafori] | veto attivo alle {adesso:yyyy.MM.dd HH:mm:ss}");
|
||||
checkVetoQueueIn();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override connessione
|
||||
/// </summary>
|
||||
public override void tryConnect()
|
||||
{
|
||||
if (!connectionOk)
|
||||
{
|
||||
// controllo che il ping sia stato tentato almeno pingTestSec fa...
|
||||
if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec"))
|
||||
{
|
||||
if (verboseLog || periodicLog)
|
||||
{
|
||||
lgInfo("Rest: ConnKO - tryConnect");
|
||||
}
|
||||
// in primis salvo data ping...
|
||||
lastPING = DateTime.Now;
|
||||
// se passa il ping faccio il resto...
|
||||
if (testPingMachine == IPStatus.Success)
|
||||
{
|
||||
string szStatusConnection = "";
|
||||
try
|
||||
{
|
||||
// ora provo connessione...
|
||||
parentForm.commPlcActive = true;
|
||||
|
||||
// chiamo metodo connect
|
||||
var checkResp = ExecuteCallGet(GetUrlResource("GetConnection"), true);
|
||||
// forse va eliminato...
|
||||
lgInfo($"GetConnection | {checkResp} (Base.tryConnect)");
|
||||
if (checkResp != null && checkResp.ToLower().Contains("true"))
|
||||
{
|
||||
connectionOk = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError($"Errore check connessione | checkResp: {checkResp}");
|
||||
}
|
||||
// refresh stato connessione!!!
|
||||
if (connectionOk)
|
||||
{
|
||||
queueInEnabCurr = true;
|
||||
if (adpRunning)
|
||||
{
|
||||
lgInfo("Connessione OK");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError("Impossibile procedere, connessione mancante...");
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
lgFatal($"Errore nella connessione all'Adapter IobRest.Base: {szStatusConnection}{Environment.NewLine}{exc}");
|
||||
connectionOk = false;
|
||||
lgInfo($"Eccezione in TryConnect, Adapter IobRest.Base NON running, pausa di {utils.CRI("waitRecMSec")} msec prima di ulteriori tentativi di riconnessione");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// loggo no risposta ping ...
|
||||
connectionOk = false;
|
||||
if (verboseLog || periodicLog)
|
||||
{
|
||||
lgInfo($"Attenzione: Rest controllo PING fallito per IP {cIobConf.cncPingAddr}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
needRefresh = true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void tryDisconnect()
|
||||
{
|
||||
// registro solo che è disconnesso
|
||||
connectionOk = false;
|
||||
queueInEnabCurr = false;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
/// <summary>
|
||||
/// Api Url di base x chiamate REST
|
||||
/// </summary>
|
||||
protected string apiUrl = "http://localhost:8733";
|
||||
|
||||
/// <summary>
|
||||
/// Num err connessioni corrente
|
||||
/// </summary>
|
||||
protected int connErrCur = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Max num err connesisone prima di disconnettere
|
||||
/// </summary>
|
||||
protected int connErrMax = 5;
|
||||
|
||||
/// <summary>
|
||||
/// LookUpTable informazioni raccolte
|
||||
/// </summary>
|
||||
protected Dictionary<string, string> RestDataLUT = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Timeout chiamate REST
|
||||
/// </summary>
|
||||
protected int tOutSec = 60;
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
/// <summary>
|
||||
/// Parametri specifici Client Rest
|
||||
/// </summary>
|
||||
protected RestParamConf restParams { get; set; } = new RestParamConf();
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// verifica stato ok ovvero connected oppure open
|
||||
/// </summary>
|
||||
/// <param name="currState"></param>
|
||||
/// <returns></returns>
|
||||
protected bool checkStateOk(System.ServiceModel.CommunicationState currState)
|
||||
{
|
||||
bool answ = false;
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua decodifica aree memoria alla bitmap usata x MAPO
|
||||
/// </summary>
|
||||
protected virtual void decodeToBaseBitmap(ref newDisplayData currDispData)
|
||||
{
|
||||
// init a zero...
|
||||
B_input = 0;
|
||||
if (queueInEnabCurr)
|
||||
{
|
||||
/* -----------------------------------------------------
|
||||
* bitmap MAPO STD 60
|
||||
* B0: POWER_ON
|
||||
* B1: RUN
|
||||
* B2: pzCount
|
||||
* B3: allarme
|
||||
* B4: manuale
|
||||
* B5: allarme TCiclo (SLOW)
|
||||
* B6: WarmUp_CoolDown
|
||||
* B7: EmergArmed (1 = NON emergenza, 0 = emergenza)
|
||||
----------------------------------------------------- */
|
||||
|
||||
// per prima cosa controllo ping e se sia connesso...
|
||||
|
||||
#if false
|
||||
if (connectionOk)
|
||||
{
|
||||
B_input = 1;
|
||||
currDispData.semIn = Semaforo.SV;
|
||||
|
||||
// se ho pesate in memoria nel periodo richiesto --> RUN
|
||||
if (listPesateCurr != null && listPesateCurr.Count > 0)
|
||||
{
|
||||
B_input += (1 << 1);
|
||||
}
|
||||
// metto manuale
|
||||
else
|
||||
{
|
||||
B_input += (1 << 4);
|
||||
}
|
||||
|
||||
// accodo NON emergenza
|
||||
B_input += (1 << 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
B_input = 0;
|
||||
currDispData.semIn = Semaforo.SR;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
lgDebug($"[VETO getDataItemValue] | veto attivo alle {DateTime.Now:yyyy.MM.dd HH:mm:ss}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Esecuzione chiamata Rest tipo GET
|
||||
/// </summary>
|
||||
/// <param name="resource">URI da chiamare</param>
|
||||
/// <param name="fastCall">Chiamata rapida (timeout rapido = 5sec)</param>
|
||||
/// <returns></returns>
|
||||
protected string ExecuteCallGet(string resource, bool fastCall = false)
|
||||
{
|
||||
string answ = "";
|
||||
if (!string.IsNullOrEmpty(resource))
|
||||
{
|
||||
if (fastCall)
|
||||
{
|
||||
restOptStd.Timeout = TimeSpan.FromSeconds(5);
|
||||
}
|
||||
try
|
||||
{
|
||||
// client chiamate rest
|
||||
using (var client = new RestClient(restOptStd))
|
||||
{
|
||||
var actReq = new RestRequest(resource, Method.Get);
|
||||
// effettuo vera chiamata
|
||||
var currResp = client.Get(actReq);
|
||||
if (currResp.StatusCode == System.Net.HttpStatusCode.OK && currResp.Content != null)
|
||||
{
|
||||
answ = currResp.Content ?? "";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
lgError($"Eccezione in ExecuteCallGet{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Esecuzione chiamata Rest tipo POST
|
||||
/// </summary>
|
||||
/// <param name="resource">URI da chiamare</param>
|
||||
/// <param name="payload">Payload da allegare (già serializzato)</param>
|
||||
/// <param name="fastCall">Chiamata rapida (timeout rapido = 5sec)</param>
|
||||
/// <returns></returns>
|
||||
protected string ExecuteCallPost(string resource, string payload, bool fastCall = false)
|
||||
{
|
||||
string answ = "";
|
||||
if (!string.IsNullOrEmpty(resource))
|
||||
{
|
||||
if (fastCall)
|
||||
{
|
||||
restOptStd.Timeout = TimeSpan.FromSeconds(5);
|
||||
}
|
||||
try
|
||||
{
|
||||
// client chiamate rest
|
||||
using (var client = new RestClient(restOptStd))
|
||||
{
|
||||
var actReq = new RestRequest(resource, Method.Post);
|
||||
actReq.AddJsonBody(payload);
|
||||
// effettuo vera chiamata
|
||||
var currResp = client.Post(actReq);
|
||||
if (currResp.StatusCode == System.Net.HttpStatusCode.OK && currResp.Content != null)
|
||||
{
|
||||
answ = currResp.Content ?? "";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
lgError($"Eccezione in ExecuteCallPost{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// restituisce URL della risorsa eventualmente completato con token o altro
|
||||
/// </summary>
|
||||
/// <param name="resName"></param>
|
||||
/// <returns></returns>
|
||||
protected string GetUrlResource(string resName)
|
||||
{
|
||||
string answ = "";
|
||||
if (restParams != null && restParams.CallList != null && restParams.CallList.Count > 0)
|
||||
{
|
||||
if (restParams.CallList.ContainsKey(resName))
|
||||
{
|
||||
answ = restParams.CallList[resName].Url;
|
||||
// eseguo eventuale sostituzione (se trovo "[[")
|
||||
if (answ.Contains("[["))
|
||||
{
|
||||
string pattern = @"\[\[.*\]\]";
|
||||
Regex regex = new Regex(pattern);
|
||||
Match match = regex.Match(answ);
|
||||
if (match.Success)
|
||||
{
|
||||
string key = match.Value.Replace("[[", "").Replace("]]", "");
|
||||
// cerco nella LUT...
|
||||
if (RestDataLUT.ContainsKey(key))
|
||||
{
|
||||
// sostituisco!
|
||||
answ = answ.Replace($"[[{key}]]", RestDataLUT[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Metodo da overridare x scrivere DAVVERO i parametri sul PLC
|
||||
/// </summary>
|
||||
/// <param name="updatedPar"></param>
|
||||
protected override void plcWriteParams(ref List<objItem> updatedPar)
|
||||
{
|
||||
lgTrace($"plcWriteParams: richiesta per {updatedPar.Count} params");
|
||||
foreach (var item in updatedPar)
|
||||
{
|
||||
lgInfo($"ITEM | {item.uid} | {item.value}");
|
||||
// salvo i valori di setup x prox volta...
|
||||
upsertKey(item.uid, item.value);
|
||||
#if false
|
||||
bool fatto = false;
|
||||
bool isPesata = false;
|
||||
bool isIN = false;
|
||||
gestWeightOut answ = new gestWeightOut();
|
||||
// se è richiesta pesata IN/OUT --> mando chiamata
|
||||
if (item.uid == "reqPesata")
|
||||
{
|
||||
isPesata = true;
|
||||
isIN = item.reqValue.ToUpper() == "IN";
|
||||
//isIN = item.value.ToUpper() == "IN";
|
||||
try
|
||||
{
|
||||
answ = reqWeight(isIN);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
lgError($"Eccezione in plcWriteParams.reqWeight | isIn: {isIN}{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
else if (item.uid == "RM" || item.uid.StartsWith("Cod"))
|
||||
{
|
||||
// comunque segno fatto x altri casi
|
||||
fatto = true;
|
||||
}
|
||||
|
||||
// se è pesata...
|
||||
if (isPesata)
|
||||
{
|
||||
// se è OK
|
||||
if (answ.feedback == "C")
|
||||
{
|
||||
lgInfo($"reqWeight | Effettuato richiesta | {answ.feedback} | {answ.notes}");
|
||||
// resetto pesata
|
||||
upsertKey(item.uid, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError($"reqWeight | Errore in richiesta peso Rest | {answ.feedback} | {answ.notes}");
|
||||
}
|
||||
item.value = "";
|
||||
item.reqValue = "";
|
||||
item.lastRead = DateTime.Now;
|
||||
item.UM = "";
|
||||
// salvo esito richiesta comunque
|
||||
upsertKey("logReq", $"{answ.feedback} | {answ.notes}");
|
||||
// faccio in modo di eseguire subito getDynData
|
||||
demFactDynData = 1;
|
||||
processDynData();
|
||||
}
|
||||
else
|
||||
{
|
||||
// se fatto --> aggiorno!
|
||||
if (fatto)
|
||||
{
|
||||
//item.value = item.reqValue;
|
||||
item.reqValue = "";
|
||||
item.lastRead = DateTime.Now;
|
||||
item.UM = "";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Esegue lettura dati + salvataggio in LUT
|
||||
/// </summary>
|
||||
protected virtual void refreshData()
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Recupero valore da cache LUT
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
protected string RestLutGet(string key)
|
||||
{
|
||||
string value = "";
|
||||
if (RestDataLUT.ContainsKey(key))
|
||||
{
|
||||
value = RestDataLUT[key];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Upsert in cache LUT del parametro
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
protected void RestLutUpsert(string key, string value)
|
||||
{
|
||||
if (RestDataLUT.ContainsKey(key))
|
||||
{
|
||||
RestDataLUT[key] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
RestDataLUT.Add(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
protected void setupRestConf(string restConfFile)
|
||||
{
|
||||
// se ho file specifico
|
||||
if (!string.IsNullOrEmpty(getOptPar("REST_CONF")))
|
||||
{
|
||||
string rawData = "";
|
||||
// leggo file e decodifico...
|
||||
string confPath = $"{Application.StartupPath}/DATA/CONF/{restConfFile}";
|
||||
lgInfo($"Apertura file {confPath}");
|
||||
using (StreamReader sr = new StreamReader(confPath))
|
||||
{
|
||||
rawData = sr.ReadToEnd().Replace("\n", "").Replace("\r", "");
|
||||
}
|
||||
// continuo decodifica
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
restParams = JsonConvert.DeserializeObject<RestParamConf>(rawData);
|
||||
if (restParams != null)
|
||||
{
|
||||
// inizializzo dal file di conf le variabili necessarie...
|
||||
tOutSec = restParams.timeOutSec;
|
||||
apiUrl = restParams.apiUrl ?? "http://localhost:8733";
|
||||
// sistemo parametri specali come samplePeriod ed errori conn...
|
||||
samplePeriod = restParams.samplePeriod;
|
||||
connErrMax = restParams.connErrorMax;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sistemo conf standard x call REST
|
||||
restOptStd = new RestClientOptions
|
||||
{
|
||||
Timeout = TimeSpan.FromSeconds(tOutSec),
|
||||
BaseUrl = new Uri(apiUrl)
|
||||
};
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
/// <summary>
|
||||
/// Conf client RestSharp standard:
|
||||
/// - timeout 1 min
|
||||
/// </summary>
|
||||
private RestClientOptions restOptStd = new RestClientOptions { Timeout = TimeSpan.FromSeconds(60) };
|
||||
|
||||
#endregion Private Fields
|
||||
}
|
||||
}
|
||||
@@ -1,733 +0,0 @@
|
||||
using IOB_UT_NEXT;
|
||||
using MapoSDK;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Entity.Core.Mapping;
|
||||
using System.IO;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Threading.Tasks;
|
||||
using static IOB_WIN_NEXT.IobRest.Citizen.Responses;
|
||||
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
|
||||
|
||||
namespace IOB_WIN_NEXT.IobRest
|
||||
{
|
||||
/// <summary>
|
||||
/// Adapter specializzato per Citizen (Colcom, MT70)
|
||||
/// </summary>
|
||||
public class Citizen : Base
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Costruttore dell'IOB SOAP della bilancia RestCitizen
|
||||
/// </summary>
|
||||
/// <param name="caller">AdapterForm chiamante</param>
|
||||
/// <param name="IOBConf">Configurazione IOB per avvio</param>
|
||||
public Citizen(AdapterFormNext caller, IobConfiguration IOBConf) : base(caller, IOBConf)
|
||||
{
|
||||
lgInfo($"Richiesto Adapter IobRest.RestCitizen con i parametri seguenti | ADDR: {IOBConf.cncIpAddr} | PORT: {IOBConf.cncPort}");
|
||||
lastPING = DateTime.Now.AddHours(-1);
|
||||
redKeyAlarm = redisMan.redHash($"IOB:Status:{cIobConf.codIOB}:Alarm:LastRead");
|
||||
lastPING = DateTime.Now.AddHours(-1);
|
||||
// predispongo configurazione specifica Rest...
|
||||
lgInfo("Rest - 01");
|
||||
if (!string.IsNullOrEmpty(getOptPar("REST_CONF")))
|
||||
{
|
||||
setupRestConf(getOptPar("REST_CONF"));
|
||||
}
|
||||
// sistemo conf errori e samplePeriod...
|
||||
|
||||
lgInfo("Rest - 02");
|
||||
if (EnableTest)
|
||||
{
|
||||
PrelimCitizenRestTest();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Implementazione custom esecuzione task specifici
|
||||
/// </summary>
|
||||
/// <param name="task2exe"></param>
|
||||
/// <returns></returns>
|
||||
public override Dictionary<string, string> executeTasks(Dictionary<string, string> task2exe)
|
||||
{
|
||||
/*---------------------------------------
|
||||
* gestione execute task SPECIFICI:
|
||||
* - setArt
|
||||
* - setComm
|
||||
* - setPzComm
|
||||
*---------------------------------------*/
|
||||
|
||||
// Verificare il protocollo: dovrebbe togliere SOLO i task eseguiti...
|
||||
Dictionary<string, string> taskDone = new Dictionary<string, string>();
|
||||
if (task2exe != null)
|
||||
{
|
||||
lgTrace($"executeTasks: richiesta esecuzione {task2exe.Count} task");
|
||||
// controllo se memMap != null...
|
||||
if (memMap != null)
|
||||
{
|
||||
bool taskOk = false;
|
||||
string taskVal = "";
|
||||
// cerco task specifici: qui sono NON standard...
|
||||
foreach (var item in task2exe)
|
||||
{
|
||||
lgInfo($"TASK | {item.Key} --> {item.Value}");
|
||||
taskOk = false;
|
||||
taskVal = "";
|
||||
// converto richiesta in enum...
|
||||
taskType tName = taskType.nihil;
|
||||
Enum.TryParse(item.Key, out tName);
|
||||
// controllo sulla KEY...
|
||||
switch (tName)
|
||||
{
|
||||
case taskType.setArt:
|
||||
case taskType.setComm:
|
||||
case taskType.setPzComm:
|
||||
lgInfo($"Task: {item.Key} | {item.Value}");
|
||||
// salvo valori in memoria prod data
|
||||
upsertKey(item.Key, item.Value);
|
||||
taskVal = $"SET task: {item.Key} --> {item.Value}";
|
||||
// invio una chiamata al sistema con i valori attuali
|
||||
taskOk = SetJobDataCitizen();
|
||||
break;
|
||||
|
||||
case taskType.setParameter:
|
||||
// richiedo da URL i parametri WRITE da popolare
|
||||
lgInfo("Chiamata setParameter --> processMemWriteRequests");
|
||||
taskVal = processMemWriteRequests();
|
||||
// se restituiscce "" faccio altra prova...
|
||||
if (string.IsNullOrEmpty(taskVal))
|
||||
{
|
||||
// i parametri me li aspetto come stringa composta paramName|paramvalue
|
||||
if (item.Value.Contains("|"))
|
||||
{
|
||||
string[] paramsJob = item.Value.Split('|');
|
||||
taskVal = $"REQUEST SET PARAMETERS: {paramsJob[0]} --> {paramsJob[1]}";
|
||||
}
|
||||
else
|
||||
{
|
||||
taskVal = $"WRONG REQUEST FOR SET PARAMETERS: {item.Value} doesnt contain pipe for splitting key/value";
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
|
||||
lgInfo($"Chiamata senza processing: taskOk: {taskOk} | taskVal: {taskVal}");
|
||||
break;
|
||||
}
|
||||
// aggiungo task!
|
||||
taskDone.Add(item.Key, taskVal);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError($"Attenzione! memMap è nullo, non posso eseguire task2exe!");
|
||||
}
|
||||
}
|
||||
return taskDone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupera dizionario allarmi (SE PRESENTE)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override Dictionary<string, string> getAlarmData()
|
||||
{
|
||||
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
||||
// verifico SE HO allarmi attivi e nel caso li invia...
|
||||
string rawData = ExecuteCallGet(GetUrlResource("GetCurrAlarm"));
|
||||
string bankVal = "OK";
|
||||
WarnInfo alarmResp = JsonConvert.DeserializeObject<WarnInfo>(rawData);
|
||||
bankVal = (alarmResp != null && alarmResp.IsAlarm) ? alarmResp.message : "OK";
|
||||
saveAlarmString(ref outVal, bankVal, "Alarms");
|
||||
// verificare eventuale invio allarmi "storici"
|
||||
return outVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero dati DYN, impiegando i valori della LUT...
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override Dictionary<string, string> getDynData()
|
||||
{
|
||||
var answ = RestDataLUT;
|
||||
// aggiungo DynData... calcolato come variazione pezzi e lampade...
|
||||
if (answ.ContainsKey("DYNDATA"))
|
||||
{
|
||||
answ.Remove("DYNDATA");
|
||||
}
|
||||
answ.Add("DYNDATA", $"LAMP_{RestLutGet("gLamp")}{RestLutGet("yLamp")}{RestLutGet("rLamp")}_PzReq_{RestLutGet("qtyReq")}_PzWrk_{RestLutGet("qtyWrk")}_PzTot_{RestLutGet("qtyTot")}");
|
||||
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupera il progName in modalità custom...
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string getPrgName()
|
||||
{
|
||||
return RestLutGet("pName");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Esegue gestioen contapezzi...
|
||||
/// </summary>
|
||||
public override void processContapezzi()
|
||||
{
|
||||
DateTime adesso = DateTime.Now;
|
||||
// controllo se sia passato il samplePeriod minimo x 3...
|
||||
if (adesso.Subtract(lastRestProcPzCount.AddMilliseconds(samplePeriod * 3)).TotalSeconds > 0)
|
||||
{
|
||||
lastRestProcPzCount = adesso;
|
||||
bool checkMachine = false;
|
||||
LadderIO ladderResp = new LadderIO();
|
||||
// in primis testo che sia connessa...
|
||||
var checkResp = ExecuteCallGet(GetUrlResource("GetConnection"), true);
|
||||
lgInfo($"GetConnection | {checkResp} | Citizen.processContapezzi");
|
||||
bool.TryParse(checkResp, out checkMachine);
|
||||
|
||||
// proseguo SOLO SE macchina OK, altrimenti disconnetto...
|
||||
if (checkMachine)
|
||||
{
|
||||
// faccio refresh token comunque...
|
||||
string token = ExecuteCallGet(GetUrlResource("GetToken"));
|
||||
token = token.Replace("\"", "");
|
||||
RestLutUpsert("token", token);
|
||||
|
||||
// contapezzi corrente
|
||||
int intVal = 0;
|
||||
string qtyWrk = ExecuteCallGet(GetUrlResource("GetQtyProd"));
|
||||
int.TryParse(qtyWrk, out intVal);
|
||||
contapezziPLC = intVal;
|
||||
RestLutUpsert("qtyWrk", qtyWrk);
|
||||
|
||||
// gestione altri contapezzi x
|
||||
string qtyTot = ExecuteCallGet(GetUrlResource("GetQtyTot"));
|
||||
string qtyReq = ExecuteCallGet(GetUrlResource("GetQtyReq"));
|
||||
RestLutUpsert("qtyTot", qtyTot);
|
||||
RestLutUpsert("qtyReq", qtyReq);
|
||||
// gestione tempociclo e nome programma...
|
||||
string cTime = ExecuteCallGet(GetUrlResource("GetCycleTime"));
|
||||
string pName = ExecuteCallGet(GetUrlResource("GetProgName"));
|
||||
RestLutUpsert("cTime", cTime);
|
||||
RestLutUpsert("pName", pName);
|
||||
|
||||
lgInfo($"Citizen | contapezziPLC {qtyWrk} | qtyReq: {qtyReq} | qtyTot: {qtyTot}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override connessione
|
||||
/// </summary>
|
||||
public override void tryConnect()
|
||||
{
|
||||
if (!connectionOk)
|
||||
{
|
||||
// controllo che il ping sia stato tentato almeno pingTestSec fa...
|
||||
if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec"))
|
||||
{
|
||||
if (verboseLog || periodicLog)
|
||||
{
|
||||
lgInfo("Rest: ConnKO - tryConnect");
|
||||
}
|
||||
// in primis salvo data ping...
|
||||
lastPING = DateTime.Now;
|
||||
bool checkMachine = false;
|
||||
// se passa il ping faccio il resto...
|
||||
if (testPingMachine == IPStatus.Success)
|
||||
{
|
||||
string szStatusConnection = "";
|
||||
try
|
||||
{
|
||||
// ora provo connessione...
|
||||
parentForm.commPlcActive = true;
|
||||
|
||||
// chiamo metodo connect
|
||||
var checkResp = ExecuteCallGet(GetUrlResource("GetConnection"), true);
|
||||
lgInfo($"GetConnection | {checkResp} | Citizen.tryConnect");
|
||||
bool.TryParse(checkResp, out checkMachine);
|
||||
if (checkMachine)
|
||||
{
|
||||
connectionOk = true;
|
||||
queueInEnabCurr = true;
|
||||
if (adpRunning)
|
||||
{
|
||||
lgInfo("Connessione Citizen OK");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError($"Errore check connessione Citizen | checkResp: {checkResp}");
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
lgFatal($"Errore nella connessione all'Adapter IobRest.Base: {szStatusConnection}{Environment.NewLine}{exc}");
|
||||
connectionOk = false;
|
||||
lgInfo($"Eccezione in TryConnect, Adapter IobRest.Base NON running, pausa di {utils.CRI("waitRecMSec")} msec prima di ulteriori tentativi di riconnessione");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// loggo no risposta ping ...
|
||||
connectionOk = false;
|
||||
if (verboseLog || periodicLog)
|
||||
{
|
||||
lgInfo($"Attenzione: Rest controllo PING fallito per IP {cIobConf.cncPingAddr}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
needRefresh = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Internal Classes
|
||||
|
||||
/// <summary>
|
||||
/// Struttura delle risposte alle chiamare REST specifiche
|
||||
/// </summary>
|
||||
internal class Responses
|
||||
{
|
||||
#region Internal Classes
|
||||
|
||||
/// <summary>
|
||||
/// Struttura info restituiti da AlarmList
|
||||
/// </summary>
|
||||
internal class AlarmInfo
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
public DateTime date { get; set; } = DateTime.Today.AddYears(-10);
|
||||
public string ErrorMessage { get; set; } = "";
|
||||
public int id { get; set; } = 0;
|
||||
public string message { get; set; } = "";
|
||||
public string type { get; set; } = "";
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Struttura info JobData da inviare x setup
|
||||
/// </summary>
|
||||
internal class CitizenJobData
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
public string itemcode { get; set; } = "";
|
||||
public string itemdescription { get; set; } = "";
|
||||
public string ordercode { get; set; } = "";
|
||||
public int piecestodo { get; set; } = 0;
|
||||
public string token { get; set; } = "";
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Struttura info restituiti x lettura Ladder
|
||||
/// </summary>
|
||||
internal class LadderIO
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
public string Address { get; set; } = "";
|
||||
public string Description { get; set; } = "";
|
||||
public string ErrorMessage { get; set; } = "";
|
||||
public string IOType { get; set; } = "";
|
||||
public string VarValue { get; set; } = "";
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Struttura info QtyData da inviare x impostazioni quantità
|
||||
/// </summary>
|
||||
internal class QtyData
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
public string token { get; set; } = "";
|
||||
public int value { get; set; } = 0;
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Struttura dato AlarmState (singolo, corrente)
|
||||
/// </summary>
|
||||
internal class WarnInfo
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
public string ErrorMessage { get; set; } = "";
|
||||
public bool IsAlarm { get; set; } = false;
|
||||
public bool IsCaution { get; set; } = false;
|
||||
public string message { get; set; } = "";
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Struttura risposta x scrittura parametri numerici (es qty)
|
||||
/// </summary>
|
||||
internal class WriteResult
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
public string ErrorMessage { get; set; } = null;
|
||||
public bool Result { get; set; } = false;
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
|
||||
#endregion Internal Classes
|
||||
}
|
||||
|
||||
#endregion Internal Classes
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Effettua decodifica aree memoria alla bitmap usata x MAPO
|
||||
/// </summary>
|
||||
protected override void decodeToBaseBitmap(ref newDisplayData currDispData)
|
||||
{
|
||||
// init a zero...
|
||||
B_input = 0;
|
||||
if (queueInEnabCurr)
|
||||
{
|
||||
/* -----------------------------------------------------
|
||||
* bitmap MAPO STD 60
|
||||
* B0: POWER_ON
|
||||
* B1: RUN
|
||||
* B2: pzCount
|
||||
* B3: allarme
|
||||
* B4: manuale
|
||||
* B5: allarme TCiclo (SLOW)
|
||||
* B6: WarmUp_CoolDown
|
||||
* B7: EmergArmed (1 = NON emergenza, 0 = emergenza)
|
||||
----------------------------------------------------- */
|
||||
|
||||
// per prima cosa controllo ping e se sia connesso...
|
||||
|
||||
if (connectionOk)
|
||||
{
|
||||
B_input = 1;
|
||||
currDispData.semIn = Semaforo.SV;
|
||||
|
||||
// controllo lampade... da rosso a verde...
|
||||
if (RestLutGet("rLamp") == "1")
|
||||
{
|
||||
B_input += (1 << 3);
|
||||
}
|
||||
else if (RestLutGet("yLamp") == "1")
|
||||
{
|
||||
B_input += (1 << 4);
|
||||
}
|
||||
else if (RestLutGet("gLamp") == "1")
|
||||
{
|
||||
B_input += (1 << 1);
|
||||
}
|
||||
|
||||
// accodo NON emergenza ... poi da cercare meglio...
|
||||
B_input += (1 << 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
B_input = 0;
|
||||
currDispData.semIn = Semaforo.SR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lgDebug($"[VETO queueInEnabCurr] | veto attivo alle {DateTime.Now:yyyy.MM.dd HH:mm:ss}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Metodo da overridare x scrivere DAVVERO i parametri sul PLC
|
||||
/// </summary>
|
||||
/// <param name="updatedPar"></param>
|
||||
protected override void plcWriteParams(ref List<objItem> updatedPar)
|
||||
{
|
||||
lgTrace($"plcWriteParams: richiesta per {updatedPar.Count} params");
|
||||
foreach (var item in updatedPar)
|
||||
{
|
||||
lgInfo($"ITEM | {item.uid} | {item.value}");
|
||||
// salvo i valori ricevuti
|
||||
upsertKey(item.uid, item.reqValue);
|
||||
// resetto richiesta!
|
||||
item.reqValue = "";
|
||||
// chiamo scrittura commessa!
|
||||
var taskOk = SetJobDataCitizen();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Esegue lettura dati + salvataggio in LUT
|
||||
/// </summary>
|
||||
protected override void refreshData()
|
||||
{
|
||||
DateTime adesso = DateTime.Now;
|
||||
// controllo se sia passato il samplePeriod minimo...
|
||||
if (adesso.Subtract(lastRestRefreshData.AddMilliseconds(samplePeriod)).TotalSeconds > 0)
|
||||
{
|
||||
lastRestRefreshData = adesso;
|
||||
bool checkMachine = false;
|
||||
LadderIO ladderResp = new LadderIO();
|
||||
// in primis testo che sia connessa...
|
||||
var checkResp = ExecuteCallGet(GetUrlResource("GetConnection"), true);
|
||||
lgInfo($"GetConnection | {checkResp} | Citizen.refreshData");
|
||||
bool.TryParse(checkResp, out checkMachine);
|
||||
|
||||
// proseguo SOLO SE macchina OK, altrimenti disconnetto...
|
||||
if (checkMachine)
|
||||
{
|
||||
//riporto err conn a zero
|
||||
connErrCur = 0;
|
||||
// faccio refresh token comunque...
|
||||
string token = ExecuteCallGet(GetUrlResource("GetToken"));
|
||||
token = token.Replace("\"", "");
|
||||
RestLutUpsert("token", token);
|
||||
|
||||
// ora controllo valori lampada SE scaduti resetto 3 valori lamp
|
||||
RestLutUpsert("gLamp", "0");
|
||||
RestLutUpsert("yLamp", "0");
|
||||
RestLutUpsert("rLamp", "0");
|
||||
|
||||
int signVal = 0;
|
||||
string gLamp = ExecuteCallGet(GetUrlResource("GetLampGreen"));
|
||||
ladderResp = JsonConvert.DeserializeObject<LadderIO>(gLamp);
|
||||
if (string.IsNullOrEmpty(ladderResp.ErrorMessage))
|
||||
{
|
||||
int.TryParse(ladderResp.VarValue, out signVal);
|
||||
RestLutUpsert("gLamp", $"{signVal}");
|
||||
}
|
||||
|
||||
// se il valore è zero --> proseguo con yellow!
|
||||
if (signVal == 0)
|
||||
{
|
||||
Task.Delay(samplePeriod / 4);
|
||||
string yLamp = ExecuteCallGet(GetUrlResource("GetLampYellow"));
|
||||
ladderResp = JsonConvert.DeserializeObject<LadderIO>(yLamp);
|
||||
if (string.IsNullOrEmpty(ladderResp.ErrorMessage))
|
||||
{
|
||||
int.TryParse(ladderResp.VarValue, out signVal);
|
||||
RestLutUpsert("yLamp", $"{signVal}");
|
||||
}
|
||||
}
|
||||
|
||||
// se il valore è zero --> proseguo con red!
|
||||
if (signVal == 0)
|
||||
{
|
||||
Task.Delay(samplePeriod / 4);
|
||||
string rLamp = ExecuteCallGet(GetUrlResource("GetLampRed"));
|
||||
ladderResp = JsonConvert.DeserializeObject<LadderIO>(rLamp);
|
||||
if (string.IsNullOrEmpty(ladderResp.ErrorMessage))
|
||||
{
|
||||
int.TryParse(ladderResp.VarValue, out signVal);
|
||||
RestLutUpsert("rLamp", $"{signVal}");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// verifico se devo disconnettere
|
||||
if (connErrCur >= connErrMax)
|
||||
{
|
||||
connErrCur = 0;
|
||||
tryDisconnect();
|
||||
}
|
||||
else
|
||||
{
|
||||
connErrCur++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private string basePath = "";
|
||||
|
||||
private DateTime lastRestProcPzCount = DateTime.Now;
|
||||
|
||||
private DateTime lastRestRefreshData = DateTime.Now;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
/// <summary>
|
||||
/// Elenco pesate attuali
|
||||
/// </summary>
|
||||
private List<AlarmInfo> listAllarmiCurr { get; set; } = new List<AlarmInfo>();
|
||||
|
||||
/// <summary>
|
||||
/// CHiave redis di salvataggio ultimo set di allarmi scaricato
|
||||
/// </summary>
|
||||
private string redKeyAlarm { get; set; } = "";
|
||||
|
||||
#endregion Private Properties
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Test preliminare comunicazione Rest Citizen
|
||||
/// </summary>
|
||||
private void PrelimCitizenRestTest()
|
||||
{
|
||||
lgInfo("Rest - 03");
|
||||
// test folder salvataggio log
|
||||
var appPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
|
||||
var fPath = Directory.GetParent(appPath).FullName;
|
||||
basePath = Path.Combine(fPath, "Test");
|
||||
if (!Directory.Exists(basePath))
|
||||
{
|
||||
Directory.CreateDirectory(basePath);
|
||||
}
|
||||
lgInfo("Rest - 04");
|
||||
|
||||
bool checkMachine = false;
|
||||
string checkResp = TestCitizenCall("checkconnection", true);
|
||||
lgInfo($"checkconnection | {checkResp}");
|
||||
bool.TryParse(checkResp, out checkMachine);
|
||||
if (checkMachine)
|
||||
{
|
||||
string token = TestCitizenCall("gettoken/mecmaticames/mecmatica@mes");
|
||||
token = token.Replace("\"", "");
|
||||
if (string.IsNullOrEmpty(token))
|
||||
{
|
||||
lgError("Errore: token vuoto");
|
||||
}
|
||||
else
|
||||
{
|
||||
string gLamp = TestCitizenCall($"getsingleladderio/{token}/Y/8E");
|
||||
string yLamp = TestCitizenCall($"getsingleladderio/{token}/Y/21");
|
||||
string rLamp = TestCitizenCall($"getsingleladderio/{token}/Y/22");
|
||||
string qtyTot = TestCitizenCall($"gettotalquantity/{token}");
|
||||
string qtyReq = TestCitizenCall($"getneededquantity/{token}");
|
||||
string qtyWrk = TestCitizenCall($"getworkedquantity/{token}");
|
||||
string cTime = TestCitizenCall($"getcycletime/{token}");
|
||||
string pName = TestCitizenCall($"getmainprogram/{token}");
|
||||
|
||||
string cAlarm = ExecuteCallGet($"getalarm/{token}");
|
||||
var sAlarm = JsonConvert.DeserializeObject<WarnInfo>(cAlarm);
|
||||
cAlarm = JsonConvert.SerializeObject(sAlarm, Formatting.Indented);
|
||||
lgInfo($"Call: getalarm/{token} | resp: {cAlarm}");
|
||||
|
||||
string allAlarm = ExecuteCallGet($"getallalarmlog/{token}");
|
||||
var alarmList = JsonConvert.DeserializeObject<List<AlarmInfo>>(allAlarm);
|
||||
allAlarm = JsonConvert.SerializeObject(alarmList, Formatting.Indented);
|
||||
lgInfo($"Call: getallalarmlog/{token} | resp: {allAlarm}");
|
||||
|
||||
string err = TestCitizenCall($"getsingleladderio/ABC/Y/22");
|
||||
|
||||
// salvo i valori
|
||||
File.WriteAllText(Path.Combine(basePath, "token.txt"), token);
|
||||
File.WriteAllText(Path.Combine(basePath, "gLamp.txt"), gLamp);
|
||||
File.WriteAllText(Path.Combine(basePath, "yLamp.txt"), yLamp);
|
||||
File.WriteAllText(Path.Combine(basePath, "rLamp.txt"), rLamp);
|
||||
File.WriteAllText(Path.Combine(basePath, "qtyTot.txt"), qtyTot);
|
||||
File.WriteAllText(Path.Combine(basePath, "qtyReq.txt"), qtyReq);
|
||||
File.WriteAllText(Path.Combine(basePath, "qtyWrk.txt"), qtyWrk);
|
||||
File.WriteAllText(Path.Combine(basePath, "cTime.txt"), cTime);
|
||||
File.WriteAllText(Path.Combine(basePath, "pName.txt"), pName);
|
||||
File.WriteAllText(Path.Combine(basePath, "cAlarm.txt"), cAlarm);
|
||||
File.WriteAllText(Path.Combine(basePath, "allAlarm.txt"), allAlarm);
|
||||
File.WriteAllText(Path.Combine(basePath, "err.txt"), err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua scrittura set di parametri del job e restitusice task eseguito...
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private bool SetJobDataCitizen()
|
||||
{
|
||||
bool answ = false;
|
||||
string varValue = "";
|
||||
CitizenJobData jobReq = new CitizenJobData();
|
||||
QtyData qtyReq = new QtyData();
|
||||
|
||||
// Token!
|
||||
varValue = RestLutGet("token");
|
||||
jobReq.token = varValue;
|
||||
qtyReq.token = varValue;
|
||||
|
||||
// Commessa
|
||||
varValue = getCurrProdData("setComm", "");
|
||||
jobReq.ordercode = varValue;
|
||||
|
||||
// Articolo
|
||||
varValue = getCurrProdData("setArt", "");
|
||||
jobReq.itemcode = varValue;
|
||||
jobReq.itemdescription = $"ART: {varValue}";
|
||||
|
||||
// Qty
|
||||
varValue = getCurrProdData("setPzComm", "");
|
||||
int pzReq = 0;
|
||||
int.TryParse(varValue, out pzReq);
|
||||
jobReq.piecestodo = pzReq;
|
||||
qtyReq.value = pzReq;
|
||||
|
||||
try
|
||||
{
|
||||
// preparo payload
|
||||
string jobPayload = JsonConvert.SerializeObject(jobReq);
|
||||
// faccio chiamata POST x invio
|
||||
var rawResp = ExecuteCallPost(GetUrlResource("SetJobData"), jobPayload);
|
||||
bool.TryParse(rawResp, out answ);
|
||||
// se andatae se ho la chaive x invio abilitata invio anche la qty richiesta...
|
||||
if (answ)
|
||||
{
|
||||
string urlNeedQty = GetUrlResource("SetNeededQuantity");
|
||||
if (string.IsNullOrEmpty(urlNeedQty))
|
||||
{
|
||||
lgInfo($"Set NeedQty NON abilitato, non invio");
|
||||
}
|
||||
else
|
||||
{
|
||||
jobPayload = JsonConvert.SerializeObject(qtyReq);
|
||||
var rawRespQty = ExecuteCallPost(GetUrlResource("SetNeededQuantity"), jobPayload);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
lgError($"Eccezione in SetJobDataCitizen{Environment.NewLine}{exc}");
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test Chiamata Citizen
|
||||
/// </summary>
|
||||
/// <param name="urlReq"></param>
|
||||
/// <returns></returns>
|
||||
private string TestCitizenCall(string urlReq, bool fastCall = false)
|
||||
{
|
||||
lgInfo($"TestCitizenCall: {urlReq}");
|
||||
string answ = ExecuteCallGet(urlReq, fastCall);
|
||||
lgInfo($"TestCitizenCall resp: {answ}");
|
||||
return answ;
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -1,740 +0,0 @@
|
||||
using EgwProxy.Gomba.GombaServ;
|
||||
using IOB_UT_NEXT;
|
||||
using MapoSDK;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net.NetworkInformation;
|
||||
|
||||
namespace IOB_WIN_NEXT.IobSoap
|
||||
{
|
||||
/// <summary>
|
||||
/// Adapter specializzato per GOMA e le chiamate tramite WS Soap alla bilancia, libreria EgwProxy.Gomba
|
||||
/// </summary>
|
||||
public class Gomba : Iob.GenericNext
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Costruttore dell'IOB SOAP della bilancia GOMBA
|
||||
/// </summary>
|
||||
/// <param name="caller">AdapterForm chiamante</param>
|
||||
/// <param name="IOBConf">Configurazione IOB per avvio</param>
|
||||
public Gomba(AdapterFormNext caller, IobConfiguration IOBConf) : base(caller, IOBConf)
|
||||
{
|
||||
lgInfo($"Richiesto Adapter IobSoap.Gomba con i parametri seguenti | ADDR: {IOBConf.cncIpAddr} | PORT: {IOBConf.cncPort}");
|
||||
redKeyPesate = redisMan.redHash($"IOB:Status:{cIobConf.codIOB}:ListPesate");
|
||||
lastPING = DateTime.Now.AddHours(-1);
|
||||
// verifico se sia attiva gestione riduzione FluxLog...
|
||||
if (!string.IsNullOrEmpty(getOptJsonKVP("numLastWeight")))
|
||||
{
|
||||
int.TryParse(getOptJsonKVP("numLastWeight"), out numLastWeight);
|
||||
lgInfo($"Gomba: setup specifico | numLastWeight: {numLastWeight}");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Implementazione custom esecuzione task specifici
|
||||
/// </summary>
|
||||
/// <param name="task2exe"></param>
|
||||
/// <returns></returns>
|
||||
public override Dictionary<string, string> executeTasks(Dictionary<string, string> task2exe)
|
||||
{
|
||||
/*---------------------------------------
|
||||
* gestione execute task SPECIFICI x pesa:
|
||||
* - salva i parametri richiesta (RM, cod1..cod6)
|
||||
* - esegue metodo richiesta (IN/OUT)
|
||||
*---------------------------------------*/
|
||||
|
||||
// Verificare il protocollo: dovrebbe togliere SOLO i task eseguiti...
|
||||
Dictionary<string, string> taskDone = new Dictionary<string, string>();
|
||||
if (task2exe != null)
|
||||
{
|
||||
lgTrace($"executeTasks: richiesta esecuzione {task2exe.Count} task");
|
||||
// controllo se memMap != null...
|
||||
if (memMap != null)
|
||||
{
|
||||
bool taskOk = false;
|
||||
string taskVal = "";
|
||||
// cerco task specifici: qui sono NON standard...
|
||||
foreach (var item in task2exe)
|
||||
{
|
||||
lgInfo($"TASK | {item.Key} --> {item.Value}");
|
||||
taskOk = false;
|
||||
taskVal = "";
|
||||
// converto richiesta in enum...
|
||||
taskType tName = taskType.nihil;
|
||||
Enum.TryParse(item.Key, out tName);
|
||||
// controllo sulla KEY...
|
||||
switch (tName)
|
||||
{
|
||||
case taskType.setParameter:
|
||||
// richiedo da URL i parametri WRITE da popolare
|
||||
lgInfo("Chiamata setParameter --> processMemWriteRequests");
|
||||
taskVal = processMemWriteRequests();
|
||||
// se restituiscce "" faccio altra prova...
|
||||
if (string.IsNullOrEmpty(taskVal))
|
||||
{
|
||||
// i parametri me li aspetto come stringa composta paramName|paramvalue
|
||||
if (item.Value.Contains("|"))
|
||||
{
|
||||
string[] paramsJob = item.Value.Split('|');
|
||||
taskVal = $"REQUEST SET PARAMETERS: {paramsJob[0]} --> {paramsJob[1]}";
|
||||
}
|
||||
else
|
||||
{
|
||||
taskVal = $"WRONG REQUEST FOR SET PARAMETERS: {item.Value} doesnt contain pipe for splitting key/value";
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
|
||||
lgInfo($"Chiamata senza processing: taskOk: {taskOk} | taskVal: {taskVal}");
|
||||
break;
|
||||
}
|
||||
// aggiungo task!
|
||||
taskDone.Add(item.Key, taskVal);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError($"Attenzione! memMap è nullo, non posso eseguire task2exe!");
|
||||
}
|
||||
}
|
||||
|
||||
return taskDone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero dati dinamici...
|
||||
/// </summary>
|
||||
public override Dictionary<string, string> getDynData()
|
||||
{
|
||||
// valore non presente in vers default... se gestito fare override
|
||||
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
||||
// controllo se ho indicato ancora che ci siano pesate già lette da inviare...
|
||||
if (num2send() > 0)
|
||||
{
|
||||
// preparo oggetti x confronto ...
|
||||
List<WeightRec> listaArch = listPesateArchivio;
|
||||
|
||||
// se non ho nulla in archivio prendo ultima pesata (essendo DESC è la prima cronologicamente)
|
||||
if (listaArch.Count == 0)
|
||||
{
|
||||
WeightRec lastRec = listPesateCurr.LastOrDefault();
|
||||
// aggiungo...
|
||||
SavePesata(ref outVal, lastRec);
|
||||
}
|
||||
// ora il confronto è cronologico sulle pesate + recenti...
|
||||
else
|
||||
{
|
||||
// prendo prima della lista pesate archiviate = più recente come dt da cui partire...
|
||||
DateTime dtRif = listaArch.FirstOrDefault().DtEvent;
|
||||
var firstRec = listPesateCurr
|
||||
.Where(x => x.DtEvent > dtRif)
|
||||
.OrderBy(x => x.DtEvent)
|
||||
.FirstOrDefault();
|
||||
if (firstRec != null)
|
||||
{
|
||||
SavePesata(ref outVal, firstRec);
|
||||
}
|
||||
}
|
||||
|
||||
// processo comunque le aree memoria READ...
|
||||
if (memMap.mMapRead.Count > 0)
|
||||
{
|
||||
foreach (var item in memMap.mMapRead)
|
||||
{
|
||||
var currVal = getCurrProdData(item.Key, "");
|
||||
if (!outVal.ContainsKey(item.Key))
|
||||
{
|
||||
outVal.Add(item.Key, $"{currVal}");
|
||||
}
|
||||
// se fosse logReq --> resetto...
|
||||
if (item.Key == "logReq" && !string.IsNullOrEmpty(currVal))
|
||||
{
|
||||
upsertKey(item.Key, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// altrimenti rileggo e cerco se ci siano
|
||||
else
|
||||
{
|
||||
Stopwatch sw = new Stopwatch();
|
||||
sw.Start();
|
||||
try
|
||||
{
|
||||
// test lettura elenco pesate... se NON nullo --> OK!
|
||||
var weightArray = gombaConn.reqWeightList("ALL", dataFrom, dataTo);
|
||||
// riordino DESC
|
||||
listPesateCurr = WeightRec.ConvertPesate(weightArray.OrderByDescending(x => x.dateIn).ToList());
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
lgError($"Eccezione in gombaConn.reqWeightList{Environment.NewLine}{exc}");
|
||||
}
|
||||
sw.Stop();
|
||||
lgInfo($"getDynData | SOAP: effettuata chiamata reqWeightList in {sw.Elapsed.TotalMilliseconds}ms | {dataFrom} --> {dataTo} | {listPesateCurr.Count} rec");
|
||||
}
|
||||
// indico esecuzione e proseguo
|
||||
lastReadPLC = DateTime.Now;
|
||||
return outVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua lettura semafori principale <paramref name="currDispData">Parametri da
|
||||
/// aggiornare x display in form</paramref>
|
||||
/// </summary>
|
||||
public override void readSemafori(ref newDisplayData currDispData)
|
||||
{
|
||||
if (connectionOk)
|
||||
{
|
||||
B_input = 1;
|
||||
currDispData.semIn = Semaforo.SV;
|
||||
|
||||
// se ho pesate in memoria nel periodo richiesto --> RUN
|
||||
if (listPesateCurr != null && listPesateCurr.Count > 0)
|
||||
{
|
||||
B_input += (1 << 1);
|
||||
}
|
||||
// metto manuale
|
||||
else
|
||||
{
|
||||
B_input += (1 << 4);
|
||||
}
|
||||
|
||||
// accodo NON emergenza
|
||||
B_input += (1 << 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
B_input = 0;
|
||||
currDispData.semIn = Semaforo.SR;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override connessione
|
||||
/// </summary>
|
||||
public override void tryConnect()
|
||||
{
|
||||
if (!connectionOk)
|
||||
{
|
||||
// controllo che il ping sia stato tentato almeno pingTestSec fa...
|
||||
if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec"))
|
||||
{
|
||||
if (verboseLog || periodicLog)
|
||||
{
|
||||
lgInfo("Gomba: ConnKO - tryConnect");
|
||||
}
|
||||
// in primis salvo data ping...
|
||||
lastPING = DateTime.Now;
|
||||
// se passa il ping faccio il resto...
|
||||
if (testPingMachine == IPStatus.Success)
|
||||
{
|
||||
string szStatusConnection = "";
|
||||
try
|
||||
{
|
||||
// ora provo connessione...
|
||||
parentForm.commPlcActive = true;
|
||||
|
||||
// init del proxy!!!
|
||||
string endpointAddr = $"https://{cIobConf.cncIpAddr}:{cIobConf.cncPort}/ws";
|
||||
lgInfo($"Tentativo avvio SOAP su endpoint {endpointAddr}");
|
||||
Stopwatch sw = new Stopwatch();
|
||||
sw.Start();
|
||||
|
||||
// salto verifica certificato
|
||||
System.Net.ServicePointManager.ServerCertificateValidationCallback = (senderX, certificate, chain, sslPolicyErrors) => { return true; };
|
||||
|
||||
// riprovo connessione SE non fosse andata...
|
||||
int maxTry = 5;
|
||||
int nTry = 1;
|
||||
// tento avvio WS SOAP!
|
||||
gombaConn = new EgwProxy.Gomba.GombaServ.lwpServiceClient("lwpServicePort", new System.ServiceModel.EndpointAddress(endpointAddr));
|
||||
while (gombaConn == null || (nTry <= maxTry && !checkStateOk(gombaConn.State)))
|
||||
{
|
||||
lgInfo($"Tentativo connessione Gomba: | endpointAddr: {endpointAddr} | nTry: {nTry}");
|
||||
// tento avvio WS SOAP!
|
||||
gombaConn = new EgwProxy.Gomba.GombaServ.lwpServiceClient("lwpServicePort", new System.ServiceModel.EndpointAddress(endpointAddr));
|
||||
nTry++;
|
||||
}
|
||||
if (checkStateOk(gombaConn.State))
|
||||
{
|
||||
connectionOk = true;
|
||||
List<gestWeightOut> weightArray = new List<gestWeightOut>();
|
||||
try
|
||||
{
|
||||
// test lettura elenco pesate... se NON nullo --> OK!
|
||||
weightArray = gombaConn.reqWeightList("ALL", dataFrom, dataTo).OrderByDescending(x => x.dateIn).ToList();
|
||||
// riordino DESC
|
||||
listPesateCurr = WeightRec.ConvertPesate(weightArray);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
lgError($"Eccezione in gombaConn.reqWeightList{Environment.NewLine}{exc}");
|
||||
}
|
||||
sw.Stop();
|
||||
lgInfo($"SOAP: effettuata chiamata connessione + reqWeightList in {sw.Elapsed.TotalMilliseconds}ms | {dataFrom} --> {dataTo}");
|
||||
if (listPesateCurr != null && listPesateCurr.Count >= 0)
|
||||
{
|
||||
lgInfo($"szStatusConnection Gomba, recuperato elenco di {listPesateCurr.Count} pesate");
|
||||
parentForm.commPlcActive = false;
|
||||
connectionOk = true;
|
||||
// sistemo data da cui iniziare recuperi successivi se ho + di numLastWeight
|
||||
if (weightArray.Count > numLastWeight)
|
||||
{
|
||||
var lastRec = weightArray
|
||||
.OrderByDescending(x => x.dateIn)
|
||||
.Skip(numLastWeight).FirstOrDefault();
|
||||
// metto giorno antecedente
|
||||
dtStartLive = lastRec.dateIn.Date.AddDays(-1);
|
||||
}
|
||||
// processo pesate!
|
||||
demFactDynData = 1;
|
||||
processDynData();
|
||||
}
|
||||
}
|
||||
// refresh stato connessione!!!
|
||||
if (connectionOk)
|
||||
{
|
||||
queueInEnabCurr = true;
|
||||
if (adpRunning)
|
||||
{
|
||||
lgInfo("Connessione OK");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError("Impossibile procedere, connessione mancante...");
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
lgFatal($"Errore nella connessione all'adapter Gomba: {szStatusConnection}{Environment.NewLine}{exc}");
|
||||
connectionOk = false;
|
||||
lgInfo($"Eccezione in TryConnect, Adapter Gomba NON running, pausa di {utils.CRI("waitRecMSec")} msec prima di ulteriori tentativi di riconnessione");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// loggo no risposta ping ...
|
||||
connectionOk = false;
|
||||
if (verboseLog || periodicLog)
|
||||
{
|
||||
lgInfo($"Attenzione: Gomba controllo PING fallito per IP {cIobConf.cncPingAddr}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
needRefresh = true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void tryDisconnect()
|
||||
{
|
||||
// registro solo che è disconnesso
|
||||
connectionOk = false;
|
||||
queueInEnabCurr = false;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
/// <summary>
|
||||
/// Proxy per connessione al SOAP webservice GOMBA
|
||||
/// </summary>
|
||||
protected EgwProxy.Gomba.GombaServ.lwpServiceClient gombaConn;
|
||||
|
||||
protected int numLastWeight = 100;
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// verifica stato ok ovvero connected oppure open
|
||||
/// </summary>
|
||||
/// <param name="currState"></param>
|
||||
/// <returns></returns>
|
||||
protected bool checkStateOk(System.ServiceModel.CommunicationState currState)
|
||||
{
|
||||
return currState == System.ServiceModel.CommunicationState.Opened || currState == System.ServiceModel.CommunicationState.Created;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Metodo da overridare x scrivere DAVVERO i parametri sul PLC
|
||||
/// </summary>
|
||||
/// <param name="updatedPar"></param>
|
||||
protected override void plcWriteParams(ref List<objItem> updatedPar)
|
||||
{
|
||||
lgTrace($"plcWriteParams: richiesta per {updatedPar.Count} params");
|
||||
foreach (var item in updatedPar)
|
||||
{
|
||||
lgInfo($"ITEM | {item.uid} | {item.value}");
|
||||
// salvo i valori di setup x prox pesata...
|
||||
upsertKey(item.uid, item.value);
|
||||
bool fatto = false;
|
||||
bool isPesata = false;
|
||||
bool isIN = false;
|
||||
gestWeightOut answ = new gestWeightOut();
|
||||
// se è richiesta pesata IN/OUT --> mando chiamata
|
||||
if (item.uid == "reqPesata")
|
||||
{
|
||||
isPesata = true;
|
||||
isIN = item.reqValue.ToUpper() == "IN";
|
||||
//isIN = item.value.ToUpper() == "IN";
|
||||
try
|
||||
{
|
||||
answ = reqWeight(isIN);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
lgError($"Eccezione in plcWriteParams.reqWeight | isIn: {isIN}{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
else if (item.uid == "RM" || item.uid.StartsWith("Cod"))
|
||||
{
|
||||
// comunque segno fatto x altri casi
|
||||
fatto = true;
|
||||
}
|
||||
|
||||
// se è pesata...
|
||||
if (isPesata)
|
||||
{
|
||||
// se è OK
|
||||
if (answ.feedback == "C")
|
||||
{
|
||||
lgInfo($"reqWeight | Effettuato richiesta | {answ.feedback} | {answ.notes}");
|
||||
// resetto pesata
|
||||
upsertKey(item.uid, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError($"reqWeight | Errore in richiesta peso GOMBA | {answ.feedback} | {answ.notes}");
|
||||
}
|
||||
item.value = "";
|
||||
item.reqValue = "";
|
||||
item.lastRead = DateTime.Now;
|
||||
item.UM = "";
|
||||
// salvo esito richiesta comunque
|
||||
upsertKey("logReq", $"{answ.feedback} | {answ.notes}");
|
||||
// faccio in modo di eseguire subito getDynData
|
||||
demFactDynData = 1;
|
||||
processDynData();
|
||||
}
|
||||
else
|
||||
{
|
||||
// se fatto --> aggiorno!
|
||||
if (fatto)
|
||||
{
|
||||
//item.value = item.reqValue;
|
||||
item.reqValue = "";
|
||||
item.lastRead = DateTime.Now;
|
||||
item.UM = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Esegue richiesta PESO
|
||||
/// </summary>
|
||||
/// <param name="reqIN">Tipo richiesta: IN (true) / OUT (false)</param>
|
||||
/// <returns></returns>
|
||||
protected gestWeightOut reqWeight(bool reqIN)
|
||||
{
|
||||
lgInfo($"reqWeight | IN: {reqIN}");
|
||||
gestWeightOut answ = null;
|
||||
try
|
||||
{
|
||||
Stopwatch sw = new Stopwatch();
|
||||
sw.Start();
|
||||
// preparo parametri
|
||||
string tipoRic = reqIN ? "IN" : "OUT";
|
||||
string rm = getCurrProdData("RM", $"{DateTime.Now:yyyyMMdd-HHmmss}");// string.IsNullOrEmpty(currProdData["RM"]) ? $"{DateTime.Now:yyyyMMdd-HHmmss}" : currProdData["RM"];
|
||||
string Cod1 = getCurrProdData("Cod1", ""); //string.IsNullOrEmpty(currProdData["Cod1"]) ? "" : currProdData["Cod1"];
|
||||
string Cod2 = getCurrProdData("Cod2", ""); //string.IsNullOrEmpty(currProdData["Cod2"]) ? "" : currProdData["Cod2"];
|
||||
string Cod3 = getCurrProdData("Cod3", ""); //string.IsNullOrEmpty(currProdData["Cod3"]) ? "" : currProdData["Cod3"];
|
||||
string Cod4 = getCurrProdData("Cod4", ""); //string.IsNullOrEmpty(currProdData["Cod4"]) ? "" : currProdData["Cod4"];
|
||||
string Cod5 = getCurrProdData("Cod5", ""); //string.IsNullOrEmpty(currProdData["Cod5"]) ? "" : currProdData["Cod5"];
|
||||
string Cod6 = getCurrProdData("Cod6", ""); //string.IsNullOrEmpty(currProdData["Cod6"]) ? "" : currProdData["Cod6"];
|
||||
// faccio chiamata
|
||||
answ = gombaConn.memWeight(tipoRic, rm, Cod1, Cod2, Cod3, Cod4, Cod5, Cod6);
|
||||
sw.Stop();
|
||||
lgInfo($"reqWeight: effettuata chiamata SOAP in {sw.Elapsed.TotalMilliseconds}ms | {dataFrom} --> {dataTo}");
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
lgError($"reqWeight | errore richiesta pesatura{Environment.NewLine}{exc}");
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
protected void SavePesata(ref Dictionary<string, string> currDict, WeightRec newRec)
|
||||
{
|
||||
DictUpsert(ref currDict, "RM", newRec.RM ?? "");
|
||||
string tag = newRec.isIn ? "In" : "Out";
|
||||
DictUpsert(ref currDict, $"lastWeight{tag}", $"{newRec.weight:N2}");
|
||||
// registro record completo ultima pesata
|
||||
DictUpsert(ref currDict, $"lastRec{tag}", formatPesata(newRec));
|
||||
// la aggiungo alle pesate archiviate...
|
||||
AppendPesata(newRec);
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Protected Classes
|
||||
|
||||
protected class WeightRec
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
public string cod1 { get; set; } = "";
|
||||
|
||||
public string cod2 { get; set; } = "";
|
||||
|
||||
public string cod3 { get; set; } = "";
|
||||
|
||||
public string cod4 { get; set; } = "";
|
||||
|
||||
public string cod5 { get; set; } = "";
|
||||
|
||||
public string cod6 { get; set; } = "";
|
||||
|
||||
public DateTime DtEvent { get; set; } = DateTime.Today;
|
||||
|
||||
public bool isIn { get; set; } = true;
|
||||
|
||||
public string RM { get; set; } = "ND";
|
||||
|
||||
public double weight { get; set; } = 0;
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Effettua converione come lista cronologica pesate (singoli record IN/OUT)
|
||||
/// </summary>
|
||||
/// <param name="pesateOrig"></param>
|
||||
/// <returns></returns>
|
||||
public static List<WeightRec> ConvertPesate(List<gestWeightOut> pesateOrig)
|
||||
{
|
||||
List<WeightRec> answ = new List<WeightRec>();
|
||||
foreach (var item in pesateOrig)
|
||||
{
|
||||
// verifico se ci sia record IN...
|
||||
if (item.dateInSpecified)
|
||||
{
|
||||
var newRec = new WeightRec()
|
||||
{
|
||||
RM = item.rm,
|
||||
DtEvent = item.dateIn,
|
||||
isIn = true,
|
||||
cod1 = item.cod1,
|
||||
cod2 = item.cod2,
|
||||
cod3 = item.cod3,
|
||||
cod4 = item.cod4,
|
||||
cod5 = item.cod5,
|
||||
cod6 = item.cod6,
|
||||
weight = double.Parse(item.weightIn, NumberStyles.Any, CultureInfo.InvariantCulture)
|
||||
};
|
||||
answ.Add(newRec);
|
||||
}
|
||||
// verifico se ci sia record IN...
|
||||
if (item.dateOutSpecified)
|
||||
{
|
||||
var newRec = new WeightRec()
|
||||
{
|
||||
RM = item.rm,
|
||||
DtEvent = item.dateOut,
|
||||
isIn = false,
|
||||
cod1 = item.cod1,
|
||||
cod2 = item.cod2,
|
||||
cod3 = item.cod3,
|
||||
cod4 = item.cod4,
|
||||
cod5 = item.cod5,
|
||||
cod6 = item.cod6,
|
||||
weight = double.Parse(item.weightOut, NumberStyles.Any, CultureInfo.InvariantCulture)
|
||||
};
|
||||
answ.Add(newRec);
|
||||
}
|
||||
}
|
||||
// riordino...
|
||||
answ = answ.OrderByDescending(x => x.DtEvent).ToList();
|
||||
// restituisco!
|
||||
return answ;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
|
||||
#endregion Protected Classes
|
||||
|
||||
#region Private Properties
|
||||
|
||||
/// <summary>
|
||||
/// Data inizio periodo dati Bilancia:
|
||||
/// - al boot impostato a -6 mesi
|
||||
/// - dopo lettura impostato a data ultimi 5 record
|
||||
/// </summary>
|
||||
private string dataFrom
|
||||
{
|
||||
get => dtStartLive.ToString("dd/MM/yyyy");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Data fine periodo dati Bilancia: oggi + 1gg
|
||||
/// </summary>
|
||||
private string dataTo
|
||||
{
|
||||
get => DateTime.Today.AddDays(1).ToString("dd/MM/yyyy");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Data riferimento x avvio processo controllo
|
||||
/// </summary>
|
||||
private DateTime dtStartLive { get; set; } = DateTime.Today.AddMonths(-6);
|
||||
|
||||
/// <summary>
|
||||
/// Gestione archivio serializzato delle pesate già processate
|
||||
/// </summary>
|
||||
private List<WeightRec> listPesateArchivio
|
||||
{
|
||||
get
|
||||
{
|
||||
List<WeightRec> answ = new List<WeightRec>();
|
||||
string redKey = $"{redKeyPesate}:ALL";
|
||||
string rawData = redisMan.getRSV(redKey);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
try
|
||||
{
|
||||
answ = JsonConvert.DeserializeObject<List<WeightRec>>(rawData);
|
||||
lgInfo($"Rilettura status listPesateArchivio: trovati {answ.Count} record");
|
||||
answ = answ.OrderByDescending(x => x.DtEvent).ToList();
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
lgError($"Errore in deserializzazione listPesateArchivio{Environment.NewLine}{exc}");
|
||||
answ = new List<WeightRec>();
|
||||
}
|
||||
}
|
||||
// rendo
|
||||
return answ;
|
||||
}
|
||||
set
|
||||
{
|
||||
// riordino prima di procedere...
|
||||
var tempList = value.OrderByDescending(x => x.DtEvent).ToList();
|
||||
// ...trimmo se fossero + di xxx record...
|
||||
if (tempList.Count > numLastWeight)
|
||||
{
|
||||
tempList = tempList.Take(numLastWeight).ToList();
|
||||
}
|
||||
string redKey = $"{redKeyPesate}:ALL";
|
||||
string rawVal = JsonConvert.SerializeObject(tempList);
|
||||
redisMan.setRSV(redKey, rawVal);
|
||||
lgInfo($"Salvataggio status listPesateArchivio | {tempList.Count} record");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco pesate attuali
|
||||
/// </summary>
|
||||
private List<WeightRec> listPesateCurr { get; set; } = new List<WeightRec>();
|
||||
|
||||
private string redKeyPesate { get; set; } = "";
|
||||
|
||||
#endregion Private Properties
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private static string formatCode(string currCode)
|
||||
{
|
||||
string code = string.IsNullOrEmpty(currCode) ? "-" : currCode;
|
||||
return $" | {code}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Formatta record completo pesata
|
||||
/// </summary>
|
||||
/// <param name="rec">record completo pesate Gomba</param>
|
||||
/// <param name="isIN">Indica se deve formattare i dati tipo IN (true) o OUT (false)</param>
|
||||
/// <returns></returns>
|
||||
private static string formatPesata(WeightRec rec)
|
||||
{
|
||||
string currVal = $"RM: {rec.RM} | ";
|
||||
try
|
||||
{
|
||||
if (rec.isIn)
|
||||
{
|
||||
currVal += $"IN | ";
|
||||
}
|
||||
else
|
||||
{
|
||||
currVal += $"OUT | ";
|
||||
}
|
||||
currVal += $"{rec.DtEvent:yyyy-MM-dd HH:mm:ss} | {rec.weight:N2} kg";
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
currVal += formatCode(rec.cod1);
|
||||
currVal += formatCode(rec.cod2);
|
||||
currVal += formatCode(rec.cod3);
|
||||
currVal += formatCode(rec.cod4);
|
||||
currVal += formatCode(rec.cod5);
|
||||
currVal += formatCode(rec.cod6);
|
||||
return currVal;
|
||||
}
|
||||
|
||||
private void AppendPesata(WeightRec newRec)
|
||||
{
|
||||
var tmpPesate = listPesateArchivio;
|
||||
tmpPesate.Add(newRec);
|
||||
listPesateArchivio = tmpPesate;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calcola numero pesate da inviare confrontando lista curr ed arch
|
||||
/// </summary>
|
||||
private int num2send()
|
||||
{
|
||||
int answ = 0;
|
||||
if (listPesateCurr.Count > 0)
|
||||
{
|
||||
var listaArch = listPesateArchivio.OrderByDescending(x => x.DtEvent).ToList();
|
||||
// se NON ne ho in archivio --> tutte!
|
||||
if (listaArch.Count == 0)
|
||||
{
|
||||
answ = listPesateCurr.Count;
|
||||
}
|
||||
// altrimenti solo nuove
|
||||
else
|
||||
{
|
||||
// prendo prima della lista pesate archiviate = più recente come dt da cui partire...
|
||||
DateTime dtRif = listaArch.FirstOrDefault().DtEvent;
|
||||
answ = listPesateCurr
|
||||
.Where(x => x.DtEvent > dtRif)
|
||||
.Count();
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="EgwProxy.Gomba" version="3.6.2309.1416" targetFramework="net462" />
|
||||
<package id="EgwProxy.Icoel" version="3.6.2309.708" targetFramework="net462" />
|
||||
<package id="EgwProxy.MultiCncLib" version="3.6.2207.1211" targetFramework="net462" />
|
||||
<package id="EgwProxy.OsaiCncLib" version="3.6.2205.2015" targetFramework="net462" />
|
||||
<package id="EgwProxy.SqlDb" version="3.6.2303.1515" targetFramework="net462" />
|
||||
<package id="EntityFramework" version="6.5.1" targetFramework="net462" />
|
||||
<package id="FluentFTP" version="51.1.0" targetFramework="net462" />
|
||||
<package id="MapoSDK" version="6.14.2411.518" targetFramework="net462" />
|
||||
<package id="MathNet.Numerics" version="5.0.0" targetFramework="net462" />
|
||||
<package id="Microsoft.Bcl.AsyncInterfaces" version="9.0.0" targetFramework="net462" />
|
||||
|
||||
+2
-2
@@ -69,8 +69,8 @@ Global
|
||||
{4B67E8A4-7AE3-47EF-9E06-EF0FA74969F7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4B67E8A4-7AE3-47EF-9E06-EF0FA74969F7}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{4B67E8A4-7AE3-47EF-9E06-EF0FA74969F7}.Release|x86.Build.0 = Release|Any CPU
|
||||
{4B67E8A4-7AE3-47EF-9E06-EF0FA74969F7}.Remote_DEBUG|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4B67E8A4-7AE3-47EF-9E06-EF0FA74969F7}.Remote_DEBUG|Any CPU.Build.0 = Release|Any CPU
|
||||
{4B67E8A4-7AE3-47EF-9E06-EF0FA74969F7}.Remote_DEBUG|Any CPU.ActiveCfg = Remote_DEBUG|Any CPU
|
||||
{4B67E8A4-7AE3-47EF-9E06-EF0FA74969F7}.Remote_DEBUG|Any CPU.Build.0 = Remote_DEBUG|Any CPU
|
||||
{4B67E8A4-7AE3-47EF-9E06-EF0FA74969F7}.Remote_DEBUG|x86.ActiveCfg = Release|Any CPU
|
||||
{4B67E8A4-7AE3-47EF-9E06-EF0FA74969F7}.Remote_DEBUG|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
|
||||
+178
-167
@@ -1,170 +1,181 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
|
||||
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
|
||||
</configSections>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
|
||||
</startup>
|
||||
<appSettings>
|
||||
<add key="appName" value="IOB-WIN-PING" />
|
||||
<add key="enableTest" value="false" />
|
||||
<add key="enableContapezzi" value="true" />
|
||||
<add key="enableMode" value="true" />
|
||||
<add key="enableOverrides" value="false" />
|
||||
<add key="enableTSVC" value="true" />
|
||||
<add key="enableDynData" value="false" />
|
||||
<add key="enableSysInfo" value="false" />
|
||||
<add key="enableAlarms" value="true" />
|
||||
<add key="doStartMemDump" value="false" />
|
||||
<add key="doSampleMemory" value="false" />
|
||||
<add key="basePrgMemPath" value="CNCMEMUSER" />
|
||||
<add key="pingMsTimeout" value="1500" />
|
||||
<add key="serverPingDisabled" value="false" />
|
||||
<add key="urlCallTOut" value="9999" />
|
||||
<add key="urlRandWait" value="200" />
|
||||
<!-- ciclo corto x invio a server: ms -->
|
||||
<add key="timerIntMs" value="10" />
|
||||
<add key="fastCount" value="20" />
|
||||
<add key="normCount" value="200" />
|
||||
<add key="slowCount" value="500" />
|
||||
<add key="verySlowCount" value="3000" />
|
||||
<add key="sampleMemCount" value="6000" />
|
||||
<add key="waitEndCycle" value="0" />
|
||||
<add key="comCheckTOut" value="10" />
|
||||
<!-- watchdog, ping, check disconnesso -->
|
||||
<add key="nMaxSend" value="10" />
|
||||
<add key="pingTestSec" value="5" />
|
||||
<add key="watchdogMaxSec" value="90" />
|
||||
<add key="disconMaxSec" value="30" />
|
||||
<add key="defIOB" value="2999" />
|
||||
<add key="pauseSendMSec" value="2000" />
|
||||
<add key="sendStartFLog" value="false" />
|
||||
<!--gestione coda-->
|
||||
<add key="maxQueueFLog" value="16384" />
|
||||
<add key="maxQueueRawTransf" value="1024" />
|
||||
<!--gestione max num errori-->
|
||||
<add key="maxAliveErrors" value="1000" />
|
||||
<add key="maxErroriCheck" value="300" />
|
||||
<add key="maxSendErrors" value="100" />
|
||||
<add key="maxReadErrors" value="20" />
|
||||
<!--parametri SIM-->
|
||||
<add key="waitSimPar" value="30" />
|
||||
<!--<add key="waitSimPar" value="45" />-->
|
||||
<!--gestione REDIS-->
|
||||
<add key="RedisConn" value="localhost,abortConnect=false,ssl=false" />
|
||||
<add key="RedisConnAdmin" value="localhost,abortConnect=false,ssl=false" />
|
||||
<add key="redisDb" value="10" />
|
||||
<!--gestione invio dati in blocchi Json-->
|
||||
<add key="minJsonData" value="2" />
|
||||
<add key="maxJsonData" value="100" />
|
||||
<add key="maxJsonDataEv" value="25" />
|
||||
<!--gestione multithread-->
|
||||
<add key="sendDataByThread" value="false" />
|
||||
<!--Modalità DEMO: DemoOUT indica che NON invia davvero al server e DemoIN che simula e NON legge da PLC-->
|
||||
<add key="DemoIn" value="false" />
|
||||
<add key="DemoInSample" value="false" />
|
||||
<add key="DemoOut" value="false" />
|
||||
<!--definizione invio dati molto variabili-->
|
||||
<add key="SendAxPos" value="false" />
|
||||
<add key="SendFeedSpeed" value="false" />
|
||||
<!--Definizione avvio Adapter-->
|
||||
<add key="autoLoadConf" value="true" />
|
||||
<add key="autoStartOnLoad" value="true" />
|
||||
<add key="startMinimized" value="false" />
|
||||
<add key="windowCanMax" value="true" />
|
||||
<add key="trayClose" value="true" />
|
||||
<add key="autoSaveSec" value="60" />
|
||||
<add key="waitRecMSec" value="60000" />
|
||||
<add key="testCharSep" value="|" />
|
||||
<add key="delayShowLogMs" value="500" />
|
||||
<add key="vetoSeconds" value="5" />
|
||||
<!--conf file-->
|
||||
<add key="dataPath" value="DATA" />
|
||||
<add key="dataConfPath" value="DATA\CONF" />
|
||||
<add key="dataDatPath" value="DATA\DAT" />
|
||||
<add key="resxPath" value="Resources" />
|
||||
<add key="mainConfFile" value="MAIN.ini" />
|
||||
<add key="defaultPersLayerFile" value="PersistData.dat" />
|
||||
<!--<add key="simDataFile" value="SimData.dat" />-->
|
||||
<!--<add key="memDumpFile" value="MemoryDump.dat" />-->
|
||||
<add key="numSim" value="1" />
|
||||
<add key="AUpdAsAdm" value="true" />
|
||||
<add key="ConfToCloud" value="false" />
|
||||
<add key="CacheConfToCloudDuratHour" value="24" />
|
||||
<!--logging-->
|
||||
<add key="recTime" value="true" />
|
||||
<add key="verbose" value="false" />
|
||||
<add key="logEvery" value="100" />
|
||||
<add key="zipLogOldDay" value="1" />
|
||||
<add key="maxLogDirSize" value="300" />
|
||||
<add key="maxLogDays" value="400" />
|
||||
<add key="numRowConsole" value="50" />
|
||||
<add key="verboseLogTOut" value="60" />
|
||||
<!--conf x FANUC-->
|
||||
<add key="ClientSettingsProvider.ServiceUri" value="" />
|
||||
<add key="pzCountDelay" value="2000" />
|
||||
</appSettings>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<probing privatePath="lib;libs" xmlns="urn:schemas-microsoft-com:asm.v1" />
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.2.0.1" newVersion="4.2.0.1" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Bcl.AsyncInterfaces" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Text.Json" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.4.1" newVersion="4.0.4.1" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.1" newVersion="4.0.1.1" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.IO.Pipelines" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.0.0.1" newVersion="5.0.0.1" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Web.WebView2.WinForms" publicKeyToken="2a8ab48044d2601e" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.0.2903.40" newVersion="1.0.2903.40" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Web.WebView2.Core" publicKeyToken="2a8ab48044d2601e" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.0.2903.40" newVersion="1.0.2903.40" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<system.web>
|
||||
<membership defaultProvider="ClientAuthenticationMembershipProvider">
|
||||
<providers>
|
||||
<add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" />
|
||||
</providers>
|
||||
</membership>
|
||||
<roleManager defaultProvider="ClientRoleProvider" enabled="true">
|
||||
<providers>
|
||||
<add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400" />
|
||||
</providers>
|
||||
</roleManager>
|
||||
</system.web>
|
||||
<configSections>
|
||||
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
|
||||
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
|
||||
</configSections>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
|
||||
</startup>
|
||||
<appSettings>
|
||||
<add key="appName" value="IOB-WIN-PING" />
|
||||
<add key="enableTest" value="false" />
|
||||
<add key="enableContapezzi" value="true" />
|
||||
<add key="enableMode" value="true" />
|
||||
<add key="enableOverrides" value="false" />
|
||||
<add key="enableTSVC" value="true" />
|
||||
<add key="enableDynData" value="false" />
|
||||
<add key="enableSysInfo" value="false" />
|
||||
<add key="enableAlarms" value="true" />
|
||||
<add key="doStartMemDump" value="false" />
|
||||
<add key="doSampleMemory" value="false" />
|
||||
<add key="basePrgMemPath" value="CNCMEMUSER" />
|
||||
<add key="pingMsTimeout" value="1500" />
|
||||
<add key="serverPingDisabled" value="false" />
|
||||
<add key="urlCallTOut" value="9999" />
|
||||
<add key="urlRandWait" value="200" />
|
||||
<!-- ciclo corto x invio a server: ms -->
|
||||
<add key="timerIntMs" value="10" />
|
||||
<add key="fastCount" value="20" />
|
||||
<add key="normCount" value="200" />
|
||||
<add key="slowCount" value="500" />
|
||||
<add key="verySlowCount" value="3000" />
|
||||
<add key="sampleMemCount" value="6000" />
|
||||
<add key="waitEndCycle" value="0" />
|
||||
<add key="comCheckTOut" value="10" />
|
||||
<!-- watchdog, ping, check disconnesso -->
|
||||
<add key="nMaxSend" value="10" />
|
||||
<add key="pingTestSec" value="5" />
|
||||
<add key="watchdogMaxSec" value="90" />
|
||||
<add key="disconMaxSec" value="30" />
|
||||
<add key="defIOB" value="2999" />
|
||||
<add key="pauseSendMSec" value="2000" />
|
||||
<add key="sendStartFLog" value="false" />
|
||||
<!--gestione coda-->
|
||||
<add key="maxQueueFLog" value="16384" />
|
||||
<add key="maxQueueRawTransf" value="1024" />
|
||||
<!--gestione max num errori-->
|
||||
<add key="maxAliveErrors" value="1000" />
|
||||
<add key="maxErroriCheck" value="300" />
|
||||
<add key="maxSendErrors" value="100" />
|
||||
<add key="maxReadErrors" value="20" />
|
||||
<!--parametri SIM-->
|
||||
<add key="waitSimPar" value="30" />
|
||||
<!--<add key="waitSimPar" value="45" />-->
|
||||
<!--gestione REDIS-->
|
||||
<add key="RedisConn" value="localhost,abortConnect=false,ssl=false" />
|
||||
<add key="RedisConnAdmin" value="localhost,abortConnect=false,ssl=false" />
|
||||
<add key="redisDb" value="10" />
|
||||
<!--gestione invio dati in blocchi Json-->
|
||||
<add key="minJsonData" value="2" />
|
||||
<add key="maxJsonData" value="100" />
|
||||
<add key="maxJsonDataEv" value="25" />
|
||||
<!--gestione multithread-->
|
||||
<add key="sendDataByThread" value="false" />
|
||||
<!--Modalità DEMO: DemoOUT indica che NON invia davvero al server e DemoIN che simula e NON legge da PLC-->
|
||||
<add key="DemoIn" value="false" />
|
||||
<add key="DemoInSample" value="false" />
|
||||
<add key="DemoOut" value="false" />
|
||||
<!--definizione invio dati molto variabili-->
|
||||
<add key="SendAxPos" value="false" />
|
||||
<add key="SendFeedSpeed" value="false" />
|
||||
<!--Definizione avvio Adapter-->
|
||||
<add key="autoLoadConf" value="true" />
|
||||
<add key="autoStartOnLoad" value="true" />
|
||||
<add key="startMinimized" value="false" />
|
||||
<add key="windowCanMax" value="true" />
|
||||
<add key="trayClose" value="true" />
|
||||
<add key="autoSaveSec" value="60" />
|
||||
<add key="waitRecMSec" value="60000" />
|
||||
<add key="testCharSep" value="|" />
|
||||
<add key="delayShowLogMs" value="500" />
|
||||
<add key="vetoSeconds" value="5" />
|
||||
<!--conf file-->
|
||||
<add key="dataPath" value="DATA" />
|
||||
<add key="dataConfPath" value="DATA\CONF" />
|
||||
<add key="dataDatPath" value="DATA\DAT" />
|
||||
<add key="resxPath" value="Resources" />
|
||||
<add key="mainConfFile" value="MAIN.ini" />
|
||||
<add key="defaultPersLayerFile" value="PersistData.dat" />
|
||||
<!--<add key="simDataFile" value="SimData.dat" />-->
|
||||
<!--<add key="memDumpFile" value="MemoryDump.dat" />-->
|
||||
<add key="numSim" value="1" />
|
||||
<add key="AUpdAsAdm" value="true" />
|
||||
<add key="ConfToCloud" value="false" />
|
||||
<add key="CacheConfToCloudDuratHour" value="24" />
|
||||
<!--logging-->
|
||||
<add key="recTime" value="true" />
|
||||
<add key="verbose" value="false" />
|
||||
<add key="logEvery" value="100" />
|
||||
<add key="zipLogOldDay" value="1" />
|
||||
<add key="maxLogDirSize" value="300" />
|
||||
<add key="maxLogDays" value="400" />
|
||||
<add key="numRowConsole" value="50" />
|
||||
<add key="verboseLogTOut" value="60" />
|
||||
<!--conf x FANUC-->
|
||||
<add key="ClientSettingsProvider.ServiceUri" value="" />
|
||||
<add key="pzCountDelay" value="2000" />
|
||||
</appSettings>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<probing privatePath="lib;libs" xmlns="urn:schemas-microsoft-com:asm.v1" />
|
||||
|
||||
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.4.0" newVersion="4.0.4.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Bcl.AsyncInterfaces" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Threading.Channels" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Extensions.Logging.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.IO.Pipelines" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.1.0" newVersion="6.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.5.0" newVersion="4.1.5.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Text.Json" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<system.web>
|
||||
<membership defaultProvider="ClientAuthenticationMembershipProvider">
|
||||
<providers>
|
||||
<add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" />
|
||||
</providers>
|
||||
</membership>
|
||||
<roleManager defaultProvider="ClientRoleProvider" enabled="true">
|
||||
<providers>
|
||||
<add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400" />
|
||||
</providers>
|
||||
</roleManager>
|
||||
</system.web>
|
||||
<entityFramework>
|
||||
<providers>
|
||||
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
|
||||
</providers>
|
||||
</entityFramework>
|
||||
</configuration>
|
||||
@@ -0,0 +1,8 @@
|
||||
<linker>
|
||||
<assembly fullname="System.Diagnostics.DiagnosticSource">
|
||||
<type fullname="System.Diagnostics.Metrics.MetricsEventSource">
|
||||
<!-- Used by System.Private.CoreLib via reflection to init the EventSource -->
|
||||
<method name="GetInstance" />
|
||||
</type>
|
||||
</assembly>
|
||||
</linker>
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\packages\EntityFramework.6.5.1\build\EntityFramework.props" Condition="Exists('..\packages\EntityFramework.6.5.1\build\EntityFramework.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
@@ -12,9 +13,11 @@
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Deterministic>true</Deterministic>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
@@ -32,9 +35,82 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Remote_DEBUG|AnyCPU'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\Remote_DEBUG\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="EgwProxy.Icoel, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\EgwProxy.Icoel.3.6.2309.708\lib\EgwProxy.Icoel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="EgwProxy.Icoel.DataLayer, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\EgwProxy.Icoel.3.6.2309.708\lib\EgwProxy.Icoel.DataLayer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="EgwProxy.SqlDb, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\EgwProxy.SqlDb.3.6.2303.1515\lib\EgwProxy.SqlDb.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\EntityFramework.6.5.1\lib\net45\EntityFramework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\EntityFramework.6.5.1\lib\net45\EntityFramework.SqlServer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MapoSDK, Version=6.14.2411.518, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\MapoSDK.6.14.2411.518\lib\MapoSDK.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=9.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.9.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions, Version=9.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.9.0.0\lib\net462\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=9.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Extensions.Logging.Abstractions.9.0.0\lib\net462\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NLog.5.3.4\lib\net46\NLog.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="StackExchange.Redis, Version=2.0.0.0, Culture=neutral, PublicKeyToken=c219ff1ca8c2ce46, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\StackExchange.Redis.2.8.24\lib\net461\StackExchange.Redis.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Buffers, Version=4.0.4.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Buffers.4.6.0\lib\net462\System.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Diagnostics.DiagnosticSource, Version=9.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Diagnostics.DiagnosticSource.9.0.0\lib\net462\System.Diagnostics.DiagnosticSource.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression" />
|
||||
<Reference Include="System.IO.Pipelines, Version=9.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.IO.Pipelines.9.0.0\lib\net462\System.IO.Pipelines.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Memory, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Memory.4.6.0\lib\net462\System.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Numerics.Vectors, Version=4.1.5.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Numerics.Vectors.4.6.0\lib\net462\System.Numerics.Vectors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.1.0\lib\net462\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Channels, Version=9.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Threading.Channels.9.0.0\lib\net462\System.Threading.Channels.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.6.0\lib\net462\System.Threading.Tasks.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
@@ -52,12 +128,16 @@
|
||||
<Compile Include="AdapterFormNext.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="IobSql\IcoelDb.cs" />
|
||||
<Compile Include="IobSql\SqlServLantek.cs" />
|
||||
<Compile Include="IobSql\SqlServPama.cs" />
|
||||
<Compile Include="Iob\GenericNext.cs" />
|
||||
<Compile Include="MainFormNext.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Content Include="ILLink\ILLink.Descriptors.LibraryBuild.xml" />
|
||||
<Content Include="Resources\STEAM-IOB-WIN.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
@@ -139,6 +219,7 @@
|
||||
<ItemGroup>
|
||||
<None Include="App.config">
|
||||
<SubType>Designer</SubType>
|
||||
<TransformOnBuild>true</TransformOnBuild>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
@@ -169,4 +250,23 @@
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="AfterBuild">
|
||||
<ItemGroup>
|
||||
<MoveToLibFolder Include="$(OutputPath)*.dll ; $(OutputPath)*.pdb ; $(OutputPath)*.xml; $(OutputPath)*.so; $(OutputPath)*.dylib" />
|
||||
</ItemGroup>
|
||||
<Move SourceFiles="@(MoveToLibFolder)" DestinationFolder="$(OutputPath)lib" OverwriteReadOnlyFiles="true" />
|
||||
</Target>
|
||||
<Target Name="FinalBuild" AfterTargets="AfterBuild">
|
||||
<Exec Command="$(ProjectDir)postBuildTgt.bat $(ConfigurationName) $(TargetDir)">
|
||||
</Exec>
|
||||
</Target>
|
||||
<Import Project="..\packages\Microsoft.VisualStudio.SlowCheetah.4.0.50\build\Microsoft.VisualStudio.SlowCheetah.targets" Condition="Exists('..\packages\Microsoft.VisualStudio.SlowCheetah.4.0.50\build\Microsoft.VisualStudio.SlowCheetah.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\EntityFramework.6.5.1\build\EntityFramework.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\EntityFramework.6.5.1\build\EntityFramework.props'))" />
|
||||
<Error Condition="!Exists('..\packages\EntityFramework.6.5.1\build\EntityFramework.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\EntityFramework.6.5.1\build\EntityFramework.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\packages\EntityFramework.6.5.1\build\EntityFramework.targets" Condition="Exists('..\packages\EntityFramework.6.5.1\build\EntityFramework.targets')" />
|
||||
</Project>
|
||||
@@ -0,0 +1,288 @@
|
||||
using EgwProxy.Icoel;
|
||||
using IOB_UT_NEXT;
|
||||
using MapoSDK;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Net.NetworkInformation;
|
||||
|
||||
namespace IOB_WIN_SQL.IobSql
|
||||
{
|
||||
/// <summary>
|
||||
/// Adapter specializzato per ICOEL e le chiamate tramite DB per i dati
|
||||
/// - accettazione lotti prodotto (frontiera / entrata ciliegie)
|
||||
/// - export (totale per prodotti)
|
||||
/// - tracciabilità (confezioni
|
||||
/// </summary>
|
||||
|
||||
public class IcoelDb : Iob.GenericNext
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Costruttore dell'IOB Icoel DB
|
||||
/// </summary>
|
||||
/// <param name="caller">AdapterForm chiamante</param>
|
||||
/// <param name="IOBConf">Configurazione IOB per avvio</param>
|
||||
public IcoelDb(AdapterFormNext caller, IobConfiguration IOBConf) : base(caller, IOBConf)
|
||||
{
|
||||
/* --------------------------------------
|
||||
* todo's
|
||||
* --------------------------------------
|
||||
* - init obj comunicazione da conf e nuget
|
||||
* - lanciare sync e verifica stato sync
|
||||
*/
|
||||
|
||||
string SyncStateServer = getOptPar("SyncStateServer");
|
||||
string SyncStateDb = getOptPar("SyncStateDb");
|
||||
string SyncStateUser = getOptPar("SyncStateUser");
|
||||
string SyncStatePwd = getOptPar("SyncStatePwd");
|
||||
string SyncStateCTout = getOptPar("SyncStateCTout");
|
||||
|
||||
string connSyncState = $"data source={SyncStateServer};initial catalog={SyncStateDb};persist security info=True;user id={SyncStateUser};password={SyncStatePwd};MultipleActiveResultSets=True;App=IOB-WIN-NEXT";
|
||||
|
||||
// gestione command timeout da https://erikej.github.io/sqlclient/2020/10/26/sqlclient-commandtimeout-preview.html
|
||||
if (!string.IsNullOrEmpty(SyncStateCTout))
|
||||
{
|
||||
connSyncState = $"{connSyncState};Command Timeout={SyncStateCTout}";
|
||||
}
|
||||
|
||||
// eccezione: NON TROVA EntityFramework 6.0.0 o successivo... why?!?
|
||||
dbProxy = new DbProxy(connSyncState);
|
||||
|
||||
lastPING = DateTime.Now.AddHours(-1);
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Implementazione custom esecuzione task specifici
|
||||
/// </summary>
|
||||
/// <param name="task2exe"></param>
|
||||
/// <returns></returns>
|
||||
public override Dictionary<string, string> executeTasks(Dictionary<string, string> task2exe)
|
||||
{
|
||||
// unico task ammissibile: fare un SYNC forzato...
|
||||
Dictionary<string, string> taskDone = new Dictionary<string, string>();
|
||||
if (task2exe != null)
|
||||
{
|
||||
// controllo se memMap != null...
|
||||
if (memMap != null)
|
||||
{
|
||||
bool taskOk = false;
|
||||
string taskVal = "";
|
||||
// cerco task specifici: se ho startSetup --> imposto bit DBB701.DBB0.4
|
||||
foreach (var item in task2exe)
|
||||
{
|
||||
taskOk = false;
|
||||
taskVal = "";
|
||||
// converto richiesta in enum...
|
||||
taskType tName = taskType.nihil;
|
||||
Enum.TryParse(item.Key, out tName);
|
||||
// controllo sulla KEY...
|
||||
switch (tName)
|
||||
{
|
||||
case taskType.syncDbData:
|
||||
lgInfo($"executeTasks --> syncDbData");
|
||||
// effettua sync
|
||||
refreshElencoStati();
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
taskVal = $"IobIcoelDb | taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
|
||||
lgInfo($"IobIcoelDb | chiamata senza processing: taskOk: {taskOk} | taskVal: {taskVal}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
lastReadPLC = DateTime.Now;
|
||||
return taskDone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero dati dinamici...
|
||||
/// </summary>
|
||||
public override Dictionary<string, string> getDynData()
|
||||
{
|
||||
// valore non presente in vers default... se gestito fare override
|
||||
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
||||
// recupero da DB locale stato sync attuale
|
||||
var elencoSyncStateCurr = dbProxy.DataController.SyncStateGetAll();
|
||||
foreach (var item in elencoSyncStateCurr)
|
||||
{
|
||||
saveValue(ref outVal, $"{item.TableName}_NumRec", item.NumRec);
|
||||
saveValue(ref outVal, $"{item.TableName}_NumRecIn", item.NumRecIn);
|
||||
saveValue(ref outVal, $"{item.TableName}_LastIdx", item.LastIdx);
|
||||
saveValue(ref outVal, $"{item.TableName}_LastIdxIn", item.LastIdxIn);
|
||||
}
|
||||
|
||||
// aggiungo anche i campi currData
|
||||
var currData = dbProxy.DataController.CurrDataGetAll();
|
||||
foreach (var item in currData)
|
||||
{
|
||||
saveValue(ref outVal, item.Topic, (double)item.CurrVal);
|
||||
}
|
||||
|
||||
lastReadPLC = DateTime.Now;
|
||||
return outVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua processing CUSTOM x Icoel:
|
||||
/// - recupera elenco batch delle 2 linee
|
||||
/// - invia al sistema
|
||||
/// </summary>
|
||||
public override void processCustomTaskLF()
|
||||
{
|
||||
lgInfo($"Richiesto processCustomTaskLF");
|
||||
// effettua sync
|
||||
refreshElencoStati();
|
||||
lastReadPLC = DateTime.Now;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua lettura semafori principale <paramref name="currDispData">Parametri da
|
||||
/// aggiornare x display in form</paramref>
|
||||
/// </summary>
|
||||
public override void readSemafori(ref newDisplayData currDispData)
|
||||
{
|
||||
if (connectionOk)
|
||||
{
|
||||
B_input = 1;
|
||||
currDispData.semIn = Semaforo.SV;
|
||||
|
||||
if (dbProxy != null && elencoSyncState != null && elencoSyncState.Count > 0)
|
||||
{
|
||||
B_input += (1 << 1);
|
||||
}
|
||||
|
||||
// accodo NON emergenza
|
||||
B_input += (1 << 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
B_input = 0;
|
||||
currDispData.semIn = Semaforo.SR;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override connessione
|
||||
/// </summary>
|
||||
public override void tryConnect()
|
||||
{
|
||||
if (!connectionOk)
|
||||
{
|
||||
// controllo che il ping sia stato tentato almeno pingTestSec fa...
|
||||
if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec"))
|
||||
{
|
||||
if (verboseLog || periodicLog)
|
||||
{
|
||||
lgInfo("IcoelSoap: ConnKO - tryConnect");
|
||||
}
|
||||
// in primis salvo data ping...
|
||||
lastPING = DateTime.Now;
|
||||
// se passa il ping faccio il resto...
|
||||
if (testPingMachine == IPStatus.Success)
|
||||
{
|
||||
string szStatusConnection = "";
|
||||
try
|
||||
{
|
||||
// ora provo connessione...
|
||||
parentForm.commPlcActive = true;
|
||||
if (dbProxy != null)
|
||||
{
|
||||
elencoSyncState = dbProxy.DataController.SyncStateDoImportAll();
|
||||
|
||||
if (elencoSyncState != null && elencoSyncState.Count > 0)
|
||||
{
|
||||
parentForm.commPlcActive = false;
|
||||
connectionOk = true;
|
||||
}
|
||||
}
|
||||
// refresh stato connessione!!!
|
||||
if (connectionOk)
|
||||
{
|
||||
queueInEnabCurr = true;
|
||||
if (adpRunning)
|
||||
{
|
||||
lgInfo("Connessione OK");
|
||||
lastReadPLC = DateTime.Now;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError("Impossibile procedere, connessione mancante...");
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
lgFatal($"Errore nella connessione all'adapter IcoelSoap: {szStatusConnection}{Environment.NewLine}{exc}");
|
||||
connectionOk = false;
|
||||
lgInfo($"Eccezione in TryConnect, Adapter IcoelSoap NON running, pausa di {utils.CRI("waitRecMSec")} msec prima di ulteriori tentativi di riconnessione");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// loggo no risposta ping ...
|
||||
connectionOk = false;
|
||||
if (verboseLog || periodicLog)
|
||||
{
|
||||
lgInfo($"Attenzione: IcoelSoap controllo PING fallito per IP {cIobConf.cncPingAddr}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
needRefresh = true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void tryDisconnect()
|
||||
{
|
||||
// registro solo che è disconnesso
|
||||
connectionOk = false;
|
||||
queueInEnabCurr = false;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
protected EgwProxy.Icoel.DbProxy dbProxy { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// Stato di sync delle tab gestite
|
||||
/// </summary>
|
||||
protected List<EgwProxy.Icoel.DataLayer.DatabaseModels.SyncStateModel> elencoSyncState { get; set; } = new List<EgwProxy.Icoel.DataLayer.DatabaseModels.SyncStateModel>();
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private void refreshElencoStati()
|
||||
{
|
||||
Stopwatch sw = new Stopwatch();
|
||||
sw.Start();
|
||||
elencoSyncState = dbProxy.DataController.SyncStateDoImportAll();
|
||||
sw.Stop();
|
||||
lastReadPLC = DateTime.Now;
|
||||
lgInfo($"DB: esecuzione task dbProxy.DataController.SyncStateGetAll() in {sw.ElapsedMilliseconds} ms");
|
||||
|
||||
if (elencoSyncState != null)
|
||||
{
|
||||
foreach (var item in elencoSyncState)
|
||||
{
|
||||
lgTrace($"TAB: {item.TableName} | IdxIN / IdxLocal {item.LastIdxIn} / {item.LastIdx} | NumIn / NumLocal {item.NumRecIn} / {item.NumRec}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,523 @@
|
||||
using EgwProxy.SqlDb.Controllers;
|
||||
using EgwProxy.SqlDb.DbModels;
|
||||
using IOB_UT_NEXT;
|
||||
using MapoSDK;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net.NetworkInformation;
|
||||
using static IOB_UT_NEXT.CustomObj;
|
||||
|
||||
namespace IOB_WIN_SQL.IobSql
|
||||
{
|
||||
/// <summary>
|
||||
/// Adapter specializzato per LANTEK e le chiamate tramite DB per i dati
|
||||
/// - PODL (ordini MES --> MACCHINA)
|
||||
/// - ProdLog (da NestingDaLantek + RigheNestingDaLantek)
|
||||
/// </summary>
|
||||
|
||||
public class SqlServLantek : Iob.GenericNext
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Costruttore dell'IOB DB LANTEK
|
||||
/// </summary>
|
||||
/// <param name="caller">AdapterForm chiamante</param>
|
||||
/// <param name="IOBConf">Configurazione IOB per avvio</param>
|
||||
public SqlServLantek(AdapterFormNext caller, IobConfiguration IOBConf) : base(caller, IOBConf)
|
||||
{
|
||||
DateTime adesso = DateTime.Now;
|
||||
string SyncStateServ = getOptPar("SyncStateServer");
|
||||
string SyncStateDb = getOptPar("SyncStateDb");
|
||||
string SyncStateUser = getOptPar("SyncStateUser");
|
||||
string SyncStatePwd = getOptPar("SyncStatePwd");
|
||||
string SyncStateCTout = getOptPar("SyncStateCTout");
|
||||
string VetoReadSec = getOptPar("VetoReadSec");
|
||||
string VetoSyncSec = getOptPar("VetoSyncSec");
|
||||
string sFullPodlUrl = getOptPar("FullPodlUrl");
|
||||
|
||||
setupSpecialParams();
|
||||
|
||||
string connSyncState = $"data source={SyncStateServ};initial catalog={SyncStateDb};persist security info=True;user id={SyncStateUser};password={SyncStatePwd};MultipleActiveResultSets=True;App=IOB-WIN-NEXT";
|
||||
|
||||
// gestione command timeout da https://erikej.github.io/sqlclient/2020/10/26/sqlclient-commandtimeout-preview.html
|
||||
if (!string.IsNullOrEmpty(SyncStateCTout))
|
||||
{
|
||||
connSyncState = $"{connSyncState};Command Timeout={SyncStateCTout}";
|
||||
}
|
||||
if (!string.IsNullOrEmpty(VetoReadSec))
|
||||
{
|
||||
int.TryParse(VetoReadSec, out vetoReadDbSec);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(VetoSyncSec))
|
||||
{
|
||||
int.TryParse(VetoSyncSec, out VetoSyncDbSec);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(sFullPodlUrl))
|
||||
{
|
||||
bool.TryParse(sFullPodlUrl, out FullPodlUrl);
|
||||
}
|
||||
|
||||
// avvio DB controller
|
||||
dbProxy = new DbController(connSyncState);
|
||||
|
||||
lastPING = DateTime.Now.AddHours(-1);
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Implementazione custom esecuzione task specifici
|
||||
/// </summary>
|
||||
/// <param name="task2exe"></param>
|
||||
/// <returns></returns>
|
||||
public override Dictionary<string, string> executeTasks(Dictionary<string, string> task2exe)
|
||||
{
|
||||
DateTime adesso = DateTime.Now;
|
||||
// unico task ammissibile: fare un SYNC forzato...
|
||||
Dictionary<string, string> taskDone = new Dictionary<string, string>();
|
||||
if (task2exe != null)
|
||||
{
|
||||
// controllo se memMap != null...
|
||||
if (memMap != null)
|
||||
{
|
||||
bool taskOk = false;
|
||||
string taskVal = "";
|
||||
// cerco task specifici: se ho startSetup --> imposto bit DBB701.DBB0.4
|
||||
foreach (var item in task2exe)
|
||||
{
|
||||
taskOk = false;
|
||||
taskVal = "";
|
||||
// converto richiesta in enum...
|
||||
taskType tName = taskType.nihil;
|
||||
Enum.TryParse(item.Key, out tName);
|
||||
// controllo sulla KEY...
|
||||
switch (tName)
|
||||
{
|
||||
case taskType.setComm:
|
||||
case taskType.syncDbData:
|
||||
lgInfo($"executeTasks --> {tName}");
|
||||
// per prima cosa recupero elenco PODL attivi x la macchina
|
||||
List<PODLModel> listaPODL = new List<PODLModel>();
|
||||
bool okPodl = false;
|
||||
var rawListPODL = callUrl(urlGetCurrPODL, false);
|
||||
if (!string.IsNullOrEmpty(rawListPODL))
|
||||
{
|
||||
try
|
||||
{
|
||||
listaPODL = JsonConvert.DeserializeObject<List<PODLModel>>(rawListPODL);
|
||||
okPodl = listaPODL.Count > 0;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
lg.Error($"Errore: chiamata elenco PODL ha restituito errore{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lg.Error($"Errore: chiamata elenco PODL ({urlGetCurrPODL}) ha restituito valore vuoto");
|
||||
}
|
||||
if (okPodl)
|
||||
{
|
||||
//mando elenco PODL...
|
||||
List<MesPODLReqModel> CurrPodlReq = listaPODL
|
||||
.Select(x => new MesPODLReqModel()
|
||||
{
|
||||
Attivabile = x.Attivabile,
|
||||
CodArticolo = x.CodArticolo,
|
||||
CodCli = x.CodCli,
|
||||
CodGruppo = x.CodGruppo,
|
||||
DueDate = x.DueDate ?? DateTime.Now,
|
||||
IdxMacchina = x.IdxMacchina,
|
||||
IdxODL = x.IdxOdl,
|
||||
IdxPromessa = x.IdxPromessa,
|
||||
InsertDate = x.InsertDate,
|
||||
KeyBCode = x.KeyBCode,
|
||||
KeyRichiesta = x.KeyRichiesta,
|
||||
Note = x.Note,
|
||||
NumPezzi = x.NumPezzi,
|
||||
Priorita = x.Priorita,
|
||||
PzPallet = x.PzPallet,
|
||||
TCAssegnato = x.Tcassegnato
|
||||
})
|
||||
.ToList();
|
||||
// scrivo i record richiesti
|
||||
bool fatto = dbProxy.MesPodlWriteReq(CurrPodlReq);
|
||||
if (fatto)
|
||||
{
|
||||
taskVal = $"EXECUTED task: {item.Key} / {item.Value}";
|
||||
// registro evento chiamata scrittura in syncState...
|
||||
string tabName = item.Key;
|
||||
var currSyncState = elencoSyncState.FirstOrDefault(x => x.TableName == tabName);
|
||||
// verifico x registrare azione
|
||||
if (currSyncState == null)
|
||||
{
|
||||
currSyncState = new SyncStateModel()
|
||||
{
|
||||
LastIdx = 0,
|
||||
LastUpdate = adesso,
|
||||
TableName = tabName,
|
||||
Note = "Init"
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
var lastRec = CurrPodlReq.OrderBy(x => x.IdxPromessa).LastOrDefault();
|
||||
currSyncState.LastIdx = lastRec != null ? lastRec.IdxPromessa : -1;
|
||||
currSyncState.Note = $"Esecuzione {tabName} per {CurrPodlReq.Count} rec | last code: {currSyncState.LastIdx}";
|
||||
currSyncState.LastUpdate = adesso;
|
||||
}
|
||||
// salvo sync...
|
||||
dbProxy.SyncStateUpsert(currSyncState);
|
||||
}
|
||||
|
||||
// effettua sync scrivendo i dati in export (PODL)
|
||||
execExportAll();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
taskVal = $"IobSqlServLantek | taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
|
||||
lgInfo($"IobSqlServLantek | chiamata senza processing: taskOk: {taskOk} | taskVal: {taskVal}");
|
||||
break;
|
||||
}
|
||||
// aggiungo task!
|
||||
taskDone.Add(item.Key, taskVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
lastReadPLC = DateTime.Now;
|
||||
return taskDone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero dati dinamici... FAKE!
|
||||
/// </summary>
|
||||
public override Dictionary<string, string> getDynData()
|
||||
{
|
||||
DateTime adesso = DateTime.Now;
|
||||
|
||||
// dizionario vuoto / gestito da altro adapter file-based
|
||||
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
||||
|
||||
lastReadPLC = DateTime.Now;
|
||||
return outVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua processing CUSTOM:
|
||||
/// - esegue tutti gli import
|
||||
/// </summary>
|
||||
public override void processCustomTaskLF()
|
||||
{
|
||||
lgInfo($"Richiesto processCustomTaskLF");
|
||||
// effettua sync
|
||||
execExportAll();
|
||||
execImportAll();
|
||||
lastReadPLC = DateTime.Now;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua lettura semafori principale <paramref name="currDispData">Parametri da
|
||||
/// aggiornare x display in form</paramref>
|
||||
/// </summary>
|
||||
public override void readSemafori(ref newDisplayData currDispData)
|
||||
{
|
||||
DateTime adesso = DateTime.Now;
|
||||
if (connectionOk)
|
||||
{
|
||||
// controllo veto checkDB
|
||||
if (adesso > vetoDataRead)
|
||||
{
|
||||
// predispongo prox veto...
|
||||
vetoDataRead = adesso.AddSeconds(vetoReadDbSec);
|
||||
if (adesso > vetoDataSync)
|
||||
{
|
||||
// effettua sync
|
||||
execImportAll();
|
||||
vetoDataSync = adesso.AddSeconds(VetoSyncDbSec);
|
||||
}
|
||||
|
||||
// semaforo
|
||||
currDispData.semIn = Semaforo.SV;
|
||||
// recupero syncState
|
||||
elencoSyncState = dbProxy.SyncStateGetAll();
|
||||
// verifico ProdData e processo
|
||||
bool sentProdData = processProdDataTable(adesso);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
B_input = 0;
|
||||
currDispData.semIn = Semaforo.SR;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override connessione
|
||||
/// </summary>
|
||||
public override void tryConnect()
|
||||
{
|
||||
if (!connectionOk)
|
||||
{
|
||||
// controllo che il ping sia stato tentato almeno pingTestSec fa...
|
||||
if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec"))
|
||||
{
|
||||
if (verboseLog || periodicLog)
|
||||
{
|
||||
lgInfo("SqlDb LANTEK: ConnKO - tryConnect");
|
||||
}
|
||||
// in primis salvo data ping...
|
||||
lastPING = DateTime.Now;
|
||||
// se passa il ping faccio il resto...
|
||||
if (testPingMachine == IPStatus.Success)
|
||||
{
|
||||
string szStatusConnection = "";
|
||||
try
|
||||
{
|
||||
// ora provo connessione...
|
||||
parentForm.commPlcActive = true;
|
||||
if (dbProxy != null)
|
||||
{
|
||||
elencoSyncState = dbProxy.SyncStateDoImportAll();
|
||||
|
||||
if (elencoSyncState != null && elencoSyncState.Count > 0)
|
||||
{
|
||||
parentForm.commPlcActive = false;
|
||||
connectionOk = true;
|
||||
}
|
||||
}
|
||||
// refresh stato connessione!!!
|
||||
if (connectionOk)
|
||||
{
|
||||
queueInEnabCurr = true;
|
||||
if (adpRunning)
|
||||
{
|
||||
lgInfo("Connessione OK");
|
||||
lastReadPLC = DateTime.Now;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError("Impossibile procedere, connessione mancante...");
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
lgFatal($"Errore nella connessione all'adapter SqlDb LANTEK: {szStatusConnection}{Environment.NewLine}{exc}");
|
||||
connectionOk = false;
|
||||
lgInfo($"Eccezione in TryConnect, Adapter SqlDb LANTEK NON running, pausa di {utils.CRI("waitRecMSec")} msec prima di ulteriori tentativi di riconnessione");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// loggo no risposta ping ...
|
||||
connectionOk = false;
|
||||
if (verboseLog || periodicLog)
|
||||
{
|
||||
lgInfo($"Attenzione: SqlDb LANTEK controllo PING fallito per IP {cIobConf.cncPingAddr}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
needRefresh = true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void tryDisconnect()
|
||||
{
|
||||
// registro solo che è disconnesso
|
||||
connectionOk = false;
|
||||
queueInEnabCurr = false;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
protected bool FullPodlUrl = false;
|
||||
protected int vetoReadDbSec = 3;
|
||||
|
||||
protected int VetoSyncDbSec = 20;
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
protected DbController dbProxy { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// Stato di sync delle tab gestite
|
||||
/// </summary>
|
||||
protected List<SyncStateModel> elencoSyncState { get; set; } = new List<SyncStateModel>();
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Esegue task EXPORT (MES PODL to MACHINE)
|
||||
/// </summary>
|
||||
private void execExportAll()
|
||||
{
|
||||
Stopwatch sw = new Stopwatch();
|
||||
sw.Start();
|
||||
elencoSyncState = dbProxy.SyncStateDoExportAll();
|
||||
sw.Stop();
|
||||
DateTime adesso = DateTime.Now;
|
||||
lastReadPLC = adesso;
|
||||
lgInfo($"DB: esecuzione task dbProxy.SyncStateDoExportAll() in {sw.ElapsedMilliseconds} ms");
|
||||
|
||||
if (elencoSyncState != null)
|
||||
{
|
||||
// registro evento chiamata scrittura in syncState...
|
||||
string tabName = "ExportAll";
|
||||
var currSyncState = elencoSyncState.FirstOrDefault(x => x.TableName == tabName);
|
||||
// verifico x registrare azione
|
||||
if (currSyncState == null)
|
||||
{
|
||||
currSyncState = new SyncStateModel()
|
||||
{
|
||||
LastIdx = 0,
|
||||
LastUpdate = adesso,
|
||||
TableName = tabName,
|
||||
Note = "Init"
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
// calcolo lastIDX valore da datetime
|
||||
int valInt = -1;
|
||||
var nowString = $"{adesso:HHmmss}";
|
||||
int.TryParse(nowString, out valInt);
|
||||
currSyncState.LastIdx = valInt;
|
||||
currSyncState.Note = $"Esecuzione {tabName} | DT code: {currSyncState.LastIdx}";
|
||||
currSyncState.LastUpdate = adesso;
|
||||
}
|
||||
// salvo sync...
|
||||
dbProxy.SyncStateUpsert(currSyncState);
|
||||
foreach (var item in elencoSyncState)
|
||||
{
|
||||
lgTrace($"TAB {item.TableName} | LastIdx {item.LastIdx} | Note {item.Note} | Last Upd {item.LastUpdate}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Esegue task IMPORT (MES PODL to MACHINE)
|
||||
/// </summary>
|
||||
private void execImportAll()
|
||||
{
|
||||
Stopwatch sw = new Stopwatch();
|
||||
sw.Start();
|
||||
elencoSyncState = dbProxy.SyncStateDoImportAll();
|
||||
sw.Stop();
|
||||
lastReadPLC = DateTime.Now;
|
||||
lgInfo($"DB: esecuzione task dbProxy.SyncStateDoImportAll() in {sw.ElapsedMilliseconds} ms");
|
||||
|
||||
if (elencoSyncState != null)
|
||||
{
|
||||
foreach (var item in elencoSyncState)
|
||||
{
|
||||
lgTrace($"TAB {item.TableName} | LastIdx {item.LastIdx} | Note {item.Note} | Last Upd {item.LastUpdate}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Esegue processing + invio dati tab ProdData
|
||||
/// </summary>
|
||||
/// <param name="adesso"></param>
|
||||
/// <returns></returns>
|
||||
private bool processProdDataTable(DateTime adesso)
|
||||
{
|
||||
bool fatto = false;
|
||||
string tabNameIn = "ProdData";
|
||||
string tabNameOut = "ProdDataToMes";
|
||||
// cerco info sui SignLog (ToMes e letti)
|
||||
var currSignLogRead = elencoSyncState.FirstOrDefault(x => x.TableName == tabNameIn);
|
||||
// se nullo inizializzo
|
||||
if (currSignLogRead == null)
|
||||
{
|
||||
currSignLogRead = new SyncStateModel()
|
||||
{
|
||||
LastIdx = 0,
|
||||
LastUpdate = adesso,
|
||||
TableName = tabNameIn,
|
||||
Note = "Init"
|
||||
};
|
||||
}
|
||||
var currSignLogSent = elencoSyncState.FirstOrDefault(x => x.TableName == tabNameOut);
|
||||
// se nullo inizializzo
|
||||
if (currSignLogSent == null)
|
||||
{
|
||||
currSignLogSent = new SyncStateModel()
|
||||
{
|
||||
LastIdx = 0,
|
||||
LastUpdate = adesso,
|
||||
TableName = tabNameOut,
|
||||
Note = "Init"
|
||||
};
|
||||
}
|
||||
// verifica se ci siano dati da trasmettere (sui valori LastIdx)
|
||||
if (currSignLogRead.LastIdx > currSignLogSent.LastIdx)
|
||||
{
|
||||
// recupero i dati dal DB...
|
||||
var data2send = dbProxy.MachProdDataGetNew(currSignLogSent.LastIdx);
|
||||
// se ho dati preparo invio
|
||||
if (data2send != null && data2send.Count > 0)
|
||||
{
|
||||
foreach (var sLog2send in data2send)
|
||||
{
|
||||
if (sLog2send.Action == "StartOrd")
|
||||
{
|
||||
if (FullPodlUrl)
|
||||
{
|
||||
// se il record è apertura PODL chiamo apertura
|
||||
trySetupPODL(sLog2send.IdxPodl, true, sLog2send.DtEve, DateTime.Now);
|
||||
}
|
||||
else
|
||||
{
|
||||
trySetupPODL(0);
|
||||
}
|
||||
}
|
||||
else if (sLog2send.Action == "EndOrd")
|
||||
{
|
||||
// se il record è chiusura PODL chiamo chiusura... DOPO aver cercato
|
||||
// PODL --> ODL
|
||||
if (FullPodlUrl)
|
||||
{
|
||||
tryClosePODL(sLog2send.IdxPodl, sLog2send.DtEve, DateTime.Now);
|
||||
}
|
||||
else
|
||||
{
|
||||
tryClosePODL(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// aggiorno idx inviato...
|
||||
currSignLogSent.Note = $"Updated from {currSignLogRead.LastIdx}";
|
||||
currSignLogSent.LastUpdate = adesso;
|
||||
currSignLogSent.LastIdx = currSignLogRead.LastIdx;
|
||||
fatto = true;
|
||||
}
|
||||
|
||||
// alla fine aggiorno i dati inviati!
|
||||
dbProxy.SyncStateUpsert(currSignLogSent);
|
||||
|
||||
return fatto;
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,686 @@
|
||||
using EgwProxy.SqlDb.Controllers;
|
||||
using EgwProxy.SqlDb.DbModels;
|
||||
using IOB_UT_NEXT;
|
||||
using MapoSDK;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net.NetworkInformation;
|
||||
using static IOB_UT_NEXT.CustomObj;
|
||||
|
||||
namespace IOB_WIN_SQL.IobSql
|
||||
{
|
||||
/// <summary>
|
||||
/// Adapter specializzato per PAMA e le chiamate tramite DB per i dati
|
||||
/// - PODL (ordini MES --> MACCHINA)
|
||||
/// - SignLog (da stato macchina)
|
||||
/// - FluxLog (da stato macchina)
|
||||
/// - ProdLog (da stato Prod)
|
||||
/// </summary>
|
||||
public class SqlServPama : Iob.GenericNext
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Costruttore dell'IOB DB PAMA
|
||||
/// </summary>
|
||||
/// <param name="caller">AdapterForm chiamante</param>
|
||||
/// <param name="IOBConf">Configurazione IOB per avvio</param>
|
||||
public SqlServPama(AdapterFormNext caller, IobConfiguration IOBConf) : base(caller, IOBConf)
|
||||
{
|
||||
string SyncStateServ = getOptPar("SyncStateServer");
|
||||
string SyncStateDb = getOptPar("SyncStateDb");
|
||||
string SyncStateUser = getOptPar("SyncStateUser");
|
||||
string SyncStatePwd = getOptPar("SyncStatePwd");
|
||||
string SyncStateCTout = getOptPar("SyncStateCTout");
|
||||
string VetoReadSec = getOptPar("VetoReadSec");
|
||||
string VetoSyncSec = getOptPar("VetoSyncSec");
|
||||
string sFullPodlUrl = getOptPar("FullPodlUrl");
|
||||
|
||||
string connSyncState = $"data source={SyncStateServ};initial catalog={SyncStateDb};persist security info=True;user id={SyncStateUser};password={SyncStatePwd};MultipleActiveResultSets=True;App=IOB-WIN-NEXT";
|
||||
|
||||
// gestione command timeout da https://erikej.github.io/sqlclient/2020/10/26/sqlclient-commandtimeout-preview.html
|
||||
if (!string.IsNullOrEmpty(SyncStateCTout))
|
||||
{
|
||||
connSyncState = $"{connSyncState};Command Timeout={SyncStateCTout}";
|
||||
}
|
||||
if (!string.IsNullOrEmpty(VetoReadSec))
|
||||
{
|
||||
int.TryParse(VetoReadSec, out vetoReadDbSec);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(VetoSyncSec))
|
||||
{
|
||||
int.TryParse(VetoSyncSec, out VetoSyncDbSec);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(sFullPodlUrl))
|
||||
{
|
||||
bool.TryParse(sFullPodlUrl, out FullPodlUrl);
|
||||
}
|
||||
|
||||
// eccezione: NON TROVA EntityFramework 6.0.0 o successivo... why?!?
|
||||
dbProxy = new DbController(connSyncState);
|
||||
|
||||
lastPING = DateTime.Now.AddHours(-1);
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Implementazione custom esecuzione task specifici
|
||||
/// </summary>
|
||||
/// <param name="task2exe"></param>
|
||||
/// <returns></returns>
|
||||
public override Dictionary<string, string> executeTasks(Dictionary<string, string> task2exe)
|
||||
{
|
||||
DateTime adesso = DateTime.Now;
|
||||
// unico task ammissibile: fare un SYNC forzato...
|
||||
Dictionary<string, string> taskDone = new Dictionary<string, string>();
|
||||
if (task2exe != null)
|
||||
{
|
||||
// controllo se memMap != null...
|
||||
if (memMap != null)
|
||||
{
|
||||
bool taskOk = false;
|
||||
string taskVal = "";
|
||||
// cerco task specifici: se ho startSetup --> imposto bit DBB701.DBB0.4
|
||||
foreach (var item in task2exe)
|
||||
{
|
||||
taskOk = false;
|
||||
taskVal = "";
|
||||
// converto richiesta in enum...
|
||||
taskType tName = taskType.nihil;
|
||||
Enum.TryParse(item.Key, out tName);
|
||||
// controllo sulla KEY...
|
||||
switch (tName)
|
||||
{
|
||||
case taskType.setComm:
|
||||
case taskType.syncDbData:
|
||||
lgInfo($"executeTasks --> {tName}");
|
||||
// per prima cosa recupero elenco PODL attivi x la macchina
|
||||
List<PODLModel> listaPODL = new List<PODLModel>();
|
||||
bool okPodl = false;
|
||||
var rawListPODL = callUrl(urlGetNextPODL, false);
|
||||
if (!string.IsNullOrEmpty(rawListPODL))
|
||||
{
|
||||
try
|
||||
{
|
||||
listaPODL = JsonConvert.DeserializeObject<List<PODLModel>>(rawListPODL);
|
||||
okPodl = listaPODL.Count > 0;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
lg.Error($"Errore: chiamata elenco PODL ha restituito errore{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lg.Error($"Errore: chiamata elenco PODL ({urlGetNextPODL}) ha restituito valore vuoto");
|
||||
}
|
||||
if (okPodl)
|
||||
{
|
||||
//mando elenco PODL...
|
||||
List<MesPODLReqModel> CurrPodlReq = listaPODL
|
||||
.Select(x => new MesPODLReqModel()
|
||||
{
|
||||
Attivabile = x.Attivabile,
|
||||
CodArticolo = x.CodArticolo,
|
||||
CodCli = x.CodCli,
|
||||
CodGruppo = x.CodGruppo,
|
||||
DueDate = x.DueDate ?? DateTime.Now,
|
||||
IdxMacchina = x.IdxMacchina,
|
||||
IdxODL = x.IdxOdl,
|
||||
IdxPromessa = x.IdxPromessa,
|
||||
InsertDate = x.InsertDate,
|
||||
KeyBCode = x.KeyBCode,
|
||||
KeyRichiesta = x.KeyRichiesta,
|
||||
Note = x.Note,
|
||||
NumPezzi = x.NumPezzi,
|
||||
Priorita = x.Priorita,
|
||||
PzPallet = x.PzPallet,
|
||||
TCAssegnato = x.Tcassegnato
|
||||
})
|
||||
.ToList();
|
||||
// scrivo i record richiesti
|
||||
bool fatto = dbProxy.MesPodlWriteReq(CurrPodlReq);
|
||||
if (fatto)
|
||||
{
|
||||
taskVal = $"EXECUTED task: {item.Key} / {item.Value}";
|
||||
// registro evento chiamata scrittura in syncState...
|
||||
string tabName = item.Key;
|
||||
var currSyncState = elencoSyncState.FirstOrDefault(x => x.TableName == tabName);
|
||||
// verifico x registrare azione
|
||||
if (currSyncState == null)
|
||||
{
|
||||
currSyncState = new SyncStateModel()
|
||||
{
|
||||
LastIdx = 0,
|
||||
LastUpdate = adesso,
|
||||
TableName = tabName,
|
||||
Note = "Init"
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
var lastRec = CurrPodlReq.OrderBy(x => x.IdxPromessa).LastOrDefault();
|
||||
currSyncState.LastIdx = lastRec != null ? lastRec.IdxPromessa : -1;
|
||||
currSyncState.Note = $"Esecuzione {tabName} per {CurrPodlReq.Count} rec | last code: {currSyncState.LastIdx}";
|
||||
currSyncState.LastUpdate = adesso;
|
||||
}
|
||||
// salvo sync...
|
||||
dbProxy.SyncStateUpsert(currSyncState);
|
||||
}
|
||||
|
||||
// effettua sync scrivendo i dati in export (PODL)
|
||||
execExportAll();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
taskVal = $"IobSqlServPama | taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
|
||||
lgInfo($"IobSqlServPama | chiamata senza processing: taskOk: {taskOk} | taskVal: {taskVal}");
|
||||
break;
|
||||
}
|
||||
// aggiungo task!
|
||||
taskDone.Add(item.Key, taskVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
lastReadPLC = DateTime.Now;
|
||||
return taskDone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero dati dinamici...
|
||||
/// </summary>
|
||||
public override Dictionary<string, string> getDynData()
|
||||
{
|
||||
DateTime adesso = DateTime.Now;
|
||||
|
||||
// dizionario vuoto / faccio direttamente accodamento in FluxLog
|
||||
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
||||
|
||||
// processo ed accodo!
|
||||
processFluxLogTable(adesso);
|
||||
|
||||
lastReadPLC = DateTime.Now;
|
||||
return outVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua processing CUSTOM:
|
||||
/// - esegue tutti gli import
|
||||
/// </summary>
|
||||
public override void processCustomTaskLF()
|
||||
{
|
||||
lgInfo($"Richiesto processCustomTaskLF");
|
||||
// effettua sync
|
||||
execImportAll();
|
||||
lastReadPLC = DateTime.Now;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua lettura semafori principale <paramref name="currDispData">Parametri da
|
||||
/// aggiornare x display in form</paramref>
|
||||
/// </summary>
|
||||
public override void readSemafori(ref newDisplayData currDispData)
|
||||
{
|
||||
DateTime adesso = DateTime.Now;
|
||||
if (connectionOk)
|
||||
{
|
||||
// controllo veto checkDB
|
||||
if (adesso > vetoDataRead)
|
||||
{
|
||||
// predispongo prox veto...
|
||||
vetoDataRead = adesso.AddSeconds(vetoReadDbSec);
|
||||
if (adesso > vetoDataSync)
|
||||
{
|
||||
// effettua sync
|
||||
execImportAll();
|
||||
vetoDataSync = adesso.AddSeconds(VetoSyncDbSec);
|
||||
}
|
||||
|
||||
// semaforo
|
||||
currDispData.semIn = Semaforo.SV;
|
||||
// recupero syncState
|
||||
elencoSyncState = dbProxy.SyncStateGetAll();
|
||||
// verifico SignLog e processo
|
||||
bool sentSignLog = processSignLogTable(adesso);
|
||||
// verifico ProdData e processo
|
||||
bool sentProdData = processProdDataTable(adesso);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
B_input = 0;
|
||||
currDispData.semIn = Semaforo.SR;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override connessione
|
||||
/// </summary>
|
||||
public override void tryConnect()
|
||||
{
|
||||
if (!connectionOk)
|
||||
{
|
||||
// controllo che il ping sia stato tentato almeno pingTestSec fa...
|
||||
if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec"))
|
||||
{
|
||||
if (verboseLog || periodicLog)
|
||||
{
|
||||
lgInfo("SqlDb PAMA: ConnKO - tryConnect");
|
||||
}
|
||||
// in primis salvo data ping...
|
||||
lastPING = DateTime.Now;
|
||||
// se passa il ping faccio il resto...
|
||||
if (testPingMachine == IPStatus.Success)
|
||||
{
|
||||
string szStatusConnection = "";
|
||||
try
|
||||
{
|
||||
// ora provo connessione...
|
||||
parentForm.commPlcActive = true;
|
||||
if (dbProxy != null)
|
||||
{
|
||||
elencoSyncState = dbProxy.SyncStateDoImportAll();
|
||||
|
||||
if (elencoSyncState != null && elencoSyncState.Count > 0)
|
||||
{
|
||||
parentForm.commPlcActive = false;
|
||||
connectionOk = true;
|
||||
}
|
||||
}
|
||||
// refresh stato connessione!!!
|
||||
if (connectionOk)
|
||||
{
|
||||
queueInEnabCurr = true;
|
||||
if (adpRunning)
|
||||
{
|
||||
lgInfo("Connessione OK");
|
||||
lastReadPLC = DateTime.Now;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError("Impossibile procedere, connessione mancante...");
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
lgFatal($"Errore nella connessione all'adapter SqlDb PAMA: {szStatusConnection}{Environment.NewLine}{exc}");
|
||||
connectionOk = false;
|
||||
lgInfo($"Eccezione in TryConnect, Adapter SqlDb PAMA NON running, pausa di {utils.CRI("waitRecMSec")} msec prima di ulteriori tentativi di riconnessione");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// loggo no risposta ping ...
|
||||
connectionOk = false;
|
||||
if (verboseLog || periodicLog)
|
||||
{
|
||||
lgInfo($"Attenzione: SqlDb PAMA controllo PING fallito per IP {cIobConf.cncPingAddr}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
needRefresh = true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void tryDisconnect()
|
||||
{
|
||||
// registro solo che è disconnesso
|
||||
connectionOk = false;
|
||||
queueInEnabCurr = false;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
protected bool FullPodlUrl = false;
|
||||
protected int vetoReadDbSec = 3;
|
||||
|
||||
protected int VetoSyncDbSec = 20;
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
protected DbController dbProxy { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// Stato di sync delle tab gestite
|
||||
/// </summary>
|
||||
protected List<SyncStateModel> elencoSyncState { get; set; } = new List<SyncStateModel>();
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Esegue task EXPORT (MES PODL to MACHINE)
|
||||
/// </summary>
|
||||
private void execExportAll()
|
||||
{
|
||||
Stopwatch sw = new Stopwatch();
|
||||
sw.Start();
|
||||
elencoSyncState = dbProxy.SyncStateDoExportAll();
|
||||
sw.Stop();
|
||||
DateTime adesso = DateTime.Now;
|
||||
lastReadPLC = adesso;
|
||||
lgInfo($"DB: esecuzione task dbProxy.SyncStateDoExportAll() in {sw.ElapsedMilliseconds} ms");
|
||||
|
||||
if (elencoSyncState != null)
|
||||
{
|
||||
// registro evento chiamata scrittura in syncState...
|
||||
string tabName = "ExportAll";
|
||||
var currSyncState = elencoSyncState.FirstOrDefault(x => x.TableName == tabName);
|
||||
// verifico x registrare azione
|
||||
if (currSyncState == null)
|
||||
{
|
||||
currSyncState = new SyncStateModel()
|
||||
{
|
||||
LastIdx = 0,
|
||||
LastUpdate = adesso,
|
||||
TableName = tabName,
|
||||
Note = "Init"
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
// calcolo lastIDX valore da datetime
|
||||
int valInt = -1;
|
||||
var nowString = $"{adesso:HHmmss}";
|
||||
int.TryParse(nowString, out valInt);
|
||||
currSyncState.LastIdx = valInt;
|
||||
currSyncState.Note = $"Esecuzione {tabName} | DT code: {currSyncState.LastIdx}";
|
||||
currSyncState.LastUpdate = adesso;
|
||||
}
|
||||
// salvo sync...
|
||||
dbProxy.SyncStateUpsert(currSyncState);
|
||||
foreach (var item in elencoSyncState)
|
||||
{
|
||||
lgTrace($"TAB {item.TableName} | LastIdx {item.LastIdx} | Note {item.Note} | Last Upd {item.LastUpdate}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Esegue task IMPORT (MES PODL to MACHINE)
|
||||
/// </summary>
|
||||
private void execImportAll()
|
||||
{
|
||||
Stopwatch sw = new Stopwatch();
|
||||
sw.Start();
|
||||
elencoSyncState = dbProxy.SyncStateDoImportAll();
|
||||
sw.Stop();
|
||||
lastReadPLC = DateTime.Now;
|
||||
lgInfo($"DB: esecuzione task dbProxy.SyncStateDoImportAll() in {sw.ElapsedMilliseconds} ms");
|
||||
|
||||
if (elencoSyncState != null)
|
||||
{
|
||||
foreach (var item in elencoSyncState)
|
||||
{
|
||||
lgTrace($"TAB {item.TableName} | LastIdx {item.LastIdx} | Note {item.Note} | Last Upd {item.LastUpdate}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Esegue processing + invio dati tab SignLog
|
||||
/// </summary>
|
||||
/// <param name="adesso"></param>
|
||||
/// <returns></returns>
|
||||
private bool processFluxLogTable(DateTime adesso)
|
||||
{
|
||||
bool fatto = false;
|
||||
string tabNameIn = "FluxLog";
|
||||
string tabNameOut = "FluxLogToMes";
|
||||
// cerco info sui FluxLog (ToMes e letti)
|
||||
var currFluxLogRead = elencoSyncState.FirstOrDefault(x => x.TableName == tabNameIn);
|
||||
// se nullo inizializzo
|
||||
if (currFluxLogRead == null)
|
||||
{
|
||||
currFluxLogRead = new SyncStateModel()
|
||||
{
|
||||
LastIdx = 0,
|
||||
LastUpdate = adesso,
|
||||
TableName = tabNameIn,
|
||||
Note = "Init"
|
||||
};
|
||||
}
|
||||
var currFluxLogSent = elencoSyncState.FirstOrDefault(x => x.TableName == tabNameOut);
|
||||
// se nullo inizializzo
|
||||
if (currFluxLogSent == null)
|
||||
{
|
||||
currFluxLogSent = new SyncStateModel()
|
||||
{
|
||||
LastIdx = 0,
|
||||
LastUpdate = adesso,
|
||||
TableName = tabNameOut,
|
||||
Note = "Init"
|
||||
};
|
||||
}
|
||||
// verifica se ci siano dati da trasmettere (sui valori LastIdx)
|
||||
if (currFluxLogRead.LastIdx > currFluxLogSent.LastIdx)
|
||||
{
|
||||
// recupero i dati dal DB...
|
||||
var data2send = dbProxy.MachFluxLogGetNew(currFluxLogSent.LastIdx);
|
||||
// se ho dati preparo invio
|
||||
if (data2send != null && data2send.Count > 0)
|
||||
{
|
||||
string sVal = "";
|
||||
foreach (var fLog2send in data2send)
|
||||
{
|
||||
sVal = $"[DYNDATA] |{fLog2send.DtEvento:yyyy-MM-dd HH:mm:ss}|{fLog2send.CodFlux}|{fLog2send.Valore}";
|
||||
// chiamo accodamento con dataora corretta...
|
||||
accodaFLog(sVal, qEncodeFLog(fLog2send.DtEvento, fLog2send.CodFlux, fLog2send.Valore));
|
||||
}
|
||||
fatto = true;
|
||||
}
|
||||
|
||||
// aggiorno idx inviato...
|
||||
currFluxLogSent.Note = $"Updated from {currFluxLogRead.LastIdx}";
|
||||
currFluxLogSent.LastUpdate = adesso;
|
||||
currFluxLogSent.LastIdx = currFluxLogRead.LastIdx;
|
||||
}
|
||||
|
||||
// alla fine aggiorno i dati inviati!
|
||||
dbProxy.SyncStateUpsert(currFluxLogSent);
|
||||
|
||||
return fatto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Esegue processing + invio dati tab ProdData
|
||||
/// </summary>
|
||||
/// <param name="adesso"></param>
|
||||
/// <returns></returns>
|
||||
private bool processProdDataTable(DateTime adesso)
|
||||
{
|
||||
bool fatto = false;
|
||||
string tabNameIn = "ProdData";
|
||||
string tabNameOut = "ProdDataToMes";
|
||||
// cerco info sui SignLog (ToMes e letti)
|
||||
var currSignLogRead = elencoSyncState.FirstOrDefault(x => x.TableName == tabNameIn);
|
||||
// se nullo inizializzo
|
||||
if (currSignLogRead == null)
|
||||
{
|
||||
currSignLogRead = new SyncStateModel()
|
||||
{
|
||||
LastIdx = 0,
|
||||
LastUpdate = adesso,
|
||||
TableName = tabNameIn,
|
||||
Note = "Init"
|
||||
};
|
||||
}
|
||||
var currSignLogSent = elencoSyncState.FirstOrDefault(x => x.TableName == tabNameOut);
|
||||
// se nullo inizializzo
|
||||
if (currSignLogSent == null)
|
||||
{
|
||||
currSignLogSent = new SyncStateModel()
|
||||
{
|
||||
LastIdx = 0,
|
||||
LastUpdate = adesso,
|
||||
TableName = tabNameOut,
|
||||
Note = "Init"
|
||||
};
|
||||
}
|
||||
// verifica se ci siano dati da trasmettere (sui valori LastIdx)
|
||||
if (currSignLogRead.LastIdx > currSignLogSent.LastIdx)
|
||||
{
|
||||
// recupero i dati dal DB...
|
||||
var data2send = dbProxy.MachProdDataGetNew(currSignLogSent.LastIdx);
|
||||
// se ho dati preparo invio
|
||||
if (data2send != null && data2send.Count > 0)
|
||||
{
|
||||
foreach (var sLog2send in data2send)
|
||||
{
|
||||
if (sLog2send.Action == "StartOrd")
|
||||
{
|
||||
if (FullPodlUrl)
|
||||
{
|
||||
// se il record è apertura PODL chiamo apertura
|
||||
trySetupPODL(sLog2send.IdxPodl);
|
||||
//trySetupPODL(sLog2send.IdxPodl, true, sLog2send.DtEve, DateTime.Now);
|
||||
}
|
||||
else
|
||||
{
|
||||
trySetupPODL(0);
|
||||
}
|
||||
}
|
||||
else if (sLog2send.Action == "EndOrd")
|
||||
{
|
||||
// se il record è chiusura PODL chiamo chiusura... DOPO aver cercato
|
||||
// PODL --> ODL
|
||||
if (FullPodlUrl)
|
||||
{
|
||||
tryClosePODL(sLog2send.IdxPodl);
|
||||
//tryClosePODL(sLog2send.IdxPodl, sLog2send.DtEve, DateTime.Now);
|
||||
}
|
||||
else
|
||||
{
|
||||
tryClosePODL(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// aggiorno idx inviato...
|
||||
currSignLogSent.Note = $"Updated from {currSignLogRead.LastIdx}";
|
||||
currSignLogSent.LastUpdate = adesso;
|
||||
currSignLogSent.LastIdx = currSignLogRead.LastIdx;
|
||||
#if false
|
||||
var lastRec = data2send.LastOrDefault();
|
||||
if (lastRec != null)
|
||||
{
|
||||
// salvo in B_input ultimo valore letto...
|
||||
B_input = lastRec.ValInt;
|
||||
}
|
||||
#endif
|
||||
fatto = true;
|
||||
}
|
||||
|
||||
// alla fine aggiorno i dati inviati!
|
||||
dbProxy.SyncStateUpsert(currSignLogSent);
|
||||
|
||||
return fatto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Esegue processing + invio dati tab SignLog
|
||||
/// </summary>
|
||||
/// <param name="adesso"></param>
|
||||
/// <returns></returns>
|
||||
private bool processSignLogTable(DateTime adesso)
|
||||
{
|
||||
bool fatto = false;
|
||||
string tabNameIn = "SignLog";
|
||||
string tabNameOut = "SignLogToMes";
|
||||
// cerco info sui SignLog (ToMes e letti)
|
||||
var currSignLogRead = elencoSyncState.FirstOrDefault(x => x.TableName == tabNameIn);
|
||||
// se nullo inizializzo
|
||||
if (currSignLogRead == null)
|
||||
{
|
||||
currSignLogRead = new SyncStateModel()
|
||||
{
|
||||
LastIdx = 0,
|
||||
LastUpdate = adesso,
|
||||
TableName = tabNameIn,
|
||||
Note = "Init"
|
||||
};
|
||||
}
|
||||
var currSignLogSent = elencoSyncState.FirstOrDefault(x => x.TableName == tabNameOut);
|
||||
// se nullo inizializzo
|
||||
if (currSignLogSent == null)
|
||||
{
|
||||
currSignLogSent = new SyncStateModel()
|
||||
{
|
||||
LastIdx = 0,
|
||||
LastUpdate = adesso,
|
||||
TableName = tabNameOut,
|
||||
Note = "Init"
|
||||
};
|
||||
}
|
||||
// verifica se ci siano dati da trasmettere (sui valori LastIdx)
|
||||
if (currSignLogRead.LastIdx > currSignLogSent.LastIdx)
|
||||
{
|
||||
// recupero i dati dal DB...
|
||||
List<MachSigLogModel> data2send = dbProxy.MachSigLogGetNew(currSignLogSent.LastIdx);
|
||||
// se ho dati preparo invio
|
||||
if (data2send != null && data2send.Count > 0)
|
||||
{
|
||||
foreach (var sLog2send in data2send)
|
||||
{
|
||||
string currVal = getEncodSigLog(sLog2send.DtEve, sLog2send.ValInt, counterSigIN);
|
||||
// verifico non sia in veto invio iniziale...
|
||||
if (queueInEnabCurr)
|
||||
{
|
||||
// --> accodo (valore già formattato)!
|
||||
QueueIN.Enqueue(currVal);
|
||||
// loggo!
|
||||
lgTrace(string.Format("[QUEUE-IN] {0}", currVal));
|
||||
counterSigIN++;
|
||||
if (counterSigIN > 9999)
|
||||
{
|
||||
counterSigIN = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lgDebug($"[VETO FOR QUEUE-IN] | {currVal} - MESSAGE NOT SENT | {adesso:yyyyMMdd_HHmmss}");
|
||||
checkVetoQueueIn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// aggiorno idx inviato...
|
||||
currSignLogSent.Note = $"Updated from {currSignLogRead.LastIdx}";
|
||||
currSignLogSent.LastUpdate = adesso;
|
||||
currSignLogSent.LastIdx = currSignLogRead.LastIdx;
|
||||
var lastRec = data2send.LastOrDefault();
|
||||
if (lastRec != null)
|
||||
{
|
||||
// salvo in B_input ultimo valore letto...
|
||||
B_input = lastRec.ValInt;
|
||||
}
|
||||
fatto = true;
|
||||
}
|
||||
|
||||
// alla fine aggiorno i dati inviati!
|
||||
dbProxy.SyncStateUpsert(currSignLogSent);
|
||||
|
||||
return fatto;
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="EgwProxy.Icoel" version="3.6.2309.708" targetFramework="net462" />
|
||||
<package id="EgwProxy.SqlDb" version="3.6.2303.1515" targetFramework="net462" />
|
||||
<package id="EntityFramework" version="6.5.1" targetFramework="net462" />
|
||||
<package id="MapoSDK" version="6.14.2411.518" targetFramework="net462" />
|
||||
<package id="Microsoft.Bcl.AsyncInterfaces" version="6.0.0" targetFramework="net462" />
|
||||
<package id="Microsoft.Extensions.Logging.Abstractions" version="6.0.0" targetFramework="net462" />
|
||||
<package id="Microsoft.Bcl.AsyncInterfaces" version="9.0.0" targetFramework="net462" />
|
||||
<package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="9.0.0" targetFramework="net462" />
|
||||
<package id="Microsoft.Extensions.Logging.Abstractions" version="9.0.0" targetFramework="net462" />
|
||||
<package id="Microsoft.VisualStudio.SlowCheetah" version="4.0.50" targetFramework="net462" developmentDependency="true" />
|
||||
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net462" />
|
||||
<package id="NLog" version="5.3.4" targetFramework="net462" />
|
||||
<package id="Pipelines.Sockets.Unofficial" version="2.2.8" targetFramework="net462" />
|
||||
<package id="StackExchange.Redis" version="2.8.24" targetFramework="net462" />
|
||||
<package id="System.Buffers" version="4.5.1" targetFramework="net462" />
|
||||
<package id="System.Buffers" version="4.6.0" targetFramework="net462" />
|
||||
<package id="System.Diagnostics.DiagnosticSource" version="9.0.0" targetFramework="net462" />
|
||||
<package id="System.IO.Compression" version="4.3.0" targetFramework="net462" />
|
||||
<package id="System.IO.Pipelines" version="5.0.1" targetFramework="net462" />
|
||||
<package id="System.Memory" version="4.5.4" targetFramework="net462" />
|
||||
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net462" />
|
||||
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.3" targetFramework="net462" />
|
||||
<package id="System.IO.Pipelines" version="9.0.0" targetFramework="net462" />
|
||||
<package id="System.Memory" version="4.6.0" targetFramework="net462" />
|
||||
<package id="System.Numerics.Vectors" version="4.6.0" targetFramework="net462" />
|
||||
<package id="System.Runtime.CompilerServices.Unsafe" version="6.1.0" targetFramework="net462" />
|
||||
<package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net462" />
|
||||
<package id="System.Threading.Channels" version="5.0.0" targetFramework="net462" />
|
||||
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net462" />
|
||||
<package id="System.Threading.Channels" version="9.0.0" targetFramework="net462" />
|
||||
<package id="System.Threading.Tasks.Extensions" version="4.6.0" targetFramework="net462" />
|
||||
</packages>
|
||||
@@ -73,23 +73,23 @@ REM copia script verso server remoto
|
||||
REM echo Debug remoto: effettuo robocopy sync (verificare remote per cliente)
|
||||
|
||||
REM FINASSI
|
||||
REM ROBOCOPY %2 \\10.150.0.1\Steamware\IOB-WIN-WPS-DEB /MIR
|
||||
REM ROBOCOPY %2 \\10.150.0.1\Steamware\IOB-WIN-SQL-DEB /MIR
|
||||
REM Baglietto
|
||||
REM ROBOCOPY %2 \\192.168.60.15\Steamware\IOB-WIN-WPS-DEB /MIR
|
||||
REM ROBOCOPY %2 \\192.168.60.15\Steamware\IOB-WIN-SQL-DEB /MIR
|
||||
REM GIACOVELLI LOCOROTONDO
|
||||
REM ROBOCOPY %2 \\192.168.1.93\Steamware\IOB-WIN-WPS-DEB /MIR
|
||||
REM ROBOCOPY %2 \\192.168.1.93\Steamware\IOB-WIN-SQL-DEB /MIR
|
||||
REM IMI Remosa
|
||||
REM ROBOCOPY %2 \\192.168.0.12\Steamware\IOB-WIN-WPS-DEB /MIR
|
||||
REM ROBOCOPY %2 \\192.168.0.12\Steamware\IOB-WIN-SQL-DEB /MIR
|
||||
|
||||
REM IOB-WIN-SIM
|
||||
REM ROBOCOPY %2 \\IOB-WIN-SIMULA\Steamware\IOB-WIN-WPS-DEB /MIR
|
||||
REM ROBOCOPY %2 \\IOB-WIN-SIMULA\Steamware\IOB-WIN-SQL-DEB /MIR
|
||||
|
||||
REM IOBVPN4MACHINE
|
||||
REM ROBOCOPY %2 \\10.51.90.5\Steamware\IOB-WIN-WPS-DEB /MIR
|
||||
REM ROBOCOPY %2 \\10.51.90.5\Steamware\IOB-WIN-WPS-DEB /MIR /log:RobocopyTransfer.log
|
||||
REM ROBOCOPY %2 Z:\IOB-WIN-WPS-DEB /MIR
|
||||
REM ROBOCOPY %2 \\10.51.90.10\Steamware\IOB-WIN-WPS-DEB /MIR
|
||||
ROBOCOPY %2 \\10.51.90.9\Steamware\IOB-WIN-WPS-DEB /MIR
|
||||
REM ROBOCOPY %2 \\10.51.90.5\Steamware\IOB-WIN-SQL-DEB /MIR
|
||||
REM ROBOCOPY %2 \\10.51.90.5\Steamware\IOB-WIN-SQL-DEB /MIR /log:RobocopyTransfer.log
|
||||
REM ROBOCOPY %2 Z:\IOB-WIN-SQL-DEB /MIR
|
||||
REM ROBOCOPY %2 \\10.51.90.10\Steamware\IOB-WIN-SQL-DEB /MIR
|
||||
ROBOCOPY %2 \\10.51.90.9\Steamware\IOB-WIN-SQL-DEB /MIR
|
||||
|
||||
goto END
|
||||
|
||||
|
||||
Reference in New Issue
Block a user