diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 1a266bc4..a743d5b1 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -36,7 +36,7 @@ variables:
.version-fix: &version-fix
- |
$env:NEW_REL = $env:VERS_MAIN+"."+(get-date –format yyMM)+"."+(get-date –format ddHH)
- $env:NUM_REL = $env:VERS_MAIN+"."+(get-date –format yyMM)+"."+(get-date –format ddHH)
+ $env:NUM_REL = $env:VERS_MAIN+"."+(get-date –format yyMM)+"."+(get-date –format dHH)
$env:NUM_DEB = $env:VERS_MAIN+"."+(get-date –format yyMM)+"-beta."+(get-date –format dHH)
$env:NEW_COPYRIGHT = "EgalWare @ 2006-" + (get-date -format yyyy)
$contenuto = Get-Content -path 'VersGen\VersGen.cs' -Raw
diff --git a/Documentazione/Icoel/Dettaglio Conferimento.sql b/Documentazione/Icoel/Dettaglio Conferimento.sql
new file mode 100644
index 00000000..41364547
--- /dev/null
+++ b/Documentazione/Icoel/Dettaglio Conferimento.sql
@@ -0,0 +1,24 @@
+SELECT *
+FROM DettagliConferimentoMES
+where FillingId = 31729
+order by PackId
+
+
+/*
+Numero lotto = sigla giorno
+sigla lotto: incrementale giornaliero
+
+in particoalre x il prodotto grosso --> seleziono da + fornitori (es fornitori grossi)
+
+PackId = id univoco scatoletta
+FillingId / FillingRow NON USATI: li posso ignorare, si applicano al caso "travaso" da bins ingresso / bins uscita "tipizzati" --> serve x precalibrare
+scaricoId = operazione di scannerizzazione ( è il barcode letto)
+codice a barre è letto x ogni etichetta di conferimento
+codice e nome fornitore = grower
+codice e descrizione prodotto : sono il GREZZO specifico
+cdice prodotto grezzo è il "ceppo" / famiglia
+sigla e numero lotto: colonna di entrata ciliegie (frontiera)
+idem x data e qta entrata
+
+
+*/
\ No newline at end of file
diff --git a/Documentazione/Icoel/Dettaglio confezioni.sql b/Documentazione/Icoel/Dettaglio confezioni.sql
new file mode 100644
index 00000000..c702736b
--- /dev/null
+++ b/Documentazione/Icoel/Dettaglio confezioni.sql
@@ -0,0 +1,16 @@
+SELECT *
+FROM DettagliConfezioniMES
+
+
+/*
+pack id = singola cassetta/scatola/cartone
+ean = barcode in uscita
+batch id / batch name = dati tracciabilità, legato ai lotti in entrata sul sizer
+lane [1/2]sizerBatchId = lotti del sizer
+pesoDecigram = peso netto confezionato (tolleranza +/-10g...20gr)
+
+tabella scritta dal momento in cui arriva il cartone/cassetta per iniziare riempimento
+
+dati live li vediamo dal sizer
+
+*/
\ No newline at end of file
diff --git a/Documentazione/Icoel/Report fine lavorazione lotto.sql b/Documentazione/Icoel/Report fine lavorazione lotto.sql
new file mode 100644
index 00000000..86b1f865
--- /dev/null
+++ b/Documentazione/Icoel/Report fine lavorazione lotto.sql
@@ -0,0 +1,19 @@
+select top 100 *
+from ProductsTotals
+
+/*
+SizerBatch id = id del batch da WS SOAP
+Index = indice di prodotto FINITO, di cui ho il NOME
+- prodotti da matrice: colonne = gradi, righe = taglie(sizes)
+- grado a colore rosso
+- do il nome prodotto rosse 26- (che sono da 22 a 26 in grado A)
+- colonna qualities = è la "somma dei qualities" ovvero le colonne che passano nelcontrollo prodotto
+- codice in 3 parametri, che sono a,b,c
+ - a = qualità interna (SEMPRE NULL x le ciliegie)
+ - b grado = qualità esterna del frutto, es rosse, nere, con stelo... ricircolo = scarto per cattiva disposizione
+ - c : calibri che mi definiscono la dimensione, tipicamente 22..32
+
+
+ si scrive tutto quando è chiuso il lotto
+ inizialmente 1 solo lotto x entrambe le linee
+*/
\ No newline at end of file
diff --git a/Documentazione/Icoel/Selezione_Frontiera.sql b/Documentazione/Icoel/Selezione_Frontiera.sql
new file mode 100644
index 00000000..f53165b5
--- /dev/null
+++ b/Documentazione/Icoel/Selezione_Frontiera.sql
@@ -0,0 +1,23 @@
+/****** Script for SelectTopNRows command from SSMS ******/
+SELECT TOP (1000) [ID_CHIAVE]
+ ,[CODBARRE]
+ ,[CODICE_FORNITORE]
+ ,[CODICE_LUOGO_PRODUZIONE]
+ ,[NOME_FORNITORE]
+ ,[INDIRIZZO_FORNITORE]
+ ,[COMUNE_FORNITORE]
+ ,[NOME_LUOGO_PRODUZIONE]
+ ,[INDIRIZZO_LUOGO_PRODUZIONE]
+ ,[COMUNE_LUOGO_PRODUZIONE]
+ ,[CODICE_PRODOTTO]
+ ,[DESCRIZIONE_PRODOTTO]
+ ,[CODICE_PRODOTTO_GREZZO]
+ ,[DESCRIZIONE_PRODOTTO_GREZZO]
+ ,[SIGLA_LOTTO]
+ ,[NUMERO_LOTTO]
+ ,[DATA_ENTRATA]
+ ,[QUANTITA_ENTRATA]
+ FROM [frontiera].[dbo].[ENTRATACILIEGIE]
+
+
+ -- utilizzare codice e descrizione prodotto...
\ No newline at end of file
diff --git a/EgwProxy.Icoel.DataLayer/App.config b/EgwProxy.Icoel.DataLayer/App.config
new file mode 100644
index 00000000..bb4630dd
--- /dev/null
+++ b/EgwProxy.Icoel.DataLayer/App.config
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/EgwProxy.Icoel.DataLayer/Controllers/DbController.cs b/EgwProxy.Icoel.DataLayer/Controllers/DbController.cs
new file mode 100644
index 00000000..98ab5ffd
--- /dev/null
+++ b/EgwProxy.Icoel.DataLayer/Controllers/DbController.cs
@@ -0,0 +1,132 @@
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+/*------------------------------------------------
+ * Aggiunto fix come da link seguente:
+ *
+ * https://stackoverflow.com/questions/14033193/entity-framework-provider-type-could-not-be-loaded
+ *
+ * I solved this by adding an using stament on top of my DBContext class, like so:
+ * using SqlProviderServices= System.Data.Entity.SqlServer.SqlProviderServices;
+ *
+ */
+
+namespace EgwProxy.Icoel.DataLayer.Controllers
+{
+ ///
+ /// Controller accesso dati DB vari x ICOEL
+ ///
+ public class DbController : IDisposable
+ {
+#if false
+ private static EntrataDbContext dbEntrataCtx;
+ private static ExportDbContext dbExportCtx;
+ private static TrackerDbContext dbTrackerCtx;
+#endif
+
+ #region Public Constructors
+
+ ///
+ /// Avvio dell'oggetto gestione DB con stringa di connessione specifica
+ ///
+ /// Connessione DB locale di SYNC
+ public DbController(string connSyncState)
+ {
+ dbSyncStateCtx = new SyncStateDbContext(connSyncState);
+ Log.Info("Avviata classe dbSyncStateCtx");
+ }
+
+ #endregion Public Constructors
+
+ #region Public Methods
+
+ ///
+ /// Recupera la tab di CurrData corrente
+ ///
+ ///
+ public List CurrDataGetAll()
+ {
+ List dbResult = new List();
+
+ dbResult = dbSyncStateCtx
+ .DbSetCurrData
+ .ToList();
+
+ return dbResult;
+ }
+
+ ///
+ /// Dispose classe
+ ///
+ public void Dispose()
+ {
+ // Clear database context
+#if false
+ dbEntrataCtx.Dispose();
+ dbExportCtx.Dispose();
+ dbTrackerCtx.Dispose();
+#endif
+ dbSyncStateCtx.Dispose();
+ }
+
+ ///
+ /// Esegue una volta la stored di ImportAll (x recupero dati da DB esterni) e poi
+ /// restitusice in output la tab di SyncState x verificare lo stato
+ ///
+ ///
+ public List SyncStateDoExportAll()
+ {
+ List dbResult = new List();
+
+ dbResult = dbSyncStateCtx
+ .Database
+ .SqlQuery("EXEC stp_ExportAll")
+ .ToList();
+
+ return dbResult;
+ }
+
+ ///
+ /// Esegue una volta la stored di ImportAll (x recupero dati da DB esterni) e poi
+ /// restitusice in output la tab di SyncState x verificare lo stato
+ ///
+ ///
+ public List SyncStateDoImportAll()
+ {
+ List dbResult = new List();
+
+ dbResult = dbSyncStateCtx
+ .Database
+ .SqlQuery("EXEC stp_ImportAll")
+ .ToList();
+
+ return dbResult;
+ }
+
+ ///
+ /// recupera la tab di SyncState corrente
+ ///
+ ///
+ public List SyncStateGetAll()
+ {
+ List dbResult = new List();
+
+ dbResult = dbSyncStateCtx
+ .DbSetSyncState
+ .ToList();
+
+ return dbResult;
+ }
+
+ #endregion Public Methods
+
+ #region Private Fields
+
+ private static SyncStateDbContext dbSyncStateCtx;
+ private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
+
+ #endregion Private Fields
+ }
+}
\ No newline at end of file
diff --git a/EgwProxy.Icoel.DataLayer/DatabaseModels/CurrDataModel.cs b/EgwProxy.Icoel.DataLayer/DatabaseModels/CurrDataModel.cs
new file mode 100644
index 00000000..f6fb6573
--- /dev/null
+++ b/EgwProxy.Icoel.DataLayer/DatabaseModels/CurrDataModel.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Data.Entity.Spatial;
+
+namespace EgwProxy.Icoel.DataLayer.DatabaseModels
+{
+
+ [Table("CurrData")]
+ public partial class CurrDataModel
+ {
+ [Key]
+ [StringLength(50)]
+ public string Topic { get; set; }
+
+ public decimal CurrVal { get; set; } = 0;
+ }
+}
diff --git a/EgwProxy.Icoel.DataLayer/DatabaseModels/DettConferimentoModel.cs b/EgwProxy.Icoel.DataLayer/DatabaseModels/DettConferimentoModel.cs
new file mode 100644
index 00000000..e1bad126
--- /dev/null
+++ b/EgwProxy.Icoel.DataLayer/DatabaseModels/DettConferimentoModel.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Data.Entity.Spatial;
+
+namespace EgwProxy.Icoel.DataLayer.DatabaseModels
+{
+
+ [Table("DettagliConferimentoMES")]
+ public partial class DettConferimentoModel
+ {
+ [Key]
+ [Column(Order = 0)]
+ [DatabaseGenerated(DatabaseGeneratedOption.None)]
+ public long PackId { get; set; }
+
+ [Key]
+ [Column(Order = 1)]
+ [DatabaseGenerated(DatabaseGeneratedOption.None)]
+ public long FillingId { get; set; }
+
+ [Key]
+ [Column(Order = 2)]
+ [DatabaseGenerated(DatabaseGeneratedOption.None)]
+ public int FilligRow { get; set; }
+
+ [Key]
+ [Column(Order = 3)]
+ [DatabaseGenerated(DatabaseGeneratedOption.None)]
+ public long ScaricoId { get; set; }
+
+ public string CODBARRE { get; set; }
+
+ public string CODICE_FORNITORE { get; set; }
+
+ public string NOME_FORNITORE { get; set; }
+
+ public string CODICE_PRODOTTO { get; set; }
+
+ public string DESCRIZIONE_PRODOTTO { get; set; }
+
+ public string CODICE_PRODOTTO_GREZZO { get; set; }
+
+ public string DESCRIZIONE_PRODOTTO_GREZZO { get; set; }
+
+ public string SIGLA_LOTTO { get; set; }
+
+ public string NUMERO_LOTTO { get; set; }
+
+ public string DATA_ENTRATA { get; set; }
+
+ public string QUANTITA_ENTRATA { get; set; }
+ }
+}
diff --git a/EgwProxy.Icoel.DataLayer/DatabaseModels/DettConfezioniModel.cs b/EgwProxy.Icoel.DataLayer/DatabaseModels/DettConfezioniModel.cs
new file mode 100644
index 00000000..e1d3aebb
--- /dev/null
+++ b/EgwProxy.Icoel.DataLayer/DatabaseModels/DettConfezioniModel.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Data.Entity.Spatial;
+
+namespace EgwProxy.Icoel.DataLayer.DatabaseModels
+{
+
+ [Table("DettagliConfezioniMES")]
+ public partial class DettConfezioniModel
+ {
+ [Key]
+ [Column("Pack Id", Order = 0)]
+ [DatabaseGenerated(DatabaseGeneratedOption.None)]
+ public long Pack_Id { get; set; }
+
+ [StringLength(50)]
+ public string EAN { get; set; }
+
+ [Key]
+ [Column("Batch Id", Order = 1)]
+ [DatabaseGenerated(DatabaseGeneratedOption.None)]
+ public long Batch_Id { get; set; }
+
+ public string BatchName { get; set; }
+
+ [Key]
+ [Column(Order = 2)]
+ [DatabaseGenerated(DatabaseGeneratedOption.None)]
+ public int Lane1SizerBatchId { get; set; }
+
+ [Key]
+ [Column(Order = 3)]
+ [DatabaseGenerated(DatabaseGeneratedOption.None)]
+ public int Lane2SizerBatchId { get; set; }
+
+ [Key]
+ [Column("End Time", Order = 4, TypeName = "datetime2")]
+ public DateTime End_Time { get; set; }
+
+ [Key]
+ [Column(Order = 5)]
+ public Guid SizerProductGUID { get; set; }
+
+ [Column("Product Name")]
+ public string Product_Name { get; set; }
+
+ [Key]
+ [Column(Order = 6)]
+ public Guid SizerPackGUID { get; set; }
+
+ [Column("Pack Name")]
+ [StringLength(50)]
+ public string Pack_Name { get; set; }
+
+ [Key]
+ [Column(Order = 7)]
+ public decimal PesoDecigram { get; set; }
+
+ [StringLength(10)]
+ public string FillingMode { get; set; }
+
+ [Key]
+ [Column(Order = 8)]
+ [DatabaseGenerated(DatabaseGeneratedOption.None)]
+ public int Quantity { get; set; }
+ }
+}
diff --git a/EgwProxy.Icoel.DataLayer/DatabaseModels/EntrataModel.cs b/EgwProxy.Icoel.DataLayer/DatabaseModels/EntrataModel.cs
new file mode 100644
index 00000000..d389d6ea
--- /dev/null
+++ b/EgwProxy.Icoel.DataLayer/DatabaseModels/EntrataModel.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Data.Entity.Spatial;
+
+namespace EgwProxy.Icoel.DataLayer.DatabaseModels
+{
+
+ [Table("ENTRATACILIEGIE")]
+ public partial class EntrataModel
+ {
+ [Key]
+ [DatabaseGenerated(DatabaseGeneratedOption.None)]
+ public long ID_CHIAVE { get; set; }
+
+ [StringLength(20)]
+ public string CODBARRE { get; set; }
+
+ public double? CODICE_FORNITORE { get; set; }
+
+ [StringLength(5)]
+ public string CODICE_LUOGO_PRODUZIONE { get; set; }
+
+ [StringLength(50)]
+ public string NOME_FORNITORE { get; set; }
+
+ [StringLength(50)]
+ public string INDIRIZZO_FORNITORE { get; set; }
+
+ [StringLength(50)]
+ public string COMUNE_FORNITORE { get; set; }
+
+ [StringLength(50)]
+ public string NOME_LUOGO_PRODUZIONE { get; set; }
+
+ [StringLength(50)]
+ public string INDIRIZZO_LUOGO_PRODUZIONE { get; set; }
+
+ [StringLength(50)]
+ public string COMUNE_LUOGO_PRODUZIONE { get; set; }
+
+ [StringLength(10)]
+ public string CODICE_PRODOTTO { get; set; }
+
+ [StringLength(50)]
+ public string DESCRIZIONE_PRODOTTO { get; set; }
+
+ [StringLength(10)]
+ public string CODICE_PRODOTTO_GREZZO { get; set; }
+
+ [StringLength(50)]
+ public string DESCRIZIONE_PRODOTTO_GREZZO { get; set; }
+
+ [StringLength(50)]
+ public string SIGLA_LOTTO { get; set; }
+
+ [StringLength(10)]
+ public string NUMERO_LOTTO { get; set; }
+
+ [Column(TypeName = "datetime2")]
+ public DateTime? DATA_ENTRATA { get; set; }
+
+ public double? QUANTITA_ENTRATA { get; set; }
+ }
+}
diff --git a/EgwProxy.Icoel.DataLayer/DatabaseModels/ProductsTotalsModel.cs b/EgwProxy.Icoel.DataLayer/DatabaseModels/ProductsTotalsModel.cs
new file mode 100644
index 00000000..8a37d147
--- /dev/null
+++ b/EgwProxy.Icoel.DataLayer/DatabaseModels/ProductsTotalsModel.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Data.Entity.Spatial;
+
+namespace EgwProxy.Icoel.DataLayer.DatabaseModels
+{
+
+ [Table("ProductsTotals")]
+ public partial class ProductsTotalsModel
+ {
+ [Key]
+ [Column(Order = 0)]
+ [DatabaseGenerated(DatabaseGeneratedOption.None)]
+ public int SizerBatchId { get; set; }
+
+ [Key]
+ [Column(Order = 1)]
+ [DatabaseGenerated(DatabaseGeneratedOption.None)]
+ public int Index { get; set; }
+
+ public string Nome { get; set; }
+
+ public string Qualities { get; set; }
+
+ public string Grado { get; set; }
+
+ public string Calibro { get; set; }
+
+ public int NumeroFrutti { get; set; }
+
+ public string Decigrammi { get; set; }
+ }
+}
diff --git a/EgwProxy.Icoel.DataLayer/DatabaseModels/SyncStateModel.cs b/EgwProxy.Icoel.DataLayer/DatabaseModels/SyncStateModel.cs
new file mode 100644
index 00000000..b37fa326
--- /dev/null
+++ b/EgwProxy.Icoel.DataLayer/DatabaseModels/SyncStateModel.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Data.Entity.Spatial;
+
+namespace EgwProxy.Icoel.DataLayer.DatabaseModels
+{
+
+ [Table("SyncState")]
+ public partial class SyncStateModel
+ {
+ [Key]
+ [StringLength(50)]
+ public string TableName { get; set; }
+
+ public long LastIdx { get; set; }
+
+ public long LastIdxIn { get; set; }
+
+ public long LastIdxOut { get; set; }
+
+ public long NumRec { get; set; }
+
+ public long NumRecIn { get; set; }
+
+ public long NumRecOut { get; set; }
+
+ public DateTime LastUpdate { get; set; } = DateTime.Today;
+ }
+}
diff --git a/EgwProxy.Icoel.DataLayer/DbConfig.cs b/EgwProxy.Icoel.DataLayer/DbConfig.cs
new file mode 100644
index 00000000..b86128ac
--- /dev/null
+++ b/EgwProxy.Icoel.DataLayer/DbConfig.cs
@@ -0,0 +1,71 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace EgwProxy.Icoel.DataLayer
+{
+ public static class DbConfig
+ {
+ #region Public Fields
+
+ public static string DATABASE_NAME = "EgtBwDb";
+
+ public static int DATABASE_PROCESS_TIMEOUT = 5;
+ public static string DATABASE_PWD = "viacremasca";
+
+ // Database config
+ public static string DATABASE_SERV = "127.0.0.1";
+
+ public static string DATABASE_USER = "EgtUser";
+
+ #endregion Public Fields
+
+ #region Public Properties
+
+ ///
+ /// DB Connection string per azioni amministrative
+ ///
+ public static string ADMIN_CONNECTION_STRING { get; set; } = "";
+
+ ///
+ /// DB Connection string
+ ///
+ public static string CONNECTION_STRING { get; set; } = "";
+
+ #endregion Public Properties
+
+ #region Public Methods
+
+ ///
+ /// Metodo di init standard per DB in rete con Master_Key
+ ///
+ /// Indirizzo del server (tipicamente indirizzo di rete)
+ /// Numero chiave
+ /// Codice/pwd associato a chaive
+ /// Numero di chiave master con cui è creato il DB
+ public static void InitDb(string server, string nKey, string sKey, string masterKey = "")
+ {
+ // se nulla metto amster come nKey...
+ masterKey = string.IsNullOrEmpty(masterKey) ? nKey : masterKey;
+ DATABASE_SERV = server;
+ DATABASE_NAME = $"EgtBwDb_{masterKey}";
+ DATABASE_USER = $"user_{nKey}";
+ DATABASE_PWD = $"pwd_{sKey}";
+ CONNECTION_STRING = $"server={DATABASE_SERV};port=3306;database={DATABASE_NAME};uid={DATABASE_USER};pwd={DATABASE_PWD};sslmode=None";
+ // stringa admin con utente root egalware...
+ ADMIN_CONNECTION_STRING = $"server={DATABASE_SERV};port=3306;database=mysql;uid=root;pwd=Egalware_24068!;sslmode=None;CHARSET=utf8";
+ }
+
+#if false
+ public static bool CheckUser(string nKey, string sKey, bool isNetwork)
+ {
+ // esecuzione script di install locale
+ return Controllers.DbController.man.checkCreateUser(DATABASE_USER, DATABASE_PWD, isNetwork);
+ }
+#endif
+
+ #endregion Public Methods
+ }
+}
diff --git a/EgwProxy.Icoel.DataLayer/EgwProxy.Icoel.DataLayer.csproj b/EgwProxy.Icoel.DataLayer/EgwProxy.Icoel.DataLayer.csproj
new file mode 100644
index 00000000..9388cba0
--- /dev/null
+++ b/EgwProxy.Icoel.DataLayer/EgwProxy.Icoel.DataLayer.csproj
@@ -0,0 +1,199 @@
+
+
+
+
+
+ Debug
+ AnyCPU
+ {E36544CB-D699-48D8-9F81-C2758E7C7D19}
+ Library
+ Properties
+ EgwProxy.Icoel.DataLayer
+ EgwProxy.Icoel.DataLayer
+ v4.6.2
+ 512
+ true
+
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\Azure.Core.1.6.0\lib\net461\Azure.Core.dll
+
+
+ ..\packages\Azure.Identity.1.3.0\lib\netstandard2.0\Azure.Identity.dll
+
+
+ ..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll
+
+
+ ..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll
+
+
+ ..\packages\Microsoft.Bcl.AsyncInterfaces.1.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll
+
+
+ ..\packages\Microsoft.Data.SqlClient.4.1.0\lib\net461\Microsoft.Data.SqlClient.dll
+
+
+ ..\packages\Microsoft.Identity.Client.4.22.0\lib\net461\Microsoft.Identity.Client.dll
+
+
+ ..\packages\Microsoft.Identity.Client.Extensions.Msal.2.16.5\lib\net45\Microsoft.Identity.Client.Extensions.Msal.dll
+
+
+ ..\packages\Microsoft.IdentityModel.JsonWebTokens.6.8.0\lib\net461\Microsoft.IdentityModel.JsonWebTokens.dll
+
+
+ ..\packages\Microsoft.IdentityModel.Logging.6.8.0\lib\net461\Microsoft.IdentityModel.Logging.dll
+
+
+ ..\packages\Microsoft.IdentityModel.Protocols.6.8.0\lib\net461\Microsoft.IdentityModel.Protocols.dll
+
+
+ ..\packages\Microsoft.IdentityModel.Protocols.OpenIdConnect.6.8.0\lib\net461\Microsoft.IdentityModel.Protocols.OpenIdConnect.dll
+
+
+ ..\packages\Microsoft.IdentityModel.Tokens.6.8.0\lib\net461\Microsoft.IdentityModel.Tokens.dll
+
+
+ ..\packages\NLog.4.7.9\lib\net45\NLog.dll
+
+
+
+ ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll
+
+
+
+
+ ..\packages\System.Configuration.ConfigurationManager.5.0.0\lib\net461\System.Configuration.ConfigurationManager.dll
+
+
+
+
+ ..\packages\System.Diagnostics.DiagnosticSource.4.6.0\lib\net46\System.Diagnostics.DiagnosticSource.dll
+
+
+
+
+ ..\packages\System.IdentityModel.Tokens.Jwt.6.8.0\lib\net461\System.IdentityModel.Tokens.Jwt.dll
+
+
+ ..\packages\System.IO.4.3.0\lib\net462\System.IO.dll
+ True
+ True
+
+
+
+ ..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll
+
+
+
+
+ ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll
+
+
+ ..\packages\System.Runtime.CompilerServices.Unsafe.4.6.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll
+
+
+ ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll
+ True
+ True
+
+
+
+
+ ..\packages\System.Security.AccessControl.5.0.0\lib\net461\System.Security.AccessControl.dll
+
+
+ ..\packages\System.Security.Cryptography.Algorithms.4.3.1\lib\net461\System.Security.Cryptography.Algorithms.dll
+ True
+ True
+
+
+ ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll
+ True
+ True
+
+
+ ..\packages\System.Security.Cryptography.ProtectedData.4.5.0\lib\net461\System.Security.Cryptography.ProtectedData.dll
+
+
+ ..\packages\System.Security.Permissions.5.0.0\lib\net461\System.Security.Permissions.dll
+
+
+ ..\packages\System.Security.Principal.Windows.5.0.0\lib\net461\System.Security.Principal.Windows.dll
+
+
+
+
+ ..\packages\System.Text.Encodings.Web.4.7.2\lib\net461\System.Text.Encodings.Web.dll
+
+
+ ..\packages\System.Text.Json.4.6.0\lib\net461\System.Text.Json.dll
+
+
+ ..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll
+
+
+
+ ..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Questo progetto fa riferimento a uno o più pacchetti NuGet che non sono presenti in questo computer. Usare lo strumento di ripristino dei pacchetti NuGet per scaricarli. Per altre informazioni, vedere http://go.microsoft.com/fwlink/?LinkID=322105. Il file mancante è {0}.
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/EgwProxy.Icoel.DataLayer/EntrataDbContext.cs b/EgwProxy.Icoel.DataLayer/EntrataDbContext.cs
new file mode 100644
index 00000000..58e851d3
--- /dev/null
+++ b/EgwProxy.Icoel.DataLayer/EntrataDbContext.cs
@@ -0,0 +1,46 @@
+using EgwProxy.Icoel.DataLayer.DatabaseModels;
+using NLog;
+using System;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Data.Entity;
+using System.Linq;
+using SqlProviderServices = System.Data.Entity.SqlServer.SqlProviderServices;
+
+namespace EgwProxy.Icoel.DataLayer
+{
+ ///
+ /// Classe per accesso dati accettazione merce Agrimatica (via ICOEL)
+ ///
+ public partial class EntrataDbContext : DbContext
+ {
+ private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
+
+ ///
+ /// Costruttore implicito
+ ///
+ public EntrataDbContext() : base("name=EntrataFrontiera")
+ {
+ Log.Info("Init 01 EntrataDbContext - DONE");
+ }
+
+ ///
+ /// Costruttore da connectionString
+ ///
+ ///
+ public EntrataDbContext(string connectionString) : base(connectionString)
+ {
+ Log.Info("Init 02 EntrataDbContext - DONE");
+ }
+ ///
+ /// DbSet record entrata merce
+ ///
+ public virtual DbSet DbSetEntrataMerce { get; set; }
+
+ protected override void OnModelCreating(DbModelBuilder modelBuilder)
+ {
+ modelBuilder.Entity()
+ .Property(e => e.DATA_ENTRATA)
+ .HasPrecision(0);
+ }
+ }
+}
diff --git a/EgwProxy.Icoel.DataLayer/ExportDbContext.cs b/EgwProxy.Icoel.DataLayer/ExportDbContext.cs
new file mode 100644
index 00000000..5402b3b7
--- /dev/null
+++ b/EgwProxy.Icoel.DataLayer/ExportDbContext.cs
@@ -0,0 +1,44 @@
+using EgwProxy.Icoel.DataLayer.DatabaseModels;
+using NLog;
+using System;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Data.Entity;
+using System.Linq;
+using SqlProviderServices = System.Data.Entity.SqlServer.SqlProviderServices;
+
+namespace EgwProxy.Icoel.DataLayer
+{
+ ///
+ /// Classe per accesso dati Tacker ICOEL
+ ///
+ public partial class ExportDbContext : DbContext
+ {
+ private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
+
+ ///
+ /// Costruttore implicito
+ ///
+ public ExportDbContext() : base("name=ExportIcoel")
+ {
+ Log.Info("Init 01 ExportDbContext - DONE");
+ }
+
+ ///
+ /// Costruttore da connectionString
+ ///
+ ///
+ public ExportDbContext(string connectionString) : base(connectionString)
+ {
+ Log.Info("Init 02 ExportDbContext - DONE");
+ }
+
+ ///
+ /// DbSet dati prodotti
+ ///
+ public virtual DbSet DbSetProductsTotals { get; set; }
+
+ protected override void OnModelCreating(DbModelBuilder modelBuilder)
+ {
+ }
+ }
+}
diff --git a/EgwProxy.Icoel.DataLayer/MainDbContext.cs b/EgwProxy.Icoel.DataLayer/MainDbContext.cs
new file mode 100644
index 00000000..66793f1c
--- /dev/null
+++ b/EgwProxy.Icoel.DataLayer/MainDbContext.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace EgwProxy.Icoel.DataLayer
+{
+ public class MainDbContext : DbContext
+ {
+ #region Private Fields
+
+ private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
+
+ #endregion Private Fields
+
+ #region Public Constructors
+
+ // Il contesto è stato configurato per utilizzare una stringa di connessione 'BBMModel' dal file di configurazione
+ // dell'applicazione (App.config o Web.config). Per impostazione predefinita, la stringa di connessione è destinata al
+ // database 'BBMModel' nell'istanza di LocalDb.
+ //
+ // Per destinarla a un database o un provider di database differente, modificare la stringa di connessione 'BBMModel'
+ // nel file di configurazione dell'applicazione.
+ [Obsolete("This constructor should never be used directly, and is only needed to generate entityframework stuff. Connection string can be adapted as pleased.")]
+ //public DatabaseContext() : base("BBMModel")
+ public MainDbContext() : base("Data Source=SQLSTEAM;Initial Catalog=SHERPA.BBM;User ID=sa;Password=keyhammer;integrated security=False;MultipleActiveResultSets=True;App=EntityFramework")
+ {
+ }
+
+ public MainDbContext(string connectionString) : base(connectionString)
+ {
+ Log.Info($"init MainDbContext - start");
+
+ try
+ {
+ Database.CreateIfNotExists();
+ Log.Error("CreateIfNotExists - DONE");
+
+ //Database.SetInitializer(new MigrateDatabaseToLatestVersion());
+ Database.SetInitializer(null);
+ Database.Initialize(false);
+ }
+ catch (Exception exc)
+ {
+ Log.Error($"Eccezione in fase init MainDbContext, connectionString: {connectionString}{Environment.NewLine}{exc}");
+ }
+ Log.Error("init MainDbContext - DONE");
+ }
+
+ #endregion Public Constructors
+
+ // Aggiungere DbSet per ogni tipo di entità che si desidera includere nel modello. Per ulteriori informazioni
+ // sulla configurazione e sull'utilizzo di un modello Code, vedere http://go.microsoft.com/fwlink/?LinkId=390109.
+
+ #region Public Properties
+
+ public virtual DbSet DbSetBaskets { get; set; }
+ public virtual DbSet DbSetCompanies { get; set; }
+ public virtual DbSet DbSetCounters { get; set; }
+ public virtual DbSet DbSetCustomers { get; set; }
+ public virtual DbSet DbSetDocs { get; set; }
+
+ public virtual DbSet DbSetFatt2Doc { get; set; }
+
+ public virtual DbSet DbSetItems { get; set; }
+
+ public virtual DbSet DbSetNegotiations { get; set; }
+
+ public virtual DbSet DbSetResources { get; set; }
+
+ #endregion Public Properties
+
+ #region Protected Methods
+
+ protected override void OnModelCreating(DbModelBuilder modelBuilder)
+ {
+ base.OnModelCreating(modelBuilder);
+
+ // Precision attribute for decimals
+ Precision.ConfigureModelBuilder(modelBuilder);
+ }
+
+ #endregion Protected Methods
+ }
+
+}
diff --git a/EgwProxy.Icoel.DataLayer/Properties/AssemblyInfo.cs b/EgwProxy.Icoel.DataLayer/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..374243d1
--- /dev/null
+++ b/EgwProxy.Icoel.DataLayer/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Le informazioni generali relative a un assembly sono controllate dal seguente
+// set di attributi. Modificare i valori di questi attributi per modificare le informazioni
+// associate a un assembly.
+[assembly: AssemblyTitle("EgwProxy.Icoel.DataLayer")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("EgwProxy.Icoel.DataLayer")]
+[assembly: AssemblyCopyright("Copyright © 2022")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Se si imposta ComVisible su false, i tipi in questo assembly non saranno visibili
+// ai componenti COM. Se è necessario accedere a un tipo in questo assembly da
+// COM, impostare su true l'attributo ComVisible per tale tipo.
+[assembly: ComVisible(false)]
+
+// Se il progetto viene esposto a COM, il GUID seguente verrà utilizzato come ID della libreria dei tipi
+[assembly: Guid("e36544cb-d699-48d8-9f81-c2758e7c7d19")]
+
+// Le informazioni sulla versione di un assembly sono costituite dai seguenti quattro valori:
+//
+// Versione principale
+// Versione secondaria
+// Numero di build
+// Revisione
+//
+// È possibile specificare tutti i valori oppure impostare valori predefiniti per i numeri relativi alla revisione e alla build
+// usando l'asterisco '*' come illustrato di seguito:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/EgwProxy.Icoel.DataLayer/SyncStateDbContext.cs b/EgwProxy.Icoel.DataLayer/SyncStateDbContext.cs
new file mode 100644
index 00000000..fd401841
--- /dev/null
+++ b/EgwProxy.Icoel.DataLayer/SyncStateDbContext.cs
@@ -0,0 +1,48 @@
+using EgwProxy.Icoel.DataLayer.DatabaseModels;
+using NLog;
+using System;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Data.Entity;
+using System.Linq;
+
+namespace EgwProxy.Icoel.DataLayer
+{
+ ///
+ /// Classe per accesso dati SyncState del DB
+ ///
+ public partial class SyncStateDbContext : DbContext
+ {
+ private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
+
+ ///
+ /// Costruttore implicito
+ ///
+ public SyncStateDbContext() : base("name=SyncState")
+ {
+ Log.Info("Init 01 SyncStateDbContext - DONE");
+ }
+
+ ///
+ /// Costruttore da connectionString
+ ///
+ ///
+ public SyncStateDbContext(string connectionString) : base(connectionString)
+ {
+ Log.Info("Init 02 SyncStateDbContext - DONE");
+ }
+
+ ///
+ /// DbSet dei dati stato sync DB esterni <--> locale
+ ///
+ public virtual DbSet DbSetSyncState { get; set; }
+
+ ///
+ /// DbSet CurrData
+ ///
+ public virtual DbSet DbSetCurrData { get; set; }
+
+ protected override void OnModelCreating(DbModelBuilder modelBuilder)
+ {
+ }
+ }
+}
diff --git a/EgwProxy.Icoel.DataLayer/TrackerDbContext.cs b/EgwProxy.Icoel.DataLayer/TrackerDbContext.cs
new file mode 100644
index 00000000..c8800f54
--- /dev/null
+++ b/EgwProxy.Icoel.DataLayer/TrackerDbContext.cs
@@ -0,0 +1,49 @@
+using EgwProxy.Icoel.DataLayer.DatabaseModels;
+using NLog;
+using System;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Data.Entity;
+using System.Linq;
+using SqlProviderServices = System.Data.Entity.SqlServer.SqlProviderServices;
+
+namespace EgwProxy.Icoel.DataLayer
+{
+ ///
+ /// Classe per accesso dati Tacker ICOEL
+ ///
+ public partial class TrackerDbContext : DbContext
+ {
+ private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
+
+ ///
+ /// Costruttore implicito
+ ///
+ public TrackerDbContext() : base("name=TrackerLotti")
+ {
+ Log.Info("Init 01 TrackerDbContext - DONE");
+ }
+
+ ///
+ /// Costruttore da connectionString
+ ///
+ ///
+ public TrackerDbContext(string connectionString) : base(connectionString)
+ {
+ Log.Info("Init 02 TrackerDbContext - DONE");
+ }
+
+ ///
+ /// DbSet dai dati conferimento <--> pack di uscita
+ ///
+ public virtual DbSet DbSetConferimento { get; set; }
+
+ ///
+ /// DbSet dai dati conferimento <--> confezioni
+ ///
+ public virtual DbSet DbSetConfezioni { get; set; }
+
+ protected override void OnModelCreating(DbModelBuilder modelBuilder)
+ {
+ }
+ }
+}
diff --git a/EgwProxy.Icoel.DataLayer/packages.config b/EgwProxy.Icoel.DataLayer/packages.config
new file mode 100644
index 00000000..d4e647cc
--- /dev/null
+++ b/EgwProxy.Icoel.DataLayer/packages.config
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/EgwProxy.Icoel.Test/App.config b/EgwProxy.Icoel.Test/App.config
index 2e734fec..3f1e6976 100644
--- a/EgwProxy.Icoel.Test/App.config
+++ b/EgwProxy.Icoel.Test/App.config
@@ -1,24 +1,73 @@
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/EgwProxy.Icoel.Test/EgwProxy.Icoel.Test.csproj b/EgwProxy.Icoel.Test/EgwProxy.Icoel.Test.csproj
index 981c75ef..fcdfd69f 100644
--- a/EgwProxy.Icoel.Test/EgwProxy.Icoel.Test.csproj
+++ b/EgwProxy.Icoel.Test/EgwProxy.Icoel.Test.csproj
@@ -34,6 +34,7 @@
+
@@ -43,9 +44,6 @@
-
-
-
@@ -59,10 +57,17 @@
+
+ {E36544CB-D699-48D8-9F81-C2758E7C7D19}
+ EgwProxy.Icoel.DataLayer
+
{c45f5e6e-866b-4a34-a598-29aab2d178ad}
EgwProxy.Icoel
+
+
+
\ No newline at end of file
diff --git a/EgwProxy.Icoel.Test/Program.cs b/EgwProxy.Icoel.Test/Program.cs
index 9f6bd3b5..0b499450 100644
--- a/EgwProxy.Icoel.Test/Program.cs
+++ b/EgwProxy.Icoel.Test/Program.cs
@@ -1,7 +1,10 @@
-using EgwProxy.Icoel.SizerService;
-using EgwProxy.Icoel.Test.INI;
+using EgwProxy.Icoel.DataLayer.DatabaseModels;
+using EgwProxy.Icoel.SizerService;
+//using EgwProxy.Icoel.Test.INI;
using System;
using System.Collections.Generic;
+using System.Configuration;
+using System.Diagnostics;
namespace EgwProxy.Icoel.Test
{
@@ -9,6 +12,33 @@ namespace EgwProxy.Icoel.Test
{
#region Internal Methods
+ ///
+ /// Mostra tutte le metriche di performance ricevute
+ ///
+ ///
+ internal static void DisplayPerfMeter(Dictionary perfMeter)
+ {
+ // mostra tutti i parametri rilevati...
+ foreach (var item in perfMeter)
+ {
+ Console.WriteLine($"{item.Key} | {item.Value:N2}");
+ }
+ }
+ ///
+ /// Mostra tutte le metriche di performance ricevute
+ ///
+ ///
+ internal static void DisplayCurrBatch(Dictionary currData)
+ {
+ // mostra tutti i parametri rilevati...
+ foreach (var item in currData)
+ {
+ Console.WriteLine($"{item.Key} | {item.Value}");
+ }
+ }
+
+
+
///
/// Generazione di una list di info sui dati variety
///
@@ -175,6 +205,26 @@ namespace EgwProxy.Icoel.Test
}
}
+ ///
+ /// legge conf in formato stringa
+ ///
+ ///
+ ///
+ protected static string ReadSetting(string key)
+ {
+ string answ = "";
+ try
+ {
+ answ = $"{ConfigurationManager.AppSettings[key]}" ?? "";
+ }
+ catch (Exception exc)
+ {
+ Console.Write("Eccezione in ReadSettings");
+ Console.Write(exc.Message);
+ }
+ return answ;
+ }
+
///
/// Programma principale
///
@@ -183,15 +233,67 @@ namespace EgwProxy.Icoel.Test
{
// leggo conf da file ini (ip/port)
Console.WriteLine("Loading Files...");
- Settaggi setup = new Settaggi();
- setup.Load();
string userInput = "";
- // oggetto x connessione
- Connector IcoelSizer = new Connector(setup.IndirizzoIpSizer, setup.SizerTcpPort);
+
+ Console.WriteLine("------------ Test DB ------------");
+ EgwProxy.Icoel.DbProxy dbProxy = new DbProxy(ReadSetting("SyncState"));
+ Console.WriteLine();
+ Console.WriteLine("--- SyncState ---");
+ bool needRedo = true;
+ int numTry = 1;
+ //int numTry = 3;
+ var elencoSyncState = dbProxy.DataController.SyncStateGetAll();
+ while (needRedo && numTry >= 0)
+ {
+ Console.WriteLine(" --- PRE --- ");
+ if (elencoSyncState != null)
+ {
+ foreach (var item in elencoSyncState)
+ {
+ Console.WriteLine($"TAB: {item.TableName} | IdxIN / IdxLocal {item.LastIdxIn} / {item.LastIdx} | NumIn / NumLocal {item.NumRecIn} / {item.NumRec}");
+ // verifico se serva redo..
+ }
+ }
+ Console.WriteLine();
+ Console.WriteLine("Premere un tasto x continuare...");
+ Console.ReadKey();
+ Stopwatch sw = new Stopwatch();
+ sw.Start();
+ elencoSyncState = dbProxy.DataController.SyncStateDoImportAll();
+ sw.Stop();
+ Console.WriteLine($" process time: {sw.ElapsedMilliseconds} ms ");
+ Console.WriteLine(" --- POST --- ");
+ if (elencoSyncState != null)
+ {
+ foreach (var item in elencoSyncState)
+ {
+ Console.WriteLine($"TAB: {item.TableName} | IdxIN / IdxLocal {item.LastIdxIn} / {item.LastIdx} | NumIn / NumLocal {item.NumRecIn} / {item.NumRec}");
+ // verifico se serva redo..
+ }
+ }
+ // processo
+ needRedo = testNeedRedo(elencoSyncState);
+ numTry--;
+ }
+ Console.WriteLine();
+ Console.WriteLine("Premere un tasto x continuare...");
+ Console.ReadKey();
+
+ // oggetto x connessione al sizer icoel
+ Connector IcoelSizer = new Connector(ReadSetting("IndirizzoIpSizer"), ReadSetting("SizerTcpPort"));
+ //Connector IcoelSizer = new Connector(setup.IndirizzoIpSizer, setup.SizerTcpPort);
+
+ Console.WriteLine("------------ Parametri CurrBatch rilevati ------------");
+ var cBatch = IcoelSizer.GetCurrBatchData();
+ if (cBatch != null)
+ {
+ DisplayCurrBatch(cBatch);
+ }
// ora effettua un pò di letture/scritture
try
{
+
Console.WriteLine("------------ TUTTE variety ------------");
var varList = IcoelSizer.GetVarietyList(false);
var varietyData = IcoelSizer.GetLayoutForVarietyList(varList);
@@ -203,6 +305,17 @@ namespace EgwProxy.Icoel.Test
Console.WriteLine("Premere un tasto x continuare...");
userInput = Console.ReadLine();
+
+ Console.WriteLine("------------ Parametri velocità rilevati ------------");
+ var perfMeter = IcoelSizer.GetPerfMeters();
+ if (perfMeter != null)
+ {
+ DisplayPerfMeter(perfMeter);
+ }
+ Console.WriteLine();
+ Console.WriteLine("Premere un tasto x continuare...");
+ userInput = Console.ReadLine();
+
// solo attive
Console.WriteLine("------------ solo attive ------------");
varList = IcoelSizer.GetVarietyList();
@@ -250,6 +363,22 @@ namespace EgwProxy.Icoel.Test
Console.ReadKey();
}
}
+ ///
+ /// Verifico necessità di rifare sync
+ ///
+ ///
+ ///
+ ///
+ private static bool testNeedRedo(List elencoSyncState)
+ {
+ bool answ = false;
+ foreach (var item in elencoSyncState)
+ {
+ answ = answ || (item.NumRecIn > item.NumRec || item.LastIdxIn > item.LastIdx);
+ }
+ return answ;
+ }
+
#endregion Private Methods
}
diff --git a/EgwProxy.Icoel.sln b/EgwProxy.Icoel.sln
index 6961afad..9b3a9da9 100644
--- a/EgwProxy.Icoel.sln
+++ b/EgwProxy.Icoel.sln
@@ -7,6 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EgwProxy.Icoel", "EgwProxy.
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EgwProxy.Icoel.Test", "EgwProxy.Icoel.Test\EgwProxy.Icoel.Test.csproj", "{A655A6AC-5997-46F9-9752-8C621B80516C}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EgwProxy.Icoel.DataLayer", "EgwProxy.Icoel.DataLayer\EgwProxy.Icoel.DataLayer.csproj", "{E36544CB-D699-48D8-9F81-C2758E7C7D19}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -21,6 +23,10 @@ Global
{A655A6AC-5997-46F9-9752-8C621B80516C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A655A6AC-5997-46F9-9752-8C621B80516C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A655A6AC-5997-46F9-9752-8C621B80516C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E36544CB-D699-48D8-9F81-C2758E7C7D19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E36544CB-D699-48D8-9F81-C2758E7C7D19}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E36544CB-D699-48D8-9F81-C2758E7C7D19}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E36544CB-D699-48D8-9F81-C2758E7C7D19}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/EgwProxy.Icoel/App.config b/EgwProxy.Icoel/App.config
index 2e734fec..3abe0f28 100644
--- a/EgwProxy.Icoel/App.config
+++ b/EgwProxy.Icoel/App.config
@@ -1,24 +1,59 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/EgwProxy.Icoel/Appunti.md b/EgwProxy.Icoel/Appunti.md
new file mode 100644
index 00000000..ae375519
--- /dev/null
+++ b/EgwProxy.Icoel/Appunti.md
@@ -0,0 +1,107 @@
+# Appunti impiego connesisoni ICOEL
+
+## Icoel SOAP
+
+Oltre ai metodi legati al batch, ci sono questi metodi x recuperare informazioni specifiche di produttivitÃ
+
+| Metodo | Descrizione |
+| ---------- | ---------- |
+| GetMachineTonnesPH() | valore tonnellate/ora di velocità impianto |
+| GetMachineTotalFPM() | valore frutti per minuto |
+| GetMachineRodsPM() | velocità catena (carrellini / minuto) |
+| GetMachineCupfill() | percentuale riempimento carrellini (100% = 1 frutto x ogni carrellino) |
+
+
+## Icoel DB
+
+Appunti sulla gestione tabelle di frontiera
+
+### Products total
+
+/****** Script for SelectTopNRows command from SSMS ******/
+SELECT TOP (1000) [SizerBatchId]
+ ,[Index]
+ ,[Nome]
+ ,[Qualities]
+ ,[Grado]
+ ,[Calibro]
+ ,[NumeroFrutti]
+ ,[Decigrammi]
+ FROM [IcoelExport].[dbo].[ProductsTotals]
+
+
+### Entrata Ciliegie
+
+SELECT *
+FROM [frontiera].[dbo].[ENTRATACILIEGIE]
+
+
+ -- utilizzare codice e descrizione prodotto...
+
+### Fine lavorazione
+select top 100 *
+from ProductsTotals
+
+/*
+SizerBatch id = id del batch da WS SOAP
+Index = indice di prodotto FINITO, di cui ho il NOME
+- prodotti da matrice: colonne = gradi, righe = taglie(sizes)
+- grado a colore rosso
+- do il nome prodotto rosse 26- (che sono da 22 a 26 in grado A)
+- colonna qualities = è la "somma dei qualities" ovvero le colonne che passano nelcontrollo prodotto
+- codice in 3 parametri, che sono a,b,c
+ - a = qualità interna (SEMPRE NULL x le ciliegie)
+ - b grado = qualità esterna del frutto, es rosse, nere, con stelo... ricircolo = scarto per cattiva disposizione
+ - c : calibri che mi definiscono la dimensione, tipicamente 22..32
+
+
+ si scrive tutto quando è chiuso il lotto
+ inizialmente 1 solo lotto x entrambe le linee
+*/
+
+### Conferimento MES
+
+
+SELECT *
+FROM DettagliConferimentoMES
+where FillingId = 31729
+order by PackId
+
+
+/*
+Numero lotto = sigla giorno
+sigla lotto: incrementale giornaliero
+
+in particoalre x il prodotto grosso --> seleziono da + fornitori (es fornitori grossi)
+
+PackId = id univoco scatoletta
+FillingId / FillingRow NON USATI: li posso ignorare, si applicano al caso "travaso" da bins ingresso / bins uscita "tipizzati" --> serve x precalibrare
+scaricoId = operazione di scannerizzazione ( è il barcode letto)
+codice a barre è letto x ogni etichetta di conferimento
+codice e nome fornitore = grower
+codice e descrizione prodotto : sono il GREZZO specifico
+cdice prodotto grezzo è il "ceppo" / famiglia
+sigla e numero lotto: colonna di entrata ciliegie (frontiera)
+idem x data e qta entrata
+
+
+*/
+
+### Confezioni Mes
+
+
+SELECT *
+FROM DettagliConfezioniMES
+
+
+pack id = singola cassetta/scatoal/cartone
+ean = barcode in uscita
+batch id / batch name = dati tracciabilità , legato ai lotti in entrata sul sizer
+lane [1/2]sizerBatchId = lotti del sizer
+pesoDecigram = peso netto confezionato (tolleranza +/-10g...20gr)
+
+tabella scritta dal momento in cui arriva il cartone/cassetta per iniziare riempimento
+
+dati live li vediamo dal sizer
+
+*/
\ No newline at end of file
diff --git a/EgwProxy.Icoel/Compac/ComClient.cs b/EgwProxy.Icoel/Compac/ComClient.cs
index 646d41af..3f5ee6e6 100644
--- a/EgwProxy.Icoel/Compac/ComClient.cs
+++ b/EgwProxy.Icoel/Compac/ComClient.cs
@@ -1,5 +1,6 @@
using EgwProxy.Icoel.SizerService;
using System;
+using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
@@ -174,6 +175,31 @@ namespace EgwProxy.Icoel.Compac
SSClient.AddBatch(batch);
}
+ ///
+ /// Recupera elenco parametri performance impianto
+ ///
+ /// Dizionario delle variabili di performance dell'impianto in formato Dictionary
+ internal Dictionary GetPerfMeters()
+ {
+ Dictionary answ = new Dictionary();
+ // velocità processo indicata in tonnellate /oOra
+ double velTonnOra = SSClient.GetMachineTonnesPH();
+ // velocità espressa in frutti/minuto
+ double velFruttiMinuto = SSClient.GetMachineTotalFPM();
+ // percentuale riempimento carrellini
+ double percRiemp = SSClient.GetMachineCupfill();
+ // Numero confezioni/ora
+ double numPackOra = SSClient.GetMachinePacksPH();
+
+ // accodo i valori ricavati
+ answ.Add("NumPacksOra", numPackOra);
+ answ.Add("PercRiemp", percRiemp);
+ answ.Add("VelFruttiMinuto", velFruttiMinuto);
+ answ.Add("VelTonnOra", velTonnOra);
+ return answ;
+ }
+
+
#endregion Internal Methods
#region Private Properties
diff --git a/EgwProxy.Icoel/Connector.cs b/EgwProxy.Icoel/Connector.cs
index 30bb284e..a25cd862 100644
--- a/EgwProxy.Icoel/Connector.cs
+++ b/EgwProxy.Icoel/Connector.cs
@@ -38,6 +38,38 @@ namespace EgwProxy.Icoel
Client.CheckGrower(GrowerData.GrowerCode, GrowerData.GrowerName);
}
}
+ ///
+ /// Recupera array varie velocità rilevate
+ ///
+ /// Dictionary delle velocità rilevate sul sizer
+ public Dictionary GetPerfMeters()
+ {
+ Dictionary answ = new Dictionary();
+ using (var Client = new ComClient(ipAddress, tcpPort))
+ {
+ answ = Client.GetPerfMeters();
+ }
+ return answ;
+ }
+
+
+ ///
+ /// Recupera array dei batch sulle 2 linee: ID batch + layout + varietà x ogni linea...
+ ///
+ /// Dictionary dei dati correnti x linea (batch, layout, variety) rilevate sul sizer
+ public Dictionary GetCurrBatchData()
+ {
+ Dictionary answ = new Dictionary();
+ var batchData = GetCurrentBatch();
+ foreach (var item in batchData)
+ {
+ answ.Add($"L{item.Key}_Batch", $"{item.Value.Id} | {item.Value.Name} | {item.Value.StartTime}");
+ answ.Add($"L{item.Key}_Grower", $"{item.Value.GrowerCode}");
+ answ.Add($"L{item.Key}_Layout", $"{item.Value.LayoutId} | {item.Value.LayoutName}");
+ answ.Add($"L{item.Key}_Variety", $"{item.Value.VarietyId} | {item.Value.VarietyName}");
+ }
+ return answ;
+ }
///
/// Invia un lotto in coda produzione sul sizer
diff --git a/EgwProxy.Icoel/DbProxy.cs b/EgwProxy.Icoel/DbProxy.cs
new file mode 100644
index 00000000..a9045a63
--- /dev/null
+++ b/EgwProxy.Icoel/DbProxy.cs
@@ -0,0 +1,42 @@
+using EgwProxy.Icoel.DataLayer.Controllers;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace EgwProxy.Icoel
+{
+ ///
+ /// Proxy connessione DB
+ ///
+ public class DbProxy
+ {
+ ///
+ /// Controller DB esposto
+ ///
+ public DbController DataController { get; set; }
+
+#if false
+ ///
+ /// Inizializzazione proxy
+ ///
+ /// stringa connesisone DB Entrata
+ /// stringa connesisone DB Tracker
+ /// stringa connesisone DB Export
+ /// Connessione DB locale di SYNC
+ public DbProxy(string connEntrata, string connTracker, string connExport, string connSyncState)
+ {
+ DataController = new DbController(connEntrata, connTracker, connExport, connSyncState);
+ }
+#endif
+ ///
+ /// Inizializzazione proxy
+ ///
+ /// Connessione DB locale di SYNC
+ public DbProxy(string connSyncState)
+ {
+ DataController = new DbController(connSyncState);
+ }
+ }
+}
diff --git a/EgwProxy.Icoel/EgwProxy.Icoel.csproj b/EgwProxy.Icoel/EgwProxy.Icoel.csproj
index 77e5750a..c3552784 100644
--- a/EgwProxy.Icoel/EgwProxy.Icoel.csproj
+++ b/EgwProxy.Icoel/EgwProxy.Icoel.csproj
@@ -39,12 +39,17 @@
+
+ ..\packages\NLog.4.7.9\lib\net45\NLog.dll
+
+
+
@@ -54,6 +59,7 @@
+
True
@@ -135,6 +141,7 @@
+
@@ -155,5 +162,11 @@
Reference.cs
+
+
+ {e36544cb-d699-48d8-9f81-c2758e7c7d19}
+ EgwProxy.Icoel.DataLayer
+
+
\ No newline at end of file
diff --git a/EgwProxy.Icoel/packages.config b/EgwProxy.Icoel/packages.config
new file mode 100644
index 00000000..1a6b20de
--- /dev/null
+++ b/EgwProxy.Icoel/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/EgwProxy.MultiCncLib/CNC/CNC.FANUC/CNC.FANUC.vb b/EgwProxy.MultiCncLib/CNC/CNC.FANUC/CNC.FANUC.vb
index c6e92a67..913522f8 100644
--- a/EgwProxy.MultiCncLib/CNC/CNC.FANUC/CNC.FANUC.vb
+++ b/EgwProxy.MultiCncLib/CNC/CNC.FANUC/CNC.FANUC.vb
@@ -1098,7 +1098,8 @@ Namespace CNC
Dim sz_routine As String = "-", sz_temp As String = "", d As Double = 0.0
Try
- If nVar >= &H8000 Then ' if var like 98xxx then use the other read routine .... ( :(( no comment )
+ If nVar >= 10000 Then ' if var like 98xxx then use the other read routine .... ( :(( no comment )
+ 'If nVar >= &H8000 Then ' if var like 98xxx then use the other read routine .... ( :(( no comment )
n_ret_code = Focas1.cnc_rdmacror3(nLibHandle(1), nVar, ONE_DATA_ONLY, MacroInfo3)
diff --git a/IOB-MAN/App.config b/IOB-MAN/App.config
index 929d1f27..376f58be 100644
--- a/IOB-MAN/App.config
+++ b/IOB-MAN/App.config
@@ -43,7 +43,7 @@
-
+
@@ -51,7 +51,7 @@
-
+
@@ -59,7 +59,7 @@
-
+
@@ -67,7 +67,7 @@
-
+
@@ -95,6 +95,10 @@
+
+
+
+
diff --git a/IOB-MAN/App_Readme/README_SteamWare.txt b/IOB-MAN/App_Readme/README_SteamWare.txt
index bf60ed18..954eff8b 100644
--- a/IOB-MAN/App_Readme/README_SteamWare.txt
+++ b/IOB-MAN/App_Readme/README_SteamWare.txt
@@ -1,5 +1,5 @@
---------------------------------------------------------------
-------- SteamWareLib SDK -------
+------- SteamWare SDK -------
---------------------------------------------------------------
Libreria di utility base di SteamWare.
diff --git a/IOB-MAN/Core/Compression/Snappy/lib/linux/libsnappy64.so b/IOB-MAN/Core/Compression/Snappy/lib/linux/libsnappy64.so
new file mode 100644
index 00000000..584bedfc
Binary files /dev/null and b/IOB-MAN/Core/Compression/Snappy/lib/linux/libsnappy64.so differ
diff --git a/IOB-MAN/Core/Compression/Snappy/lib/osx/libsnappy64.dylib b/IOB-MAN/Core/Compression/Snappy/lib/osx/libsnappy64.dylib
new file mode 100644
index 00000000..bbce3c21
Binary files /dev/null and b/IOB-MAN/Core/Compression/Snappy/lib/osx/libsnappy64.dylib differ
diff --git a/IOB-MAN/Core/Compression/Zstandard/lib/linux/libzstd.so b/IOB-MAN/Core/Compression/Zstandard/lib/linux/libzstd.so
new file mode 100644
index 00000000..8309c49b
Binary files /dev/null and b/IOB-MAN/Core/Compression/Zstandard/lib/linux/libzstd.so differ
diff --git a/IOB-MAN/Core/Compression/Zstandard/lib/osx/libzstd.dylib b/IOB-MAN/Core/Compression/Zstandard/lib/osx/libzstd.dylib
new file mode 100644
index 00000000..5400d760
Binary files /dev/null and b/IOB-MAN/Core/Compression/Zstandard/lib/osx/libzstd.dylib differ
diff --git a/IOB-MAN/IOB-MAN.csproj b/IOB-MAN/IOB-MAN.csproj
index c149f9bd..f4c3cc5e 100644
--- a/IOB-MAN/IOB-MAN.csproj
+++ b/IOB-MAN/IOB-MAN.csproj
@@ -38,42 +38,38 @@
IobManIcon.ico
-
- ..\packages\Crc32C.NET.1.0.5.0\lib\net20\Crc32C.NET.dll
-
-
- ..\packages\DnsClient.1.5.0\lib\net45\DnsClient.dll
+
+ ..\packages\DnsClient.1.6.0\lib\net45\DnsClient.dll
..\packages\SharpZipLib.1.3.3\lib\net45\ICSharpCode.SharpZipLib.dll
-
- ..\packages\MapoSDK.6.14.2109.2809\lib\net40\MapoSDK.dll
+
+ ..\packages\MapoSDK.6.14.2204.2616\lib\MapoSDK.dll
-
- ..\packages\Microsoft.Bcl.AsyncInterfaces.5.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll
+
+ ..\packages\Microsoft.Bcl.AsyncInterfaces.6.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll
-
- ..\packages\MongoDB.Bson.2.13.2\lib\net452\MongoDB.Bson.dll
+
+ ..\packages\MongoDB.Bson.2.15.0\lib\netstandard2.0\MongoDB.Bson.dll
-
- ..\packages\MongoDB.Driver.2.13.2\lib\net452\MongoDB.Driver.dll
+
+ ..\packages\MongoDB.Driver.2.15.0\lib\netstandard2.0\MongoDB.Driver.dll
-
- ..\packages\MongoDB.Driver.Core.2.13.2\lib\net452\MongoDB.Driver.Core.dll
+
+ ..\packages\MongoDB.Driver.Core.2.15.0\lib\netstandard2.0\MongoDB.Driver.Core.dll
-
- ..\packages\MongoDB.Libmongocrypt.1.2.3\lib\netstandard2.0\MongoDB.Libmongocrypt.dll
+
+ ..\packages\MongoDB.Libmongocrypt.1.3.0\lib\netstandard2.0\MongoDB.Libmongocrypt.dll
..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll
- ..\packages\NLog.4.7.12\lib\net45\NLog.dll
- True
+ ..\packages\NLog.4.7.15\lib\net45\NLog.dll
- ..\packages\Pipelines.Sockets.Unofficial.2.2.0\lib\net461\Pipelines.Sockets.Unofficial.dll
+ ..\packages\Pipelines.Sockets.Unofficial.2.2.2\lib\net461\Pipelines.Sockets.Unofficial.dll
..\packages\RestSharp.106.15.0\lib\net452\RestSharp.dll
@@ -81,23 +77,20 @@
..\packages\RestSharp.Serializers.NewtonsoftJson.106.15.0\lib\net452\RestSharp.Serializers.NewtonsoftJson.dll
-
- ..\packages\SharpCompress.0.30.0\lib\net461\SharpCompress.dll
-
-
- ..\packages\Snappy.NET.1.1.1.8\lib\net45\Snappy.NET.dll
+
+ ..\packages\SharpCompress.0.31.0\lib\net461\SharpCompress.dll
- ..\packages\StackExchange.Redis.2.2.79\lib\net461\StackExchange.Redis.dll
+ ..\packages\StackExchange.Redis.2.5.61\lib\net461\StackExchange.Redis.dll
-
- ..\packages\SteamWare.IO.5.1.2109.1716\lib\net462\SteamWare.IO.dll
+
+ ..\packages\SteamWare.IO.5.2.2205.1719\lib\net462\SteamWare.IO.dll
-
- ..\packages\SteamWare.Logger.5.1.2109.1716\lib\net462\SteamWare.Logger.dll
+
+ ..\packages\SteamWare.Logger.5.2.2205.1719\lib\net462\SteamWare.Logger.dll
-
- ..\packages\Steamware.Scheduler.5.1.2109.1716\lib\net462\Steamware.Scheduler.dll
+
+ ..\packages\SteamWare.Scheduler.5.2.2205.1719\lib\net462\SteamWare.Scheduler.dll
@@ -105,8 +98,8 @@
-
- ..\packages\System.Diagnostics.PerformanceCounter.5.0.1\lib\net461\System.Diagnostics.PerformanceCounter.dll
+
+ ..\packages\System.Diagnostics.PerformanceCounter.6.0.1\lib\net461\System.Diagnostics.PerformanceCounter.dll
..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll
@@ -114,8 +107,8 @@
True
-
- ..\packages\System.IO.Pipelines.5.0.1\lib\net461\System.IO.Pipelines.dll
+
+ ..\packages\System.IO.Pipelines.6.0.2\lib\net461\System.IO.Pipelines.dll
..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll
@@ -129,8 +122,8 @@
..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll
-
- ..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\net45\System.Runtime.CompilerServices.Unsafe.dll
+
+ ..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll
..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll
@@ -159,11 +152,11 @@
True
-
- ..\packages\System.Text.Encoding.CodePages.5.0.0\lib\net461\System.Text.Encoding.CodePages.dll
+
+ ..\packages\System.Text.Encoding.CodePages.6.0.0\lib\net461\System.Text.Encoding.CodePages.dll
-
- ..\packages\System.Threading.Channels.5.0.0\lib\net461\System.Threading.Channels.dll
+
+ ..\packages\System.Threading.Channels.6.0.0\lib\net461\System.Threading.Channels.dll
..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll
@@ -236,6 +229,10 @@
+
+
+
+
Always
@@ -276,13 +273,13 @@
-
+
- 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}.
+ Questo progetto fa riferimento a uno o più pacchetti NuGet che non sono presenti in questo computer. Usare lo strumento di ripristino dei pacchetti NuGet per scaricarli. Per altre informazioni, vedere http://go.microsoft.com/fwlink/?LinkID=322105. Il file mancante è {0}.
-
-
+
+
-
+
\ No newline at end of file
diff --git a/IOB-MAN/IOBManPanel.cs b/IOB-MAN/IOBManPanel.cs
index 55028d14..6289073a 100644
--- a/IOB-MAN/IOBManPanel.cs
+++ b/IOB-MAN/IOBManPanel.cs
@@ -2,7 +2,7 @@
using Newtonsoft.Json;
using RestSharp;
using RestSharp.Serializers.NewtonsoftJson;
-using Steamware.Scheduler;
+using SteamWare.Scheduler;
using SteamWare.IO;
using SteamWare.Logger;
using System;
diff --git a/IOB-MAN/NLog.config b/IOB-MAN/NLog.config
index 350bebf8..124f6170 100644
--- a/IOB-MAN/NLog.config
+++ b/IOB-MAN/NLog.config
@@ -12,7 +12,7 @@
name="f_base"
fileName="${logDir}/${var:codIOB:default=0000}/${shortdate}.log"
layout="${longdate} [${uppercase:${level}}] ${logger:shortName=true}|${message}"
- archiveFileName="${logDir}/${var:codIOB:default=0000}/${shortdate}.{###}.zip"
+ archiveFileName="${logDir}/${var:codIOB:default=0000}/${shortdate}.{###}.log"
archiveNumbering="Sequence"
archiveAboveSize="10240000"
maxArchiveFiles="60"
@@ -23,7 +23,7 @@
name="f_error"
fileName="${logDir}/${var:codIOB:default=0000}/${shortdate}.log"
layout="${longdate} [${uppercase:${level}}] ${logger:shortName=true}|${message}${newline}${exception:format=tostring}"
- archiveFileName="${logDir}/${var:codIOB:default=0000}/${shortdate}.{###}.zip"
+ archiveFileName="${logDir}/${var:codIOB:default=0000}/${shortdate}.{###}.log"
archiveNumbering="Sequence"
archiveAboveSize="10240000"
maxArchiveFiles="60"
diff --git a/IOB-MAN/RedisMan.cs b/IOB-MAN/RedisMan.cs
index 9fd85ad4..c550295c 100644
--- a/IOB-MAN/RedisMan.cs
+++ b/IOB-MAN/RedisMan.cs
@@ -29,6 +29,16 @@ namespace IOB_MAN
///
public float counterMAC { get; set; } = 0;
+ ///
+ /// Ultimo stato noto dei parametri in memoria letti dalla macchina
+ ///
+ public Dictionary currParams { get; set; } = new Dictionary();
+
+ ///
+ /// Note (libere) da child a controller
+ ///
+ public string freeNotes { get; set; } = "";
+
///
/// Tipo IOB
///
@@ -39,6 +49,11 @@ namespace IOB_MAN
///
public DateTime lastDataIn { get; set; } = DateTime.Now.AddMinutes(-1);
+ ///
+ /// DataOra ultima comunicazione OUT (con MP Server)
+ ///
+ public DateTime lastDataOut { get; set; } = DateTime.Now.AddDays(-1);
+
///
/// DataOra ultima comunicazione OUT (con MP Server)
///
@@ -49,21 +64,6 @@ namespace IOB_MAN
///
public bool online { get; set; } = false;
-#if false
- ///
- /// Indica se sia correntemente in setup
- ///
- public bool inSetup { get; set; } = false;
- ///
- /// Semaforo IN (IOB-PLC)
- ///
- public Semaforo SemIn { get; set; } = Semaforo.ND;
- ///
- /// Semaforo OUT (IOB-MPserver)
- ///
- public Semaforo SemOut { get; set; } = Semaforo.ND;
-#endif
-
///
/// Lungh coda ALLARMI in uscita
///
@@ -84,73 +84,26 @@ namespace IOB_MAN
///
public int queueMsLen { get; set; } = 0;
- #endregion Public Properties
+ ///
+ /// Semaforo IN (IOB-Macchina)
+ ///
+ public string semIn { get; set; } = "ND";
-#if false
- ///
- /// DataOra ultima comunicazione OUT (con MP Server)
- ///
- public DateTime lastDataOut { get; set; } = DateTime.Now.AddDays(-1);
- ///
- /// Ultimo stato noto dei parametri in memoria letti da PLC
- ///
- public Dictionary currParams { get; set; } = null;
-#endif
+ ///
+ /// Semaforo OUT (IOB-MPServer)
+ ///
+ public string semOut { get; set; } = "ND";
+
+ ///
+ /// Parametri configurazione (es IP target, porta, ...)
+ ///
+ public Dictionary setupParams { get; set; } = new Dictionary();
+
+ #endregion Public Properties
}
public class RedisIobCache
{
- #region Private Fields
-
- ///
- /// Connessione lazy a redis...
- ///
- private Lazy lazyConnection = new Lazy(() =>
- {
- string RedisConn = utils.CRS("RedisConn");
- if (string.IsNullOrEmpty(RedisConn))
- {
- RedisConn = "localhost,abortConnect=false,ssl=false";
- }
-
- return ConnectionMultiplexer.Connect(RedisConn);
- });
-
- ///
- /// Connessione lazy a redis...
- ///
- private Lazy lazyConnectionAdmin = new Lazy(() =>
- {
- string RedisConnAdmin = utils.CRS("RedisConnAdmin");
- if (string.IsNullOrEmpty(RedisConnAdmin))
- {
- RedisConnAdmin = "localhost,abortConnect=false,ssl=false,allowAdmin=true";
- }
-
- return ConnectionMultiplexer.Connect(RedisConnAdmin);
- });
-
- #endregion Private Fields
-
- #region Protected Fields
-
- ///
- /// Cod IOB
- ///
- protected string CodIob = "000";
-
- ///
- /// Hash redis x dati IOB
- ///
- protected string redIobKey = "";
-
- ///
- /// Hash redis x dati server
- ///
- protected string redServKey = "";
-
- #endregion Protected Fields
-
#region Public Constructors
///
@@ -225,15 +178,6 @@ namespace IOB_MAN
#endregion Public Enums
- #region Private Properties
-
- ///
- /// Oggetto currentDb locale
- ///
- private IDatabase _currDB { get; set; }
-
- #endregion Private Properties
-
#region Public Properties
///
@@ -385,36 +329,11 @@ namespace IOB_MAN
#endregion Public Properties
- #region Private Methods
-
- ///
- /// Effettua comaprazione x CHIAVE in KVP ASC
- ///
- ///
- ///
- ///
- private int CompareKey(KeyValuePair x, KeyValuePair y)
- {
- return x.Key.CompareTo(y.Key);
- }
-
- ///
- /// Effettua comaprazione x CHIAVE in KVP DESC
- ///
- ///
- ///
- ///
- private int CompareKeyDesc(KeyValuePair x, KeyValuePair y)
- {
- return y.Key.CompareTo(x.Key);
- }
-
- #endregion Private Methods
-
#region Public Methods
///
- /// Nome della variabile HASH da utilizzare (dato CodModulo / Server / DB impiegato da funzionalita' DbConfig) + keyName richiesto...
+ /// Nome della variabile HASH da utilizzare (dato CodModulo / Server / DB impiegato da
+ /// funzionalita' DbConfig) + keyName richiesto...
///
public static string redHash(string keyName)
{
@@ -556,8 +475,7 @@ namespace IOB_MAN
public int redCountKey(string keyPattern)
{
int answ = 0;
- // cerco se ci sia valore in redis...
- // se vuoto = ALL...
+ // cerco se ci sia valore in redis... se vuoto = ALL...
keyPattern = string.IsNullOrEmpty(keyPattern) ? "**" : keyPattern;
try
{
@@ -607,8 +525,7 @@ namespace IOB_MAN
public bool redFlushKey(string keyPattern)
{
bool answ = false;
- // cerco se ci sia valore in redis...
- // se vuoto = ALL...
+ // cerco se ci sia valore in redis... se vuoto = ALL...
keyPattern = string.IsNullOrEmpty(keyPattern) ? "**" : keyPattern;
try
{
@@ -895,7 +812,9 @@ namespace IOB_MAN
///
/// chiave
/// valori
- /// scadenza preimpostata hash (secondi) | defaoult = -1 (non scade)
+ ///
+ /// scadenza preimpostata hash (secondi) | defaoult = -1 (non scade)
+ ///
///
public bool redSaveHash(string hashKey, KeyValuePair[] hashFields, double expireSeconds = -1)
{
@@ -953,7 +872,9 @@ namespace IOB_MAN
///
/// chiave
/// valori
- /// scadenza preimpostata hash (secondi) | defaoult = -1 (non scade)
+ ///
+ /// scadenza preimpostata hash (secondi) | defaoult = -1 (non scade)
+ ///
///
public bool redSaveHashDict(string hashKey, Dictionary hashFields, double expireSeconds = -1)
{
@@ -1109,7 +1030,7 @@ namespace IOB_MAN
}
///
- /// Salva un set KVP (Key Value Pair) in RedisCache
+ /// Salva un set KVP (Key Value Pair) in RedisCache
///
/// Set KVP chiave-valore da salvare
///
@@ -1174,6 +1095,92 @@ namespace IOB_MAN
}
#endregion Public Methods
+
+ #region Protected Fields
+
+ ///
+ /// Cod IOB
+ ///
+ protected string CodIob = "000";
+
+ ///
+ /// Hash redis x dati IOB
+ ///
+ protected string redIobKey = "";
+
+ ///
+ /// Hash redis x dati server
+ ///
+ protected string redServKey = "";
+
+ #endregion Protected Fields
+
+ #region Private Fields
+
+ ///
+ /// Connessione lazy a redis...
+ ///
+ private Lazy lazyConnection = new Lazy(() =>
+ {
+ string RedisConn = utils.CRS("RedisConn");
+ if (string.IsNullOrEmpty(RedisConn))
+ {
+ RedisConn = "localhost,abortConnect=false,ssl=false";
+ }
+
+ return ConnectionMultiplexer.Connect(RedisConn);
+ });
+
+ ///
+ /// Connessione lazy a redis...
+ ///
+ private Lazy lazyConnectionAdmin = new Lazy(() =>
+ {
+ string RedisConnAdmin = utils.CRS("RedisConnAdmin");
+ if (string.IsNullOrEmpty(RedisConnAdmin))
+ {
+ RedisConnAdmin = "localhost,abortConnect=false,ssl=false,allowAdmin=true";
+ }
+
+ return ConnectionMultiplexer.Connect(RedisConnAdmin);
+ });
+
+ #endregion Private Fields
+
+ #region Private Properties
+
+ ///
+ /// Oggetto currentDb locale
+ ///
+ private IDatabase _currDB { get; set; }
+
+ #endregion Private Properties
+
+ #region Private Methods
+
+ ///
+ /// Effettua comaprazione x CHIAVE in KVP ASC
+ ///
+ ///
+ ///
+ ///
+ private int CompareKey(KeyValuePair x, KeyValuePair y)
+ {
+ return x.Key.CompareTo(y.Key);
+ }
+
+ ///
+ /// Effettua comaprazione x CHIAVE in KVP DESC
+ ///
+ ///
+ ///
+ ///
+ private int CompareKeyDesc(KeyValuePair x, KeyValuePair y)
+ {
+ return y.Key.CompareTo(x.Key);
+ }
+
+ #endregion Private Methods
}
///
diff --git a/IOB-MAN/Resources/NLog._demo.config b/IOB-MAN/Resources/NLog._demo.config
index b144b03e..490ed2bc 100644
--- a/IOB-MAN/Resources/NLog._demo.config
+++ b/IOB-MAN/Resources/NLog._demo.config
@@ -48,12 +48,12 @@
name="f"
fileName="${logDir}/${var:codIOB:default=0000}/${shortdate}.log"
layout="${longdate} [${uppercase:${level}}] ${logger:shortName=true}|${message}|${exception:format=tostring}"
- archiveFileName="${logDir}/${var:codIOB:default=0000}/${shortdate}.{###}.zip"
+ archiveFileName="${logDir}/${var:codIOB:default=0000}/${shortdate}.{###}.log"
archiveNumbering="Sequence"
archiveEvery="Day"
archiveOldFileOnStartup="true"
maxArchiveFiles="90"
- enableArchiveFileCompression="true"
+ enableArchiveFileCompression="false"
keepFileOpen="true"
/>-->
diff --git a/IOB-MAN/Resources/NLog.template.config b/IOB-MAN/Resources/NLog.template.config
index 216df569..515b7ac3 100644
--- a/IOB-MAN/Resources/NLog.template.config
+++ b/IOB-MAN/Resources/NLog.template.config
@@ -12,7 +12,7 @@
name="f_base"
fileName="${logDir}/${var:codIOB:default=0000}/${shortdate}.log"
layout="${longdate} [${uppercase:${level}}] ${logger:shortName=true}|${message}"
- archiveFileName="${logDir}/${var:codIOB:default=0000}/${shortdate}.{###}.zip"
+ archiveFileName="${logDir}/${var:codIOB:default=0000}/${shortdate}.{###}.log"
archiveNumbering="Sequence"
archiveAboveSize="10240000"
maxArchiveFiles="60"
@@ -23,7 +23,7 @@
name="f_error"
fileName="${logDir}/${var:codIOB:default=0000}/${shortdate}.log"
layout="${longdate} [${uppercase:${level}}] ${logger:shortName=true}|${message}${newline}${exception:format=tostring}"
- archiveFileName="${logDir}/${var:codIOB:default=0000}/${shortdate}.{###}.zip"
+ archiveFileName="${logDir}/${var:codIOB:default=0000}/${shortdate}.{###}.log"
archiveNumbering="Sequence"
archiveAboveSize="10240000"
maxArchiveFiles="60"
@@ -33,7 +33,7 @@
-
+
diff --git a/IOB-MAN/packages.config b/IOB-MAN/packages.config
index a762bb63..fc4b5a6f 100644
--- a/IOB-MAN/packages.config
+++ b/IOB-MAN/packages.config
@@ -1,43 +1,41 @@

-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
+
-
+
-
-
-
-
-
+
+
+
+
-
+
-
+
-
+
-
-
+
+
\ No newline at end of file
diff --git a/IOB-UT-NEXT/BinaryFormatter.cs b/IOB-UT-NEXT/BinaryFormatter.cs
index a91b074e..0619bf95 100644
--- a/IOB-UT-NEXT/BinaryFormatter.cs
+++ b/IOB-UT-NEXT/BinaryFormatter.cs
@@ -6,20 +6,6 @@ namespace IOB_UT_NEXT
{
public class BinaryUtils : IFormatProvider, ICustomFormatter
{
- #region Private Methods
-
- private string HandleOtherFormats(string format, object arg)
- {
- if (arg is IFormattable)
- return ((IFormattable)arg).ToString(format, CultureInfo.CurrentCulture);
- else if (arg != null)
- return arg.ToString();
- else
- return String.Empty;
- }
-
- #endregion Private Methods
-
#region Public Methods
// Format number in binary (B), octal (O), or hexadecimal (H).
@@ -29,8 +15,7 @@ namespace IOB_UT_NEXT
int baseNumber;
// Handle null or empty format string, string with precision specifier.
string thisFmt = String.Empty;
- // Extract first character of format string (precision specifiers
- // are not supported).
+ // Extract first character of format string (precision specifiers are not supported).
if (!String.IsNullOrEmpty(format))
thisFmt = format.Length > 1 ? format.Substring(0, 1) : format;
@@ -140,5 +125,19 @@ namespace IOB_UT_NEXT
}
#endregion Public Methods
+
+ #region Private Methods
+
+ private string HandleOtherFormats(string format, object arg)
+ {
+ if (arg is IFormattable)
+ return ((IFormattable)arg).ToString(format, CultureInfo.CurrentCulture);
+ else if (arg != null)
+ return arg.ToString();
+ else
+ return String.Empty;
+ }
+
+ #endregion Private Methods
}
}
\ No newline at end of file
diff --git a/IOB-UT-NEXT/Enums.cs b/IOB-UT-NEXT/Enums.cs
index 92572e53..e4b87443 100644
--- a/IOB-UT-NEXT/Enums.cs
+++ b/IOB-UT-NEXT/Enums.cs
@@ -1,6 +1,4 @@
-using Newtonsoft.Json;
-using Newtonsoft.Json.Converters;
-using System;
+using System;
namespace IOB_UT_NEXT
{
@@ -309,6 +307,11 @@ namespace IOB_UT_NEXT
///
MODBUS_TCP_CEDAX,
+ ///
+ /// Adapter ModBus TCP versione Centerfrigo (Giacovelli)
+ ///
+ MODBUS_TCP_CENTERFRIGO,
+
///
/// Adapter ModBus TCP versione HAM (Pizzaferri)
///
@@ -439,6 +442,11 @@ namespace IOB_UT_NEXT
///
SIEMENS_LASCO,
+ ///
+ /// Adapter SIEMENS, interfaccia versione NWSE (Giacovelli, impianto filtrazione NWS)
+ ///
+ SIEMENS_NWSE,
+
///
/// Adapter SIEMENS, interfaccia versione PRESSOIL + CEI (Valvital, Pressa Idraulica)
///
@@ -470,35 +478,6 @@ namespace IOB_UT_NEXT
WPS
}
-#if false
- ///
- /// Enumerazione tipi di semaforo
- ///
- public enum Semaforo
- {
- ///
- /// Stato non definito
- ///
- ND,
- ///
- /// Verde
- ///
- SV,
- ///
- /// Giallo
- ///
- SG,
- ///
- /// Rosso
- ///
- SR,
- ///
- /// Grigio/Spento
- ///
- SS
- }
-#endif
-
///
/// Enumerazione tipi di tipi di URL x invio
///
@@ -514,30 +493,14 @@ namespace IOB_UT_NEXT
///
SignIN,
+ ///
+ /// Salvataggio RawTransf (valori raw da decodificare a valle)
+ ///
+ RawTransf,
+
///
/// Salvataggio UserLog (valori log attività utente)
///
ULog
}
-
- ///
- /// Tipologia dato Raw Transfer (derivare da MapoSdk e togliere qui)
- ///
- /// serializzazione Native
- /// [JsonConverter(typeof(JsonStringEnumConverter))]
- /// serializzazione Newtonsoft json
- /// [JsonConverter(typeof(StringEnumConverter))]
- [JsonConverter(typeof(StringEnumConverter))]
- public enum rawTransfType
- {
- ND = 0,
- ///
- /// Icoel: Batch info
- ///
- IcoelBatch,
- ///
- /// Icoel: Variety + layout info relative
- ///
- IcoelVarInfo
- }
}
\ No newline at end of file
diff --git a/IOB-UT-NEXT/Eurom63.cs b/IOB-UT-NEXT/Eurom63.cs
index d601eabe..0ffba8c9 100644
--- a/IOB-UT-NEXT/Eurom63.cs
+++ b/IOB-UT-NEXT/Eurom63.cs
@@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
namespace IOB_UT_NEXT
{
@@ -39,7 +36,8 @@ namespace IOB_UT_NEXT
TimeSet,
///
- /// Verificato il canale di comunicazione è OK, fatta pulizia con AbortAll, NON ci sono report attivi
+ /// Verificato il canale di comunicazione è OK, fatta pulizia con AbortAll, NON ci sono
+ /// report attivi
///
ChannelOk,
@@ -135,7 +133,8 @@ namespace IOB_UT_NEXT
public int PzPallet { get; set; } = 1;
///
- /// Indica se sia possibile impostare i pezzi pallet dal server, ed in tal caso moltiplica i pezzi letti dalla macchina per il valore pzPallet (vedi sopra)
+ /// Indica se sia possibile impostare i pezzi pallet dal server, ed in tal caso
+ /// moltiplica i pezzi letti dalla macchina per il valore pzPallet (vedi sopra)
///
public bool SetPzPalletFromSrv { get; set; } = false;
@@ -170,7 +169,8 @@ namespace IOB_UT_NEXT
public List FileList { get; set; } = new List();
///
- /// Numero MAX di esecuzioni da mantenere in HIST prima di eliminare i + vecchi (fare folder HIST\SESSnnnn)
+ /// Numero MAX di esecuzioni da mantenere in HIST prima di eliminare i + vecchi (fare
+ /// folder HIST\SESSnnnn)
///
public int Max2Keep { get; set; } = 50;
@@ -190,7 +190,7 @@ namespace IOB_UT_NEXT
public string RespOk { get; set; } = "PROCESSED";
///
- /// Seconds before do a new retry (default = 0 --> no veto)
+ /// Seconds before do a new retry (default = 0 --> no veto)
///
public double RetrySec { get; set; } = 0;
diff --git a/IOB-UT-NEXT/IOB-UT-NEXT.csproj b/IOB-UT-NEXT/IOB-UT-NEXT.csproj
index 8dbe51fe..1fdf8d09 100644
--- a/IOB-UT-NEXT/IOB-UT-NEXT.csproj
+++ b/IOB-UT-NEXT/IOB-UT-NEXT.csproj
@@ -59,8 +59,8 @@
..\packages\SharpZipLib.1.3.1\lib\net45\ICSharpCode.SharpZipLib.dll
-
- ..\packages\MapoSDK.6.14.2204.2616\lib\MapoSDK.dll
+
+ ..\packages\MapoSDK.6.14.2205.2808\lib\MapoSDK.dll
..\packages\Microsoft.Bcl.AsyncInterfaces.6.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll
@@ -123,6 +123,7 @@
+
@@ -134,7 +135,6 @@
-
diff --git a/IOB-UT-NEXT/IniFile.cs b/IOB-UT-NEXT/IniFile.cs
index 1ea22447..a23f2453 100644
--- a/IOB-UT-NEXT/IniFile.cs
+++ b/IOB-UT-NEXT/IniFile.cs
@@ -1,7 +1,7 @@
using System;
+using System.Globalization;
using System.Runtime.InteropServices;
using System.Text;
-using System.Globalization;
namespace IOB_UT_NEXT
{
@@ -16,9 +16,6 @@ namespace IOB_UT_NEXT
#endregion Public Fields
- // INI filename
-
- // import windows dll functions
#region Public Constructors
@@ -33,25 +30,6 @@ namespace IOB_UT_NEXT
#endregion Public Constructors
- #region Private Methods
-
- [DllImport("kernel32")]
- private static extern int GetPrivateProfileInt(string section, string key, int def, string filePath);
-
- [DllImport("kernel32")]
- private static extern int GetPrivateProfileSection(string section, IntPtr retVal, uint size, string filePath);
-
- [DllImport("kernel32")]
- private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
-
- [DllImport("kernel32")]
- private static extern bool WritePrivateProfileSection(string section, string value, string filePath);
-
- [DllImport("kernel32", CharSet = CharSet.Auto, BestFitMapping = false)]
- private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
-
- #endregion Private Methods
-
#region Public Methods
///
@@ -149,7 +127,9 @@ namespace IOB_UT_NEXT
///
///
/// Section name
- /// restituisce delle stringhe keys=values da suddividere appunto come key/val successivamente
+ ///
+ /// restituisce delle stringhe keys=values da suddividere appunto come key/val successivamente
+ ///
public string[] ReadSection(string Section)
{
const int bufferSize = 2048; // max is 32767
@@ -270,5 +250,68 @@ namespace IOB_UT_NEXT
}
#endregion Public Methods
+
+ #region Private Methods
+
+
+ // INI filename
+
+ ///
+ /// GetPrivateProfileInt: import windows dll functions
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ [DllImport("kernel32")]
+ private static extern int GetPrivateProfileInt(string section, string key, int def, string filePath);
+
+ ///
+ /// GetPrivateProfileSection: import windows dll functions
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ [DllImport("kernel32")]
+ private static extern int GetPrivateProfileSection(string section, IntPtr retVal, uint size, string filePath);
+
+ ///
+ /// GetPrivateProfileString: import windows dll functions
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ [DllImport("kernel32")]
+ private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
+
+ ///
+ /// WritePrivateProfileSection: import windows dll functions
+ ///
+ ///
+ ///
+ ///
+ ///
+ [DllImport("kernel32")]
+ private static extern bool WritePrivateProfileSection(string section, string value, string filePath);
+
+ ///
+ /// WritePrivateProfileString: import windows dll functions
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ [DllImport("kernel32", CharSet = CharSet.Auto, BestFitMapping = false)]
+ private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
+
+ #endregion Private Methods
}
}
\ No newline at end of file
diff --git a/IOB-UT-NEXT/IobWinStatus.cs b/IOB-UT-NEXT/IobWinStatus.cs
new file mode 100644
index 00000000..2422f53b
--- /dev/null
+++ b/IOB-UT-NEXT/IobWinStatus.cs
@@ -0,0 +1,177 @@
+using System;
+using System.Collections.Generic;
+
+namespace IOB_UT_NEXT
+{
+ ///
+ /// Rappresentazione dello stato corrente dell'IOB
+ ///
+ public class IobWinStatus
+ {
+ #region Public Properties
+
+ ///
+ /// ID univoco
+ ///
+ public string CodIob { get; set; } = "0";
+
+ ///
+ /// Contatore IOB
+ ///
+ public float counterIOB { get; set; } = 0;
+
+ ///
+ /// Contatore Macchina
+ ///
+ public float counterMAC { get; set; } = 0;
+
+ ///
+ /// Ultimo stato noto dei parametri in memoria letti dalla macchina
+ ///
+ public Dictionary currParams { get; set; } = new Dictionary();
+
+ ///
+ /// Note (libere) da child a controller
+ ///
+ public string freeNotes { get; set; } = "";
+
+ ///
+ /// Tipo IOB
+ ///
+ public string IobType { get; set; } = "";
+
+ ///
+ /// DataOra ultima comunicazione IN (con PLC)
+ ///
+ public DateTime lastDataIn { get; set; } = DateTime.Now.AddMinutes(-1);
+
+ ///
+ /// DataOra ultima comunicazione OUT (con MP Server)
+ ///
+ public DateTime lastDataOut { get; set; } = DateTime.Now.AddDays(-1);
+
+ ///
+ /// DataOra ultima comunicazione OUT (con MP Server)
+ ///
+ public DateTime lastUpdate { get; set; } = DateTime.Now.AddDays(-1);
+
+ ///
+ /// Status del SINGOLO IOB
+ ///
+ public bool online { get; set; } = false;
+
+ ///
+ /// Lungh coda ALLARMI in uscita
+ ///
+ public int queueAlLen { get; set; } = 0;
+
+ ///
+ /// Lunghezza coda EVENTI in uscita
+ ///
+ public int queueEvLen { get; set; } = 0;
+
+ ///
+ /// Lunghezza coda FluxLog in uscita
+ ///
+ public int queueFlLen { get; set; } = 0;
+
+ ///
+ /// Lungh coda MESSAGGI in uscita
+ ///
+ public int queueMsLen { get; set; } = 0;
+
+ ///
+ /// Lungh coda UserLog in uscita
+ ///
+ public int queueRawTransfLen { get; set; } = 0;
+
+ ///
+ /// Lungh coda UserLog in uscita
+ ///
+ public int queueUlLen { get; set; } = 0;
+
+ ///
+ /// Semaforo IN (IOB-Macchina)
+ ///
+ public string semIn { get; set; } = "ND";
+
+ ///
+ /// Semaforo OUT (IOB-MPServer)
+ ///
+ public string semOut { get; set; } = "ND";
+
+ ///
+ /// Parametri configurazione (es IP target, porta, ...)
+ ///
+ public Dictionary setupParams { get; set; } = new Dictionary();
+
+ #endregion Public Properties
+
+ #region Public Methods
+
+ ///
+ /// Override metodo di equality
+ ///
+ ///
+ ///
+ public override bool Equals(object obj)
+ {
+ if (!(obj is IobWinStatus item))
+ return false;
+
+ if (online != item.online)
+ return false;
+ // controllo se sia ALMENO 1 sec...
+ if (lastDataIn != item.lastDataIn)
+ {
+ if (lastDataIn.Subtract(item.lastDataIn).TotalSeconds > 1)
+ return false;
+ }
+ // controllo se sia ALMENO 1 sec...
+ if (lastDataOut != item.lastDataOut)
+ {
+ if (lastDataOut.Subtract(item.lastDataOut).TotalSeconds > 1)
+ return false;
+ }
+ if (semIn != item.semIn)
+ return false;
+ if (semOut != item.semOut)
+ return false;
+ //if (!currParams.Equals(item.currParams))
+ // return false;
+ if (counterIOB != item.counterIOB)
+ return false;
+ if (counterMAC != item.counterMAC)
+ return false;
+ if (queueAlLen != item.queueAlLen)
+ return false;
+ if (queueEvLen != item.queueEvLen)
+ return false;
+ if (queueFlLen != item.queueFlLen)
+ return false;
+ if (queueMsLen != item.queueMsLen)
+ return false;
+ if (queueRawTransfLen != item.queueRawTransfLen)
+ return false;
+ if (queueUlLen != item.queueUlLen)
+ return false;
+ if (freeNotes != item.freeNotes)
+ return false;
+ //if (setupParams != item.setupParams)
+ // return false;
+ if (IobType != item.IobType)
+ return false;
+ if (CodIob != item.CodIob)
+ return false;
+
+ return true;
+ }
+
+ public override int GetHashCode()
+ {
+ return base.GetHashCode();
+ }
+
+ #endregion Public Methods
+ }
+}
\ No newline at end of file
diff --git a/IOB-UT-NEXT/Logging.cs b/IOB-UT-NEXT/Logging.cs
index ab425119..795dfd44 100644
--- a/IOB-UT-NEXT/Logging.cs
+++ b/IOB-UT-NEXT/Logging.cs
@@ -1,15 +1,10 @@
using NLog;
using NLog.Config;
using NLog.Targets;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
namespace IOB_UT_NEXT
{///
- /// Classe helper x LOG basata su NLog
- ///
+ /// Classe helper x LOG basata su NLog
public static class Logging
{
#region Public Constructors
diff --git a/IOB-UT-NEXT/Objects.cs b/IOB-UT-NEXT/Objects.cs
index dbe3a6f0..d10b609e 100644
--- a/IOB-UT-NEXT/Objects.cs
+++ b/IOB-UT-NEXT/Objects.cs
@@ -117,32 +117,6 @@ namespace IOB_UT_NEXT
#endregion Public Methods
}
- ///
- /// Classe di base per trasferimento informazioni di tipo RawTransfer FixMe Todo Fare !!!
- /// elimnare usando SDK MAPO
- ///
- public class BaseRawTransf
- {
- #region Public Properties
-
- ///
- /// Data-Ora riferimento (x ordinamento fifo)
- ///
- public DateTime dataRif { get; set; } = DateTime.Now;
-
- ///
- /// Messaggio in modalità raw/stringa
- ///
- public object mesContent { get; set; } = null;
-
- ///
- /// Tipo di messaggio trasmesso
- ///
- public rawTransfType mesType { get; set; } = rawTransfType.ND;
-
- #endregion Public Properties
- }
-
///
/// Cache a tempo valori INT
///
@@ -231,6 +205,7 @@ namespace IOB_UT_NEXT
#endregion Public Properties
}
+#if false
///
/// Rappresentazione dello stato corrente dell'IOB
///
@@ -305,6 +280,8 @@ namespace IOB_UT_NEXT
#endregion Public Properties
+ #region Public Methods
+
///
/// Override metodo di equality
///
@@ -333,7 +310,7 @@ namespace IOB_UT_NEXT
return false;
if (queueRawTransfLen != item.queueRawTransfLen)
return false;
- if (queueUlLen!= item.queueUlLen)
+ if (queueUlLen != item.queueUlLen)
return false;
return true;
@@ -343,7 +320,10 @@ namespace IOB_UT_NEXT
{
return base.GetHashCode();
}
- }
+
+ #endregion Public Methods
+ }
+#endif
///
/// Elenco oggetti del monitoraggio (DynData, Status) per WPS
diff --git a/IOB-UT-NEXT/RedisMan.cs b/IOB-UT-NEXT/RedisMan.cs
index 5bda2a2e..0de3697f 100644
--- a/IOB-UT-NEXT/RedisMan.cs
+++ b/IOB-UT-NEXT/RedisMan.cs
@@ -2,68 +2,12 @@
using StackExchange.Redis;
using System;
using System.Collections.Generic;
-using System.Linq;
using System.Text;
namespace IOB_UT_NEXT
{
public class RedisIobCache
{
- #region Private Fields
-
- ///
- /// Connessione lazy a redis...
- ///
- private Lazy lazyConnection = new Lazy(() =>
- {
- string RedisConn = baseUtils.CRS("RedisConn");
- if (string.IsNullOrEmpty(RedisConn))
- {
- RedisConn = "localhost,abortConnect=false,ssl=false";
- }
-
- return ConnectionMultiplexer.Connect(RedisConn);
- });
-
- ///
- /// Connessione lazy a redis...
- ///
- private Lazy lazyConnectionAdmin = new Lazy(() =>
- {
- string RedisConnAdmin = baseUtils.CRS("RedisConnAdmin");
- if (string.IsNullOrEmpty(RedisConnAdmin))
- {
- RedisConnAdmin = "localhost,abortConnect=false,ssl=false,allowAdmin=true";
- }
-
- return ConnectionMultiplexer.Connect(RedisConnAdmin);
- });
-
- #endregion Private Fields
-
- #region Protected Fields
-
- ///
- /// Cod IOB
- ///
- protected string currCodIob = "000";
- ///
- /// Tipo IOB
- ///
- protected string currIobType = "ND";
-
- ///
- /// Hash redis x dati IOB
- ///
- protected string redIobKey = "";
-
- ///
- /// Hash redis x dati server
- ///
- protected string redServKey = "";
-
- #endregion Protected Fields
-
#region Public Constructors
///
@@ -97,7 +41,7 @@ namespace IOB_UT_NEXT
IobWinStatus newIobStatus = new IobWinStatus()
{
CodIob = currCodIob,
- IobType= currIobType,
+ IobType = currIobType,
online = false
};
// salvo in area REDIS
@@ -137,15 +81,6 @@ namespace IOB_UT_NEXT
#endregion Public Enums
- #region Private Properties
-
- ///
- /// Oggetto currentDb locale
- ///
- private IDatabase _currDB { get; set; }
-
- #endregion Private Properties
-
#region Public Properties
///
@@ -216,7 +151,7 @@ namespace IOB_UT_NEXT
answ = new IobWinStatus()
{
CodIob = currCodIob,
- IobType=currIobType,
+ IobType = currIobType,
online = false
};
// salvo serializzando...
@@ -233,7 +168,32 @@ namespace IOB_UT_NEXT
set
{
string rawData = JsonConvert.SerializeObject(value);
- setRSV(redIobKey, rawData);
+ saveAndSendMessage(redIobKey, redIobChannel, rawData);
+ //setRSV(redIobKey, rawData);
+ }
+ }
+
+ ///
+ /// MEssage Dispatcher: oggetto comunicazione pub/sub via REDIS channels corrente
+ ///
+ public ISubscriber messageDisp
+ {
+ get
+ {
+ ISubscriber answ;
+ // se già valorizzato uso oggetto private...
+ if (_currSub != null)
+ {
+ answ = _currSub;
+ }
+ else
+ {
+ // init DB (sullo 0)
+ answ = connRedis.GetSubscriber();
+ _currSub = answ;
+ }
+ // restituisco oggetto DB
+ return answ;
}
}
@@ -298,39 +258,6 @@ namespace IOB_UT_NEXT
#endregion Public Properties
- #region Private Methods
-
- ///
- /// Effettua comaprazione x CHIAVE in KVP ASC
- ///
- ///
- ///
- ///
- private int CompareKey(KeyValuePair x, KeyValuePair y)
- {
- return x.Key.CompareTo(y.Key);
- }
-
- ///
- /// Effettua comaprazione x CHIAVE in KVP DESC
- ///
- ///
- ///
- ///
- private int CompareKeyDesc(KeyValuePair x, KeyValuePair y)
- {
- return y.Key.CompareTo(x.Key);
- }
-
- private void initHashKeys()
- {
- // init dati di base...
- redServKey = redHash($"MP");
- redIobKey = redHash($"IOB:{currCodIob}");
- }
-
- #endregion Private Methods
-
#region Public Methods
///
@@ -477,8 +404,7 @@ namespace IOB_UT_NEXT
public int redCountKey(string keyPattern)
{
int answ = 0;
- // cerco se ci sia valore in redis...
- // se vuoto = ALL...
+ // cerco se ci sia valore in redis... se vuoto = ALL...
keyPattern = string.IsNullOrEmpty(keyPattern) ? "**" : keyPattern;
try
{
@@ -528,8 +454,7 @@ namespace IOB_UT_NEXT
public bool redFlushKey(string keyPattern)
{
bool answ = false;
- // cerco se ci sia valore in redis...
- // se vuoto = ALL...
+ // cerco se ci sia valore in redis... se vuoto = ALL...
keyPattern = string.IsNullOrEmpty(keyPattern) ? "**" : keyPattern;
try
{
@@ -702,7 +627,8 @@ namespace IOB_UT_NEXT
}
///
- /// Nome della variabile HASH da utilizzare (dato CodModulo / Server / DB impiegato da funzionalita' DbConfig) + keyName richiesto...
+ /// Nome della variabile HASH da utilizzare (dato CodModulo / Server / DB impiegato da
+ /// funzionalita' DbConfig) + keyName richiesto...
///
public string redHash(string keyName)
{
@@ -834,7 +760,9 @@ namespace IOB_UT_NEXT
///
/// chiave
/// valori
- /// scadenza preimpostata hash (secondi) | defaoult = -1 (non scade)
+ ///
+ /// scadenza preimpostata hash (secondi) | defaoult = -1 (non scade)
+ ///
///
public bool redSaveHash(string hashKey, KeyValuePair[] hashFields, double expireSeconds = -1)
{
@@ -891,7 +819,9 @@ namespace IOB_UT_NEXT
///
/// chiave
/// valori
- /// scadenza preimpostata hash (secondi) | defaoult = -1 (non scade)
+ ///
+ /// scadenza preimpostata hash (secondi) | defaoult = -1 (non scade)
+ ///
///
public bool redSaveHashDict(string hashKey, Dictionary hashFields, double expireSeconds = -1)
{
@@ -992,6 +922,43 @@ namespace IOB_UT_NEXT
return answ;
}
+ ///
+ /// Invia un messaggio tramite notify channel + salva in cache (se scaduto periodo veto)
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool saveAndSendMessage(string memKey, string notifyChannel, string message)
+ {
+ bool fatto = false;
+ // effettuo la scrittura nell'area di memoria indicata SE passato intervallo minimo
+ bool doSave = true;
+ if (LastKeySave.ContainsKey(memKey))
+ {
+ if (DateTime.Now.Subtract(LastKeySave[memKey]).TotalSeconds < 1)
+ {
+ doSave = false;
+ }
+ }
+ else
+ {
+ LastKeySave.Add(memKey, DateTime.Now);
+ }
+ if (doSave)
+ {
+ cache.StringSet(memKey, message);
+ LastKeySave[memKey] = DateTime.Now;
+ Logging.Instance.Trace($"Redis Cache Key: {memKey}");
+ }
+
+ // invio notifica tramite il canale richiesto
+ messageDisp.Publish(notifyChannel, message);
+ fatto = true;
+ // restituisco!
+ return fatto;
+ }
+
///
/// Serializzazione di un oggetto generico
///
@@ -1058,7 +1025,7 @@ namespace IOB_UT_NEXT
}
///
- /// Salva un set KVP (Key Value Pair) in RedisCache
+ /// Salva un set KVP (Key Value Pair) in RedisCache
///
/// Set KVP chiave-valore da salvare
///
@@ -1123,5 +1090,119 @@ namespace IOB_UT_NEXT
}
#endregion Public Methods
+
+ #region Protected Fields
+
+ ///
+ /// Cod IOB
+ ///
+ protected string currCodIob = "000";
+
+ ///
+ /// Tipo IOB
+ ///
+ protected string currIobType = "ND";
+
+ ///
+ /// Hash REDIS x dati IOB
+ ///
+ protected string redIobKey = "";
+
+ ///
+ /// Nome del channel REDIS x dati IOB
+ ///
+ protected string redIobChannel = "IobChannel";
+
+ ///
+ /// Hash REDIS x dati server
+ ///
+ protected string redServKey = "";
+
+ #endregion Protected Fields
+
+ #region Private Fields
+
+ ///
+ /// Dizionario delle ultime scritture in cache redis dei messaggi
+ ///
+ private Dictionary LastKeySave = new Dictionary();
+
+ ///
+ /// Connessione lazy a redis...
+ ///
+ private Lazy lazyConnection = new Lazy(() =>
+ {
+ string RedisConn = baseUtils.CRS("RedisConn");
+ if (string.IsNullOrEmpty(RedisConn))
+ {
+ RedisConn = "localhost,abortConnect=false,ssl=false";
+ }
+
+ return ConnectionMultiplexer.Connect(RedisConn);
+ });
+
+ ///
+ /// Connessione lazy a redis...
+ ///
+ private Lazy lazyConnectionAdmin = new Lazy(() =>
+ {
+ string RedisConnAdmin = baseUtils.CRS("RedisConnAdmin");
+ if (string.IsNullOrEmpty(RedisConnAdmin))
+ {
+ RedisConnAdmin = "localhost,abortConnect=false,ssl=false,allowAdmin=true";
+ }
+
+ return ConnectionMultiplexer.Connect(RedisConnAdmin);
+ });
+
+ #endregion Private Fields
+
+ #region Private Properties
+
+ ///
+ /// Oggetto currentDb REDIS locale
+ ///
+ private IDatabase _currDB { get; set; }
+
+ ///
+ /// Oggetto subscriber x pubblicazione/sottoscrizione canali REDIS
+ ///
+ private ISubscriber _currSub { get; set; }
+
+ #endregion Private Properties
+
+ #region Private Methods
+
+ ///
+ /// Effettua comaprazione x CHIAVE in KVP ASC
+ ///
+ ///
+ ///
+ ///
+ private int CompareKey(KeyValuePair x, KeyValuePair y)
+ {
+ return x.Key.CompareTo(y.Key);
+ }
+
+ ///
+ /// Effettua comaprazione x CHIAVE in KVP DESC
+ ///
+ ///
+ ///
+ ///
+ private int CompareKeyDesc(KeyValuePair x, KeyValuePair y)
+ {
+ return y.Key.CompareTo(x.Key);
+ }
+
+ private void initHashKeys()
+ {
+ // init dati di base...
+ redServKey = redHash($"MP");
+ redIobKey = redHash($"IOB:{currCodIob}");
+ redIobChannel = $"IobChannel_{currCodIob}";
+ }
+
+ #endregion Private Methods
}
}
\ No newline at end of file
diff --git a/IOB-UT-NEXT/TCMan.cs b/IOB-UT-NEXT/TCMan.cs
index 0a8c1937..c513a8c0 100644
--- a/IOB-UT-NEXT/TCMan.cs
+++ b/IOB-UT-NEXT/TCMan.cs
@@ -1,7 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
namespace IOB_UT_NEXT
{
@@ -27,50 +24,6 @@ namespace IOB_UT_NEXT
#endregion Public Constructors
- #region Protected Properties
-
- ///
- /// Fattore lambda (innovazione) per calcolo EWMA valore TCiclo corrente
- ///
- protected double _lambda { get; set; } = 0.4;
-
- ///
- /// Ultimo TCiclo osservato in SECONDI
- ///
- protected double _lastTC { get; set; } = 0;
-
- ///
- /// ULTIMO Contapezzi IOB VALIDO
- ///
- protected int _lastValidPzCountIOB { get; set; } = 0;
-
- ///
- /// ULTIMO Contapezzi PLC VALIDO
- ///
- protected int _lastValidPzCountPLC { get; set; } = 0;
-
- ///
- /// Fattore massimo ammesso di delay x il TCiclo
- ///
- protected double _maxDelayFactor { get; set; } = 1.2;
-
- ///
- /// Incremento amssimo pezzi per cui fare calcolo del tempociclo attuale
- ///
- protected double _maxIncrPz { get; set; } = 2;
-
- ///
- /// Contapezzi IOB
- ///
- protected int _pzCountIOB { get; set; } = 0;
-
- ///
- /// Contapezzi PLC
- ///
- protected int _pzCountPLC { get; set; } = 0;
-
- #endregion Protected Properties
-
#region Public Properties
///
@@ -171,5 +124,49 @@ namespace IOB_UT_NEXT
}
#endregion Public Properties
+
+ #region Protected Properties
+
+ ///
+ /// Fattore lambda (innovazione) per calcolo EWMA valore TCiclo corrente
+ ///
+ protected double _lambda { get; set; } = 0.4;
+
+ ///
+ /// Ultimo TCiclo osservato in SECONDI
+ ///
+ protected double _lastTC { get; set; } = 0;
+
+ ///
+ /// ULTIMO Contapezzi IOB VALIDO
+ ///
+ protected int _lastValidPzCountIOB { get; set; } = 0;
+
+ ///
+ /// ULTIMO Contapezzi PLC VALIDO
+ ///
+ protected int _lastValidPzCountPLC { get; set; } = 0;
+
+ ///
+ /// Fattore massimo ammesso di delay x il TCiclo
+ ///
+ protected double _maxDelayFactor { get; set; } = 1.2;
+
+ ///
+ /// Incremento amssimo pezzi per cui fare calcolo del tempociclo attuale
+ ///
+ protected double _maxIncrPz { get; set; } = 2;
+
+ ///
+ /// Contapezzi IOB
+ ///
+ protected int _pzCountIOB { get; set; } = 0;
+
+ ///
+ /// Contapezzi PLC
+ ///
+ protected int _pzCountPLC { get; set; } = 0;
+
+ #endregion Protected Properties
}
}
\ No newline at end of file
diff --git a/IOB-UT-NEXT/ToMapo.cs b/IOB-UT-NEXT/ToMapo.cs
index f91154da..56a1011b 100644
--- a/IOB-UT-NEXT/ToMapo.cs
+++ b/IOB-UT-NEXT/ToMapo.cs
@@ -1,11 +1,7 @@
using MapoSDK;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
-using System;
-using System.Collections;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
namespace IOB_UT_NEXT
{
@@ -14,7 +10,23 @@ namespace IOB_UT_NEXT
///
public class BaseAlarmConf
{
- #region Public Fields
+ #region Public Properties
+
+ ///
+ /// Elenco dei contatori blink x gestione caso fronte salita/discesa segnale che blinka
+ ///
+ public int[] alarmsBlinkCounter { get; set; }
+
+ ///
+ /// BitMask 16bit (1 = valido, 0 = filtro) degli allarmi silenziati/disabilitati (se
+ /// iniziano per ##) come valore da sottrarre x check
+ ///
+ public uint[] alarmsMask { get; set; }
+
+ ///
+ /// Array dei valori allarme correnti
+ ///
+ public uint[] alarmsState { get; set; }
///
/// valore di partenza x un segnale di blink in caso di fine variazione (fronte discesa)
@@ -26,25 +38,6 @@ namespace IOB_UT_NEXT
///
public int blinkUpVal { get; set; } = 3;
- #endregion Public Fields
-
- #region Public Properties
-
- ///
- /// Elenco dei contatori blink x gestione caso fronte salita/discesa segnale che blinka
- ///
- public int[] alarmsBlinkCounter { get; set; }
-
- ///
- /// BitMask 16bit (1 = valido, 0 = filtro) degli allarmi silenziati/disabilitati (se iniziano per ##) come valore da sottrarre x check
- ///
- public uint[] alarmsMask { get; set; }
-
- ///
- /// Array dei valori allarme correnti
- ///
- public uint[] alarmsState { get; set; }
-
///
/// Descrizione area allarmi
///
@@ -177,7 +170,8 @@ namespace IOB_UT_NEXT
alarmsState = new uint[size / 2];
alarmsMask = new uint[size / 2];
- // una volta inizializzata la classe di base sistemo vettori allarmi disabilitati ed il contatore blink dei fronti di discesa
+ // una volta inizializzata la classe di base sistemo vettori allarmi disabilitati ed il
+ // contatore blink dei fronti di discesa
alarmsBlinkCounter = new int[messages.Count];
int idx = 0;
int bank = 0;
@@ -217,7 +211,8 @@ namespace IOB_UT_NEXT
}
///
- /// Classe gestione configurazione parametri di base x configuraizone estesa (es MTConnect, OPC-UA, ...)
+ /// Classe gestione configurazione parametri di base x configuraizone estesa (es MTConnect,
+ /// OPC-UA, ...)
///
public class BaseParamConf
{
@@ -229,14 +224,13 @@ namespace IOB_UT_NEXT
public List condWork { get; set; } = new List();
///
- /// Indica se l'emergenza armata va riportata verso Mapo come bit a TRUE
- /// True --> armata = 1 / triggered = 0
- /// False --> triggered = 1 / armata = 0
+ /// Indica se l'emergenza armata va riportata verso Mapo come bit a TRUE True --> armata
+ /// = 1 / triggered = 0 False --> triggered = 1 / armata = 0
///
public bool emergencyArmedTrue { get; set; } = true;
///
- /// Elenco items FILTRATI da invio come dynData --> FluxLog (events o samples)
+ /// Elenco items FILTRATI da invio come dynData --> FluxLog (events o samples)
///
public List fluxLogVeto { get; set; } = new List();
@@ -309,7 +303,8 @@ namespace IOB_UT_NEXT
}
///
- /// Classe per rappresentare una lista di oggetti chiave/valore target x controlo condizioni multiple + indicazione modalità di controllo (AND/OR/...)
+ /// Classe per rappresentare una lista di oggetti chiave/valore target x controlo condizioni
+ /// multiple + indicazione modalità di controllo (AND/OR/...)
///
public class diCheckCondSetup
{
@@ -326,13 +321,75 @@ namespace IOB_UT_NEXT
public boolCheckMode checkMode { get; set; } = boolCheckMode.AND;
///
- /// indica se il check vada NEGATO (esempio se cerco la condizione opposta, esempio num allarmi 0 --> se true NEGO la condizione HO ALLARMI)
+ /// indica se il check vada NEGATO (esempio se cerco la condizione opposta, esempio num
+ /// allarmi 0 --> se true NEGO la condizione HO ALLARMI)
///
public bool negateValue { get; set; } = false;
#endregion Public Properties
}
+ ///
+ /// Classe x definizione delle azioni in fase di setup macchina
+ ///
+ public class MachineSetupAction
+ {
+ #region Public Properties
+
+ ///
+ /// Indica se vada disabilitato il contapezzi quando la condizione NotEqual sia soddisfatta
+ ///
+ public bool DisablePzCountNotEqual { get; set; } = false;
+
+ ///
+ /// Parametro target dell'azione
+ ///
+ public string TargetParam { get; set; } = "";
+
+ ///
+ /// parametro da impostare SE il check da esito EQUAL
+ ///
+ public int TargetValEqual { get; set; } = 0;
+
+ ///
+ /// parametro da impostare SE il check da esito NOT EQUAL
+ ///
+ public int TargetValNotEqual { get; set; } = 1;
+
+ #endregion Public Properties
+ }
+
+ ///
+ /// Definizione parametri di setup incrociato...
+ ///
+ public class MachineSetupConf
+ {
+ #region Public Properties
+
+ ///
+ /// Dizionario dei parametri di corrispondenza tra variabili MES e variabili Macchina MES =
+ /// scritte dal MES Macchina = scritte da macchina
+ ///
+ public Dictionary checkParList { get; set; } = new Dictionary();
+
+ ///
+ /// Abilitazione gestione Setup Avanzato (= scrittura)
+ ///
+ public bool EnableAdvSetup { get; set; } = false;
+
+ ///
+ /// Modalità gestione setup
+ ///
+ public MachineSetupMode SetupMode { get; set; } = MachineSetupMode.ND;
+
+ /// Dizionario dei parametri da scrivere quando si rilevano differenze tra i
+ /// parametri MES/Macchina string (key) --> memoria da scrivere tuple --> valori da scrivere quando uguali o diversi
+ public List writeParAction { get; set; } = new List();
+
+ #endregion Public Properties
+ }
+
///
/// COnfigurazione blocchi x accesso memoria ottimizzato
///
@@ -360,84 +417,6 @@ namespace IOB_UT_NEXT
#endregion Public Properties
}
- ///
- /// Definizione parametri watchdog
- ///
- public class WatchDogConf
- {
- ///
- /// Abilitazione WatchDog
- ///
- public bool IsEnabled { get; set; } = false;
- ///
- /// Conf memoria x lettura WatchDog (ToMes), se !="" è gestito
- ///
- public string MemConfRead { get; set; } = "";
- ///
- /// Conf memoria x scrittura WatchDog (FromMes), se !="" è gestito
- ///
- public string MemConfWrite { get; set; } = "";
- ///
- /// Valore max contatore prima di resettare
- ///
- public int MaxVal { get; set; } = 9999;
- }
-
- ///
- /// Definizione parametri di setup incrociato...
- ///
- public class MachineSetupConf
- {
- ///
- /// Modalità gestione setup
- ///
- public MachineSetupMode SetupMode { get; set; } = MachineSetupMode.ND;
-
- ///
- /// Abilitazione gestione Setup Avanzato (= scrittura)
- ///
- public bool EnableAdvSetup { get; set; } = false;
-
- ///
- /// Dizionario dei parametri di corrispondenza tra variabili MES e variabili Macchina
- /// MES = scritte dal MES
- /// Macchina = scritte da macchina
- ///
- public Dictionary checkParList { get; set; } = new Dictionary();
-
- ///
- /// Dizionario dei parametri da scrivere quando si rilevano differenze tra i parametri MES/Macchina
- /// string (key) --> memoria da scrivere
- /// tuple --> valori da scrivere quando uguali o diversi
- ///
- public List writeParAction { get; set; } = new List();
- }
-
- ///
- /// Classe x definizione delle azioni in fase di setup macchina
- ///
- public class MachineSetupAction
- {
- ///
- /// Parametro target dell'azione
- ///
- public string TargetParam { get; set; } = "";
-
- ///
- /// parametro da impostare SE il check da esito EQUAL
- ///
- public int TargetValEqual { get; set; } = 0;
- ///
- /// parametro da impostare SE il check da esito NOT EQUAL
- ///
- public int TargetValNotEqual { get; set; } = 1;
-
- ///
- /// Indica se vada disabilitato il contapezzi quando la condizione NotEqual sia soddisfatta
- ///
- public bool DisablePzCountNotEqual { get; set; } = false;
- }
-
///
/// Classe gestione configurazione parametri specifici OPC-UA da BaseParamConf
///
@@ -470,12 +449,6 @@ namespace IOB_UT_NEXT
///
public diCheckCondSetup condError { get; set; } = new diCheckCondSetup();
-
- ///
- /// Struttura dati x check condizione Errore
- ///
- public diCheckCondSetup condWorkOpc { get; set; } = new diCheckCondSetup();
-
///
/// Struttura dati x check condizione Emergenza
///
@@ -496,6 +469,11 @@ namespace IOB_UT_NEXT
///
public diCheckCondSetup condReady { get; set; } = new diCheckCondSetup();
+ ///
+ /// Struttura dati x check condizione Setup
+ ///
+ public diCheckCondSetup condSetup { get; set; } = new diCheckCondSetup();
+
///
/// Struttura dati x check condizione WarmUp - CoolDown
///
@@ -505,16 +483,19 @@ namespace IOB_UT_NEXT
/// Struttura dati x check condizione Warning
///
public diCheckCondSetup condWarning { get; set; } = new diCheckCondSetup();
+
///
- /// Struttura dati x check condizione Setup
+ /// Struttura dati x check condizione Errore
///
- public diCheckCondSetup condSetup { get; set; } = new diCheckCondSetup();
+ public diCheckCondSetup condWorkOpc { get; set; } = new diCheckCondSetup();
///
/// Elenco dei NodeId da ignorare intesi come interi rami (se vuoto NON filtro)
///
public List filterItemsNodeId { get; set; } = new List();
+ public UserIdent Identity { get; set; } = new UserIdent();
+
///
/// Aree di memoria lettura
///
@@ -525,34 +506,66 @@ namespace IOB_UT_NEXT
///
public Dictionary mMapWrite { get; set; } = new Dictionary();
- ///
- /// Elenco dei SOLI item sottoscritti (se vuoto TUTTI)
- ///
- public List subscribedItems { get; set; } = new List();
-
///
/// Elenco item RAW sottoscritti e relative configurazioni di decodifica da byte[]
///
public Dictionary rawSubscribedItemsConf { get; set; } = new Dictionary();
- ///
- /// Conf Gestione WatchDog
- ///
- public WatchDogConf WatchDog { get; set; } = new WatchDogConf();
-
///
/// Conf gestione setup macchina
///
public MachineSetupConf SetupConf { get; set; } = new MachineSetupConf();
- public UserIdent Identity { get; set; } = new UserIdent();
+ ///
+ /// Elenco dei SOLI item sottoscritti (se vuoto TUTTI)
+ ///
+ public List subscribedItems { get; set; } = new List();
+
+ ///
+ /// Conf Gestione WatchDog
+ ///
+ public WatchDogConf WatchDog { get; set; } = new WatchDogConf();
#endregion Public Properties
}
public class UserIdent
{
- public string UserName { get; set; } = "";
+ #region Public Properties
+
public string Passwd { get; set; } = "";
+ public string UserName { get; set; } = "";
+
+ #endregion Public Properties
+ }
+
+ ///
+ /// Definizione parametri watchdog
+ ///
+ public class WatchDogConf
+ {
+ #region Public Properties
+
+ ///
+ /// Abilitazione WatchDog
+ ///
+ public bool IsEnabled { get; set; } = false;
+
+ ///
+ /// Valore max contatore prima di resettare
+ ///
+ public int MaxVal { get; set; } = 9999;
+
+ ///
+ /// Conf memoria x lettura WatchDog (ToMes), se !="" è gestito
+ ///
+ public string MemConfRead { get; set; } = "";
+
+ ///
+ /// Conf memoria x scrittura WatchDog (FromMes), se !="" è gestito
+ ///
+ public string MemConfWrite { get; set; } = "";
+
+ #endregion Public Properties
}
}
\ No newline at end of file
diff --git a/IOB-UT-NEXT/baseUtils.cs b/IOB-UT-NEXT/baseUtils.cs
index 7f074349..a038471d 100644
--- a/IOB-UT-NEXT/baseUtils.cs
+++ b/IOB-UT-NEXT/baseUtils.cs
@@ -1,4 +1,3 @@
-using MapoSDK;
using NLog;
using System;
using System.Collections;
@@ -49,35 +48,6 @@ namespace IOB_UT_NEXT
#endregion Public Fields
-#if false
- {
- get
- {
- return redisMan.servStatus.dtVetoPing;
- }
- set
- {
- var currData = redisMan.servStatus;
- currData.dtVetoPing = value;
- redisMan.servStatus = currData;
- }
- }
-#endif
-
- #region Protected Properties
-
- ///
- /// Oggetto WebClient BASE da riutilizzare
- ///
- protected static WebClientWT client { get; set; }
-
- ///
- /// Oggetto WebClient con PAYLOAD da riutilizzare
- ///
- protected static WebClientWT clientPayload { get; set; }
-
- #endregion Protected Properties
-
#region Public Properties
///
@@ -89,10 +59,10 @@ namespace IOB_UT_NEXT
{
// parto dal dato std di veto per pauseSendMSec
int answ = CRI("pauseSendMSec");
- // aggiungo NOISE... +/- 33%
+ // aggiungo NOISE... +/- 50%
Random rnd = new Random();
- int noise = rnd.Next(1, answ / 3);
- answ += noise - (answ / 6);
+ int noise = rnd.Next(1, answ / 2);
+ answ += noise - (answ / 4);
return answ;
}
}
@@ -117,6 +87,7 @@ namespace IOB_UT_NEXT
{ }
return answ;
}
+
///
/// formatta un numero in forma binaria 0/1
///
@@ -409,7 +380,9 @@ namespace IOB_UT_NEXT
/// number will be formatted as a 32-character binary number in two's compliment.
///
/// self-explanatory
- /// if binary number contains fewer characters leading zeros are added
+ ///
+ /// if binary number contains fewer characters leading zeros are added
+ ///
/// string as described above
public static string IntToBinStr(int theNumber, int minimumDigits)
{
@@ -420,7 +393,9 @@ namespace IOB_UT_NEXT
/// verifica se un dato bit sia alzato (come flag di strobe)
///
/// valore da testare
- /// valore cercato, può essere un singolo valore o un insieme in modalità AND
+ ///
+ /// valore cercato, può essere un singolo valore o un insieme in modalità AND
+ ///
///
public static bool IsSetAll(StFlag32 value, StFlag32 flag)
{
@@ -431,7 +406,9 @@ namespace IOB_UT_NEXT
/// verifica se un dato bit sia alzato (come flag di strobe)
///
/// valore da testare
- /// valore cercato, può essere un singolo valore o un insieme in modalità OR
+ ///
+ /// valore cercato, può essere un singolo valore o un insieme in modalità OR
+ ///
///
public static bool IsSetAny(StFlag32 value, StFlag32 flag)
{
@@ -586,7 +563,8 @@ namespace IOB_UT_NEXT
}
///
- /// provvede a verificare la dim della cartella dei log e cancella i + vecchi fino a restare a dim inferiori a _logMaxMb
+ /// provvede a verificare la dim della cartella dei log e cancella i + vecchi fino a restare
+ /// a dim inferiori a _logMaxMb
///
public static void shrinkDir(string dirPath)
{
@@ -616,7 +594,8 @@ namespace IOB_UT_NEXT
// inizio con eliminare file + vecchi della data indicata...
int maxLogDays = CRI("maxLogDays");
fileMover.obj.deleteOlderThan(maxLogDays);
- // ora controllo SE sia superata la dim max della directory --> in tal caso cancello dal + vecchio...
+ // ora controllo SE sia superata la dim max della directory --> in tal caso cancello dal
+ // + vecchio...
dirSizeMb = fileMover.obj.totalMb();
int maxLogDirSize = CRI("maxLogDirSize");
int maxTry = 100;
@@ -723,6 +702,20 @@ namespace IOB_UT_NEXT
}
#endregion Public Methods
+
+ #region Protected Properties
+
+ ///
+ /// Oggetto WebClient BASE da riutilizzare
+ ///
+ protected static WebClientWT client { get; set; }
+
+ ///
+ /// Oggetto WebClient con PAYLOAD da riutilizzare
+ ///
+ protected static WebClientWT clientPayload { get; set; }
+
+ #endregion Protected Properties
}
///
diff --git a/IOB-UT-NEXT/packages.config b/IOB-UT-NEXT/packages.config
index 70e045e6..26591de3 100644
--- a/IOB-UT-NEXT/packages.config
+++ b/IOB-UT-NEXT/packages.config
@@ -1,6 +1,6 @@

-
+
diff --git a/IOB-UT-NEXT/val.cs b/IOB-UT-NEXT/val.cs
deleted file mode 100644
index 94029a5c..00000000
--- a/IOB-UT-NEXT/val.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace IOB_UT_NEXT
-{
- internal class val
- {
- }
-}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/AdapterForm.cs b/IOB-WIN-NEXT/AdapterForm.cs
index 728abef3..2c6b6890 100644
--- a/IOB-WIN-NEXT/AdapterForm.cs
+++ b/IOB-WIN-NEXT/AdapterForm.cs
@@ -122,7 +122,7 @@ namespace IOB_WIN_NEXT
// inizializzo orologi
firstStart = DateTime.Now;
- lastStartTry = DateTime.Now;
+ lastStartTry = DateTime.Now.AddHours(-1);
initDatamonitor();
@@ -274,7 +274,7 @@ namespace IOB_WIN_NEXT
protected int maxFlQueue { get; set; }
protected int maxMsQueue { get; set; }
-
+
protected int maxRwTrQueue { get; set; }
protected int maxUlQueue { get; set; }
@@ -286,7 +286,7 @@ namespace IOB_WIN_NEXT
protected int qFlLen { get; set; }
protected int qMsLen { get; set; }
-
+
protected int qRTrLen { get; set; }
protected int qUlLen { get; set; }
@@ -1168,7 +1168,7 @@ namespace IOB_WIN_NEXT
cpuType = fIni.ReadString("CNC", "CPUTYPE", ""),
rack = (short)fIni.ReadInteger("CNC", "RACK", 0),
slot = (short)fIni.ReadInteger("CNC", "SLOT", 0),
- serverData = new serverMapo(fIni.ReadString("SERVER", "MPIP", "::1"), fIni.ReadString("SERVER", "MPURL", "/MP/IO"), fIni.ReadString("SERVER", "CMDBASE", "/IOB/input/"), fIni.ReadString("SERVER", "CMDFLOG", "/IOB/flog/"), fIni.ReadString("SERVER", "CMDULOG", "/IOB/ulog/"), fIni.ReadString("SERVER", "CMDALIVE", "/"), fIni.ReadString("SERVER", "CMDENABLED", "/"), fIni.ReadString("SERVER", "CMDREBO", "/"), fIni.ReadString("SERVER", "CMD_ODL_STARTED", "/IOB/getCurrOdlStart/"), fIni.ReadString("SERVER", "CLI_INST", "SW_CLI"), fIni.ReadString("SERVER", "CMD_FORCLE_SPLIT_ODL", "/IOB/forceSplitOdlFull/")),
+ serverData = new serverMapo(fIni.ReadString("SERVER", "MPIP", "::1"), fIni.ReadString("SERVER", "MPURL", "/MP/IO"), fIni.ReadString("SERVER", "CMDBASE", "/IOB/input/"), fIni.ReadString("SERVER", "CMDFLOG", "/IOB/flog/"), fIni.ReadString("SERVER", "CMDULOG", "/IOB/ulog/"), fIni.ReadString("SERVER", "CMDALIVE", "/"), fIni.ReadString("SERVER", "CMDENABLED", "/"), fIni.ReadString("SERVER", "CMDREBO", "/"), fIni.ReadString("SERVER", "CMD_ODL_STARTED", "/IOB/getCurrOdlStart/"), fIni.ReadString("SERVER", "CLI_INST", "SW_CLI"), fIni.ReadString("SERVER", "CMD_FORCLE_SPLIT_ODL", "/IOB/forceSplitOdlFull/"), fIni.ReadString("SERVER", "CMDRAWTRANSF", "/IOB/rawTransfJson/")),
MAX_COUNTER_BLINK = Convert.ToInt32(fIni.ReadString("BLINK", "MAX_COUNTER_BLINK", "1")),
BLINK_FILT = Convert.ToInt32(fIni.ReadString("BLINK", "BLINK_FILT", "0")),
TCMaxDelayFactor = Convert.ToDouble(fIni.ReadString("OPTPAR", "TC_MAX_TC_FACTOR", "1.2").Replace(".", ",")),
@@ -1243,6 +1243,7 @@ namespace IOB_WIN_NEXT
iobObj = new IobIcoelDb(this, IOBConf);
start.Enabled = true;
break;
+
case tipoAdapter.IcoelSoap:
iobObj = new IobIcoelSoap(this, IOBConf);
start.Enabled = true;
@@ -1258,6 +1259,11 @@ namespace IOB_WIN_NEXT
start.Enabled = true;
break;
+ case tipoAdapter.MODBUS_TCP_CENTERFRIGO:
+ iobObj = new IobModbusTCPCenterfrigo(this, IOBConf);
+ start.Enabled = true;
+ break;
+
case tipoAdapter.MODBUS_TCP_HAM:
iobObj = new IobModbusTCPHam(this, IOBConf);
start.Enabled = true;
@@ -1377,6 +1383,11 @@ namespace IOB_WIN_NEXT
start.Enabled = true;
break;
+ case tipoAdapter.SIEMENS_NWSE:
+ iobObj = new IobSiemensNWSE(this, IOBConf);
+ start.Enabled = true;
+ break;
+
case tipoAdapter.SIEMENS_PRESSOIL_CEI:
iobObj = new IobSiemensPressoilCei(this, IOBConf);
start.Enabled = true;
@@ -1492,6 +1503,10 @@ namespace IOB_WIN_NEXT
// aggiorno labels counters...
counterIob = $"pz IOB {iobObj.contapezziIOB}";
counterMac = $"pz PLC {iobObj.contapezziPLC}";
+ Dictionary setPar = new Dictionary();
+ setPar.Add("IP", iobObj.cIobConf.cncIpAddr);
+ setPar.Add("PORT", iobObj.cIobConf.cncPort);
+ string note = $"DT ultimo avvio: {iobObj.dtAvvioAdp}";
// verifico IOB status
IobWinStatus currIobStatus = new IobWinStatus()
{
@@ -1507,7 +1522,10 @@ namespace IOB_WIN_NEXT
counterMAC = iobObj.contapezziPLC,
lastUpdate = lastIobStatus.lastUpdate,
online = utils.IOB_Online,
- lastDataIn = iobObj.lastReadPLC
+ lastDataIn = iobObj.lastReadPLC,
+ lastDataOut = iobObj.lastIobOnline,
+ setupParams = setPar,
+ freeNotes = note
};
// se diverso SALVO!
if (!lastIobStatus.Equals(currIobStatus))
diff --git a/IOB-WIN-NEXT/App.config b/IOB-WIN-NEXT/App.config
index 13ffb3ff..679e165b 100644
--- a/IOB-WIN-NEXT/App.config
+++ b/IOB-WIN-NEXT/App.config
@@ -1,164 +1,174 @@

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/3025.ini b/IOB-WIN-NEXT/DATA/CONF/3025.ini
index 008d6846..59840aed 100644
--- a/IOB-WIN-NEXT/DATA/CONF/3025.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/3025.ini
@@ -26,7 +26,7 @@ CMDREBO=/sendReboot.aspx?idxMacchina=
; Red: Y31.4 | Yellow: Y31.5 | Green Y31.6 | riscaldamento Y7.4 ???
;BIT0=CONN
BIT1=Y31.6
-BIT2=PZCOUNT.PAR.6711
+BIT2=STD.MACRO.10100
BIT3=Y31.4
BIT4=Y31.5
BIT5=Y7.4
@@ -59,7 +59,10 @@ BLINK_FILT=0
[OPTPAR]
;PZCOUNT_MODE=STD|BIT
-PZCOUNT_MODE=STD.PAR.6711
+;PZCOUNT_MODE=STD.PAR.6711
+;PZREQ_MODE=STD.PAR.6713
+PZCOUNT_MODE=STD.MACRO.10100
+PZREQ_MODE=STD.MACRO.10000
PZGTOT_MODE=STD.PAR.6712
PZREQ_MODE=STD.PAR.6713
;PZCAD_MODE=STD.D.6408.DW
diff --git a/IOB-WIN-NEXT/DATA/CONF/FINASSI_HELPI_01.json b/IOB-WIN-NEXT/DATA/CONF/FINASSI_HELPI_01.json
index aa1a3a1c..c0f4eb4f 100644
--- a/IOB-WIN-NEXT/DATA/CONF/FINASSI_HELPI_01.json
+++ b/IOB-WIN-NEXT/DATA/CONF/FINASSI_HELPI_01.json
@@ -151,7 +151,7 @@
},
"PPM": {
"name": "PPM",
- "description": "Velocità espressa come Pacchi Per Minuto",
+ "description": "Velocit� espressa come Pacchi Per Minuto",
"memAddr": "41106",
"tipoMem": "Real",
"index": 1106,
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_001.ini b/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_001.ini
new file mode 100644
index 00000000..cdf3faf6
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_001.ini
@@ -0,0 +1,76 @@
+;Configurazione IOB-WIN
+[IOB]
+;Impianto Cedax di Turi (test) - Giacovelli
+CNCTYPE=MODBUS_TCP_CEDAX
+PING_MS_TIMEOUT=1000
+
+[MACHINE]
+VENDOR=CEDAX
+MODEL=CEDAX Hydrocooler
+
+[CNC]
+IP=192.168.2.60
+PORT=502
+
+[SERVER]
+MPIP=http://192.168.1.14
+MPURL=/MP/IO
+CMDBASE=/IOB/input/
+CMDFLOG=/IOB/flog/
+CMDALIVE=/IOB
+CMDENABLED=/IOB/enabled/
+CMDADV1=?valore=
+CMDREBO=/sendReboot.aspx?idxMacchina=
+
+[MEMORY]
+ADDR_READ=41001
+ADDR_WRITE=41021
+SIZE_READ=20
+SIZE_WRITE=0
+HR_BASE_ADDR=40000
+
+
+[BLINK]
+;MAX_COUNTER_BLINK = 30
+MAX_COUNTER_BLINK = 15
+;bit0 = 0
+;bit1 = 0
+;bit2 = 1
+;bit3 = 1
+;bit4 = 1
+;bit5 = 0
+;bit6 = 0
+;bit7 = 0
+BLINK_FILT=0
+;BLINK_FILT=28
+
+[OPTPAR]
+;PZCOUNT_MODE=STD.[PAR/MEM].info|BIT.indice
+PZCOUNT_MODE=STD.DB85.DBRE16
+DISABLE_PZCOUNT=TRUE
+ENABLE_SEND_PZC_BLOCK=TRUE
+MIN_SEND_PZC_BLOCK=0
+MAX_SEND_PZC_BLOCK=100
+; GEST DATI DYN
+ENABLE_DYN_DATA=TRUE
+FORCE_DYN_DATA=TRUE
+; gestione delta minimo accettabile tra min/MAX
+DELTA_VAL=0.1
+
+; clock base (da 10ms)
+timerIntMs=10
+
+; conf parametri memoria READ/WRITE
+PARAM_CONF=GIACO_CEDAX_001.json
+
+NO_PING=FALSE
+; conf blocchi memoria x READ
+MEM_BLOCK=GIACO_CEDAX_001_MBlock.json
+; conf aree allarme
+ALARM_CONF=GIACO_CEDAX_001_alarm.json
+
+; rimozione check limiti min/max dynData
+disDynDataRangeCheck=true
+
+[BRANCH]
+NAME=master
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_001.json b/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_001.json
new file mode 100644
index 00000000..edf4343e
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_001.json
@@ -0,0 +1,258 @@
+{
+ "mMapWrite": {
+ "Dose_Staz_1": {
+ "name": "Dose_Staz_1",
+ "description": "Dose Stazione 1",
+ "memAddr": "40024",
+ "tipoMem": "Int",
+ "index": 24,
+ "size": 1,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "%"
+ },
+ "Dose_Staz_2": {
+ "name": "Dose_Staz_2",
+ "description": "Dose Stazione 2",
+ "memAddr": "40025",
+ "tipoMem": "Int",
+ "index": 25,
+ "size": 1,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "%"
+ },
+ "Dose_Staz_3": {
+ "name": "Dose_Staz_3",
+ "description": "Dose Stazione 3",
+ "memAddr": "40026",
+ "tipoMem": "Int",
+ "index": 26,
+ "size": 1,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "%"
+ },
+ "Dose_Staz_4": {
+ "name": "Dose_Staz_4",
+ "description": "Dose Stazione 4",
+ "memAddr": "40027",
+ "tipoMem": "Int",
+ "index": 27,
+ "size": 1,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "%"
+ }
+ },
+ "mMapRead": {
+ "Stag_H2O": {
+ "name": "Stag_H2O",
+ "description": "Totale H2O Stagione",
+ "memAddr": "41001",
+ "tipoMem": "HLPInt",
+ "index": 1001,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 1,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "l"
+ },
+ "Stag_Prod1": {
+ "name": "Stag_Prod1",
+ "description": "Totale Prodotto 1 Stagione",
+ "memAddr": "41003",
+ "tipoMem": "HLPInt",
+ "index": 1003,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 1,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "l"
+ },
+ "Stag_Prod2": {
+ "name": "Stag_Prod2",
+ "description": "Totale Prodotto 2 Stagione",
+ "memAddr": "41005",
+ "tipoMem": "HLPInt",
+ "index": 1005,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 1,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "l"
+ },
+ "Stag_Prod3": {
+ "name": "Stag_Prod3",
+ "description": "Totale Prodotto 3 Stagione",
+ "memAddr": "41007",
+ "tipoMem": "HLPInt",
+ "index": 1007,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "l"
+ },
+ "Stag_Prod4": {
+ "name": "Stag_Prod4",
+ "description": "Totale Prodotto 4 Stagione",
+ "memAddr": "41009",
+ "tipoMem": "HLPInt",
+ "index": 1009,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "l"
+ },
+ "Giorno_H2O": {
+ "name": "Giorno_H2O",
+ "description": "Totale H2O Giorno",
+ "memAddr": "41011",
+ "tipoMem": "HLPInt",
+ "index": 1011,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 1,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "l"
+ },
+ "Giorno_Prod1": {
+ "name": "Giorno_Prod1",
+ "description": "Totale Prodotto 1 Giorno",
+ "memAddr": "41013",
+ "tipoMem": "HLPInt",
+ "index": 1013,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 1,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "l"
+ },
+ "Giorno_Prod2": {
+ "name": "Giorno_Prod2",
+ "description": "Totale Prodotto 2 Giorno",
+ "memAddr": "41015",
+ "tipoMem": "HLPInt",
+ "index": 1015,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 1,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "l"
+ },
+ "Giorno_Prod3": {
+ "name": "Giorno_Prod3",
+ "description": "Totale Prodotto 3 Giorno",
+ "memAddr": "41017",
+ "tipoMem": "HLPInt",
+ "index": 1017,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "l"
+ },
+ "Giorno_Prod4": {
+ "name": "Giorno_Prod4",
+ "description": "Totale Prodotto 4 Giorno",
+ "memAddr": "41019",
+ "tipoMem": "HLPInt",
+ "index": 1019,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "l"
+ },
+ "Dose_Staz_1": {
+ "name": "Dose_Staz_1",
+ "description": "Dose Stazione 1",
+ "memAddr": "40024",
+ "tipoMem": "Int",
+ "index": 24,
+ "size": 1,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "%"
+ },
+ "Dose_Staz_2": {
+ "name": "Dose_Staz_2",
+ "description": "Dose Stazione 2",
+ "memAddr": "40025",
+ "tipoMem": "Int",
+ "index": 25,
+ "size": 1,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "%"
+ },
+ "Dose_Staz_3": {
+ "name": "Dose_Staz_3",
+ "description": "Dose Stazione 3",
+ "memAddr": "40026",
+ "tipoMem": "Int",
+ "index": 26,
+ "size": 1,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "%"
+ },
+ "Dose_Staz_4": {
+ "name": "Dose_Staz_4",
+ "description": "Dose Stazione 4",
+ "memAddr": "40027",
+ "tipoMem": "Int",
+ "index": 27,
+ "size": 1,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "%"
+ }
+ }
+}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_001_MBlock.json b/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_001_MBlock.json
new file mode 100644
index 00000000..6ce9d4fd
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_001_MBlock.json
@@ -0,0 +1,6 @@
+{
+ "ReadBlocks": {
+ "40016": 16,
+ "40999": 32
+ }
+}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_01_alarm.json b/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_001_alarm.json
similarity index 100%
rename from IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_01_alarm.json
rename to IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_001_alarm.json
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_01.ini b/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_002.ini
similarity index 78%
rename from IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_01.ini
rename to IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_002.ini
index 0af3ab79..def79ad2 100644
--- a/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_01.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_002.ini
@@ -6,23 +6,21 @@ PING_MS_TIMEOUT=1000
[MACHINE]
VENDOR=CEDAX
-MODEL=CEDAX
+MODEL=CEDAX Scarico
[CNC]
-IP=10.74.82.65
+IP=192.168.2.61
PORT=502
[SERVER]
-MPIP=https://iis01.egalware.com
-;MPIP=https://gwms.egalware.com
+MPIP=http://192.168.1.14
MPURL=/MP/IO
CMDBASE=/IOB/input/
CMDFLOG=/IOB/flog/
CMDALIVE=/IOB
CMDENABLED=/IOB/enabled/
CMDADV1=?valore=
-CMDREBO=/IOB/sendReboot?idxMacchina=
-;CMDREBO=/sendReboot.aspx?idxMacchina=
+CMDREBO=/sendReboot.aspx?idxMacchina=
[MEMORY]
ADDR_READ=41001
@@ -63,13 +61,16 @@ DELTA_VAL=0.1
timerIntMs=10
; conf parametri memoria READ/WRITE
-PARAM_CONF=GIACO_CEDAX_01.json
+PARAM_CONF=GIACO_CEDAX_002.json
NO_PING=TRUE
; conf blocchi memoria x READ
-MEM_BLOCK=GIACO_CEDAX_01_MBlock.json
+MEM_BLOCK=GIACO_CEDAX_002_MBlock.json
; conf aree allarme
-ALARM_CONF=GIACO_CEDAX_01_alarm.json
+ALARM_CONF=GIACO_CEDAX_002_alarm.json
+
+; rimozione check limiti min/max dynData
+disDynDataRangeCheck=true
[BRANCH]
NAME=master
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_002.json b/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_002.json
new file mode 100644
index 00000000..bef5f18f
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_002.json
@@ -0,0 +1,286 @@
+{
+ "mMapWrite": {
+ "Dose_Staz_1": {
+ "name": "Dose_Staz_1",
+ "description": "Dose Stazione 1",
+ "memAddr": "40024",
+ "tipoMem": "Int",
+ "index": 24,
+ "size": 1,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "%"
+ },
+ "Dose_Staz_2": {
+ "name": "Dose_Staz_2",
+ "description": "Dose Stazione 2",
+ "memAddr": "40025",
+ "tipoMem": "Int",
+ "index": 25,
+ "size": 1,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "%"
+ },
+ "Dose_Staz_3": {
+ "name": "Dose_Staz_3",
+ "description": "Dose Stazione 3",
+ "memAddr": "40026",
+ "tipoMem": "Int",
+ "index": 26,
+ "size": 1,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "%"
+ },
+ "Dose_Staz_4": {
+ "name": "Dose_Staz_4",
+ "description": "Dose Stazione 4",
+ "memAddr": "40027",
+ "tipoMem": "Int",
+ "index": 27,
+ "size": 1,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "%"
+ }
+ },
+ "mMapRead": {
+ "A_Stag_H2O": {
+ "name": "A_Stag_H2O",
+ "description": "Linea A Totale H2O Stagione",
+ "memAddr": "41001",
+ "tipoMem": "HLPInt",
+ "index": 1001,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 1,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "l"
+ },
+ "A_Stag_Prod1": {
+ "name": "A_Stag_Prod1",
+ "description": "Linea A Totale Prodotto 1 Stagione",
+ "memAddr": "40003",
+ "tipoMem": "HLPInt",
+ "index": 1003,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "l"
+ },
+ "A_Stag_Prod2": {
+ "name": "A_Stag_Prod2",
+ "description": "Linea A Totale Prodotto 2 Stagione",
+ "memAddr": "40005",
+ "tipoMem": "HLPInt",
+ "index": 1005,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "l"
+ },
+ "A_Giorno_H2O": {
+ "name": "A_Giorno_H2O",
+ "description": "Linea A Totale H2O Giorno",
+ "memAddr": "41007",
+ "tipoMem": "HLPInt",
+ "index": 1007,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 1,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "l"
+ },
+ "A_Giorno_Prod1": {
+ "name": "A_Giorno_Prod1",
+ "description": "Linea A Totale Prodotto 1 Giorno",
+ "memAddr": "40009",
+ "tipoMem": "HLPInt",
+ "index": 1009,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "l"
+ },
+ "A_Giorno_Prod2": {
+ "name": "A_Giorno_Prod2",
+ "description": "Linea A Totale Prodotto 2 Giorno",
+ "memAddr": "40011",
+ "tipoMem": "HLPInt",
+ "index": 1011,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "l"
+ },
+ "B_Stag_H2O": {
+ "name": "B_Stag_H2O",
+ "description": "Linea B Totale H2O Stagione",
+ "memAddr": "41013",
+ "tipoMem": "HLPInt",
+ "index": 1013,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 1,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "l"
+ },
+ "B_Stag_Prod1": {
+ "name": "B_Stag_Prod1",
+ "description": "Linea B Totale Prodotto 1 Stagione",
+ "memAddr": "40015",
+ "tipoMem": "HLPInt",
+ "index": 1015,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "l"
+ },
+ "B_Stag_Prod2": {
+ "name": "B_Stag_Prod2",
+ "description": "Linea B Totale Prodotto 2 Stagione",
+ "memAddr": "40017",
+ "tipoMem": "HLPInt",
+ "index": 1009,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "l"
+ },
+ "B_Giorno_H2O": {
+ "name": "B_Giorno_H2O",
+ "description": "Linea B Totale H2O Giorno",
+ "memAddr": "41019",
+ "tipoMem": "HLPInt",
+ "index": 1019,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 1,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "l"
+ },
+ "B_Giorno_Prod1": {
+ "name": "B_Giorno_Prod1",
+ "description": "Linea B Totale Prodotto 1 Giorno",
+ "memAddr": "40021",
+ "tipoMem": "HLPInt",
+ "index": 1021,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "l"
+ },
+ "B_Giorno_Prod2": {
+ "name": "B_Giorno_Prod2",
+ "description": "Linea B Totale Prodotto 2 Giorno",
+ "memAddr": "40023",
+ "tipoMem": "HLPInt",
+ "index": 1023,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "l"
+ },
+ "Dose_Staz_1": {
+ "name": "Dose_Staz_1",
+ "description": "Dose Stazione 1",
+ "memAddr": "40024",
+ "tipoMem": "Int",
+ "index": 24,
+ "size": 1,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "%"
+ },
+ "Dose_Staz_2": {
+ "name": "Dose_Staz_2",
+ "description": "Dose Stazione 2",
+ "memAddr": "40025",
+ "tipoMem": "Int",
+ "index": 25,
+ "size": 1,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "%"
+ },
+ "Dose_Staz_3": {
+ "name": "Dose_Staz_3",
+ "description": "Dose Stazione 3",
+ "memAddr": "40026",
+ "tipoMem": "Int",
+ "index": 26,
+ "size": 1,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "%"
+ },
+ "Dose_Staz_4": {
+ "name": "Dose_Staz_4",
+ "description": "Dose Stazione 4",
+ "memAddr": "40027",
+ "tipoMem": "Int",
+ "index": 27,
+ "size": 1,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "%"
+ }
+ }
+}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_002_MBlock.json b/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_002_MBlock.json
new file mode 100644
index 00000000..6ce9d4fd
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_002_MBlock.json
@@ -0,0 +1,6 @@
+{
+ "ReadBlocks": {
+ "40016": 16,
+ "40999": 32
+ }
+}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_002_alarm.json b/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_002_alarm.json
new file mode 100644
index 00000000..c684acec
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_002_alarm.json
@@ -0,0 +1,27 @@
+[
+ {
+ "description": "Allarmi Impianto",
+ "tipoMem": "DInt",
+ "memAddr": "40999",
+ "index": 999,
+ "size": 2,
+ "messages": [
+ "##On Pompa 1",
+ "Allarme Pompa 1",
+ "##On Pompa 2",
+ "Allarme Pompa 2",
+ "##On Pompa 3",
+ "Allarme Pompa 3",
+ "##On Pompa 4",
+ "Allarme Pompa 4",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##"
+ ]
+ }
+]
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_003.ini b/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_003.ini
new file mode 100644
index 00000000..fae12535
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_003.ini
@@ -0,0 +1,76 @@
+;Configurazione IOB-WIN
+[IOB]
+;Impianto Cedax di Turi (test) - Giacovelli
+CNCTYPE=MODBUS_TCP_CEDAX
+PING_MS_TIMEOUT=1000
+
+[MACHINE]
+VENDOR=CEDAX
+MODEL=CEDAX Lavorazione
+
+[CNC]
+IP=192.168.2.62
+PORT=502
+
+[SERVER]
+MPIP=http://192.168.1.14
+MPURL=/MP/IO
+CMDBASE=/IOB/input/
+CMDFLOG=/IOB/flog/
+CMDALIVE=/IOB
+CMDENABLED=/IOB/enabled/
+CMDADV1=?valore=
+CMDREBO=/sendReboot.aspx?idxMacchina=
+
+[MEMORY]
+ADDR_READ=41001
+ADDR_WRITE=41021
+SIZE_READ=20
+SIZE_WRITE=0
+HR_BASE_ADDR=40000
+
+
+[BLINK]
+;MAX_COUNTER_BLINK = 30
+MAX_COUNTER_BLINK = 15
+;bit0 = 0
+;bit1 = 0
+;bit2 = 1
+;bit3 = 1
+;bit4 = 1
+;bit5 = 0
+;bit6 = 0
+;bit7 = 0
+BLINK_FILT=0
+;BLINK_FILT=28
+
+[OPTPAR]
+;PZCOUNT_MODE=STD.[PAR/MEM].info|BIT.indice
+PZCOUNT_MODE=STD.DB85.DBRE16
+DISABLE_PZCOUNT=TRUE
+ENABLE_SEND_PZC_BLOCK=TRUE
+MIN_SEND_PZC_BLOCK=0
+MAX_SEND_PZC_BLOCK=100
+; GEST DATI DYN
+ENABLE_DYN_DATA=TRUE
+FORCE_DYN_DATA=TRUE
+; gestione delta minimo accettabile tra min/MAX
+DELTA_VAL=0.1
+
+; clock base (da 10ms)
+timerIntMs=10
+
+; conf parametri memoria READ/WRITE
+PARAM_CONF=GIACO_CEDAX_003.json
+
+NO_PING=TRUE
+; conf blocchi memoria x READ
+MEM_BLOCK=GIACO_CEDAX_003_MBlock.json
+; conf aree allarme
+ALARM_CONF=GIACO_CEDAX_003_alarm.json
+
+; rimozione check limiti min/max dynData
+disDynDataRangeCheck=true
+
+[BRANCH]
+NAME=master
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_01.json b/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_003.json
similarity index 62%
rename from IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_01.json
rename to IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_003.json
index 30690b79..0635e72c 100644
--- a/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_01.json
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_003.json
@@ -1,5 +1,47 @@
{
"mMapWrite": {
+ "Dose_Staz_1": {
+ "name": "Dose_Staz_1",
+ "description": "Dose Stazione 1",
+ "memAddr": "40024",
+ "tipoMem": "Int",
+ "index": 24,
+ "size": 1,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "%"
+ },
+ "Dose_Staz_2": {
+ "name": "Dose_Staz_2",
+ "description": "Dose Stazione 2",
+ "memAddr": "40025",
+ "tipoMem": "Int",
+ "index": 25,
+ "size": 1,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "%"
+ },
+ "Dose_Staz_3": {
+ "name": "Dose_Staz_3",
+ "description": "Dose Stazione 3",
+ "memAddr": "40026",
+ "tipoMem": "Int",
+ "index": 26,
+ "size": 1,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "%"
+ }
},
"mMapRead": {
"Stag_H2O": {
@@ -58,26 +100,12 @@
"maxVal": 999999999,
"unit": "l"
},
- "Stag_Prod4": {
- "name": "Stag_Prod4",
- "description": "Totale Prodotto 4 Stagione",
- "memAddr": "40009",
- "tipoMem": "HLPInt",
- "index": 1009,
- "size": 2,
- "func": "MEDIAN",
- "period": 90,
- "factor": 0.01,
- "minVal": 0,
- "maxVal": 999999999,
- "unit": "l"
- },
"Giorno_H2O": {
"name": "Giorno_H2O",
"description": "Totale H2O Giorno",
- "memAddr": "41011",
+ "memAddr": "41009",
"tipoMem": "HLPInt",
- "index": 1011,
+ "index": 1009,
"size": 2,
"func": "MEDIAN",
"period": 90,
@@ -89,9 +117,9 @@
"Giorno_Prod1": {
"name": "Giorno_Prod1",
"description": "Totale Prodotto 1 Giorno",
- "memAddr": "40013",
+ "memAddr": "40011",
"tipoMem": "HLPInt",
- "index": 1013,
+ "index": 1011,
"size": 2,
"func": "MEDIAN",
"period": 90,
@@ -103,9 +131,9 @@
"Giorno_Prod2": {
"name": "Giorno_Prod2",
"description": "Totale Prodotto 2 Giorno",
- "memAddr": "40015",
+ "memAddr": "40013",
"tipoMem": "HLPInt",
- "index": 1015,
+ "index": 1013,
"size": 2,
"func": "MEDIAN",
"period": 90,
@@ -117,9 +145,9 @@
"Giorno_Prod3": {
"name": "Giorno_Prod3",
"description": "Totale Prodotto 3 Giorno",
- "memAddr": "40017",
+ "memAddr": "40015",
"tipoMem": "HLPInt",
- "index": 1017,
+ "index": 1015,
"size": 2,
"func": "MEDIAN",
"period": 90,
@@ -128,19 +156,47 @@
"maxVal": 999999999,
"unit": "l"
},
- "Giorno_Prod4": {
- "name": "Giorno_Prod4",
- "description": "Totale Prodotto 4 Giorno",
- "memAddr": "40021",
- "tipoMem": "HLPInt",
- "index": 1021,
- "size": 2,
+ "Dose_Staz_1": {
+ "name": "Dose_Staz_1",
+ "description": "Dose Stazione 1",
+ "memAddr": "40024",
+ "tipoMem": "Int",
+ "index": 24,
+ "size": 1,
"func": "MEDIAN",
"period": 90,
"factor": 0.01,
"minVal": 0,
"maxVal": 999999999,
- "unit": "l"
+ "unit": "%"
+ },
+ "Dose_Staz_2": {
+ "name": "Dose_Staz_2",
+ "description": "Dose Stazione 2",
+ "memAddr": "40025",
+ "tipoMem": "Int",
+ "index": 25,
+ "size": 1,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "%"
+ },
+ "Dose_Staz_3": {
+ "name": "Dose_Staz_3",
+ "description": "Dose Stazione 3",
+ "memAddr": "40026",
+ "tipoMem": "Int",
+ "index": 26,
+ "size": 1,
+ "func": "MEDIAN",
+ "period": 90,
+ "factor": 0.01,
+ "minVal": 0,
+ "maxVal": 999999999,
+ "unit": "%"
}
}
}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_003_MBlock.json b/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_003_MBlock.json
new file mode 100644
index 00000000..6ce9d4fd
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_003_MBlock.json
@@ -0,0 +1,6 @@
+{
+ "ReadBlocks": {
+ "40016": 16,
+ "40999": 32
+ }
+}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_003_alarm.json b/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_003_alarm.json
new file mode 100644
index 00000000..c684acec
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_003_alarm.json
@@ -0,0 +1,27 @@
+[
+ {
+ "description": "Allarmi Impianto",
+ "tipoMem": "DInt",
+ "memAddr": "40999",
+ "index": 999,
+ "size": 2,
+ "messages": [
+ "##On Pompa 1",
+ "Allarme Pompa 1",
+ "##On Pompa 2",
+ "Allarme Pompa 2",
+ "##On Pompa 3",
+ "Allarme Pompa 3",
+ "##On Pompa 4",
+ "Allarme Pompa 4",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##"
+ ]
+ }
+]
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_01_MBlock.json b/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_01_MBlock.json
deleted file mode 100644
index b5e46ee5..00000000
--- a/IOB-WIN-NEXT/DATA/CONF/GIACO_CEDAX_01_MBlock.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "ReadBlocks": {
- "40999": 30
- }
-}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_CENTERFRIGO.ini b/IOB-WIN-NEXT/DATA/CONF/GIACO_CENTERFRIGO.ini
new file mode 100644
index 00000000..80cf0d15
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_CENTERFRIGO.ini
@@ -0,0 +1,79 @@
+;Configurazione IOB-WIN
+[IOB]
+;Impianto Cedax di Turi (test) - Giacovelli
+CNCTYPE=MODBUS_TCP_CENTERFRIGO
+PING_MS_TIMEOUT=1000
+
+[MACHINE]
+VENDOR=Centerfrigo
+MODEL=Impianto Turi
+
+[CNC]
+IP=192.168.4.161
+PORT=502
+
+[SERVER]
+MPIP=http://192.168.1.14
+MPURL=/MP/IO
+CMDBASE=/IOB/input/
+CMDFLOG=/IOB/flog/
+CMDALIVE=/IOB
+CMDENABLED=/IOB/enabled/
+CMDADV1=?valore=
+CMDREBO=/sendReboot.aspx?idxMacchina=
+
+[MEMORY]
+ADDR_READ=40001
+ADDR_WRITE=41000
+SIZE_READ=2400
+SIZE_WRITE=0
+HR_BASE_ADDR=40000
+DELTA_BASE=0
+
+[BLINK]
+;MAX_COUNTER_BLINK = 30
+MAX_COUNTER_BLINK = 15
+;bit0 = 0
+;bit1 = 0
+;bit2 = 1
+;bit3 = 1
+;bit4 = 1
+;bit5 = 0
+;bit6 = 0
+;bit7 = 0
+BLINK_FILT=0
+;BLINK_FILT=28
+
+[OPTPAR]
+;PZCOUNT_MODE=STD.[PAR/MEM].info|BIT.indice
+PZCOUNT_MODE=STD.DB85.DBRE16
+DISABLE_PZCOUNT=TRUE
+ENABLE_SEND_PZC_BLOCK=TRUE
+MIN_SEND_PZC_BLOCK=0
+MAX_SEND_PZC_BLOCK=100
+; GEST DATI DYN
+ENABLE_DYN_DATA=TRUE
+FORCE_DYN_DATA=TRUE
+; gestione delta minimo accettabile tra min/MAX
+DELTA_VAL=0.1
+
+; clock base (da 10ms)
+timerIntMs=100
+minWait=50
+maxWait=150
+
+
+; conf parametri memoria READ/WRITE
+PARAM_CONF=GIACO_CENTERFRIGO.json
+
+NO_PING=FALSE
+; conf blocchi memoria x READ
+MEM_BLOCK=GIACO_CENTERFRIGO_MBlock.json
+; conf aree allarme
+ALARM_CONF=GIACO_CENTERFRIGO_alarm.json
+
+; rimozione check limiti min/max dynData
+disDynDataRangeCheck=true
+
+[BRANCH]
+NAME=master
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_CENTERFRIGO.json b/IOB-WIN-NEXT/DATA/CONF/GIACO_CENTERFRIGO.json
new file mode 100644
index 00000000..7b06ce3d
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_CENTERFRIGO.json
@@ -0,0 +1,426 @@
+{
+ "mMapWrite": {
+ "TestWrite": {
+ "name": "TestWrite",
+ "description": "Test Scrittura",
+ "memAddr": "41621",
+ "tipoMem": "Real",
+ "index": 1621,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "SetPoint_Tunnel": {
+ "name": "SetPoint_Tunnel",
+ "description": "Setpoint Tunnel",
+ "memAddr": "41560",
+ "tipoMem": "Real",
+ "index": 1560,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ }
+ },
+ "mMapRead": {
+ "Temp_Tunnel": {
+ "name": "Temp_Tunnel",
+ "description": "Temperatura Tunnel",
+ "memAddr": "41520",
+ "tipoMem": "Real",
+ "index": 1520,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "SetPoint_Tunnel": {
+ "name": "SetPoint_Tunnel",
+ "description": "Setpoint Tunnel",
+ "memAddr": "41560",
+ "tipoMem": "Real",
+ "index": 1560,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "Temp_Cella_01": {
+ "name": "Temp_Cella_01",
+ "description": "Temperatura Cella 01",
+ "memAddr": "41660",
+ "tipoMem": "Real",
+ "index": 1660,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "SetPoint_Cella_01": {
+ "name": "SetPoint_Cella_01",
+ "description": "Setpoint Cella 01",
+ "memAddr": "41700",
+ "tipoMem": "Real",
+ "index": 1700,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "Temp_Cella_02": {
+ "name": "Temp_Cella_02",
+ "description": "Temperatura Cella 02",
+ "memAddr": "41810",
+ "tipoMem": "Real",
+ "index": 1810,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "SetPoint_Cella_02": {
+ "name": "SetPoint_Cella_02",
+ "description": "Setpoint Cella 02",
+ "memAddr": "41840",
+ "tipoMem": "Real",
+ "index": 1840,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "Temp_Cella_03": {
+ "name": "Temp_Cella_03",
+ "description": "Temperatura Cella 03",
+ "memAddr": "41930",
+ "tipoMem": "Real",
+ "index": 1930,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "SetPoint_Cella_03": {
+ "name": "SetPoint_Cella_03",
+ "description": "Setpoint Cella 03",
+ "memAddr": "41960",
+ "tipoMem": "Real",
+ "index": 1960,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "Temp_Cella_04": {
+ "name": "Temp_Cella_04",
+ "description": "Temperatura Cella 04",
+ "memAddr": "42050",
+ "tipoMem": "Real",
+ "index": 2050,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "SetPoint_Cella_04": {
+ "name": "SetPoint_Cella_04",
+ "description": "Setpoint Cella 04",
+ "memAddr": "41840",
+ "tipoMem": "Real",
+ "index": 1840,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "Temp_Sala_Bassa": {
+ "name": "Temp_Sala_Bassa",
+ "description": "Temperatura Sala Zona Bassa",
+ "memAddr": "42290",
+ "tipoMem": "Real",
+ "index": 2290,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "SetPoint_Sala_Bassa": {
+ "name": "SetPoint_Sala_Bassa",
+ "description": "Setpoint Sala Zona Bassa",
+ "memAddr": "42330",
+ "tipoMem": "Real",
+ "index": 2330,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "Temp_Sala_Alta": {
+ "name": "Temp_Sala_Alta",
+ "description": "Temperatura Sala Zona Alta",
+ "memAddr": "42420",
+ "tipoMem": "Real",
+ "index": 2420,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "SetPoint_Sala_Alta": {
+ "name": "SetPoint_Sala_Alta",
+ "description": "Setpoint Sala Zona Alta",
+ "memAddr": "42460",
+ "tipoMem": "Real",
+ "index": 2460,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "Temp_Hydrocooler": {
+ "name": "Temp_Hydrocooler",
+ "description": "Temperatura Hydrocooler",
+ "memAddr": "42550",
+ "tipoMem": "Real",
+ "index": 2550,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "SetPoint_Hydrocooler": {
+ "name": "SetPoint_Hydrocooler",
+ "description": "Setpoint Hydrocooler",
+ "memAddr": "42580",
+ "tipoMem": "Real",
+ "index": 2580,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "Temp_Calibr_01": {
+ "name": "Temp_Calibr_01",
+ "description": "Temperatura Calibratrice 01",
+ "memAddr": "42670",
+ "tipoMem": "Real",
+ "index": 2670,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "SetPoint_Calibr_01": {
+ "name": "SetPoint_Calibr_01",
+ "description": "SetPoint Calibratrice 01",
+ "memAddr": "42710",
+ "tipoMem": "Real",
+ "index": 2710,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "Temp_Calibr_02": {
+ "name": "Temp_Calibr_02",
+ "description": "Temperatura Calibratrice 02",
+ "memAddr": "42800",
+ "tipoMem": "Real",
+ "index": 2800,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "SetPoint_Calibr_02": {
+ "name": "SetPoint_Calibr_02",
+ "description": "SetPoint Calibratrice 02",
+ "memAddr": "42830",
+ "tipoMem": "Real",
+ "index": 2830,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "Temp_Calibr_03": {
+ "name": "Temp_Calibr_03",
+ "description": "Temperatura Calibratrice 03",
+ "memAddr": "42920",
+ "tipoMem": "Real",
+ "index": 2920,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "SetPoint_Calibr_03": {
+ "name": "SetPoint_Calibr_03",
+ "description": "SetPoint Calibratrice 03",
+ "memAddr": "42950",
+ "tipoMem": "Real",
+ "index": 2950,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "Temp_Calibr_04": {
+ "name": "Temp_Calibr_04",
+ "description": "Temperatura Calibratrice 04",
+ "memAddr": "43050",
+ "tipoMem": "Real",
+ "index": 3050,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "SetPoint_Calibr_04": {
+ "name": "SetPoint_Calibr_04",
+ "description": "SetPoint Calibratrice 04",
+ "memAddr": "43080",
+ "tipoMem": "Real",
+ "index": 3080,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "Temp_Serbatoi": {
+ "name": "Temp_Serbatoi",
+ "description": "Temperatura Searbatoi",
+ "memAddr": "43170",
+ "tipoMem": "Real",
+ "index": 3170,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "SetPoint_Searbatoi": {
+ "name": "SetPoint_Searbatoi",
+ "description": "SetPoint Searbatoi",
+ "memAddr": "43200",
+ "tipoMem": "Real",
+ "index": 3200,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "Temp_Serpentine": {
+ "name": "Temp_Serpentine",
+ "description": "Temperatura Serpentine",
+ "memAddr": "43290",
+ "tipoMem": "Real",
+ "index": 3290,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ },
+ "SetPoint_Serpentine": {
+ "name": "SetPoint_Serpentine",
+ "description": "SetPoint Serpentine",
+ "memAddr": "43320",
+ "tipoMem": "Real",
+ "index": 3320,
+ "size": 2,
+ "func": "MEDIAN",
+ "period": 60,
+ "factor": 1,
+ "minVal": -100,
+ "maxVal": 100,
+ "unit": "°C"
+ }
+ }
+}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_CENTERFRIGO_MBlock.json b/IOB-WIN-NEXT/DATA/CONF/GIACO_CENTERFRIGO_MBlock.json
new file mode 100644
index 00000000..da89c677
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_CENTERFRIGO_MBlock.json
@@ -0,0 +1,25 @@
+{
+ "ReadBlocks": {
+ "41500": 32,
+ "41532": 32,
+ "41616": 32,
+ "41650": 32,
+ "41682": 32,
+ "41800": 32,
+ "41832": 32,
+ "41920": 44,
+ "42040": 44,
+ "42160": 8,
+ "42290": 44,
+ "42410": 32,
+ "42442": 32,
+ "42540": 44,
+ "42660": 32,
+ "42692": 32,
+ "42790": 44,
+ "42910": 44,
+ "43040": 44,
+ "43160": 44,
+ "43280": 44
+ }
+}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_CENTERFRIGO_alarm.json b/IOB-WIN-NEXT/DATA/CONF/GIACO_CENTERFRIGO_alarm.json
new file mode 100644
index 00000000..2220b2a4
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_CENTERFRIGO_alarm.json
@@ -0,0 +1,227 @@
+[
+ {
+ "description": "Centrale Frigorifera",
+ "tipoMem": "DInt",
+ "memAddr": "41508",
+ "index": 1508,
+ "size": 2,
+ "messages": [
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "ALLARME CENTRALE FRIGORIFERA",
+ "ALLARME GENERICO IMPIANTO",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##"
+ ]
+ },
+ {
+ "description": "Allarmi Tunnel",
+ "tipoMem": "DInt",
+ "memAddr": "41654",
+ "index": 1654,
+ "size": 2,
+ "messages": [
+ "ALLARME ALTA TEMPERATURA AMBIENTE TUNNEL",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "ALLARME CUMULATIVO TUNNEL",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##"
+ ]
+ },
+ {
+ "description": "Allarmi Cella 01",
+ "tipoMem": "DInt",
+ "memAddr": "41804",
+ "index": 1804,
+ "size": 2,
+ "messages": [
+ "ALLARME ALTA TEMPERATURA AMBIENTE CELLA 01",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "ALLARME CUMULATIVO CELLA 01",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##"
+ ]
+ },
+ {
+ "description": "Allarmi Cella 02",
+ "tipoMem": "DInt",
+ "memAddr": "41924",
+ "index": 1924,
+ "size": 2,
+ "messages": [
+ "ALLARME ALTA TEMPERATURA AMBIENTE CELLA 02",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "ALLARME CUMULATIVO CELLA 02",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##"
+ ]
+ },
+ {
+ "description": "Allarmi Cella 03",
+ "tipoMem": "DInt",
+ "memAddr": "42044",
+ "index": 2044,
+ "size": 2,
+ "messages": [
+ "ALLARME ALTA TEMPERATURA AMBIENTE CELLA 03",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "ALLARME CUMULATIVO CELLA 03",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##"
+ ]
+ },
+// {
+// "description": "Allarmi Cella 04",
+// "tipoMem": "DInt",
+// "memAddr": "42164",
+// "index": 2164,
+// "size": 2,
+// "messages": [
+// "ALLARME ALTA TEMPERATURA AMBIENTE CELLA 04",
+// "##",
+// "##",
+// "##",
+// "##",
+// "##",
+// "##",
+// "##",
+// "##",
+// "##",
+// "ALLARME CUMULATIVO CELLA 04",
+// "##",
+// "##",
+// "##",
+// "##",
+// "##"
+// ]
+// },
+ {
+ "description": "Allarmi Sala Bassa",
+ "tipoMem": "DInt",
+ "memAddr": "42414",
+ "index": 2414,
+ "size": 2,
+ "messages": [
+ "ALLARME ALTA TEMPERATURA AMBIENTE SALA BASSA",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "ALLARME CUMULATIVO SALA BASSA",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##"
+ ]
+ },
+ {
+ "description": "Allarmi Sala Alta",
+ "tipoMem": "DInt",
+ "memAddr": "42544",
+ "index": 2544,
+ "size": 2,
+ "messages": [
+ "ALLARME ALTA TEMPERATURA AMBIENTE SALA ALTA",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "ALLARME CUMULATIVO SALA ALTA",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##"
+ ]
+ },
+ {
+ "description": "Allarmi Hydrocooler",
+ "tipoMem": "DInt",
+ "memAddr": "42664",
+ "index": 2664,
+ "size": 2,
+ "messages": [
+ "ALLARME ALTA TEMPERATURA AMBIENTE HYDROCOOLER",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "ALLARME CUMULATIVO HYDROCOOLER",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##"
+ ]
+ }
+]
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_ICOEL_001.ini b/IOB-WIN-NEXT/DATA/CONF/GIACO_ICOEL_001.ini
index 7eee9efe..1e80902f 100644
--- a/IOB-WIN-NEXT/DATA/CONF/GIACO_ICOEL_001.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_ICOEL_001.ini
@@ -3,7 +3,6 @@
;Centro di lavoro OpcUa
CNCTYPE=OpcUaOmronIcoel
PING_MS_TIMEOUT=500
-IOB_NAME=GIACO_ICOEL
[MACHINE]
VENDOR=ICOEL
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_ICOEL_002.ini b/IOB-WIN-NEXT/DATA/CONF/GIACO_ICOEL_002.ini
index 16caef0b..3cf5fb6e 100644
--- a/IOB-WIN-NEXT/DATA/CONF/GIACO_ICOEL_002.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_ICOEL_002.ini
@@ -3,7 +3,7 @@
;WebService SOAP x sizer
CNCTYPE=IcoelSoap
PING_MS_TIMEOUT=500
-IOB_NAME=GIACO_ICOEL
+;IOB_NAME=GIACO_ICOEL
[MACHINE]
VENDOR=ICOEL
@@ -19,6 +19,7 @@ MPIP=http://192.168.1.14
MPURL=/MP/IO
CMDBASE=/IOB/input/
CMDFLOG=/IOB/flog/
+CMDRAWTRANSF=/IOB/rawTransfJson/
CMDALIVE=/IOB
CMDENABLED=/IOB/enabled/
CMDADV1=?valore=
@@ -60,14 +61,17 @@ DISABLE_PZCOUNT=FALSE
ENABLE_SEND_PZC_BLOCK=TRUE
MIN_SEND_PZC_BLOCK=0
MAX_SEND_PZC_BLOCK=100
-ENABLE_DYN_DATA=FALSE
+ENABLE_DYN_DATA=TRUE
FORCE_DYN_DATA=TRUE
+DEM_FACT_DYN_DATA=2
ENABLE_DATA_FILTER=TRUE
ENABLE_CLI_RESTART=TRUE
-VETO_SIG_IN=TRUE
+
+; clock base (da 10ms)
+timerIntMs=40
; conf parametri memoria READ/WRITE
-OPC_PARAM_CONF=GIACO_ICOEL_001.json
+PARAM_CONF=GIACO_ICOEL_002.json
[BRANCH]
NAME=master
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_ICOEL_002.json b/IOB-WIN-NEXT/DATA/CONF/GIACO_ICOEL_002.json
new file mode 100644
index 00000000..df6898b4
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_ICOEL_002.json
@@ -0,0 +1,124 @@
+{
+ "mMapWrite": {
+ "setSupplier": {
+ "name": "setSupplier",
+ "description": "Send Batch req (GrowerCode|Descript)",
+ "tipoMem": "String",
+ "memAddr": "setSupplier",
+ "index": 0,
+ "size": 50
+ }
+ },
+ "mMapRead": {
+ "VelTonnOra": {
+ "name": "VelTonnOra",
+ "description": "Vel. Impianto Tonnellate / Ora",
+ "memAddr": "VelTonnOra",
+ "tipoMem": "Real",
+ "index": 0,
+ "size": 0,
+ "func": "AVG",
+ "period": 50,
+ "factor": 1
+ },
+ "VelFruttiMinuto": {
+ "name": "VelFruttiMinuto",
+ "description": "Vel. Impianto Frutti / Minuto",
+ "memAddr": "VelFruttiMinuto",
+ "tipoMem": "Real",
+ "index": 0,
+ "size": 0,
+ "func": "AVG",
+ "period": 50,
+ "factor": 1
+ },
+ "NumPacksOra": {
+ "name": "NumPacksOra",
+ "description": "Numero confezioni / Ora",
+ "memAddr": "NumPacksOra",
+ "tipoMem": "Real",
+ "index": 0,
+ "size": 0,
+ "func": "AVG",
+ "period": 50,
+ "factor": 1
+ },
+ "PercRiemp": {
+ "name": "PercRiemp",
+ "description": "Percentuale riempimento carrelli",
+ "memAddr": "PercRiemp",
+ "tipoMem": "Real",
+ "index": 0,
+ "size": 0,
+ "func": "AVG",
+ "period": 50,
+ "factor": 1
+ },
+ "L1_Batch": {
+ "name": "L1_Batch",
+ "description": "Curr Batch",
+ "tipoMem": "String",
+ "memAddr": "L1_Batch",
+ "index": 0,
+ "size": 50,
+ "func": "POINT",
+ "period": 120,
+ "factor": 1
+ },
+ "L2_Batch": {
+ "name": "L2_Batch",
+ "description": "Curr Batch",
+ "tipoMem": "String",
+ "memAddr": "L2_Batch",
+ "index": 0,
+ "size": 50,
+ "func": "POINT",
+ "period": 120,
+ "factor": 1
+ },
+ "L1_Grower": {
+ "name": "L1_Grower",
+ "description": "Grower Data",
+ "tipoMem": "String",
+ "memAddr": "L1_Grower",
+ "index": 0,
+ "size": 50,
+ "func": "POINT",
+ "period": 120,
+ "factor": 1
+ },
+ "L2_Grower": {
+ "name": "L2_Grower",
+ "description": "Grower Data",
+ "tipoMem": "String",
+ "memAddr": "L2_Grower",
+ "index": 0,
+ "size": 50,
+ "func": "POINT",
+ "period": 120,
+ "factor": 1
+ },
+ "L1_Variety": {
+ "name": "L1_Variety",
+ "description": "Variety Data",
+ "tipoMem": "String",
+ "memAddr": "L1_Variety",
+ "index": 0,
+ "size": 50,
+ "func": "POINT",
+ "period": 120,
+ "factor": 1
+ },
+ "L2_Variety": {
+ "name": "L2_Variety",
+ "description": "Variety Data",
+ "tipoMem": "String",
+ "memAddr": "L2_Variety",
+ "index": 0,
+ "size": 50,
+ "func": "POINT",
+ "period": 120,
+ "factor": 1
+ }
+ }
+}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_ICOEL_003.ini b/IOB-WIN-NEXT/DATA/CONF/GIACO_ICOEL_003.ini
new file mode 100644
index 00000000..249ff7e5
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_ICOEL_003.ini
@@ -0,0 +1,81 @@
+;Configurazione IOB-WIN
+[IOB]
+;Accesso gestione sync DB x sync ICOEL --> MoonPro_ISF --> MoonPro_IS
+CNCTYPE=IcoelDb
+PING_MS_TIMEOUT=500
+;IOB_NAME=GIACO_ICOEL
+
+[MACHINE]
+VENDOR=ICOEL
+MODEL=Impianto Ciliegie Turi
+
+[CNC]
+IP=192.168.137.11
+PORT=1443
+GETPRGNAME=false
+
+[SERVER]
+MPIP=http://192.168.1.14
+MPURL=/MP/IO
+CMDBASE=/IOB/input/
+CMDFLOG=/IOB/flog/
+CMDRAWTRANSF=/IOB/rawTransfJson/
+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
+;BIT0=CONN
+;BIT1=DB60.DBB1
+;BIT2=PZCOUNT.STD.DB700.DBW22
+;BIT3=DB60.DBB3
+;BIT4=DB60.DBB4
+
+
+[BLINK]
+;MAX_COUNTER_BLINK = 30
+MAX_COUNTER_BLINK = 15
+;bit0 = 0
+;bit1 = 0
+;bit2 = 1
+;bit3 = 1
+;bit4 = 1
+;bit5 = 0
+;bit6 = 0
+;bit7 = 0
+BLINK_FILT=0
+;BLINK_FILT=28
+
+[OPTPAR]
+AUTO_CHANGE_ODL=false
+CHANGE_ODL_MODE=TIME
+CHANGE_ODL_HOURS=24
+CHANGE_ODL_IDLE_MIN=5
+PZCOUNT_MODE=Icoel
+DISABLE_PZCOUNT=FALSE
+ENABLE_SEND_PZC_BLOCK=TRUE
+MIN_SEND_PZC_BLOCK=0
+MAX_SEND_PZC_BLOCK=100
+ENABLE_DYN_DATA=TRUE
+FORCE_DYN_DATA=TRUE
+DEM_FACT_DYN_DATA=5
+ENABLE_DATA_FILTER=TRUE
+ENABLE_CLI_RESTART=TRUE
+SyncStateDb=localhost\sqlexpress
+SyncStateUser=egalware
+SyncStatePwd=egalware2022
+SyncStateCTout=
+
+; clock base (da 10ms)
+timerIntMs=20
+
+; conf parametri memoria READ/WRITE
+PARAM_CONF=GIACO_ICOEL_003.json
+
+[BRANCH]
+NAME=master
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_ICOEL_003.json b/IOB-WIN-NEXT/DATA/CONF/GIACO_ICOEL_003.json
new file mode 100644
index 00000000..96401b9a
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_ICOEL_003.json
@@ -0,0 +1,29 @@
+{
+ "mMapWrite": {
+
+ },
+ "mMapRead": {
+ "TotMerceProcTonn": {
+ "name": "TotMerceProcTonn",
+ "description": "Totale merce processata oggi su impianto (Tonn)",
+ "memAddr": "TotMerceProcTonn",
+ "tipoMem": "Real",
+ "index": 0,
+ "size": 0,
+ "func": "MAX",
+ "period": 60,
+ "factor": 1
+ },
+ "TotMerceCaricTonn": {
+ "name": "TotMerceCaricTonn",
+ "description": "Totale merce caricata oggi su impianto (Tonn)",
+ "memAddr": "TotMerceCaricTonn",
+ "tipoMem": "Real",
+ "index": 0,
+ "size": 0,
+ "func": "MAX",
+ "period": 60,
+ "factor": 1
+ }
+ }
+}
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_NWSE.ini b/IOB-WIN-NEXT/DATA/CONF/GIACO_NWSE.ini
new file mode 100644
index 00000000..a05d14d4
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_NWSE.ini
@@ -0,0 +1,71 @@
+;Configurazione IOB-WIN
+[IOB]
+;Macchina pulitrice RobotService x Donati
+CNCTYPE=SIEMENS_NWSE
+PING_MS_TIMEOUT=500
+
+[MACHINE]
+VENDOR=NWS
+MODEL=Impianto Turi
+
+[CNC]
+IP=192.168.19.10
+CPUTYPE=S71200
+RACK=0
+SLOT=0
+
+[SERVER]
+MPIP=http://192.168.1.14
+MPURL=/MP/IO
+CMDBASE=/IOB/input/
+CMDFLOG=/IOB/flog/
+CMDALIVE=/IOB
+CMDENABLED=/IOB/enabled/
+CMDADV1=?valore=
+CMDREBO=/sendReboot.aspx?idxMacchina=
+
+[MEMORY]
+ADDR_READ=DB100.DBB0
+ADDR_WRITE=DB101.DBB0
+SIZE_READ=54
+SIZE_WRITE=8
+
+
+[BLINK]
+;MAX_COUNTER_BLINK = 30
+MAX_COUNTER_BLINK = 15
+;bit0 = 0
+;bit1 = 0
+;bit2 = 1
+;bit3 = 1
+;bit4 = 1
+;bit5 = 0
+;bit6 = 0
+;bit7 = 0
+BLINK_FILT=0
+;BLINK_FILT=28
+
+[OPTPAR]
+;PZCOUNT_MODE=STD.[PAR/MEM].info|BIT.indice
+PZCOUNT_MODE=STD.DB15.DBDW2
+DISABLE_PZCOUNT=TRUE
+ENABLE_SEND_PZC_BLOCK=TRUE
+MIN_SEND_PZC_BLOCK=0
+MAX_SEND_PZC_BLOCK=100
+; gestione custom timer
+timerIntMs=30
+; GEST DATI DYN
+ENABLE_DYN_DATA=TRUE
+FORCE_DYN_DATA=TRUE
+; gestione scrittura string/char[]: true = string / false = char[]
+WRITE_PRE=TRUE
+; gestione emergenza forzata (ignora valore letto, mette sempre ARMED)
+EMERGENCY_BYPASS=true
+
+; conf parametri memoria READ/WRITE
+PARAM_CONF=GIACO_NWSE.json
+; conf aree allarme
+ALARM_CONF=GIACO_NWSE_alarm.json
+
+[BRANCH]
+NAME=master
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_NWSE.json b/IOB-WIN-NEXT/DATA/CONF/GIACO_NWSE.json
new file mode 100644
index 00000000..4c8c25cf
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_NWSE.json
@@ -0,0 +1,212 @@
+{
+ "mMapWrite": {
+ "resetCountAcqua": {
+ "name": "resetCountAcqua",
+ "description": "Reset contatori acqua OSMOSI / DEPURAZIONE",
+ "tipoMem": "Int",
+ "memAddr": "DB101.DBB0",
+ "index": 0,
+ "size": 2
+ }
+ },
+ "mMapRead": {
+ "CondOsmosi": {
+ "name": "CondOsmosi",
+ "description": "Conducib. H2O Osmosi",
+ "memAddr": "DB100.DBB40",
+ "tipoMem": "Int",
+ "index": 40,
+ "size": 2,
+ "func": "MAX",
+ "period": 60,
+ "factor": 1
+ },
+ "VolOsmosi": {
+ "name": "VolOsmosi",
+ "description": "Volume H2O Osmosi mc",
+ "memAddr": "DB100.DBB42",
+ "tipoMem": "Int",
+ "index": 40,
+ "size": 2,
+ "func": "MAX",
+ "period": 60,
+ "factor": 1
+ },
+ "StatoOsmosi": {
+ "name": "StatoOsmosi",
+ "description": "Stato Osmosi Inversa",
+ "memAddr": "DB100.DBB20",
+ "tipoMem": "BitMap",
+ "index": 20,
+ "size": 2,
+ "func": "MAX",
+ "period": 60,
+ "factor": 1,
+ "decodeMap": [
+ "Impianto in servizio"
+ ]
+ },
+ "TorbDepuraz": {
+ "name": "TorbDepuraz",
+ "description": "Torb. H2O Depurazione",
+ "memAddr": "DB100.DBB44",
+ "tipoMem": "Int",
+ "index": 44,
+ "size": 2,
+ "func": "MAX",
+ "period": 60,
+ "factor": 1
+ },
+ "VolDepuraz": {
+ "name": "VolDepuraz",
+ "description": "Volume acqua Depurazione mc",
+ "memAddr": "DB100.DBB46",
+ "tipoMem": "Int",
+ "index": 40,
+ "size": 2,
+ "func": "MAX",
+ "period": 60,
+ "factor": 1
+ },
+ "StatoDepurazione": {
+ "name": "StatoDepurazione",
+ "description": "Stato Depurazione",
+ "memAddr": "DB100.DBB22",
+ "tipoMem": "BitMap",
+ "index": 22,
+ "size": 2,
+ "func": "MAX",
+ "period": 60,
+ "factor": 1,
+ "decodeMap": [
+ "Basso Livello",
+ "Alto Livello"
+ ]
+ },
+ "TorbFiltri": {
+ "name": "TorbFiltri",
+ "description": "Torb. H2O Filtri",
+ "memAddr": "DB100.DBB48",
+ "tipoMem": "Int",
+ "index": 44,
+ "size": 2,
+ "func": "MAX",
+ "period": 60,
+ "factor": 1
+ },
+ "StatoFiltro01": {
+ "name": "StatoFiltro01",
+ "description": "Stato Filtro 1",
+ "memAddr": "DB100.DBB24",
+ "tipoMem": "BitMap",
+ "index": 24,
+ "size": 2,
+ "func": "MAX",
+ "period": 60,
+ "factor": 1,
+ "decodeMap": [
+ "Spazzola in salita",
+ "Spazzola in discesa",
+ "Valvola scarico Chiusa",
+ "Valvola scarico Aperta",
+ "Impianto in Servizio",
+ "Impianto in Lavaggio"
+ ]
+ },
+ "StatoFiltro02": {
+ "name": "StatoFiltro02",
+ "description": "Stato Filtro 2",
+ "memAddr": "DB100.DBB26",
+ "tipoMem": "BitMap",
+ "index": 26,
+ "size": 2,
+ "func": "MAX",
+ "period": 60,
+ "factor": 1,
+ "decodeMap": [
+ "Spazzola in salita",
+ "Spazzola in discesa",
+ "Valvola scarico Chiusa",
+ "Valvola scarico Aperta",
+ "Impianto in Servizio",
+ "Impianto in Lavaggio"
+ ]
+ },
+ "StatoFiltro03": {
+ "name": "StatoFiltro03",
+ "description": "Stato Filtro 3",
+ "memAddr": "DB100.DBB28",
+ "tipoMem": "BitMap",
+ "index": 28,
+ "size": 2,
+ "func": "MAX",
+ "period": 60,
+ "factor": 1,
+ "decodeMap": [
+ "Spazzola in salita",
+ "Spazzola in discesa",
+ "Valvola scarico Chiusa",
+ "Valvola scarico Aperta",
+ "Impianto in Servizio",
+ "Impianto in Lavaggio"
+ ]
+ },
+ "StatoFiltro04": {
+ "name": "StatoFiltro04",
+ "description": "Stato Filtro 4",
+ "memAddr": "DB100.DBB30",
+ "tipoMem": "BitMap",
+ "index": 30,
+ "size": 2,
+ "func": "MAX",
+ "period": 60,
+ "factor": 1,
+ "decodeMap": [
+ "Spazzola in salita",
+ "Spazzola in discesa",
+ "Valvola scarico Chiusa",
+ "Valvola scarico Aperta",
+ "Impianto in Servizio",
+ "Impianto in Lavaggio"
+ ]
+ },
+ "StatoFiltro05": {
+ "name": "StatoFiltro05",
+ "description": "Stato Filtro 5",
+ "memAddr": "DB100.DBB32",
+ "tipoMem": "BitMap",
+ "index": 32,
+ "size": 2,
+ "func": "MAX",
+ "period": 60,
+ "factor": 1,
+ "decodeMap": [
+ "Spazzola in salita",
+ "Spazzola in discesa",
+ "Valvola scarico Chiusa",
+ "Valvola scarico Aperta",
+ "Impianto in Servizio",
+ "Impianto in Lavaggio"
+ ]
+ },
+ "StatoFiltro06": {
+ "name": "StatoFiltro06",
+ "description": "Stato Filtro 6",
+ "memAddr": "DB100.DBB34",
+ "tipoMem": "BitMap",
+ "index": 34,
+ "size": 2,
+ "func": "MAX",
+ "period": 60,
+ "factor": 1,
+ "decodeMap": [
+ "Spazzola in salita",
+ "Spazzola in discesa",
+ "Valvola scarico Chiusa",
+ "Valvola scarico Aperta",
+ "Impianto in Servizio",
+ "Impianto in Lavaggio"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_NWSE_alarm.json b/IOB-WIN-NEXT/DATA/CONF/GIACO_NWSE_alarm.json
new file mode 100644
index 00000000..d8226c2d
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_NWSE_alarm.json
@@ -0,0 +1,202 @@
+[
+ {
+ "description": "Allarmi Impianto Osmosi",
+ "tipoMem": "Boolean",
+ "memAddr": "DB100.DBB0",
+ "index": 0,
+ "size": 2,
+ "messages": [
+ "Avaria pompa ingresso",
+ "Avaria pompa alta pressione",
+ "Livello basso vasca osmosi",
+ "Livello basso vasca acqua grezza",
+ "Impianto in allarme",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "Allarme comunicazione con Gateway"
+ ]
+ },
+ {
+ "description": "Allarmi Impianto Depurazione",
+ "tipoMem": "Boolean",
+ "memAddr": "DB100.DBB2",
+ "index": 2,
+ "size": 2,
+ "messages": [
+ "Avaria pompa 1",
+ "Avaria pompa 2",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "Allarme comunicazione con Gateway"
+ ]
+ },
+ {
+ "description": "Allarmi Filtro 1",
+ "tipoMem": "Boolean",
+ "memAddr": "DB100.DBB4",
+ "index": 4,
+ "size": 2,
+ "messages": [
+ "Avaria pompa",
+ "Livello basso vasca",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##"
+ ]
+ },
+ {
+ "description": "Allarmi Filtro 2",
+ "tipoMem": "Boolean",
+ "memAddr": "DB100.DBB6",
+ "index": 6,
+ "size": 2,
+ "messages": [
+ "Avaria pompa",
+ "Livello basso vasca",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##"
+ ]
+ },
+ {
+ "description": "Allarmi Filtro 3",
+ "tipoMem": "Boolean",
+ "memAddr": "DB100.DBB8",
+ "index": 8,
+ "size": 2,
+ "messages": [
+ "Avaria pompa",
+ "Livello basso vasca",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##"
+ ]
+ },
+ {
+ "description": "Allarmi Filtro 4",
+ "tipoMem": "Boolean",
+ "memAddr": "DB100.DBB10",
+ "index": 10,
+ "size": 2,
+ "messages": [
+ "Avaria pompa",
+ "Livello basso vasca",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##"
+ ]
+ },
+ {
+ "description": "Allarmi Filtro 5",
+ "tipoMem": "Boolean",
+ "memAddr": "DB100.DBB12",
+ "index": 12,
+ "size": 2,
+ "messages": [
+ "Avaria pompa",
+ "Livello basso vasca",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##"
+ ]
+ },
+ {
+ "description": "Allarmi Filtro 6",
+ "tipoMem": "Boolean",
+ "memAddr": "DB100.DBB14",
+ "index": 14,
+ "size": 2,
+ "messages": [
+ "Avaria pompa",
+ "Livello basso vasca",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##",
+ "##"
+ ]
+ }
+]
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/MAIN.ini b/IOB-WIN-NEXT/DATA/CONF/MAIN.ini
index cb0aa7c3..54d5fe95 100644
--- a/IOB-WIN-NEXT/DATA/CONF/MAIN.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/MAIN.ini
@@ -19,8 +19,7 @@ NAME=master
;MPIP=192.168.1.14
; Server Steamware
-MPIP=192.168.1.14
-;MPIP=10.74.82.218
+MPIP=10.74.82.218
MPURL=/MP/IO
CMDREBO=/IOB/sendRebootGateway?GWIP=
CMDIOB2CALL=/IOB/getIob2call?GWIP=
@@ -29,56 +28,16 @@ CMDIOB2CALL=/IOB/getIob2call?GWIP=
CLI_INST=SteamWareSim
[IOB]
-;--- TEST sul campo
-;STARTLIST=VL24
-;STARTLIST=3018,3019
-;STARTLIST=WPS
-
-;SAET TEMPRA
-;STARTLIST=VL20
-
-;COMUR DENTA
-;STARTLIST=VL21
-
-;LASCO
-;STARTLIST=VL22
-
-;PRESSOIL CEI
-;STARTLIST=VL23
-
-;SAET FORNO
-;STARTLIST=VL24
-
-;AUTOMAZIONE INGENIA
-;STARTLIST=VL25
-
-; INTERCLAYS FORNO
-;STARTLIST=INTERCL_01
-
-; INTERCLAYS MISCELA
-;STARTLIST=INTERCL_02
-
-; IMI REMOSA
-;STARTLIST=IMI_50
-
+;--- TEST sul campo
; SIMULAZIONE verso server ufficio
;STARTLIST=SIMUL_01,SIMUL_02,SIMUL_03,SIMUL_04
-;STARTLIST=TEST
-;STARTLIST=SIM_DP_01
-;STARTLIST=SIMUL_01
-;STARTLIST=1032
-;STARTLIST=PIZ03
-;STARTLIST=PIZ04
-;STARTLIST=OPC_UA
-;STARTLIST=FOV062
-;STARTLIST=FP_TR2
-;STARTLIST=SIM_PIZ03
-;STARTLIST=MECART_80
-;STARTLIST=PING
;STARTLIST=PIZ09
;STARTLIST=VL25
;STARTLIST=SIMUL_03
-;STARTLIST=GIACO_CEDAX_01
-STARTLIST=GIACO_ICOEL_002
+;STARTLIST=GIACO_CEDAX_001
+;STARTLIST=GIACO_ICOEL_002
+;STARTLIST=GIACO_CENTERFRIGO
+;STARTLIST=GIACO_NWSE
+STARTLIST=SIMUL_01
MAXCNC=10
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/SIMUL_01.ini b/IOB-WIN-NEXT/DATA/CONF/SIMUL_01.ini
index 67eae433..187454cf 100644
--- a/IOB-WIN-NEXT/DATA/CONF/SIMUL_01.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/SIMUL_01.ini
@@ -43,10 +43,10 @@ MIN_SEND_PZC_BLOCK=0
MAX_SEND_PZC_BLOCK=100
; gestione cambio ODL automatico (minuti minimi durata)
MIN_DURATA_ODL=240
-; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE in ms, default 1 secondo)
-PER_BASE=10100
+; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE in ms, default 10 secondi)
+PER_BASE=10100
SIM_PZCNT=5|1
-SIM_ALARM=1000|20
+SIM_ALARM=100|10
SIM_MANU=50|6
; indica gestione e simulazione bit 5 --> slow
SIM_SLOW=3600|20
diff --git a/IOB-WIN-NEXT/DATA/CONF/SIMUL_02.ini b/IOB-WIN-NEXT/DATA/CONF/SIMUL_02.ini
index bca734ed..1d29f7ce 100644
--- a/IOB-WIN-NEXT/DATA/CONF/SIMUL_02.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/SIMUL_02.ini
@@ -37,7 +37,7 @@ CHANGE_ODL_IDLE_MIN=0
;PZCOUNT_MODE=STD.[PAR/MEM].info|BIT.indice
PZCOUNT_MODE=BIT
ENABLE_PZ_RESET=TRUE
-; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE in ms, default 1 secondo)
+; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE in ms, default 10 secondi)
PER_BASE=9500
SIM_PZCNT=8|1
SIM_ALARM=900|15
diff --git a/IOB-WIN-NEXT/DATA/CONF/SIMUL_03.ini b/IOB-WIN-NEXT/DATA/CONF/SIMUL_03.ini
index 08296d7e..bf726ca2 100644
--- a/IOB-WIN-NEXT/DATA/CONF/SIMUL_03.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/SIMUL_03.ini
@@ -38,7 +38,7 @@ CHANGE_ODL_IDLE_MIN=0
;PZCOUNT_MODE=STD.[PAR/MEM].info|BIT.indice
PZCOUNT_MODE=BIT
ENABLE_PZ_RESET=TRUE
-; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE, default 1 secondo)
+; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE in ms, default 10 secondi)
PER_BASE=10400
SIM_PZCNT=15|1
SIM_ALARM=1000|20
diff --git a/IOB-WIN-NEXT/DATA/CONF/SIMUL_04.ini b/IOB-WIN-NEXT/DATA/CONF/SIMUL_04.ini
index 403966e7..9cab64cb 100644
--- a/IOB-WIN-NEXT/DATA/CONF/SIMUL_04.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/SIMUL_04.ini
@@ -37,7 +37,7 @@ CHANGE_ODL_IDLE_MIN=0
;PZCOUNT_MODE=STD.[PAR/MEM].info|BIT.indice
PZCOUNT_MODE=BIT
ENABLE_PZ_RESET=TRUE
-; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE, default 1 secondo)
+; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE in ms, default 10 secondi)
PER_BASE=10300
SIM_PZCNT=13|1
SIM_ALARM=1000|20
diff --git a/IOB-WIN-NEXT/DATA/CONF/SIMUL_05.ini b/IOB-WIN-NEXT/DATA/CONF/SIMUL_05.ini
index 050dbbc5..de3910c9 100644
--- a/IOB-WIN-NEXT/DATA/CONF/SIMUL_05.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/SIMUL_05.ini
@@ -37,7 +37,7 @@ CHANGE_ODL_IDLE_MIN=0
;PZCOUNT_MODE=STD.[PAR/MEM].info|BIT.indice
PZCOUNT_MODE=BIT
ENABLE_PZ_RESET=TRUE
-; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE, default 1 secondo)
+; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE in ms, default 10 secondi)
PER_BASE=10200
SIM_PZCNT=13|1
SIM_ALARM=1000|20
diff --git a/IOB-WIN-NEXT/DATA/CONF/SIMUL_06.ini b/IOB-WIN-NEXT/DATA/CONF/SIMUL_06.ini
index 4e62781a..080f15ea 100644
--- a/IOB-WIN-NEXT/DATA/CONF/SIMUL_06.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/SIMUL_06.ini
@@ -37,7 +37,7 @@ CHANGE_ODL_IDLE_MIN=0
;PZCOUNT_MODE=STD.[PAR/MEM].info|BIT.indice
PZCOUNT_MODE=BIT
ENABLE_PZ_RESET=TRUE
-; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE, default 1 secondo)
+; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE in ms, default 10 secondi)
PER_BASE=9600
SIM_PZCNT=13|1
SIM_ALARM=1000|20
diff --git a/IOB-WIN-NEXT/DATA/CONF/SIMUL_07.ini b/IOB-WIN-NEXT/DATA/CONF/SIMUL_07.ini
index 344cbac7..d1d2e317 100644
--- a/IOB-WIN-NEXT/DATA/CONF/SIMUL_07.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/SIMUL_07.ini
@@ -37,7 +37,7 @@ CHANGE_ODL_IDLE_MIN=0
;PZCOUNT_MODE=STD.[PAR/MEM].info|BIT.indice
PZCOUNT_MODE=BIT
ENABLE_PZ_RESET=TRUE
-; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE, default 1 secondo)
+; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE in ms, default 10 secondi)
PER_BASE=9900
SIM_PZCNT=13|1
SIM_ALARM=200|20
diff --git a/IOB-WIN-NEXT/DATA/CONF/SIMUL_08.ini b/IOB-WIN-NEXT/DATA/CONF/SIMUL_08.ini
index 6acfc014..2050389c 100644
--- a/IOB-WIN-NEXT/DATA/CONF/SIMUL_08.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/SIMUL_08.ini
@@ -37,7 +37,7 @@ CHANGE_ODL_IDLE_MIN=10
;PZCOUNT_MODE=STD.[PAR/MEM].info|BIT.indice
PZCOUNT_MODE=BIT
ENABLE_PZ_RESET=TRUE
-; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE, default 1 secondo)
+; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE in ms, default 10 secondi)
PER_BASE=9800
SIM_PZCNT=13|1
SIM_ALARM=200|10
diff --git a/IOB-WIN-NEXT/DATA/CONF/SIM_DP_01.ini b/IOB-WIN-NEXT/DATA/CONF/SIM_DP_01.ini
index e94ec473..ed602c4d 100644
--- a/IOB-WIN-NEXT/DATA/CONF/SIM_DP_01.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/SIM_DP_01.ini
@@ -44,7 +44,7 @@ ENABLE_SEND_PZC_BLOCK=TRUE
MIN_SEND_PZC_BLOCK=0
MAX_SEND_PZC_BLOCK=100
MIN_DURATA_ODL=240
-; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE in ms, default 1 secondo)
+; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE in ms, default 10 secondi)
PER_BASE=10500
SIM_PZCNT=10|3
SIM_ALARM=1000|20
diff --git a/IOB-WIN-NEXT/DATA/CONF/SIM_DP_02.ini b/IOB-WIN-NEXT/DATA/CONF/SIM_DP_02.ini
index ed26ab45..3b8d3b95 100644
--- a/IOB-WIN-NEXT/DATA/CONF/SIM_DP_02.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/SIM_DP_02.ini
@@ -44,7 +44,7 @@ ENABLE_SEND_PZC_BLOCK=TRUE
MIN_SEND_PZC_BLOCK=0
MAX_SEND_PZC_BLOCK=100
MIN_DURATA_ODL=240
-; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE in ms, default 1 secondo)
+; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE in ms, default 10 secondi)
PER_BASE=10400
SIM_PZCNT=10|2
SIM_ALARM=1000|20
diff --git a/IOB-WIN-NEXT/DATA/CONF/SIM_PIZ03.ini b/IOB-WIN-NEXT/DATA/CONF/SIM_PIZ03.ini
index 370e9c26..769edb89 100644
--- a/IOB-WIN-NEXT/DATA/CONF/SIM_PIZ03.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/SIM_PIZ03.ini
@@ -38,7 +38,7 @@ DISABLE_SIM_STATUS=true
;PZCOUNT_MODE=STD.[PAR/MEM].info|BIT.indice
PZCOUNT_MODE=BIT
ENABLE_PZ_RESET=TRUE
-; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE, default 1 secondo)
+; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE in ms, default 10 secondi)
PER_BASE=9800
SIM_PZCNT=13|1
SIM_ALARM=200|10
diff --git a/IOB-WIN-NEXT/DATA/CONF/SIM_PIZ04.ini b/IOB-WIN-NEXT/DATA/CONF/SIM_PIZ04.ini
index 370e9c26..769edb89 100644
--- a/IOB-WIN-NEXT/DATA/CONF/SIM_PIZ04.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/SIM_PIZ04.ini
@@ -38,7 +38,7 @@ DISABLE_SIM_STATUS=true
;PZCOUNT_MODE=STD.[PAR/MEM].info|BIT.indice
PZCOUNT_MODE=BIT
ENABLE_PZ_RESET=TRUE
-; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE, default 1 secondo)
+; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE in ms, default 10 secondi)
PER_BASE=9800
SIM_PZCNT=13|1
SIM_ALARM=200|10
diff --git a/IOB-WIN-NEXT/DATA/CONF/SIM_PIZ05.ini b/IOB-WIN-NEXT/DATA/CONF/SIM_PIZ05.ini
index 370e9c26..769edb89 100644
--- a/IOB-WIN-NEXT/DATA/CONF/SIM_PIZ05.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/SIM_PIZ05.ini
@@ -38,7 +38,7 @@ DISABLE_SIM_STATUS=true
;PZCOUNT_MODE=STD.[PAR/MEM].info|BIT.indice
PZCOUNT_MODE=BIT
ENABLE_PZ_RESET=TRUE
-; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE, default 1 secondo)
+; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE in ms, default 10 secondi)
PER_BASE=9800
SIM_PZCNT=13|1
SIM_ALARM=200|10
diff --git a/IOB-WIN-NEXT/DATA/CONF/SIM_PIZ08.ini b/IOB-WIN-NEXT/DATA/CONF/SIM_PIZ08.ini
index 370e9c26..769edb89 100644
--- a/IOB-WIN-NEXT/DATA/CONF/SIM_PIZ08.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/SIM_PIZ08.ini
@@ -38,7 +38,7 @@ DISABLE_SIM_STATUS=true
;PZCOUNT_MODE=STD.[PAR/MEM].info|BIT.indice
PZCOUNT_MODE=BIT
ENABLE_PZ_RESET=TRUE
-; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE, default 1 secondo)
+; per il simulatore: 50|1 = WAIT 50, DURATION 1 con riferimento al PERIODO base (PER_BASE in ms, default 10 secondi)
PER_BASE=9800
SIM_PZCNT=13|1
SIM_ALARM=200|10
diff --git a/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj b/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj
index e5807f3c..7c8fcee7 100644
--- a/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj
+++ b/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj
@@ -1,5 +1,6 @@

+
@@ -87,23 +88,32 @@
..\packages\EasyModbusTCP.5.6.0\lib\net40\EasyModbus.dll
- ..\packages\EgwProxy.Icoel.3.6.2205.2012\lib\EgwProxy.Icoel.dll
+ ..\packages\EgwProxy.Icoel.3.6.2206.2811\lib\EgwProxy.Icoel.dll
+
+
+ ..\packages\EgwProxy.Icoel.3.6.2206.2811\lib\EgwProxy.Icoel.DataLayer.dll
- ..\packages\EgwProxy.MultiCncLib.3.6.2205.2012\lib\EgwProxy.MultiCncLib.dll
+ ..\packages\EgwProxy.MultiCncLib.3.6.2205.2319\lib\EgwProxy.MultiCncLib.dll
- ..\packages\EgwProxy.OsaiCncLib.3.6.2205.2012\lib\EgwProxy.OsaiCncLib.dll
+ ..\packages\EgwProxy.OsaiCncLib.3.6.2205.2015\lib\EgwProxy.OsaiCncLib.dll
- ..\packages\EgwProxy.OsaiCncLib.3.6.2205.2012\lib\EgwProxy.OsaiCncLib.XmlSerializers.dll
+ ..\packages\EgwProxy.OsaiCncLib.3.6.2205.2015\lib\EgwProxy.OsaiCncLib.XmlSerializers.dll
+
+
+ ..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll
+
+
+ ..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll
False
ExtLib\krcc.dll
-
- ..\packages\MapoSDK.6.14.2204.2616\lib\MapoSDK.dll
+
+ ..\packages\MapoSDK.6.14.2206.2718\lib\MapoSDK.dll
..\packages\MathNet.Numerics.4.15.0\lib\net461\MathNet.Numerics.dll
@@ -144,6 +154,7 @@
..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll
+
@@ -196,6 +207,7 @@
+
@@ -203,6 +215,7 @@
+
@@ -272,6 +285,57 @@
Always
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ PreserveNewest
+
@@ -310,6 +374,21 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
Always
@@ -445,9 +524,6 @@
Always
-
- Always
-
Always
@@ -493,21 +569,12 @@
Always
-
- Always
-
-
- Always
-
Always
Always
-
- Always
-
Always
@@ -911,9 +978,12 @@
+
+
+
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/IobConfiguration.cs b/IOB-WIN-NEXT/IobConfiguration.cs
index 98af38be..b29b8739 100644
--- a/IOB-WIN-NEXT/IobConfiguration.cs
+++ b/IOB-WIN-NEXT/IobConfiguration.cs
@@ -147,7 +147,7 @@ namespace IOB_WIN_NEXT
/// Comando x reboot
/// Comando x check data avvio ODL
/// Comando x forzare split ODL
- public serverMapo(string MPIP_, string MPURL_ = "/MP/IO", string CMDBASE_ = "/IOB/input/", string CMDFLOG_ = "/IOB/flog/", string CMDULOG_ = "/IOB/ulog/", string CMDALIVE_ = "IOB", string CMDENABLED_ = "/IOB/enabled/", string CMDREBO_ = "/sendReboot.aspx?idxMacchina=", string CMD_ODL_STARTED_ = "/IOB/getCurrOdlStart/", string CLI_INST_ = "SteamWare", string CMD_FORCLE_SPLIT_ODL_ = "/IOB/forceSplitOdlFull/", string CMD_IDLE_TIME_ = "/IOB/getIdlePeriod/")
+ public serverMapo(string MPIP_, string MPURL_ = "/MP/IO", string CMDBASE_ = "/IOB/input/", string CMDFLOG_ = "/IOB/flog/", string CMDULOG_ = "/IOB/ulog/", string CMDALIVE_ = "IOB", string CMDENABLED_ = "/IOB/enabled/", string CMDREBO_ = "/sendReboot.aspx?idxMacchina=", string CMD_ODL_STARTED_ = "/IOB/getCurrOdlStart/", string CLI_INST_ = "SteamWare", string CMD_FORCLE_SPLIT_ODL_ = "/IOB/forceSplitOdlFull/", string CMD_IDLE_TIME_ = "/IOB/getIdlePeriod/", string CMDRAWTRANSFJSON_ = "/IOB/rawTransfJson/")
{
if (!string.IsNullOrEmpty(MPIP_))
{
@@ -160,6 +160,7 @@ namespace IOB_WIN_NEXT
MPURL = MPURL_;
CMDBASE = CMDBASE_;
CMDFLOG = CMDFLOG_;
+ CMDRAWTRANSF_JSON = CMDRAWTRANSFJSON_;
CMDULOG = CMDULOG_;
if (!string.IsNullOrEmpty(CMDBASE_))
{
@@ -241,6 +242,11 @@ namespace IOB_WIN_NEXT
///
public string CMDULOG { get; set; } = "";
+ ///
+ /// comando base x Raw Transf LOG - salvataggio valori generici in modalità JSON payload come lista
+ ///
+ public string CMDRAWTRANSF_JSON { get; set; } = "";
+
///
/// comando base x USER LOG - salvataggio parametri extra sistema MAPO in modalità JSON payload come lista
///
diff --git a/IOB-WIN-NEXT/IobFanuc.cs b/IOB-WIN-NEXT/IobFanuc.cs
index 8a171a92..d3657864 100644
--- a/IOB-WIN-NEXT/IobFanuc.cs
+++ b/IOB-WIN-NEXT/IobFanuc.cs
@@ -212,7 +212,7 @@ namespace IOB_WIN_NEXT
}
catch (Exception exc)
{
- lgError(exc, "Errore in contapezzi FANUC");
+ lgError(exc, "Errore in contapezzi FANUC 01");
}
}
// finisco INIT ADAPTER
@@ -587,6 +587,23 @@ namespace IOB_WIN_NEXT
// salvo valore
answ = outputVal.ToString();
}
+ // 2022.05.23 gestione MACRO da testare (Jetco)
+ else if (memAddr.StartsWith("MACRO."))
+ {
+ lgTrace($"Decodifica memoria MACRO | memAddr: {memAddr}");
+ // recupero parametro...
+ int.TryParse(memAddr.Replace("MACRO.", ""), out cntAddr);
+ // processo parametro
+ stopwatch.Restart();
+ double macroVal = 0;
+ FANUC_ref.F_Read_macro(cntAddr, ref macroVal);
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, string.Format("R{0}-MACRO", 5), stopwatch.ElapsedTicks);
+ }
+ // salvo valore
+ answ = macroVal.ToString();
+ }
// altrimenti se legge da area memoria specifica leggo da li... formto tipo STD.D.1604.DW
else
{
@@ -1012,7 +1029,6 @@ namespace IOB_WIN_NEXT
{
cntAddr = 6711;
}
-
// processo parametro contapezzi (lavorati)
stopwatch.Restart();
FANUC_ref.F_RW_Param_Integer(false, cntAddr, 3, ref outputVal);
@@ -1020,22 +1036,38 @@ namespace IOB_WIN_NEXT
{
TimingData.addResult(cIobConf.codIOB, string.Format("R{0}-PAR", 4), stopwatch.ElapsedTicks);
}
-
// salvo ultimo conteggio rilevato
int newVal = -1;
Int32.TryParse(outputVal.ToString(), out newVal);
contapezziPLC = newVal > -1 ? newVal : contapezziPLC;
}
+ // 2022.05.23 gestione MACRO da testare (Jetco)
+ else if (memAddr.StartsWith("MACRO."))
+ {
+ lgTrace($"Decodifica memoria MACRO | memAddr: {memAddr}");
+ // recupero parametro...
+ int.TryParse(memAddr.Replace("MACRO.", ""), out cntAddr);
+ // processo parametro
+ stopwatch.Restart();
+ double macroVal = 0;
+ FANUC_ref.F_Read_macro(cntAddr, ref macroVal);
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, string.Format("R{0}-MACRO", 5), stopwatch.ElapsedTicks);
+ }
+ // salvo ultimo conteggio rilevato
+ int newVal = -1;
+ Int32.TryParse($"{macroVal}", out newVal);
+ contapezziPLC = newVal > -1 ? newVal : contapezziPLC;
+ }
// altrimenti se legge da area memoria specifica leggo da li... formto tipo STD.D.1604.DW
else
{
memAddressFanuc areaCounter = new memAddressFanuc(memAddr);
-
if (isVerboseLog)
{
lgInfo("[0] area memoria: {0}.{1}.{2}", areaCounter.mType, areaCounter.mPos, areaCounter.vType);
}
-
// leggo!
stopwatch.Restart();
// switch x tipo dati --> tipo lettura... e salvo ultimo conteggio rilevato
@@ -1076,7 +1108,6 @@ namespace IOB_WIN_NEXT
{
TimingData.addResult(cIobConf.codIOB, string.Format("R-{0}.{1}.{2}", areaCounter.mType, areaCounter.mPos, areaCounter.vType), stopwatch.ElapsedTicks);
}
-
// salvo...
int newVal = -1;
Int32.TryParse(outputVal.ToString(), out newVal);
@@ -1093,7 +1124,7 @@ namespace IOB_WIN_NEXT
}
catch (Exception exc)
{
- lgError(exc, "Errore in contapezzi FANUC");
+ lgError(exc, "Errore in contapezzi FANUC 02");
connectionOk = false;
}
}
diff --git a/IOB-WIN-NEXT/IobGeneric.cs b/IOB-WIN-NEXT/IobGeneric.cs
index 743edaa8..a662ab24 100644
--- a/IOB-WIN-NEXT/IobGeneric.cs
+++ b/IOB-WIN-NEXT/IobGeneric.cs
@@ -22,173 +22,6 @@ namespace IOB_WIN_NEXT
{
public class IobGeneric
{
- #region Protected Fields
-
- ///
- /// wrapper di log
- ///
- protected static Logger lg;
-
- protected bool _connOk = false;
-
- ///
- /// valore booleano di check se sia in fase di COMUNICAZIONE ATTIVA con il PLC/NC
- ///
- protected bool adpCommAct;
-
- ///
- /// porta x adapter (x restart)
- ///
- protected int adpPortNum;
-
- ///
- /// DataOra ultimo avvio adapter x watchdog
- ///
- protected DateTime adpStartRun;
-
- ///
- /// Vettore 32 BIT valori in ingresso al filtro
- ///
- protected int B_input;
-
- ///
- /// Vettore 32 BIT valori in uscita dal filtro
- ///
- protected int B_output;
-
- ///
- /// Vettore 32 BIT valori precedenti
- ///
- protected int B_previous;
-
- ///
- /// Num errori check alive
- ///
- protected int currAliveErrors = 0;
-
- ///
- /// Variabile numero errori vari (in lettura) --> se supera soglia maxErroriCheck --> disconnette
- ///
- protected int numErroriCheck = 0;
-
- ///
- /// Soglia massima errori priam di disconnesisone automatica
- ///
- protected int maxErroriCheck = 100;
-
- ///
- /// Dizionario valori impostati x produzione
- ///
- protected Dictionary currProdData = new Dictionary();
-
- ///
- /// num corrente errori read PLC
- ///
- protected int currReadErrors = 0;
-
- ///
- /// num errori send
- ///
- protected int currSendErrors = 0;
-
- ///
- /// Periodo wathdog di default (2 sec se non specificato)
- ///
- protected int watchDogPeriod = 2;
-
- ///
- /// Array dei contatori x segnali blinking
- ///
- protected int[] i_counters;
-
- ///
- /// Indica impianto IN SETUP (fino a quando SMETTE di esserlo...)
- ///
- protected bool inSetup = false;
-
- ///
- /// ultimo tentativo connessione...
- ///
- protected DateTime lastConnectTry;
-
- ///
- /// Dizionario ULTIMI valori impostati x produzione
- ///
- protected Dictionary lastProdData = new Dictionary();
-
- ///
- /// Ultimo invio contapezzi (x invio delayed)
- ///
- protected DateTime lastPzCountSend;
-
-
- ///
- /// Ultimo LOG registrazione avvio (x ridurre log notturni...)
- ///
- protected DateTime lastLogStartup = DateTime.Today.AddHours(-1);
-
- ///
- /// Veto per registrazione completa log di startup (minuti)
- ///
- protected int vetoLogStartupDuration = 60;
-
- ///
- /// Dizionario ultimi valori (double) delle TSVC
- ///
- protected Dictionary LastTSVC = new Dictionary();
-
- ///
- /// Ultima registrazione warning x ODL mancante (x scrivere solo ogni 15 secondi)
- ///
- protected DateTime lastWarnODL;
-
- ///
- /// Num massimo di errori in funzionalità check alive
- ///
- protected int maxAliveErrors = utils.CRI("maxAliveErrors");
-
- ///
- /// Num massimo di errori di rete read (dal PLC)
- ///
- protected int maxReadErrors = utils.CRI("maxReadErrors");
-
- ///
- /// Num massimodi errori di rete send al server
- ///
- protected int maxSendErrors = utils.CRI("maxSendErrors");
-
- ///
- /// indica se serva refresh parametri e quindi PLC...
- ///
- protected bool needRefresh = true;
-
- ///
- /// Form chiamante
- ///
- protected AdapterForm parentForm;
-
- ///
- /// Timeout x ping al server
- ///
- protected int pingServerMsTimeout = utils.CRI("pingMsTimeout");
-
- ///
- /// Ritardo minimo x invio contapezzi
- ///
- protected int pzCountDelay;
-
- ///
- /// Dizionario di VC da trattare come TimeSeries (con conf decodificata + processing successivo...)
- ///
- protected Dictionary TSVC_Data = new Dictionary();
-
- ///
- /// Dizionario di VARIABILI da trattare come eventi (da inviare quando cambiano oppure a scadenza periodo...)
- ///
- protected Dictionary VarArray = new Dictionary();
-
- #endregion Protected Fields
-
#region Public Fields
///
@@ -196,11 +29,6 @@ namespace IOB_WIN_NEXT
///
public bool adpRunning = false;
- ///
- /// Valore di attesa (random) dopo ogni invio x evitare congestione send...
- ///
- protected static int urlRandWait = 0;
-
///
/// valore booleano di check se l'adapter STIA SALVANDO
///
@@ -309,7 +137,7 @@ namespace IOB_WIN_NEXT
///
/// dataOra ultimo PING inviato verso il PLC...
///
- public DateTime lastPING;
+ public DateTime lastPING = DateTime.Now.AddHours(-1);
///
/// DataOra ultima lettura da PLC
@@ -362,7 +190,8 @@ namespace IOB_WIN_NEXT
public Dictionary persistenceLayer;
///
- /// Determina se utilizzare blocchi di memoria IOT contigui (e quindi processing "monoblocco" semplificato"=
+ /// Determina se utilizzare blocchi di memoria IOT contigui (e quindi processing
+ /// "monoblocco" semplificato"=
///
public bool procIotMem = false;
@@ -387,7 +216,7 @@ namespace IOB_WIN_NEXT
public ConcurrentQueue QueueMessages = new ConcurrentQueue();
///
- /// Oggetto della coda degli elementi di tipo RawTransf (e non ancora trasmessi)
+ /// Oggetto della coda degli elementi di tipo RawTransf (e non ancora trasmessi)
/// NB: sono salvati serializzati come stringhe
///
public ConcurrentQueue QueueRawTransf = new ConcurrentQueue();
@@ -497,383 +326,6 @@ namespace IOB_WIN_NEXT
#endregion Public Events
- #region Private Properties
-
- ///
- /// Verifica se la IOB sia ENABLED (da server o Demo)
- ///
- private bool checkIobEnabled
- {
- get
- {
- bool answ = false;
- // controllo se ho veto al check...
- if (dtVetoCheckIOB < DateTime.Now)
- {
- if (DemoOut)
- {
- answ = (QueueIN.Count + QueueFLog.Count >= nMaxSend);
- IobOnline = answ;
- }
- else
- {
- try
- {
- // chiamo URL, se restituisce "OK" è enabled!
- string callResp = callUrl(urlIobEnabled, true);
- answ = (callResp == "OK");
- // attesa casuale se necessario
- var rand = new Random();
- // primi 2 test
- int maxTry = 2;
- while (maxTry > 0 && !answ)
- {
- Thread.Sleep(rand.Next(250, 500));
- callResp = callUrl(urlIobEnabled, true);
- answ = (callResp == "OK");
- maxTry--;
- }
- // se NON OK riprovo ANCORA 1 volta...
- if (!answ)
- {
- resetWebClients();
- Thread.Sleep(rand.Next(250, 1000));
- callResp = callUrl(urlIobEnabled, false);
- answ = (callResp == "OK");
- }
- // altri 2
- maxTry = 2;
- while (maxTry > 0 && !answ)
- {
- Thread.Sleep(rand.Next(250, 500));
- callResp = callUrl(urlIobEnabled, false);
- answ = (callResp == "OK");
- maxTry--;
- }
- // salvo status...
- IobOnline = answ;
- // se online imposto veto check a 5 x tempo reinvio...
- if (answ)
- {
- lastIobOnline = DateTime.Now;
- }
- dtVetoCheckIOB = DateTime.Now.AddMilliseconds(baseUtils.nextPauseSendMSec * 5);
- }
- catch
- { }
- }
- // verifico SE è variato stato online/offline...
- if (IobOnline != answ)
- {
- // se ORA sono online riporto...
- if (answ)
- {
- lgInfo("IOB ONLINE for server MP/IO");
- }
- else
- {
- lgInfo("IOB OFFLINE for server MP/IO");
- }
- }
- // fix colore
- if (answ)
- {
- parentForm.commSrvActive = 2;
- }
- else
- {
- parentForm.commSrvActive = 1;
- }
- }
- else
- {
- // altrimenti passo ultimo valore noto
- answ = IobOnline;
- }
- return answ;
- }
- }
-
- ///
- /// test ping all'indirizzo impostato nei parametri
- ///
- ///
- private IPStatus testPingServer
- {
- get
- {
- IPStatus answ = IPStatus.Unknown;
- // se disabilitato salto...
- if (pingDisabled)
- {
- answ = IPStatus.Success;
- }
- else
- {
- IPAddress address;
- PingReply reply;
- var rand = new Random();
- int pingTOut = 500;
- using (Ping pingSender = new Ping())
- {
- address = IPAddress.Loopback;
- int maxRetry = maxPingRetry + 1;
- int numRetry = 1;
- string ipAddr = cIobConf.serverData.MPIP.Replace($"{cIobConf.serverData.TRANSP}://", "");
- // fix se fosse ip + porta...
- if (ipAddr.IndexOf(":") >= 0)
- {
- ipAddr = ipAddr.Substring(0, ipAddr.IndexOf(":"));
- }
- IPAddress.TryParse(ipAddr, out address);
- // se null --> provo DNS...
- if (address == null)
- {
- var rawAddresses = Dns.GetHostAddresses(ipAddr);
- if (rawAddresses.Length > 0)
- {
- address = rawAddresses[0];
- }
- }
- try
- {
- // se != null --> uso address...
- if (address != null)
- {
- pingTOut = rand.Next(200, 400);
- reply = pingSender.Send(address, pingTOut);
- }
- else
- {
- pingTOut = rand.Next(300, 600);
- reply = pingSender.Send(cIobConf.cncIpAddr, pingTOut);
- }
- }
- catch (Exception exc)
- {
- pingTOut = rand.Next(100, 200);
- reply = pingSender.Send(IPAddress.Loopback, pingTOut);
- lgError($"ping to loopback addres per eccezione:{Environment.NewLine}{exc}");
- }
- // se ho timeout riprovo...
- while (reply.Status != IPStatus.Success && numRetry < maxRetry)
- {
- Thread.Sleep(rand.Next(50, 200));
- pingTOut = pingServerMsTimeout * numRetry / 2;
- reply = pingSender.Send(address, pingTOut);
- numRetry++;
- if (reply.Status == IPStatus.Success)
- {
- lgInfo("Server PING OK!");
- break;
- }
- else
- {
- lgInfo($"Server Ping KO | reply: {reply.Status} --> retry | TimeOut: {pingTOut}");
- }
- }
- }
- answ = reply.Status;
- }
- return answ;
- }
- }
-
- #endregion Private Properties
-
- #region Protected Properties
-
- ///
- /// Valore del num max invii consecutivi da coda...
- ///
- protected static int nMaxSend
- {
- get
- {
- int answ = 5;
- try
- {
- answ = utils.CRI("nMaxSend");
- }
- catch
- { }
- return answ;
- }
- }
-
- ///
- /// Indica il counter della key richiesta attiva
- /// - gestito tramite Redis
- /// - a scadenza 25h
- /// - incrementato ogni invio di auto ODL
- ///
- protected int countKeyRichiesta
- {
- get
- {
- // calcolo key odierna
- int answ = redisMan.getKReqCount(dailyKey);
- return answ;
- }
- set
- {
- // calcolo key odierna
- redisMan.setKReqCount(dailyKey, value);
- }
- }
-
- protected string dailyKey
- {
- get
- {
- return DateTime.Today.ToString("yyMMdd");
- }
- }
-
- ///
- /// Variabile di appoggio GLOBALE x indicare che si può forzare reset contapezzi con macchina in RUN
- ///
- protected bool forceResetInRun { get; set; } = false;
-
- ///
- /// Variabile di appoggio GLOBALE x indicare macchina RUN (es x gestione su reset pezzi)
- ///
- protected bool isRunning { get; set; } = false;
-
- ///
- /// Valore limite MASSIMO di invio di dati come array Json
- ///
- protected int maxJsonData { get; set; } = utils.CRI("maxJsonData");
-
- ///
- /// Valore limite MASSIMO di invio di dati come array Json x EVENTI
- ///
- protected int maxJsonDataEv { get; set; } = utils.CRI("maxJsonDataEv");
-
- ///
- /// Max tentativi ping permessi (default: 5)
- ///
- protected int maxPingRetry { get; set; } = 5;
-
- ///
- /// Coda massima ammessa per FLog (se <=0 disattivata...)
- ///
- protected int maxQueueFLog { get; set; } = utils.CRI("maxQueueFLog");
-
- ///
- /// Valore MINIMO limite x decidere invio di dati come array Json
- ///
- protected int minJsonData { get; set; } = utils.CRI("minJsonData");
-
- protected string nextKeyRich
- {
- get
- {
- return $"{dailyKey}{countKeyRichiesta:00}";
- }
- }
-
- ///
- /// Numero letture IN da avvio
- ///
- protected int nReadFilt { get; set; }
-
- ///
- /// Numero letture IN da avvio
- ///
- protected int nReadIN { get; set; }
-
- ///
- /// Numero invii OUT (svuotamento coda)
- ///
- protected int nSendOut { get; set; }
-
- ///
- /// Numero simulazioni ammesse...
- ///
- protected int numSim { get; set; }
-
- ///
- /// Indica se sia stato resettato un contapezzi
- ///
- protected bool pzCountResetted { get; set; } = false;
-
- ///
- /// Fornisce il valore letto da BITMAP in formato valido x messa in coda nel formato dtEve#value#cont
- ///
- protected string qEncodeIN
- {
- get
- {
- string answ = "";
- try
- {
- answ = string.Format("{0:yyyyMMddHHmmssfff}#{1:X2}#{2}", DateTime.Now, B_output, counterSigIN);
- }
- catch
- { }
- return answ;
- }
- }
-
- ///
- /// Indica se vada inviata la key richiesta con lo split/autoODL
- ///
- protected bool sendKeyRichiesta { get; set; } = false;
-
- ///
- /// test ping all'indirizzo PLC/CNC impostato nei parametri
- ///
- ///
- protected IPStatus testPingMachine
- {
- get
- {
- IPStatus answ = IPStatus.Unknown;
- // se disabilitato salto...
- if (pingDisabled)
- {
- answ = IPStatus.Success;
- }
- else
- {
- IPAddress address;
- PingReply reply;
- using (Ping pingSender = new Ping())
- {
- address = IPAddress.Loopback;
- int pingMsTimeout = cIobConf.pingMsTimeout;
- IPAddress.TryParse(cIobConf.cncIpAddr, out address);
- try
- {
- // se != null --> uso address...
- if (address != null)
- {
- reply = pingSender.Send(address, pingMsTimeout);
- }
- else
- {
- reply = pingSender.Send(cIobConf.cncIpAddr, pingMsTimeout);
- }
- }
- catch
- {
- reply = pingSender.Send(IPAddress.Loopback, pingMsTimeout);
- }
- answ = reply.Status;
- }
- }
- return answ;
- }
- }
-
- ///
- /// Secondi standard x veto check status e log
- ///
- protected int vetoSeconds { get; set; } = utils.CRI("vetoSeconds");
-
- #endregion Protected Properties
-
#region Public Properties
///
@@ -1108,6 +560,11 @@ namespace IOB_WIN_NEXT
///
public int counterFLog { get; set; }
+ ///
+ /// Contatore x invio dati RawTransf
+ ///
+ public int counterRawTransf { get; set; }
+
///
/// Contatore x invio dati SignalIN
///
@@ -1119,7 +576,7 @@ namespace IOB_WIN_NEXT
public int counterULog { get; set; }
///
- /// Verifica se sia in modalità DEMO --> da tipo IOB SIMULA...
+ /// Verifica se sia in modalità DEMO --> da tipo IOB SIMULA...
///
public bool DemoIn
{
@@ -1218,7 +675,8 @@ namespace IOB_WIN_NEXT
public string lastUrl { get; set; }
///
- /// Valore massimo accettato x incremento pezzi letti dal PLC (valore moltiplicato per 100... 200% --> 200)
+ /// Valore massimo accettato x incremento pezzi letti dal PLC (valore moltiplicato per
+ /// 100... 200% --> 200)
///
public int maxPzDeltaPerc
{
@@ -1713,751 +1171,2978 @@ namespace IOB_WIN_NEXT
#endregion Public Properties
- #region Private Methods
+ #region Public Methods
///
- /// Verifica e se necessario comprime directory log...
+ /// Effettua chiamata URL e restituisce risultato
///
- private void checkShrinkDir()
+ ///
+ /// invio in modalità async (NON GARANTITO ordine...)
+ ///
+ public static string callUrl(string URL, bool doAsync)
{
- string path = string.Format("{0}logs\\{1}", AppDomain.CurrentDomain.BaseDirectory, cIobConf.codIOB);
- baseUtils.shrinkDir(path);
- }
-
- ///
- /// Mostra i dati grezzi letti in esadecimale
- /// Parametri da aggiornare x display in form
- ///
- private void displayRawData(ref newDisplayData currDispData)
- {
- // mostro update...
- string newString = string.Format("{0:X}", B_input);
- currDispData.newInData = newString;
- }
-
- ///
- /// Esegue filtraggio dati x bit blinking!!!
- ///
- private void filterData()
- {
- // effettuo filtraggio dei valori letti... inizializzo OUT!
- B_output = 0;
- // in primis verifico SE ci siano bit blinkng... se non ci sono OUT=IN...
- if (cIobConf.BLINK_FILT == 0)
+ string answ = "";
+ // Chiamata ASINCRONA
+ if (doAsync)
{
- B_output = B_input;
+ //Task resp = utils.callUrlAsync(URL);
+ //answ = resp.Result;
+ answ = utils.callUrlAsync(URL);
+ if (urlRandWait > 0)
+ {
+ Random rnd = new Random();
+ Thread.Sleep(rnd.Next(urlRandWait / 10, urlRandWait));
+ }
+ }
+ // chiamata SOLO NORMALE SINCRONA...
+ else
+ {
+ answ = utils.callUrl(URL);
+ if (urlRandWait > 0)
+ {
+ Random rnd = new Random();
+ Thread.Sleep(rnd.Next(urlRandWait / 10, urlRandWait));
+ }
+ }
+ return answ;
+ }
+
+ ///
+ /// Effettua chiamata URL e restituisce risultato
+ ///
+ ///
+ ///
+ /// invio in modalità async (NON GARANTITO ordine...)
+ ///
+ public static string callUrlWithPayload(string URL, string payload, bool doAsync)
+ {
+ string answ = "";
+ // Chiamata ASINCRONA
+ if (doAsync)
+ {
+ answ = utils.callUrlAsync(URL, payload);
+ if (urlRandWait > 0)
+ {
+ Random rnd = new Random();
+ Thread.Sleep(rnd.Next(urlRandWait / 10, urlRandWait));
+ }
+ }
+ // chiamata SOLO NORMALE SINCRONA...
+ else
+ {
+ answ = utils.callUrl(URL, payload);
+ if (urlRandWait > 0)
+ {
+ Random rnd = new Random();
+ Thread.Sleep(rnd.Next(urlRandWait / 10, urlRandWait));
+ }
+ }
+ return answ;
+ }
+
+ ///
+ /// processa dataLayer e se necessario salva/mostra
+ ///
+ public static void checkSavePersDataLayer()
+ {
+ }
+
+ public static string GetMACAddress()
+ {
+ NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
+ String sMacAddress = string.Empty;
+ foreach (NetworkInterface adapter in nics)
+ {
+ if (string.IsNullOrEmpty(sMacAddress))// only return MAC Address from first card
+ {
+ IPInterfaceProperties properties = adapter.GetIPProperties();
+ //sMacAddress = adapter.GetPhysicalAddress().ToString();
+ sMacAddress = string.Join(":", (from z in adapter.GetPhysicalAddress().GetAddressBytes() select z.ToString("X2")).ToArray());
+ }
+ }
+ return sMacAddress;
+ }
+
+ public static void resetDebugConsole()
+ {
+ }
+
+ ///
+ /// Reset dei webclients
+ ///
+ public static void resetWebClients()
+ {
+ utils.resetWebClients();
+ }
+
+ ///
+ /// Accumula in coda i valori ALARM e logga...
+ ///
+ /// VALORE RAW (x display)
+ /// VALORE già processato con qEncodeFLog(...)
+ public void accodaAlarmLog(string val, string encodedVal)
+ {
+ // mostro dati variati letti...
+ displayOtherData(val);
+ // accodo IN PRIMIS al FluxLog --> accodo (valore già formattato)!
+ QueueFLog.Enqueue(encodedVal);
+ // accodo ANCHE alla coda allarmi che trasmetterò SOLO SE a scadenza impostata (10 sec?)
+ // ho allarmi perdurati...
+
+ // loggo!
+ lgInfo(string.Format("[QUEUE-ALARM-LOG] {0}", encodedVal));
+ counterFLog++;
+ if (counterFLog > 9999)
+ {
+ counterFLog = 0;
+ }
+ }
+
+ ///
+ /// Accumula in coda i valori Flux Log e logga...
+ ///
+ /// VALORE RAW (x display)
+ /// VALORE già processato con qEncodeFLog(...)
+ public void accodaFLog(string val, string encodedVal)
+ {
+ // mostro dati variati letti...
+ displayOtherData(val);
+ // --> accodo (valore già formattato)!
+ QueueFLog.Enqueue(encodedVal);
+ // se abilitato controllo coda FLog (superiore a 0...)
+ if (maxQueueFLog > 0)
+ {
+ // se ho una coda superiore a max ammesso
+ if (QueueFLog.Count > maxQueueFLog)
+ {
+ // elimino valori iniziali fino a tornare al max ammesso...
+ while (QueueFLog.Count > maxQueueFLog)
+ {
+ string currVal = "";
+ QueueFLog.TryDequeue(out currVal);
+ lgInfo($"Eliminazione da coda FLog per superamento maxLengh: {currVal}");
+ }
+ }
+ }
+ // loggo!
+ lgTrace(string.Format("[QUEUE-FLOG] {0}", encodedVal));
+ counterFLog++;
+ if (counterFLog > 9999)
+ {
+ counterFLog = 0;
+ }
+ }
+
+ ///
+ /// Accoda (visualizzando in cima allo stack) la nuova stringa di output per area OTHER DATA
+ ///
+ ///
+ public void accodaOtherData(string newLine)
+ {
+ // inserisco in cima allo stack, trimmo e aggiorno display
+ string strOtherData = limitLine2show(string.Format("{0}{1}{2}", newLine, Environment.NewLine, parentForm.dataMonitor_3));
+ //parentForm.dataMonitor_3 = strOtherData;
+ parentForm.WriteTextSafe(strOtherData);
+ }
+
+ ///
+ /// Accumula in coda i valori RawData + log
+ ///
+ ///
+ ///
+ public void accodaRawData(rawTransfType mesType, object mesContent)
+ {
+ /*--------------------------------
+ * nuova gestione coda dictionary
+ * fixme todo da fare !!!
+ *
+ * - conterrà una lista di oggetti baseRawTransf
+ * - i dati vanno poi "scodati" dal + vecchio ed inviati a MP/IO
+ * - mostra un sunto delle info da inviare
+ * - accodamento vero e proprio
+ * - verifica (opzionale) coda massima x gestire roundRobin ultimi eventi
+ * - trace della coda
+ * - counter invio??? valutare se c'è dataora e poi sono da salvare su MongoDb / Redis
+ *
+ * */
+
+ // serializzo il valore...
+ BaseRawTransf newVal = new BaseRawTransf(DateTime.Now, mesContent, mesType);
+ string encodedVal = JsonConvert.SerializeObject(newVal);
+ // --> accodo (valore già formattato)!
+ QueueRawTransf.Enqueue(encodedVal);
+ // se abilitato controllo coda Max (superiore a 0...)
+ if (maxQueueRawTransf > 0)
+ {
+ // se ho una coda superiore a max ammesso
+ if (QueueRawTransf.Count > maxQueueRawTransf)
+ {
+ // elimino valori iniziali fino a tornare al max ammesso...
+ while (QueueRawTransf.Count > maxQueueRawTransf)
+ {
+ string currVal = "";
+ QueueRawTransf.TryDequeue(out currVal);
+ lgInfo($"Eliminazione da coda RawTransf per superamento maxLengh: {currVal}");
+ }
+ }
+ }
+ // loggo!
+ lgTrace(string.Format("[QUEUE-RTRANSF] {0}", encodedVal));
+ counterRawTransf++;
+ if (counterRawTransf > 9999)
+ {
+ counterRawTransf = 0;
+ }
+ }
+
+ ///
+ /// Accumula in coda i valori Signal IN e logga... Parametri
+ /// da aggiornare x display in form
+ ///
+ public void accodaSigIN(ref newDisplayData currDispData)
+ {
+ // mostro dati variati letti...
+ displayInData(ref currDispData);
+ // verifico veto a invio status macchina
+ string keyName = "VETO_SIG_IN";
+ if (getOptPar(keyName).ToUpper() == "TRUE")
+ {
+ lgTrace($"Filtrato accodamento valore da conf IOB | {keyName} | [QUEUE-IN] {qEncodeIN}");
}
else
{
- // incomincio con i valori NON blinking: questi "passano invariati", inizio a sommare nel valore OUT...
- B_output = B_input & ~cIobConf.BLINK_FILT;
- // calcolo il valore dei BIT che "passano la maschera"
- int iBlink = B_input & cIobConf.BLINK_FILT;
- // ...aggiungo i "bit che passano"
- B_output += iBlink;
+ // --> accodo (valore già formattato)!
+ QueueIN.Enqueue(qEncodeIN);
+ // loggo!
+ lgTrace(string.Format("[QUEUE-IN] {0}", qEncodeIN));
+ }
+ // aggiorno counters ed eventuale reset
+ nReadFilt++;
+ if (nReadFilt > int.MaxValue - 1)
+ {
+ nReadFilt = 0; // per evitare buffer overflow...
+ }
- // calcolo QUALI valori (tra quelli blink) siano PASSATI da 0 a 1 --> init counters...
- BitArray bBlinkStart = new BitArray(new byte[] { Convert.ToByte(iBlink) });
- int[] bitsUp = bBlinkStart.Cast().Select(bit => bit ? 1 : 0).ToArray();
- for (int i = 0; i < bitsUp.Length; i++)
+ counterSigIN++;
+ if (counterSigIN > 9999)
+ {
+ counterSigIN = 0;
+ }
+ }
+
+ ///
+ /// Accumula in coda i valori USER LOG e logga...
+ ///
+ /// VALORE RAW (x display)
+ /// VALORE già processato con qEncodeULog(...)
+ public void accodaUserLog(string val, string encodedVal)
+ {
+ // mostro dati variati letti...
+ displayOtherData(val);
+ // accodo IN PRIMIS al FluxLog --> accodo (valore già formattato)!
+ QueueULog.Enqueue(encodedVal);
+
+ // loggo!
+ lgInfo(string.Format("[QUEUE-USER-LOG] {0}", encodedVal));
+ counterULog++;
+ if (counterULog > 9999)
+ {
+ counterFLog = 0;
+ }
+ }
+
+ ///
+ /// Update visualizzaizone BIT in ingresso Parametri da
+ /// aggiornare x display in form
+ ///
+ public void displayInData(ref newDisplayData currDispData)
+ {
+ if (currDispData != null)
+ {
+ // mostro update...
+ string newString = string.Format("{0:0000}|{1}", counterSigIN, utils.IntToBinStr(B_output, 8));
+ currDispData.newSignalData = newString;
+ }
+ }
+
+ ///
+ /// Mostra cosa ha/avrebbe inviato
+ ///
+ ///
+ public void displayOtherData(string newData)
+ {
+ // mostro update...
+ accodaOtherData(newData);
+ }
+
+ ///
+ /// Esecuzione dei task richiesti e pulizia coda richieste eseguite
+ ///
+ ///
+ public virtual Dictionary executeTasks(Dictionary task2exe)
+ {
+ // Verificare il protocollo: dovrebbe togliere SOLO i task eseguiti...
+ Dictionary taskDone = new Dictionary();
+ if (task2exe != null)
+ {
+ // controllo se memMap != null...
+ if (memMap != null)
{
- // SE 1... impostiamo contatori al MAX
- if (bitsUp[i] == 1)
+ bool taskOk = false;
+ string taskVal = "";
+ // cerco task specifici: se ho startSetup --> imposto bit DBB701.DBB0.4
+ foreach (var item in task2exe)
{
- // se era zero indico START blink...
- if (i_counters[i] == 0)
+ taskOk = false;
+ taskVal = "";
+ // converto richiesta in enum...
+ taskType tName = taskType.nihil;
+ Enum.TryParse(item.Key, out tName);
+ // controllo sulla KEY...
+ switch (tName)
{
- lgTrace("START BLINK: B{0}", i);
+ case taskType.setArt:
+ case taskType.setComm:
+ case taskType.setProg:
+ case taskType.setPzComm:
+ // recupero dati da memMap...
+ if (memMap != null && memMap.mMapWrite != null)
+ {
+ if (memMap.mMapWrite.ContainsKey(item.Key))
+ {
+ dataConf currMem = memMap.mMapWrite[item.Key];
+ string addr = currMem.memAddr;
+ taskVal = $"SET task: {item.Key} --> {item.Value} | mem: {currMem.memAddr} - {currMem.size} byte";
+ // salvo il nuovo valore nella memoria... così prox invio lo trasmetterÃ
+ memMap.mMapWrite[item.Key].value = item.Value;
+ }
+ else
+ {
+ taskVal = $"NO DATA MEM, SET task: {item.Key} --> {item.Value}";
+ }
+ }
+ else
+ {
+ taskVal = $"NO MemMap found, SET task: {item.Key} --> {item.Value}";
+ }
+ // salvo in currProd..
+ saveProdData(new KeyValuePair(item.Key, item.Value));
+
+ break;
+
+ case taskType.forceResetPzCount:
+ // reset contapezzi inizio setup
+ taskOk = resetcontapezziPLC();
+ taskVal = taskOk ? "RESET PZ COUNT OK" : "PZ RESET DISABLED | NO EXEC";
+ lgInfo($"Chiamata forceResetPzCount: taskOk: {taskOk} | taskVal: {taskVal}");
+ break;
+
+ case taskType.startSetup:
+ // reset contapezzi inizio setup
+ taskOk = resetcontapezziPLC();
+ taskVal = taskOk ? "RESET: SETUP START" : "PZ RESET DISABLED | NO EXEC";
+ lgInfo($"Chiamata startSetup: taskOk: {taskOk} | taskVal: {taskVal}");
+ break;
+
+ case taskType.stopSetup:
+ // reset contapezzi fine setup SE ESPLICITAMENTE IMPOSTATO
+ if (cIobConf.optPar.Count > 0 && getOptPar("ENABLE_PZ_RESET_stopSetup") == "TRUE")
+ {
+ taskOk = resetcontapezziPLC();
+ }
+ taskVal = taskOk ? "RESET: SETUP END" : "PZ RESET DISABLED | NO EXEC";
+ lgInfo($"Chiamata stopSetup: taskOk: {taskOk} | taskVal: {taskVal}");
+ 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;
}
- // imposto comunque contatore al cambio fronte...
- i_counters[i] = cIobConf.MAX_COUNTER_BLINK;
+ // aggiungo task!
+ taskDone.Add(item.Key, taskVal);
}
}
-
- // quelli che sono zero... LI RECUPERO E LI PROCESSO...
- int iZero = ~B_input & cIobConf.BLINK_FILT;
- BitArray bBlinkEnd = new BitArray(new byte[] { Convert.ToByte(iZero) });
- int[] bitsDown = bBlinkEnd.Cast().Select(bit => bit ? 1 : 0).ToArray();
- for (int i = 0; i < bitsDown.Length; i++)
+ else
{
- // se era a zero (invertito...)
- if (bitsDown[i] == 1)
+ lgError($"Attenzione! memMap è nullo, non posso eseguire task2exe!");
+ }
+ }
+
+ return taskDone;
+ }
+
+ ///
+ /// Effettua verifica delle memorie WRITE, se ci siano variazioni da riportare verso il PLC
+ /// Da impiegare ad esempio in caso di chiamate complesse (ad 2 aree di memoria condivise
+ /// sul PLC; coem commessa + articolo EWON)
+ ///
+ ///
+ /// Cerca parametri opzionali in modalità "like" del nome
+ ///
+ ///
+ ///
+ public Dictionary findOptPar(string keyStartSearch = "")
+ {
+ Dictionary answ = new Dictionary();
+ // controllo SE keySearch !=""
+ if (!string.IsNullOrWhiteSpace(keyStartSearch))
+ {
+ if (cIobConf.optPar.Count > 0)
+ {
+ // ciclo su tutti e cerco occorrenze che INIZINO...
+ foreach (var item in cIobConf.optPar)
{
- // SE è in corso il conteggio...
- if (i_counters[i] > 0)
+ if (item.Key.StartsWith(keyStartSearch))
{
- // decremento!
- i_counters[i] -= 1;
- // se è zero NON faccio nulla, altrimenti SOMMO...
- if (i_counters[i] > 0)
- {
- B_output += 1 << i;
- }
- else
- {
- lgTrace("END BLINK: B{0}", i);
- }
+ answ.Add(item.Key, item.Value);
}
}
}
}
+ return answ;
}
///
- /// Imposta eventuali altri valori default
+ /// forza reset ODL
///
- private void fixDefaultPar()
+ public void forceResetOdl()
{
- // parametro max tentativi PING...
- string s_maxPingRetry = getOptPar("MAX_PING_RETRY");
- if (!string.IsNullOrEmpty(s_maxPingRetry))
- {
- int numRetry = 5;
- int.TryParse(s_maxPingRetry, out numRetry);
- maxPingRetry = numRetry;
- }
-
- string s_maxErrCheck = getOptPar("MAX_ERR_CHECK");
- if (!string.IsNullOrEmpty(s_maxErrCheck))
- {
- int numErr = 50;
- int.TryParse(s_maxErrCheck, out numErr);
- maxErroriCheck = numErr;
- }
-
- string s_watchDogPer = getOptPar("WATCHDOG_PERIOD");
- if (!string.IsNullOrEmpty(s_watchDogPer))
- {
- int numPer = 3;
- int.TryParse(s_watchDogPer, out numPer);
- watchDogPeriod = numPer;
- }
+ lgInfo("Registrato richiesta forzatura reset ODL");
+ pzCountResetted = true;
}
///
- /// recupera valore salvato in persistence layer (se non c'è crea...)
+ /// Effettua chiamata x split ODL
///
- ///
///
- private string getStoredVal(string keyVal)
+ public bool forceSplitOdl()
{
- string value = "";
- try
+ bool fatto = false;
+ if (vetoSplit < DateTime.Now)
{
- if (persistenceLayer != null)
+ lgInfo("Richiesto forceSplitOdl");
+ // imposto veto x 1 minuto ad altre chiamate...
+ vetoSplit = DateTime.Now.AddMinutes(1);
+ // eseguo SOLO SE sono online...
+ if (MPOnline && IobOnline)
{
- if (!persistenceLayer.TryGetValue(keyVal, out value))
+ string fullUrl = "";
+ string rawSplit = "";
+ string IOB_MULTI_CNAME = "";
+ string[] elencoMulti = null;
+
+ try
{
- persistenceLayer.Add(keyVal, "0");
+ /***************************************************
+ * Descrizione procedura (OK X SIMULATORI...)
+ *
+ * - chiamata su MP/IO
+ * - verifica che su DB sia abilitato AUTO ODL
+ * - il server inserisce un evento fine prod HW 1 minuto prima e inizio setup HW
+ * - viene duplicato e chiuso ODL corrente
+ * - viene fatto partire ODL nuovo ADESSO
+ * - num pezzi come ODL precedente (o da media 3 ODL precedenti)
+ * - conferme pezzi & co... gestione NULL (NON SERVONO si tratta di impianti SENZA gestione vera ODL)
+ * - reset contapezzi PLC locale...
+ *
+ *
+ *
+ * DA VALUTARE (x macchine tipo linea con + impianti... es valvital) SE
+ * - creare una gestione ALTERNATIVA sul server che preveda impianto LEADER e impianti follower (RIGIDAMENTE CONFIGURATI)
+ * - ogni volta che si fa setup LEADER --> si ripete su impianti FOLLOWER (eventi!!!)
+ * - viene fatto reset contapezzi sui follower (+ altre operazioni opzionali, ES imposstazione nome commessa, quantità , articolo...)
+ * - viene fatto reset + nuovo ODL (con stessi articoli e quantità ) su follower, SENZA avere gestione x ODL di un codice esterno (quindi registra TUTTO ma NON RITORNERA' dati non avendo link verso esterno)
+ * - serve NUOVA TABELLA delle macchine LEADER | FOLLOWER (1:n) e gestione da MP/IO
+ *
+ * ***************************************************/
+
+ if (isMulti)
+ {
+ // devo chiamare cambio ODL x OGNI tavola: mi servono i parametri opzionali...
+ IOB_MULTI_CNAME = getOptPar("IOB_MULTI_CNAME");
+ elencoMulti = IOB_MULTI_CNAME.Split(',');
+ }
+ // se normale splitto!
+ if (!isMulti)
+ {
+ // invio chiamata URL x reset ODL su macchina
+ rawSplit = callUrl(urlForceSplit, false);
+ fatto = (rawSplit != "KO") ? true : false;
+ }
+ // se multi gestisco il bit delle tavole...
+ else
+ {
+ foreach (string item in elencoMulti)
+ {
+ // invio chiamata URL x reset ODL su macchina, ATTENZIONE scriviamo
+ // | al posto di "#" che in URL sarebbe filtrato...
+ fullUrl = $"{urlForceSplit}&multi={item}";
+ rawSplit = callUrl(fullUrl, false);
+ lgDebug($"Esecuzione forceSplit | URL: {fullUrl} | esito: {rawSplit}");
+ }
+ fatto = (rawSplit == "OK") ? true : false;
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError($"Eccezione in forceSplitOdl{Environment.NewLine}{exc}");
+ }
+ // se fatto --> resetto contapezzi!!!
+ if (fatto)
+ {
+ contapezziPLC = 0;
+ contapezziIOB = 0;
}
}
+ else
+ {
+ lgError("Richiesto forceSplitOdl ma MP/IOB offline --> NON eseguito");
+ }
}
- catch (Exception exc)
+ else
{
- lgError(string.Format("Eccezione in getStoredVal: {0}{1}", Environment.NewLine, exc));
+ lgError("Richiesto forceSplitOdl ma veto attivo --> NON eseguito");
}
- return value;
+ return fatto;
}
///
- /// recupera valore salvato in persistence layer (se non c'è crea...) come double
+ /// Effettua conversione da valore bitmap ai valori configurati x allarme
///
- ///
+ /// Configurazione banco allarmi
+ /// BitState allarmi
///
- private double getStoredValDouble(string keyVal)
+ public string getAlarmState(BaseAlarmConf memConf, byte[] bState)
{
- double answ = 0;
- try
+ string valTransl = "";
+ List descAttivi = new List();
+ BitArray bitAttivi = new BitArray(bState);
+ bool[] bitStati = new bool[bitAttivi.Count];
+ bitAttivi.CopyTo(bitStati, 0);
+ // cerco bit attivi
+ int idx = 0;
+ foreach (var item in bitStati)
{
- answ = Convert.ToDouble(getStoredVal(keyVal));
+ if (item && memConf.messages.Count > idx)
+ {
+ string currState = memConf.messages[idx];
+ descAttivi.Add(currState);
+ }
+ idx++;
}
- catch (Exception exc)
- {
- lgError(string.Format("Eccezione in getStoredValDouble: {0}{1}", Environment.NewLine, exc));
- }
- answ = (answ < (double.MaxValue / 10 * 9)) ? answ : 0;
- return answ;
+ // combino string
+ valTransl = string.Join(",", descAttivi);
+ return valTransl;
}
///
- /// recupera valore salvato in persistence layer (se non c'è crea...) come INT
+ /// effettua recupero dati ed invio valori modificati...
///
- ///
- ///
- private long getStoredValLong(string keyVal)
- {
- long answ = 0;
- try
- {
- answ = Convert.ToInt64(getStoredVal(keyVal));
- }
- catch
- { }
- // verifico che il valore sia minore di 9/10 del valore massimo...
- answ = (answ < (long.MaxValue / 10 * 9)) ? answ : 0;
- return answ;
- }
-
- ///
- /// recupera valore salvato in persistence layer (se non c'è crea...) come UINT
- ///
- ///
- ///
- private uint getStoredValUInt(string keyVal)
- {
- uint answ = 0;
- try
- {
- answ = Convert.ToUInt32(getStoredVal(keyVal));
- }
- catch (Exception exc)
- {
- lgError(string.Format("Eccezione in getStoredValUInt: {0}{1}", Environment.NewLine, exc));
- }
- // verifico che il valore sia minore di 9/10 del valore massimo...
- answ = (answ < (uint.MaxValue / 10 * 9)) ? answ : 0;
- return answ;
- }
-
- ///
- /// Classe fittizia in caso di processing GLOBALE di tutto in 1 solo colpo...
- ///
- private void processAllMemory()
+ ///
+ public void getAndSend(gatherCycle ciclo)
{
// init obj display
newDisplayData currDispData = new newDisplayData();
- // in primis SALVO valori previous/precedenti
- B_previous = B_output;
- // poi faccio lettura NUOVI valori
- readAllData(ref currDispData);
- // eseguo il filtering dei valori (per i bit "blinking")
- filterData();
- // effettuo confronto valori vecchi/nuovi... SE trovo variazione OPPURE se è passato + di un timeout di controllo...
- if (B_output != B_previous)
+ // IN OGNI CASO a prima di tutto EFFETTUO GESTIONE INVII dati da code!!!
+ try
{
- accodaSigIN(ref currDispData);
+ trySendValues();
+ }
+ catch (Exception exc)
+ {
+ lgError(exc, "Errore in gestione svuotamento/invio preliminare code memoria");
+ currDispData.semOut = Semaforo.SR;
+ }
+ // controllo connessione/connettivitÃ
+ if (connectionOk)
+ {
+ // controllo non sia già in esecuzione...
+ if (!adpCommAct)
+ {
+ // provo ad avviare
+ try
+ {
+ // imposto flag adapter running..
+ adpCommAct = true;
+ adpStartRun = DateTime.Now;
+ }
+ catch (Exception exc)
+ {
+ string errore = $"Adapter NOT STARTED!!!{Environment.NewLine}{exc}";
+ adpCommAct = false;
+ adpStartRun = DateTime.Now;
+ currDispData.newLiveLogData = errore;
+ }
+ if (adpCommAct)
+ {
+ // try / catch generale altrimenti segno che è disconnesso...
+ try
+ {
+ bool showDebugData = false;
+ if (ciclo == gatherCycle.VHF)
+ {
+ processVHF();
+ }
+ // processing dati memoria (lettura, filtraggio, enqueque)
+ else if (ciclo == gatherCycle.HF)
+ {
+ processWhatchDog();
+ processAllMemory();
+ processMode();
+ }
+ else if (ciclo == gatherCycle.MF)
+ {
+ processServerRequests();
+ processOverride();
+ processContapezzi();
+ processCncAlarms();
+ processDynData();
+ processMem2Write();
+ }
+ else if (ciclo == gatherCycle.LF)
+ {
+ processCustomTaskLF();
+ processOtherCounters();
+ processProgram();
+ // verifico se devo gestire cambio ODL in modo automatico
+ processAutoOdl();
+ }
+ else if (ciclo == gatherCycle.VLF)
+ {
+ if (utils.CRB("enableContapezzi"))
+ {
+ // rilettura contapezzi da server...
+ lgTrace("Ciclo VLF: pzCntReload(true)");
+ if (!isMulti)
+ {
+ pzCntReload(true);
+ }
+ // refresh associazione Macchina - IOB
+ sendM2IOB();
+ }
+ // recupero dati SETUP (sysinfo) e li invio/mostro se variati...
+ processSysInfo();
+ // checkLogDir x shrink!
+ checkShrinkDir();
+ // eventuale log!
+ if (utils.CRB("recTime"))
+ {
+ logTimeResults();
+ }
+ }
+ // mostra eventuali altri dati di processo...
+ reportDataProc();
+ if (showDebugData)
+ {
+ // verifica se debba salvare e mostrare dati
+ checkSavePersDataLayer();
+ }
+ }
+ catch (Exception exc)
+ {
+ // segnalo eccezione e indico disconnesso...
+ lgError(exc, string.Format("Errore in gestione ciclo principale ADP, fermo adapter{0}{1}", Environment.NewLine, exc));
+ parentForm.fermaAdapter(true, false, true);
+ }
+ // tolgo flag running
+ adpCommAct = false;
+ }
+ else
+ {
+ if (periodicLog)
+ {
+ lgDebug("ADP not running...");
+ }
+ }
+ }
+ else
+ {
+ // log ADP running
+ lgError("Non eseguo chiamata: ADP ancora in running");
+ // se è bloccato da oltre maxSec lo sblocco...
+ if (DateTime.Now.Subtract(adpStartRun).TotalSeconds > utils.CRI("maxAdapterLockSec"))
+ {
+ // tolgo flag running
+ adpCommAct = false;
+ adpStartRun = DateTime.Now;
+ }
+ }
+ }
+ else
+ {
+ // provo a riconnettere SE abilitato tryRestart...
+ if (adpTryRestart && !connectionOk)
+ {
+ // controllo se sia scaduto periodi di veto al tryConnect...
+ int waitRecMSec = utils.CRI("waitRecMSec") * 2;
+ DateTime dtVeto = lastConnectTry.AddMilliseconds(waitRecMSec);
+ if (DateTime.Now > dtVeto)
+ {
+ lgInfo($"Veto Time Elapsed | lastConnectTry: {lastConnectTry} | waitRecMSec {waitRecMSec} ms) | NOW tryConnect");
+ lastConnectTry = DateTime.Now;
+ tryConnect();
+ }
+ }
+ currDispData.semIn = Semaforo.SR;
+ processDisconnectedTask();
}
raiseRefresh(currDispData);
}
- private void processMem2Write()
+ ///
+ /// Effettua conversione da valore bitmap ai valori configurati
+ ///
+ ///
+ ///
+ ///
+ public string getBitmapState(dataConfTSVC memConf, byte[] bState)
{
- List updatedPar = new List();
- // ciclo tutti gli oggetti write x vedere se modificati...
- foreach (var item in currProdData)
+ string valTransl = "";
+ List descAttivi = new List();
+ BitArray bitAttivi = new BitArray(bState);
+ bool[] bitStati = new bool[bitAttivi.Count];
+ bitAttivi.CopyTo(bitStati, 0);
+ // cerco bit attivi
+ int idx = 0;
+ foreach (var item in bitStati)
{
- bool needWrite = false;
- // li cerco su last... se non ci sono o modificati --> salvo da scrivere e copio
- if (lastProdData.ContainsKey(item.Key))
+ if (item && memConf.decodeMap.Count > idx)
{
- // verifico se variato...
- if (!item.Value.Equals(lastProdData[item.Key]))
- {
- needWrite = true;
- lastProdData[item.Key] = item.Value;
- }
+ string currState = memConf.decodeMap[idx];
+ descAttivi.Add(currState);
}
- // aggiungo
- else
+ idx++;
+ }
+ // combino string
+ valTransl = string.Join(",", descAttivi);
+ return valTransl;
+ }
+
+ ///
+ /// Recupera eventuali allarmi CNC...
+ ///
+ public virtual Dictionary getCncAlarms()
+ {
+ Dictionary outVal = new Dictionary();
+ return outVal;
+ }
+
+ ///
+ /// Restituisce info DINAMICHE
+ ///
+ ///
+ public virtual Dictionary getDynData()
+ {
+ Dictionary outVal = new Dictionary();
+ return outVal;
+ }
+
+ ///
+ /// Cerca se esiste il parametro opzionale e lo restituisce
+ ///
+ ///
+ ///
+ public string getOptPar(string key)
+ {
+ string answ = "";
+ if (cIobConf.optPar.Count > 0)
+ {
+ // controllo SE HO il parametro
+ if (cIobConf.optPar.ContainsKey(key))
{
- needWrite = true;
- lastProdData.Add(item.Key, item.Value);
- }
- // se devo scrivere --> riporto
- if (needWrite)
- {
- if (memMap.mMapWrite.ContainsKey(item.Key))
- {
- // preparo obj da scrivere
- objItem newWrite = new objItem()
- {
- uid = item.Key,
- name = item.Key,
- reqValue = memMap.mMapWrite[item.Key].value,
- lastRequest = DateTime.Now,
- writable = true
- };
- updatedPar.Add(newWrite);
- }
+ answ = cIobConf.optPar[key];
}
}
- // se ho da scrivere... scrivo TUTTI!
- if (updatedPar.Count > 0)
+ return answ;
+ }
+
+ ///
+ /// Restituisce info OVERRIDES
+ ///
+ ///
+ public virtual Dictionary getOverrides()
+ {
+ Dictionary outVal = new Dictionary();
+ return outVal;
+ }
+
+ ///
+ /// Restituisce programma in esecuzione
+ ///
+ public virtual string getPrgName()
+ {
+ return "";
+ }
+
+ ///
+ /// Restituisce info sistema
+ ///
+ ///
+ public virtual Dictionary getSysInfo()
+ {
+ Dictionary outVal = new Dictionary();
+ return outVal;
+ }
+
+ ///
+ /// Recupera la VC x TS, svuotando lista e resettando periodo partenza
+ ///
+ /// Nome della VC
+ /// Reimposta e resetta array VC
+ ///
+ public double getVal_TSVC(string VCName, bool doReset)
+ {
+ double answ = -999999;
+ // cerco VC...
+ if (TSVC_Data.ContainsKey(VCName))
{
- // scrivo valore!
- lgInfo("Chiamata di plcWriteParams da processMem2Write");
- plcWriteParams(ref updatedPar);
- // invio su cloud parametri!
- string rawData = JsonConvert.SerializeObject(updatedPar);
- utils.callUrl($"{urlUpdateWriteParams}", rawData);
- lgInfo($"Notificato a server scrittura {updatedPar.Count} parametri");
+ try
+ {
+ switch (TSVC_Data[VCName].Funzione)
+ {
+ case VC_func.POINT:
+ // prendo PRIMO
+ answ = TSVC_Data[VCName].dataArray.FirstOrDefault();
+ break;
+
+ case VC_func.AVG:
+ answ = TSVC_Data[VCName].dataArray.Average();
+ break;
+
+ case VC_func.MEDIAN:
+ answ = TSVC_Data[VCName].dataArray.Median();
+ break;
+
+ case VC_func.MIN:
+ answ = TSVC_Data[VCName].dataArray.Min();
+ break;
+
+ case VC_func.MAX:
+ default:
+ answ = TSVC_Data[VCName].dataArray.Max();
+ break;
+ }
+ }
+ catch
+ { }
+ // ora resetto... SE richiesto...
+ if (doReset)
+ {
+ TSVC_Data[VCName].dataArray = new List();
+ TSVC_Data[VCName].DTStart = DateTime.Now;
+ }
+ }
+ return answ;
+ }
+
+ ///
+ /// Recupera la VC x TS, svuotando lista e resettando periodo partenza
+ ///
+ /// Nome della VC
+ /// Reimposta e resetta array VC
+ ///
+ public int getVal_TSVC_int(string VCName, bool doReset)
+ {
+ int answ = 0;
+ // cerco VC...
+ if (TSVC_Data.ContainsKey(VCName))
+ {
+ // !!!FARE!!! vero calcolo... x ora FIX a MAX...
+ foreach (var item in TSVC_Data[VCName].dataArray)
+ {
+ answ = (int)item > answ ? (int)item : answ;
+ }
+ // ora resetto... SE richiesto..
+ if (doReset)
+ {
+ TSVC_Data[VCName].dataArray = new List();
+ TSVC_Data[VCName].DTStart = DateTime.Now;
+ }
+ }
+ return answ;
+ }
+
+ ///
+ /// Restituisce un payload in formato json della lista di valori ricevuta
+ ///
+ /// Tipo di URL (eventi / FLog)
+ /// elenco di valori da coda string salvata
+ ///
+ public string jsonPayload(urlType tipoUrl, List elencoValori)
+ {
+ string answ = "";
+ if (elencoValori != null)
+ {
+ string[] valori;
+ int counter = 0;
+ DateTime dtEve = DateTime.Now;
+ switch (tipoUrl)
+ {
+ case urlType.FLog:
+ flogData currFlData = new flogData();
+ flogJsonPayload fullFlObj = new flogJsonPayload();
+ fullFlObj.fluxData = new List();
+ // inizio processando ogni valore
+ foreach (var item in elencoValori)
+ {
+ valori = qDecodeIN(item);
+ CultureInfo provider = CultureInfo.InvariantCulture;
+ DateTime.TryParseExact(valori[0], "yyyyMMddHHmmssfff", provider, DateTimeStyles.AssumeLocal, out dtEve);
+ int.TryParse(valori[3], out counter);
+ currFlData = new flogData()
+ {
+ flux = valori[1],
+ valore = valori[2],
+ dtEve = dtEve,
+ dtCurr = DateTime.Now,
+ cnt = counter
+ };
+ fullFlObj.fluxData.Add(currFlData);
+ }
+ // conversione finale
+ try
+ {
+ answ = JsonConvert.SerializeObject(fullFlObj);
+ }
+ catch (Exception exc)
+ {
+ lgError($"FLog Errore in costruzione jsonPayload:{Environment.NewLine}{exc}");
+ }
+ break;
+
+ case urlType.SignIN:
+ evData currSigData = new evData();
+ evJsonPayload fullEvObj = new evJsonPayload();
+ fullEvObj.eventList = new List();
+ // inizio processando ogni valore
+ foreach (var item in elencoValori)
+ {
+ valori = qDecodeIN(item);
+ CultureInfo provider = CultureInfo.InvariantCulture;
+ DateTime.TryParseExact(valori[0], "yyyyMMddHHmmssfff", provider, DateTimeStyles.AssumeLocal, out dtEve);
+ int.TryParse(valori[2], out counter);
+ currSigData = new evData()
+ {
+ valore = valori[1],
+ dtEve = dtEve,
+ dtCurr = DateTime.Now,
+ cnt = counter
+ };
+ fullEvObj.eventList.Add(currSigData);
+ }
+ // conversione finale
+ try
+ {
+ answ = JsonConvert.SerializeObject(fullEvObj);
+ }
+ catch (Exception exc)
+ {
+ lgError($"SignIN Errore in costruzione jsonPayload:{Environment.NewLine}{exc}");
+ }
+ break;
+
+ case urlType.RawTransf:
+ BaseRawTransf currRTData = new BaseRawTransf();
+#if false
+ rawTransfJsonPayload fullRTObj = new rawTransfJsonPayload();
+ fullRTObj.rawTransfData = new List();
+ // inizio processando ogni valore
+ foreach (var item in elencoValori)
+ {
+ try
+ {
+ currRTData = JsonConvert.DeserializeObject(item);
+ }
+ catch (Exception exc)
+ {
+ lgError($"Eccezione in deserializzazione BaseRawTransf:{Environment.NewLine}{exc}");
+ }
+ fullRTObj.rawTransfData.Add(currRTData);
+ }
+ // conversione finale
+ try
+ {
+ answ = JsonConvert.SerializeObject(fullRTObj);
+ }
+ catch (Exception exc)
+ {
+ lgError($"RawTransf Errore in costruzione jsonPayload:{Environment.NewLine}{exc}");
+ }
+#endif
+
+ // provo una serializzazione "brutale", ovvero aggiungo alla stringa il
+ // valore di testa...
+ string rawResult = "";
+ foreach (var item in elencoValori)
+ {
+ rawResult += $"{item},";
+ }
+ if (rawResult.Length > 0)
+ {
+ rawResult = rawResult.Substring(0, rawResult.Length - 1);
+ }
+ answ = "{" + $"\"rawTransfData\":[{rawResult}]" + "}";
+
+ break;
+
+ case urlType.ULog:
+ int numVal = 0;
+ int matrOp = 0;
+ ulogData currUlData = new ulogData();
+ ulogJsonPayload fullUlObj = new ulogJsonPayload();
+ fullUlObj.fluxData = new List();
+ // inizio processando ogni valore
+ foreach (var item in elencoValori)
+ {
+ valori = qDecodeIN(item);
+ CultureInfo provider = CultureInfo.InvariantCulture;
+ DateTime.TryParseExact(valori[0], "yyyyMMddHHmmssfff", provider, DateTimeStyles.AssumeLocal, out dtEve);
+ int.TryParse(valori[3], out matrOp);
+ int.TryParse(valori[5], out numVal);
+ int.TryParse(valori[6], out counter);
+ currUlData = new ulogData()
+ {
+ flux = valori[1],
+ valore = valori[2],
+ dtEve = dtEve,
+ dtCurr = DateTime.Now,
+ cnt = counter,
+ matrOpr = matrOp,
+ label = valori[4],
+ valNum = numVal
+ };
+ fullUlObj.fluxData.Add(currUlData);
+ }
+ // conversione finale
+ try
+ {
+ answ = JsonConvert.SerializeObject(fullUlObj);
+ }
+ catch (Exception exc)
+ {
+ lgError($"ULog Errore in costruzione jsonPayload:{Environment.NewLine}{exc}");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return answ;
+ }
+
+ ///
+ /// Effettua un trim della stringa al numero max di linee da mostrare a video
+ ///
+ ///
+ ///
+ public string limitLine2show(string newString)
+ {
+ // se num righe superiore a limite trimmo...
+ if (newString.Split('\n').Length > parentForm.nLine2show)
+ {
+ //int idx = newString.LastIndexOf('\r');
+ int idx = newString.LastIndexOf(Environment.NewLine);
+ newString = newString.Substring(0, idx);
+ }
+ return newString;
+ }
+
+ ///
+ /// riporta il log di tutti i dati di results temporali registrati
+ ///
+ public void logTimeResults()
+ {
+ if (TimingData.results.Count > 0)
+ {
+ lgInfo("{0}--------------- START TIMING DATA ---------------", Environment.NewLine);
+ int globNumCall = 0;
+ TimeSpan globAvgMsec = new TimeSpan(0);
+ foreach (TimeRec item in TimingData.results)
+ {
+ // loggo SOLO se del mio IOB corrente...
+ if (item.classCall == cIobConf.codIOB)
+ {
+ lgInfo("{4}|Chiamate {0}: effettuate {1}, tempo medio {2:N2} msec | impegno canale {3:P3}", item.codCall, item.numCall, item.avgMsec, item.totMsec.TotalSeconds / DateTime.Now.Subtract(dtAvvioAdp).TotalSeconds, cIobConf.codIOB);
+ globNumCall += item.numCall;
+ globAvgMsec += item.totMsec;
+ }
+ }
+ // riporto conteggio medio al secondo...
+ lgInfo("{4}|Chiamate GLOBALI: {0}, periodo: {1:N2} minuti.cent, tempo medio {2:N2} msec | impegno canale {3:P3}", globNumCall, DateTime.Now.Subtract(dtAvvioAdp).TotalMinutes, globAvgMsec.TotalMilliseconds / globNumCall, globAvgMsec.TotalSeconds / DateTime.Now.Subtract(dtAvvioAdp).TotalSeconds, cIobConf.codIOB);
+ lgInfo("{0}--------------- STOP TIMING DATA ---------------{0}", Environment.NewLine);
+ // mostro in form statistiche globali!
+ parentForm.updateComStats(string.Format("Periodo: {0:N2}min | {1} x {2:N2}ms | canale {3:P3}", DateTime.Now.Subtract(dtAvvioAdp).TotalMinutes, globNumCall, globAvgMsec.TotalMilliseconds / globNumCall, globAvgMsec.TotalSeconds / DateTime.Now.Subtract(dtAvvioAdp).TotalSeconds));
}
}
///
- /// Effettua gestioen programma: legge e mostra su display...
+ /// Processa un monitoredItem, e ritorna boolean SE richiede invio (cambio o scadenza)
///
- private void processProgram()
+ ///
+ ///
+ ///
+ public bool monItem2Send(string newVal, DynDataItem item)
{
- string currPrgName = "";
- // se abilitata lettura prgName
- if (enablePrgName)
+ bool answ = false;
+ if (item != null)
{
- if (connectionOk)
+ // controllo in base al tipo di function...
+ switch (item.func)
{
- currPrgName = getPrgName();
+ case "SAMPLE":
+ // controllo se scaduto sample period...
+ if (item.DTScad < DateTime.Now)
+ {
+ answ = true;
+ }
+ break;
+
+ case "CHANGE":
+ default:
+ // controllo se scaduto o se variato...
+ if (newVal != item.actVal || item.DTScad < DateTime.Now)
+ {
+ // aggiorno scadenza e che vada inviato
+ answ = true;
+ }
+ break;
+ }
+ }
+ return answ;
+ }
+
+ ///
+ /// Verifica e processing x gestione ODL automatica
+ ///
+ public void processAutoOdl()
+ {
+ bool fatto = false;
+ if (!string.IsNullOrEmpty(getOptPar("AUTO_CHANGE_ODL")))
+ {
+ lgTrace("Richiesta processAutoOdl");
+ string IOB_MULTI_CNAME = "";
+ string[] elencoMulti = null;
+ string fullUrl = "";
+ if (isMulti)
+ {
+ // devo chiamare cambio ODL x OGNI tavola: mi servono i parametri opzionali...
+ IOB_MULTI_CNAME = getOptPar("IOB_MULTI_CNAME");
+ elencoMulti = IOB_MULTI_CNAME.Split(',');
+ }
+ // controllo SIA abilitato...
+ bool doProc = false;
+ DateTime adesso = DateTime.Now;
+ bool.TryParse(getOptPar("AUTO_CHANGE_ODL"), out doProc);
+ if (doProc)
+ {
+ lgTrace("AUTO_CHANGE_ODL abilitato");
+ bool callChangeODL = false;
+ // modalità change ODL
+ string CHANGE_ODL_MODE = "TIME";
+ if (!string.IsNullOrEmpty(getOptPar("CHANGE_ODL_MODE")))
+ {
+ CHANGE_ODL_MODE = getOptPar("CHANGE_ODL_MODE");
+ }
+ if (CHANGE_ODL_MODE == "PZCOUNT_RESET")
+ {
+ /* verifico se sia "armato" il reset cambio ODL, DEVO essere :
+ * - NON in produzione
+ * - contapezzi ACT < contapezzi LAST
+ * */
+ lgTrace("processAutoOdl: caso PZCOUNT_RESET");
+ if ((!isRunning || forceResetInRun) && pzCountResetted)
+ {
+ callChangeODL = true;
+ lgInfo("Attivato cambio ODL da PZCOUNT_RESET");
+ }
+ else
+ {
+ lgInfo($"isRunning: {isRunning} | pzCountResetted: {pzCountResetted} | forceResetInRun: {forceResetInRun} | contapezziIOB: {contapezziIOB} | contapezziPLC: {contapezziPLC}");
+ }
+ }
+ else if (CHANGE_ODL_MODE == "TIME")
+ {
+ // carico i parametri di configurazione x reset ODL...
+ string CHANGE_ODL_HOURS = getOptPar("CHANGE_ODL_HOURS");
+ string CHANGE_ODL_IDLE_MIN = getOptPar("CHANGE_ODL_IDLE_MIN");
+ if (!string.IsNullOrEmpty(CHANGE_ODL_HOURS) && !string.IsNullOrEmpty(CHANGE_ODL_IDLE_MIN))
+ {
+ int minOdlDurHours = -1;
+ int minPlcIdelMin = -1;
+ int.TryParse(CHANGE_ODL_HOURS, out minOdlDurHours);
+ int.TryParse(CHANGE_ODL_IDLE_MIN, out minPlcIdelMin);
+ // controllo parametri validi
+ if (minOdlDurHours > 0 && minPlcIdelMin >= 0)
+ {
+ // leggo da server inizio ODL... se non multi 1 solo...
+ DateTime inizioOdl = DateTime.Now;
+ string rawDataInizio = "";
+ if (!isMulti)
+ {
+ rawDataInizio = callUrl(urlInizioOdlIob, false);
+ DateTime.TryParse(rawDataInizio, out inizioOdl);
+ }
+ else
+ {
+ DateTime tmpData = DateTime.Now;
+ // prendo il + vecchio...
+ foreach (var item in elencoMulti)
+ {
+ fullUrl = $"{urlInizioOdlIob}|{item}";
+ rawDataInizio = callUrl(fullUrl, false);
+ DateTime.TryParse(rawDataInizio, out tmpData);
+ inizioOdl = (tmpData < inizioOdl) ? tmpData : inizioOdl;
+ }
+ }
+ // verifico se sia scaduto...
+ if (inizioOdl.AddHours(minOdlDurHours) < adesso)
+ {
+ string rawIdle = "";
+ int idlePeriod = 0;
+ if (!isMulti)
+ {
+ // controllo SE sono fermo (spento o in manuale) per il
+ // periodo minimo richiesto...
+ rawIdle = callUrl(urlIdleTime, false);
+ int.TryParse(rawIdle, out idlePeriod);
+ }
+ else
+ {
+ int tmpIdle = 0;
+ // prendo il + grande...
+ foreach (var item in elencoMulti)
+ {
+ fullUrl = $"{urlIdleTime}|{item}";
+ rawIdle = callUrl(fullUrl, false);
+ int.TryParse(rawIdle, out tmpIdle);
+ idlePeriod = tmpIdle > idlePeriod ? tmpIdle : idlePeriod;
+ }
+ }
+ if (idlePeriod >= minPlcIdelMin)
+ {
+ callChangeODL = true;
+ }
+ }
+ }
+ }
+ }
+
+ // vero processing...
+ if (callChangeODL)
+ {
+ lgTrace("Chiamata: processAutoOdl --> forceSplitODL");
+ fatto = forceSplitOdl();
+ pzCountResetted = false;
+ lgInfo("Esecuzione processAutoOdl completata --> pzCountResetted = false");
+ }
}
else
{
- lgError("Errore connessione mancante x getPrgName");
+ lgTrace("AUTO_CHANGE_ODL DISABILITATO");
+ }
+ }
+ // loggo se fatto
+ if (fatto)
+ {
+ lgTrace("Effettuato processAutoOdl");
+ }
+ }
+
+ ///
+ /// Effettua processing degli allarmi CNC SE disponibili
+ ///
+ public void processCncAlarms()
+ {
+ if (utils.CRB("enableAlarms"))
+ {
+ Dictionary currAlarms = new Dictionary();
+ if (connectionOk)
+ {
+ currAlarms = getCncAlarms();
+ }
+ else
+ {
+ lgError("Errore connessione mancante x getCncAlarms");
+ }
+ // verifico SE sia cambiato il programma...
+ if (currAlarms.Count > 0)
+ {
+ try
+ {
+ string sVal = "";
+ if (lastAlarm != currAlarms["CNC_ALARM"])
+ {
+ // salvo!
+ lastAlarm = currAlarms["CNC_ALARM"];
+ // per ogni valore del dizionario mostro ed accodo!
+ foreach (var item in currAlarms)
+ {
+ sVal = string.Format("[CNC_ALARM]{0}|{1}", item.Key, item.Value);
+ // chiamo accodamento...
+ accodaFLog(sVal, qEncodeFLog(item.Key, item.Value));
+ }
+ }
+ // accodo ALTRI allarmi NON CNC...
+ foreach (var item in currAlarms.Where(X => X.Key != "CNC_ALARM"))
+ {
+ sVal = $"{item.Key} | {item.Value}";
+ accodaFLog(sVal, qEncodeFLog(item.Key, item.Value));
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError("Eccezione in processCncAlarms{0}{1}", Environment.NewLine, exc);
+ }
+ }
+ }
+ }
+
+ ///
+ /// Effettua processing contapezzi (ed eventualmente alza il bit di contapezzo...)
+ ///
+ public virtual void processContapezzi()
+ { }
+
+ ///
+ /// Effettua processing CUSTOM x l'IOB corrente (ed invia ad IO) (task svolto tipicamente
+ /// ogni 5 sec se base timer 10ms, vedere app.config)
+ ///
+ public virtual void processCustomTaskLF()
+ { }
+
+ ///
+ /// Task periodici SE disconnesso
+ ///
+ public virtual void processDisconnectedTask()
+ {
+ }
+
+ ///
+ /// Effettua processing del recupero dei valori dinamici:
+ /// es: speed (RPM, feedrate) degli assi, valori pressioni, temeprature
+ ///
+ public void processDynData()
+ {
+ bool enableByApp = utils.CRB("enableDynData");
+ bool enableByIob = (getOptPar("ENABLE_DYN_DATA") == "TRUE");
+ bool forceSendByIob = (getOptPar("FORCE_DYN_DATA") == "TRUE");
+ Dictionary currDynData = new Dictionary();
+
+ if (enableByApp || enableByIob)
+ {
+ // verifico se ho fattore demoltiplica...
+ if (demFactDynData > 1)
+ {
+ lgTrace($"Non eseguo processDynData: fatt veto {demFactDynData}");
+ // ricudo...
+ demFactDynData--;
+ }
+ else
+ {
+ lgInfo("Inizio processDynData");
+ // sistemo il valore di demoltiplica a default
+ fixDemFactDynData();
+ // proseguo
+ if (connectionOk)
+ {
+ currDynData = getDynData();
+ try
+ {
+ string sVal = "";
+ // se richiesto send diretto...
+ if (forceSendByIob)
+ {
+ // per ogni valore del dizionario mostro ed accodo!
+ foreach (var item in currDynData)
+ {
+ sVal = string.Format("[DYNDATA]{0}|{1}", item.Key, item.Value);
+ // chiamo accodamento...
+ accodaFLog(sVal, qEncodeFLog(item.Key, item.Value));
+ }
+ }
+ // altrimenti verifico SE sia cambiato il valore dei DynData...
+ else if (lastDynDataCtrlVal != currDynData["DYNDATA"])
+ {
+ // salvo!
+ lastDynDataCtrlVal = currDynData["DYNDATA"];
+ // per ogni valore del dizionario mostro ed accodo!
+ foreach (var item in currDynData)
+ {
+ sVal = string.Format("[DYNDATA]{0}|{1}", item.Key, item.Value);
+ // chiamo accodamento...
+ accodaFLog(sVal, qEncodeFLog(item.Key, item.Value));
+ }
+ }
+ // salvo array...
+ lastDynData = currDynData;
+ }
+ catch (Exception exc)
+ {
+ lgError(exc, "Eccezione in processDynData");
+ }
+ }
+ else
+ {
+ lgError("Errore connessione mancante x getDynData");
+ }
+ }
+ }
+ }
+
+ ///
+ /// Processa gestione memoria x invio dati QUANDO IOB è disconnesso da CNC...
+ ///
+ public void processMemoryDiscon()
+ {
+ // init obj display
+ newDisplayData currDispData = new newDisplayData();
+ // controllo contatore invio "keepalive"... invio solo a scadenza
+ if (DateTime.Now.Subtract(lastDisconnCheck).TotalSeconds > utils.CRI("disconMaxSec"))
+ {
+ // resetto tutti i valori BYTE IN/PREV/OUT... così invio macchina spenta...
+ B_input = 0;
+ B_output = 0;
+ B_previous = 0;
+ accodaSigIN(ref currDispData);
+ // update controllo
+ lastDisconnCheck = DateTime.Now;
+ }
+ raiseRefresh(currDispData);
+ }
+
+ ///
+ /// Effettua processing mode/status (EDIT/MDI/...)
+ ///
+ public virtual void processMode()
+ { }
+
+ ///
+ /// Effettua processing ALTRI contatori/parametri (ed invia ad IO)
+ ///
+ public virtual void processOtherCounters()
+ { }
+
+ ///
+ /// Effettua processing del recupero delle OVERRIDE (spindle, feedrate, rapid)
+ ///
+ public virtual void processOverride()
+ {
+ bool enableByApp = utils.CRB("enableOverrides");
+ bool enableByIob = (getOptPar("ENABLE_OVERRIDES") == "TRUE");
+ Dictionary currOverride = new Dictionary();
+ if (enableByApp || enableByIob)
+ {
+ lgInfo("Inizio processOverride");
+ if (connectionOk)
+ {
+ currOverride = getOverrides();
+ }
+ else
+ {
+ lgError("Errore connessione mancante x getOverrides");
+ }
+
+ // SE sono connesso...
+ if (connectionOk)
+ {
+ // se HO dei valori override...
+ if (currOverride.Count > 0)
+ {
+ // verifico SE sia cambiato il programma...
+ if (lastOverrideFS != currOverride["FEED_OVER"] || lastOverrideRapid != currOverride["RAPID_OVER"])
+ {
+ // salvo!
+ lastOverrideFS = currOverride["FEED_OVER"];
+ lastOverrideRapid = currOverride["RAPID_OVER"];
+ // per ogni valore del dizionario mostro ed accodo!
+ string sVal = "";
+ foreach (var item in currOverride)
+ {
+ sVal = string.Format("[OVERRIDES]{0}|{1}", item.Key, item.Value);
+ // chiamo accodamento...
+ accodaFLog(sVal, qEncodeFLog(item.Key, item.Value));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ ///
+ /// Effettua ciclo controllo richieste server
+ ///
+ public void processServerRequests()
+ {
+ Dictionary task2exe = new Dictionary();
+ Dictionary taskDone = new Dictionary();
+ // recupero elenco delle cose da fare
+ string resp = getTask2exe();
+ if (!string.IsNullOrEmpty(resp))
+ {
+ try
+ {
+ task2exe = JsonConvert.DeserializeObject>(resp);
+ // se ho da fare chiamo esecuzione..
+ if (task2exe.Count > 0)
+ {
+ taskDone = processTask(task2exe);
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError($"Eccezione in processServerRequests:{Environment.NewLine}{exc}");
+ }
+ }
+ }
+
+ public Dictionary processTask(Dictionary task2exe)
+ {
+ Dictionary taskDone = new Dictionary();
+ if (task2exe != null)
+ {
+ lgInfo($"Task2Exe S01: {task2exe.Count} task ricevuti:");
+ int idTask = 0;
+ foreach (var item in task2exe)
+ {
+ idTask++;
+ lgInfo($"[{idTask:00}] - {item.Key} --> {item.Value}");
+ }
+ // chiamo procedura esecutiva (diversa x ogni IOB)
+ taskDone = executeTasks(task2exe);
+ lgInfo($"Task2Exe S02: eseguiti {taskDone.Count} task");
+ // loggo tutti i task done...
+ foreach (var item in taskDone)
+ {
+ sendToTaskWatch(item.Key, item.Value);
+ }
+ // ora chiamo la cancellazione dei task eseguiti...
+ foreach (var item in taskDone)
+ {
+ remTask2exe(item.Key, item.Value);
+ }
+ }
+ return taskDone;
+ }
+
+ ///
+ /// Classe fittizia in caso di processing task in VHF
+ ///
+ public virtual void processVHF()
+ {
+ }
+
+ ///
+ /// Classe fittizia in caso di processing watchdog data
+ ///
+ public virtual void processWhatchDog()
+ {
+ }
+
+ ///
+ /// Effettua rilettura del contapezzi dal server MP/IO
+ ///
+ /// Forza rilettura da DB tempi ciclo rilevati
+ public void pzCntReload(bool forceCountRec)
+ {
+ // legge da IO server ULTIMO valore CONTPEZZI al riavvio...
+ string currServerCount = "";
+ string lastIdxODL = "";
+ if (checkServerAlive)
+ {
+ // leggo PRIMA ODL ....
+ lastIdxODL = utils.callUrl(urlGetCurrODL);
+ lgTrace("Lettura ODL dall'url {0} --> {1}", urlGetCurrODL, lastIdxODL);
+ // se ho valori in coda da trasmettere uso dati REDIS
+ if (forceCountRec)
+ {
+ // uso dati da TCiclo registrati...
+ currServerCount = utils.callUrl(urlGetPzCountRec);
+ lgInfo("Lettura contapezzi da TCiclo dall'url {0} --> num pz: {1}", urlGetPzCountRec, currServerCount);
+ }
+ else
+ {
+ // uso il contapezzi dichiarato dall'IOB stesso
+ currServerCount = utils.callUrl(urlGetPzCount);
+ lgInfo("Lettura contapezzi dall'url {0}", urlGetPzCount);
+ }
+ // controllo: SE NON HO ODL...
+ if (string.IsNullOrEmpty(lastIdxODL) || lastIdxODL == "0")
+ {
+ // NON AGGIORNO
+ contapezziIOB = contapezziPLC;
+ lgError($"Errore lettura ODL (vuoto) resta tutto invariato contapezzi: {contapezziIOB} | contapezziPLC {contapezziPLC}");
+ }
+ else
+ {
+ if (!string.IsNullOrEmpty(currServerCount))
+ {
+ // se "-1" resto a ultimo...
+ if (currServerCount != "-1")
+ {
+ int newVal = -1;
+ Int32.TryParse(currServerCount, out newVal);
+ contapezziIOB = newVal > -1 ? newVal : contapezziIOB;
+ lgInfo("Ricevuta conferma da server di {0} pezzi registrati per ODL", currServerCount);
+ }
+ else
+ {
+ // NON AGGIORNO
+ contapezziIOB = contapezziPLC;
+ lgError($"Errore lettura contapezzi (-1) - uso contapezziPLC --> {contapezziPLC}");
+ }
+ }
+ else
+ {
+ // registro che ho UN NUOVO ODL
+ lgInfo($"Lettura ODL in pzCntReload, currIdxODL {currIdxODL} --> lastIdxODL {lastIdxODL}");
+ // se ODL differente e NUOVO è zero --> resetto!
+ if (currIdxODL.ToString() != lastIdxODL && lastIdxODL == "0")
+ {
+ // cambiato ODL quindi reset...
+ contapezziIOB = 0;
+ lgInfo("Nuovo ODL==0, RESET contapezzi (-->ZERO)");
+ }
+ // provo a salvare nuovo ODL
+ int.TryParse(lastIdxODL, out currIdxODL);
+ }
}
}
else
{
- currPrgName = lastPrgName;
- }
- // verifico SE sia cambiato il programma...
- if (lastPrgName != currPrgName)
- {
- // salvo!
- lastPrgName = currPrgName;
- string sVal = string.Format("[PROG]{0}", currPrgName);
-
- // chiamo accodamento...
- accodaFLog(sVal, qEncodeFLog("PROG", currPrgName));
+ // se server NON pronto...
+ contapezziIOB = contapezziPLC;
+ lgError("Errore server NON pronto in pzCntReload");
}
}
///
- /// Processo lettura dati sysinfo
+ /// Fornisce il valore di flusso e valore in formato valido x messa in coda nel formato
+ /// dtEve#flusso#valore#cont Flusso datiValore da salvare
///
- private void processSysInfo()
+ public string qEncodeFLog(string flusso, string valore)
{
- if (utils.CRB("enableSysInfo"))
+ string answ = "";
+ try
{
- Dictionary currSysInfo = new Dictionary();
+ answ = $"{DateTime.Now:yyyyMMddHHmmssfff}#{flusso}#{valore}#{counterULog}";
+ }
+ catch
+ { }
+ return answ;
+ }
+ ///
+ /// Fornisce il valore di flusso e valore in formato valido x messa in coda nel formato
+ /// dtEve#flux#value#cont DataOra evento
+ /// registratoFlusso datiValore da salvare
+ ///
+ public string qEncodeFLog(DateTime eventDT, string flusso, string valore)
+ {
+ string answ = "";
+ try
+ {
+ answ = $"{eventDT:yyyyMMddHHmmssfff}#{flusso}#{valore}#{counterFLog}";
+ }
+ catch
+ { }
+ return answ;
+ }
+
+ ///
+ /// Fornisce il valore di UserLog e valore in formato valido x messa in coda nel formato:
+ /// dtEve#flusso#value#cont#matrOpr#label#valNum Flusso dati
+ /// (RC/RS/DI)Valore da inviare
+ /// (valStringMatricola operatoreValore etichetta: causale scarto / tagCodeValore numerico: esitoOk (0/1) / nuo scarti
+ ///
+ public string qEncodeULog(string flusso, string valore, int matrOpr, string label, int valNum)
+ {
+ string answ = "";
+ try
+ {
+ answ = $"{DateTime.Now:yyyyMMddHHmmssfff}#{flusso}#{valore}#{matrOpr}#{label}#{valNum}#{counterULog}";
+ }
+ catch
+ { }
+ return answ;
+ }
+
+ ///
+ /// Effettua lettura dati Parametri da aggiornare x display in form
+ ///
+ public virtual void readAllData(ref newDisplayData currDispData)
+ {
+ if (currDispData == null)
+ {
+ currDispData = new newDisplayData();
+ }
+ try
+ {
+ if (DemoIn)
+ {
+ // segnalo che sono in Demo
+ currDispData.semIn = Semaforo.SV;
+ }
if (connectionOk)
{
- currSysInfo = getSysInfo();
+ readSemafori(ref currDispData);
}
else
{
- lgError("Errore connessione mancante x getSysInfo");
+ lgError("Errore connessione mancante x readSemafori");
}
- // verifico SE sia cambiato il programma...
- if (lastSysInfo != currSysInfo["SYSINFO"])
+
+ nReadIN++;
+ // aggiorno valore mostrato...
+ displayRawData(ref currDispData);
+ }
+ catch
+ {
+ currDispData.semIn = Semaforo.SR;
+ }
+ raiseRefresh(currDispData);
+ }
+
+ ///
+ /// Effettua lettura semafori principale Parametri da
+ /// aggiornare x display in form
+ ///
+ public virtual void readSemafori(ref newDisplayData currDispData)
+ {
+ lastReadPLC = DateTime.Now;
+ }
+
+ ///
+ /// Aggiunge ai dati da inviare alla parentform i valori di RawInput rilevati (32bit)
+ /// 2021.08.27: filtrati secondo i valori setup start/size RawDataInput
+ ///
+ public virtual void reportRawInput(ref newDisplayData currDispData)
+ {
+ // processo eventualmente aggiungendo ad elementi esistenti...
+ if (currDispData == null)
+ {
+ currDispData = new newDisplayData();
+ }
+ try
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.Append($"B_input --> {(short)B_input}{Environment.NewLine}");
+ sb.Append($"{baseUtils.binaryForm(B_input)}{Environment.NewLine}");
+ sb.Append($"{Environment.NewLine}");
+ sb.Append($"----------- RAW Data Memory -----------{Environment.NewLine}");
+ // Do x scontato siano VALIDI i valori di RawDataInputStart / size --> filtro...
+ var filtRawData = new byte[RawDataInputSize];
+ Array.Copy(RawInput, RawDataInputStart, filtRawData, 0, RawDataInputSize);
+ int i = RawDataInputStart;
+ foreach (var item in filtRawData)
{
- // salvo!
- lastSysInfo = currSysInfo["SYSINFO"];
- // per ogni valore del dizionario mostro ed accodo!
- string sVal = "";
- foreach (var item in currSysInfo)
+ sb.Append($"B{i:00} --> {baseUtils.binaryForm(item)} = {(short)item}{Environment.NewLine}");
+ i++;
+ }
+ sb.Append("-------------------------------");
+ currDispData.currBitmap = sb.ToString();
+ }
+ catch
+ { }
+ }
+
+ ///
+ /// Metodo generico di reset contapezzi...
+ ///
+ ///
+ public virtual bool resetcontapezziPLC()
+ {
+ return false;
+ }
+
+ ///
+ /// metodo dummy x salvataggio aree memoria conf x CN
+ ///
+ /// tipo di DUMP
+ public virtual void saveMemDump(dumpType tipo)
+ {
+ }
+
+ ///
+ /// Salva valori indicati in prod data
+ ///
+ /// Item KVP di cui salvare i dati in currProdData come chiave/valore
+ ///
+ public void saveProdData(KeyValuePair item)
+ {
+ // imposto i valori...
+ if (currProdData.ContainsKey(item.Key))
+ {
+ currProdData[item.Key] = item.Value;
+ }
+ else
+ {
+ currProdData.Add(item.Key, item.Value);
+ }
+ }
+
+ ///
+ /// Effettua salvataggio in LUT del valore ricevuto (valori numerici)
+ ///
+ ///
+ ///
+ ///
+ ///
+ public virtual void saveValue(ref Dictionary outVal, double valore, string chiave)
+ {
+ //check obj preliminare
+ if (outVal == null)
+ {
+ outVal = new Dictionary();
+ }
+ bool scaduto = stackVal_TSVC(chiave, valore);
+ // recupero VC
+ valore = getVal_TSVC(chiave, scaduto);
+ if (scaduto)
+ {
+ // limite a 3 digit x valore float
+ outVal.Add(chiave, $"{valore:N3}");
+ }
+ LastTSVC[chiave] = valore;
+ }
+
+ ///
+ /// Effettua salvataggio in LUT del valore ricevuto (valori string)
+ /// - non serve calcolo medie o altro
+ /// - accoda in out val e basta
+ ///
+ /// Array eventi da popolare
+ /// valore da salvare
+ /// ID/chiave di riferimento
+ ///
+ public virtual void saveAlarmString(ref Dictionary outVal, string valore, string chiave)
+ {
+ DateTime adesso = DateTime.Now;
+ //check obj preliminare
+ if (outVal == null)
+ {
+ outVal = new Dictionary();
+ }
+ // default invio: blindato a 120 sec (rivedere da conf?)
+ int vetoSendAlarms = 120;
+ // verifico se sia scaduto OVVERO variato rispetto a prima oppure oltre tempo
+ bool scaduto = !LastTSSSend.ContainsKey(chiave) || (LastTSSSend[chiave].AddSeconds(vetoSendAlarms) < adesso);
+ bool cambiato = !LastTSS.ContainsKey(chiave) || !LastTSS[chiave].Equals(valore);
+ if (scaduto || cambiato)
+ {
+ outVal.Add(chiave, valore);
+ LastTSS[chiave] = valore;
+ LastTSSSend[chiave] = adesso;
+ }
+ }
+
+ ///
+ /// Effettua salvataggio in LUT del valore ricevuto (valori string)
+ /// - non serve calcolo medie o altro
+ /// - accoda in out val e basta
+ ///
+ /// Array eventi da popolare
+ /// valore da salvare
+ /// ID/chiave di riferimento
+ ///
+ public virtual void saveValueString(ref Dictionary outVal, string valore, string chiave)
+ {
+ DateTime adesso = DateTime.Now;
+ //check obj preliminare
+ if (outVal == null)
+ {
+ outVal = new Dictionary();
+ }
+ int maxVetoSeconds = 60;
+
+ // cerco VC...
+ if (TSVC_Data.ContainsKey(chiave))
+ {
+ maxVetoSeconds = TSVC_Data[chiave].Period;
+ }
+ // verifico se sia scaduto OVVERO variato rispetto a prima oppure oltre tempo
+ bool scaduto = !LastTSSSend.ContainsKey(chiave) || (LastTSSSend[chiave].AddSeconds(maxVetoSeconds) < adesso);
+ bool cambiato = !LastTSS.ContainsKey(chiave) || !LastTSS[chiave].Equals(valore);
+ if (scaduto || cambiato)
+ {
+ outVal.Add(chiave, valore);
+ LastTSS[chiave] = valore;
+ LastTSSSend[chiave] = adesso;
+ }
+ }
+
+ ///
+ /// Invio la variazione dello stato allarmi (se avvenuta)
+ ///
+ /// COD memoria allarmi
+ /// Indice memoria allarmi
+ /// ultimo stato rilevato
+ /// stato corrente
+ /// Lista allarmi validi per l'area
+ ///
+ public bool sendAlarmVariations(string memAddr, int index, uint lastStatus, uint currStatus, List AlarmList)
+ {
+ bool fatto = false;
+ if (lastStatus != currStatus)
+ {
+ List ActiveAlarmList = new List();
+ // invio GET del MemoryAddress, del banco e del valore currStatus
+ lastUrl = $"{urlSendAlarm}?memAddr={memAddr}&index={index}&currStatus={currStatus}";
+ if (currStatus == 0)
+ {
+ ActiveAlarmList.Add("ALL OK");
+ }
+ else
+ {
+ // calcolo quali allarmi mostrare dato currStatus ed elenco allarmi
+ string bitMap = Convert.ToString(currStatus, 2);
+ int bitLen = bitMap.Length;
+ // ciclo x associare tutti gli allarmi
+ for (int i = 0; i < bitLen; i++)
{
- sVal = string.Format("[SYSINFO]{0}|{1}", item.Key, item.Value);
- // chiamo accodamento...
- accodaFLog(sVal, qEncodeFLog(item.Key, item.Value));
+ // se è 1 --> aggiungo!
+ if (bitMap[bitLen - i - 1] == '1')
+ {
+ // se sono entro limiti
+ if (AlarmList.Count >= i)
+ {
+ ActiveAlarmList.Add($"{i:000}-{AlarmList.ElementAt(i)}");
+ }
+ //else
+ //{
+ // ActiveAlarmList.Add($"Unknown Bit.{i}");
+ //}
+ }
}
}
- }
- }
- private void reportDataProc()
- {
- // update valori visualizzazione...
- parentForm.dataProcLabel = string.Format("RAW: {0} --> IN: {1} --> OUT: {2}", nReadIN, nReadFilt, nSendOut);
- }
+ string rawData = JsonConvert.SerializeObject(ActiveAlarmList);
- ///
- /// Imposto alcuni valori di default
- ///
- /// indica se sia richeisto di SVUOTARE le code delel info
- private void setDefaults(bool resetQueue)
- {
- numSim = utils.CRI("numSim");
- lastPrgName = "";
- nReadIN = 0;
- nReadFilt = 0;
- nSendOut = 0;
- currMode = 0;
- lastAlarm = "";
- doStartMemDump = utils.CRB("doStartMemDump");
- doSampleMemory = utils.CRB("doSampleMemory");
- // fix url wait random...
- urlRandWait = utils.CRI("urlRandWait");
-
- // svuoto code se richiesto
- if (resetQueue)
- {
- QueueAlarm = new ConcurrentQueue();
- QueueIN = new ConcurrentQueue();
- QueueFLog = new ConcurrentQueue();
- QueueMessages = new ConcurrentQueue();
- QueueRawTransf = new ConcurrentQueue();
- QueueULog = new ConcurrentQueue();
- }
- // imposto contatori blink a zero...
- i_counters = new int[32];
- lastPeriodicLog = DateTime.Now;
- // fix parametri generali...
- enablePrgName = true;
- }
-
- private void svuotaCodaContapezzi()
- {
- // permetto al max 2 tentativi infruttuosi...
- int maxTry = 2;
- int oldContapezzi = contapezziIOB;
- // se ho contapezzi OLTRE limite...
- while ((MPOnline) && (contapezziPLC > contapezziIOB + minSendPzCountBlock))
- {
- lgInfo($"Ciclo svuotaCodaContapezzi --> contapezziPLC: {contapezziPLC} | contapezziIOB: {contapezziIOB}");
- if (!isMulti)
+ //string resp = utils.callUrlNow(lastUrl, rawData);
+ string resp = utils.callUrlAsync(lastUrl, rawData);
+ if (!string.IsNullOrEmpty(resp))
{
- pzCntReload(true);
- }
- // provo invio
- trySendPzCountBlock();
- // verifica per evitare loop infinito invio fallito
- if (oldContapezzi == contapezziIOB)
- {
- maxTry--;
+ if (resp.ToUpper() == "OK")
+ {
+ // segnalo fatto
+ fatto = true;
+ }
}
else
{
- maxTry = 2;
- oldContapezzi = contapezziIOB;
+ lgError($"Errore in invio richiesta registrazione allarme: URL: {lastUrl}{Environment.NewLine}Payload:{Environment.NewLine}{rawData}");
}
- // verifico maxTry: se li ho esauriti esco!
- if (maxTry <= 0)
- {
- return;
- }
- // aspetto x dare tempo calcolo
- Thread.Sleep(400);
}
+ return fatto;
}
///
- /// Processo la coda FLog...
+ /// Invia una LISTA di valori
///
- private void svuotaCodaFLog()
+ ///
+ ///
+ public void sendDataBlock(urlType tipoUrl, List listQueueVal)
{
- // controllo se è passato oltre watchdog e non ho inviato nulla --> RE-INVIO (ultimo inviato)!!!!
- if (DateTime.Now.Subtract(lastWatchDog).TotalSeconds > utils.CRI("watchdogMaxSec"))
+ // init obj display
+ newDisplayData currDispData = new newDisplayData();
+ if (listQueueVal != null)
{
- string wdStatus = "elapsed";
- string sVal = string.Format("[WDST]{0}", wdStatus);
- // chiamo accodamento...
- accodaFLog(sVal, qEncodeFLog("WDST", wdStatus));
- lastWatchDog = DateTime.Now;
- }
- // verifico SE la coda abbia dei valori...
- if (QueueFLog.Count > 0)
- {
- // invio pacchetto di dati (max da conf)
- for (int i = 0; i < nMaxSend; i++)
+ try
{
- // SE ho qualcosa in coda...
- if (QueueFLog.Count > 0)
+ // recupero e formatto URL dati da coda...
+ lastUrl = urlDataBlock(tipoUrl);
+ // in base al tipo di dato compongo il payload Json da inviare
+ string payload = jsonPayload(tipoUrl, listQueueVal);
+ // async a true SE FLog
+ bool doAsync = tipoUrl == urlType.FLog ? true : false;
+ // se NON sono in demo effettuo invio!
+ if (!DemoOut)
{
- string currVal = "";
- if (MPOnline)
+ // SE server alive...
+ if (checkServerAlive)
{
- if (IobOnline)
+ // chiamo URL!
+ string answ = callUrlWithPayload(lastUrl, payload, doAsync);
+ // attesa opzionale se configurata
+
+ // loggo!
+ lgInfo($"[SEND payload] TipoURL: {tipoUrl} | {listQueueVal.Count} records --> {answ}");
+ // se "OK" verde, altrimenti errore --> ROSSO
+ if (answ.Contains("OK"))
{
- // se ho + di 2 elementi in coda --> uso invio JSON in blocco...
- if (QueueFLog.Count > 1)
+ currDispData.semOut = Semaforo.SV;
+ // se oltre 1 min NON era online --> check pezzi!
+ if (DateTime.Now.Subtract(lastIobOnline).TotalMinutes > 1 && !isMulti)
{
- List listaValori = new List();
- // se ho + di maxJsonData elementi --> invio un set di dati alla volta
- if (QueueFLog.Count > maxJsonData)
- {
- // prendoi primi maxJsonDataValori
- for (int j = 0; j < maxJsonData; j++)
- {
- QueueFLog.TryDequeue(out currVal);
- listaValori.Add(currVal);
- }
- sendDataBlock(urlType.FLog, listaValori);
- lastWatchDog = DateTime.Now;
- }
- else
- {
- // invio in blocco
- listaValori = QueueFLog.ToList();
- // invio
- sendDataBlock(urlType.FLog, listaValori);
- // svuoto!
- QueueFLog = new ConcurrentQueue();
- lastWatchDog = DateTime.Now;
- }
- }
- else
- {
- // INVIO SINGOLO...!!!
- QueueFLog.TryDequeue(out currVal);
- sendToMoonPro(urlType.FLog, currVal);
- lastWatchDog = DateTime.Now;
+ lgInfo($"sendDataBlock --> offline timeout ({lastIobOnline}) --> pzCntReload(true)");
+ pzCntReload(true);
}
+ lastIobOnline = DateTime.Now;
}
else
{
- break;
+ currDispData.semOut = Semaforo.SR;
}
}
else
{
- break;
+ lgInfo($"[SERVER KO] {listQueueVal.Count}");
}
}
else
{
- break;
+ currDispData.semOut = Semaforo.SV;
+ // loggo!
+ lgInfo($"{listQueueVal.Count} records --> [SIM]");
}
+ nSendOut += listQueueVal.Count;
+ // riporto cosa inviato
+ currDispData.newUrlCallData = lastUrl;
+ // aggiorno data ultimo watchdog...
+ lastWatchDog = DateTime.Now;
}
- }
- }
-
- //
- /// Processo la coda UserLog...
- ///
- private void svuotaCodaULog()
- {
- // verifico SE la coda abbia dei valori...
- if (QueueULog.Count > 0)
- {
- // invio pacchetto di dati (max da conf)
- for (int i = 0; i < nMaxSend; i++)
+ catch
{
- // SE ho qualcosa in coda...
- if (QueueULog.Count > 0)
- {
- string currVal = "";
- if (MPOnline)
- {
- if (IobOnline)
- {
- List listaValori = new List();
- // se ho + di maxJsonData elementi --> invio un set di dati alla volta
- if (QueueULog.Count > maxJsonData)
- {
- // prendoi primi maxJsonDataValori
- for (int j = 0; j < maxJsonData; j++)
- {
- QueueULog.TryDequeue(out currVal);
- listaValori.Add(currVal);
- }
- sendDataBlock(urlType.ULog, listaValori);
- }
- else
- {
- // invio in blocco
- listaValori = QueueULog.ToList();
- // invio
- sendDataBlock(urlType.ULog, listaValori);
- // svuoto!
- QueueULog = new ConcurrentQueue();
- }
- }
- else
- {
- break;
- }
- }
- else
- {
- break;
- }
- }
- else
- {
- break;
- }
+ currDispData.semOut = Semaforo.SR;
}
}
+ raiseRefresh(currDispData);
}
///
- /// Cerca di inviare su un altro thread i vari dati accumulati...
+ /// Effettua invio a MoonPro del valore richiesto
///
- private void trySendValues()
+ ///
+ ///
+ /// Valore da trasmettere: es
+ /// INPUT: lo status rilevato in HEX
+ /// FLog: il valore da trasmettere per il flusso indicato
+ ///
+ public void sendToMoonPro(urlType tipoUrl, string queueVal)
{
// init obj display
newDisplayData currDispData = new newDisplayData();
try
{
- // verifico se risponde il server...
- if (checkServerAlive)
+ // recupero e formatto URL dati da coda...
+ switch (tipoUrl)
{
- bool iobOk = false;
- if (utils.CRB("sendDataByThread"))
+ case urlType.FLog:
+ lastUrl = urlFLog(queueVal);
+ break;
+
+ case urlType.SignIN:
+ lastUrl = urlInput(queueVal);
+ break;
+
+ default:
+ lastUrl = "";
+ break;
+ }
+ // se NON sono in demo effettuo invio!
+ if (!DemoOut)
+ {
+ // SE server alive...
+ if (checkServerAlive)
{
- Task taskCheck = Task.Run(() => iobOk = checkIobEnabled);
- }
- else
- {
- iobOk = checkIobEnabled;
- }
- // verifico SE posso inviare dati
- if (iobOk)
- {
- currDispData.semOut = Semaforo.SV;
- // verificare come gestire il task secondario senza interferenza (chiamate update su FORM da thread secondari danno errori)
- if (utils.CRB("sendDataByThread"))
+ // chiamo URL!
+ string answ = callUrl(lastUrl, false);
+ // loggo!
+ lgDebug(string.Format("[SEND] {0} -> {1}", queueVal, answ));
+ // se oltre 1 min NON era online --> check pezzi!
+ if (DateTime.Now.Subtract(lastIobOnline).TotalMinutes > 1 && !isMulti)
{
- // invio con thread separato...
- Task taskSigIN = Task.Run(() => svuotaCodaSignIN());
- Task taskFLog = Task.Run(() => svuotaCodaFLog());
- Task taskULog = Task.Run(() => svuotaCodaULog());
+ lgInfo($"sendToMoonPro --> offline timeout ({lastIobOnline}) --> pzCntReload(true)");
+ pzCntReload(true);
+ }
+ // se richiesto effettuo refresh contapezzi
+ if (needRefreshPzCount && !isMulti)
+ {
+ pzCntReload(true);
+ needRefreshPzCount = false;
+ }
+ lastIobOnline = DateTime.Now;
+ // se "OK" verde, altrimenti errore --> ROSSO
+ if (answ == "OK")
+ {
+ currDispData.semOut = Semaforo.SV;
}
else
{
- // gestione queue SignalIN (invio, display)
- svuotaCodaSignIN();
- currDispData.counter = contapezziIOB;
- raiseRefresh(currDispData);
- // provo a svuotare coda contapezzi
- svuotaCodaContapezzi();
- currDispData.counter = contapezziIOB;
- raiseRefresh(currDispData);
- // gestione queue FluxLog (invio, display)
- svuotaCodaFLog();
- // coda UserLog
- svuotaCodaULog();
- // refresh
- raiseRefresh(currDispData);
+ currDispData.semOut = Semaforo.SR;
}
- // se arrivo è tutto ok...
- currSendErrors = 0;
}
else
{
- // mostro VETO-SEND x invio... GIALLO
- currDispData.semOut = Semaforo.SG;
- if (periodicLog)
- {
- lgInfo("IOB - VETO SEND");
- }
+ lgError(string.Format("[SERVER KO] {0}", queueVal));
}
}
else
{
- // mostro SERVER KO x invio... ROSSO
- currDispData.semOut = Semaforo.SR;
- if (periodicLog)
- {
- lgError("IOB - SERVER NOT READY");
- }
+ currDispData.semOut = Semaforo.SV;
+ // loggo!
+ lgDebug(string.Format("{0} -> [SIM]", queueVal));
}
+ nSendOut++;
+ currDispData.newUrlCallData = lastUrl;
+ // aggiorno data ultimo watchdog...
+ lastWatchDog = DateTime.Now;
}
- catch (Exception exc)
+ catch
{
- lgError($"Errore in fase trySendValues | currSendErrors: {currSendErrors}{Environment.NewLine}{exc}");
currDispData.semOut = Semaforo.SR;
}
raiseRefresh(currDispData);
}
///
- /// Aggiorna un valore del dizionario in INCREMENTO e lo restituisce
+ /// Metodo generico di IMPOSTAZIONE FORZATA del contapezzi...
///
- ///
- ///
- ///
- /// Nuovo valore incrementato
- private double updateValDoubleByIncr(int i, double delta, string searchString)
+ /// Pezzi richiesti
+ ///
+ public virtual bool setcontapezziPLC(int newPzCount)
{
- // stringa da cercare..
- string keyVal = string.Format(searchString, i + 1);
- // recupero valore precedente...
- double contAct = getStoredValDouble(keyVal);
- // nuovo valore...
- contAct += delta;
- // salvo in ram!
- persistenceLayer[keyVal] = contAct.ToString();
- // rendo il valore!
- return contAct;
+ return false;
}
///
- /// Aggiorna un valore del dizionario in INCREMENTO e lo restituisce
+ /// Processing di Variabili Campionarie x TimeSeries, accoda valori x la VC (se esiste) e
+ /// restituisce bool val se SCADUTO periodo controllo
///
- ///
- ///
- ///
- /// Nuovo valore incrementato
- private long updateValLongByIncr(int i, long delta, string searchString)
+ /// Nome della VC
+ /// Valore (nuovo) delal VC
+ ///
+ public bool stackVal_TSVC(string VCName, double VCVal)
{
- // stringa da cercare..
- string keyVal = string.Format(searchString, i + 1);
- // recupero valore precedente...
- long contAct = getStoredValLong(keyVal);
- // nuovo valore...
- contAct += delta;
- // salvo in ram!
- persistenceLayer[keyVal] = contAct.ToString();
- // rendo il valore!
- return contAct;
+ bool answ = false;
+ // cerco VC...
+ if (TSVC_Data.ContainsKey(VCName))
+ {
+ TSVC_Data[VCName].dataArray.Add(VCVal);
+ // ora verifico scadenza...
+ if (TSVC_Data[VCName].DTStart.AddSeconds(TSVC_Data[VCName].Period) < DateTime.Now)
+ {
+ answ = true;
+ }
+ }
+ return answ;
}
///
- /// Aggiorna un valore del dizionario in SOSTITUZIONE
+ /// Avvia l'adapter sulla porta richiesta
///
- ///
- ///
- ///
- /// Nuovo valore incrementato
- private void updateValString(int i, string newVal, string searchString)
+ /// indica se sia richeisto di SVUOTARE le code delel info
+ public virtual void startAdapter(bool resetQueue)
{
- // stringa da cercare..
- string keyVal = string.Format(searchString, i + 1);
- // salvo in ram!
- persistenceLayer[keyVal] = newVal;
+ DateTime adesso = DateTime.Now; ;
+ DateTime scaduto = adesso.AddMinutes(-10);
+ lgInfo("Starting adapter...");
+ maxJsonData = utils.CRI("maxJsonData");
+ maxJsonDataEv = utils.CRI("maxJsonDataEv");
+ parentForm.commPlcActive = false;
+ adpRunning = true;
+ dtAvvioAdp = adesso;
+ lastWatchDog = scaduto;
+ lastPING = scaduto;
+ lastReadPLC = scaduto;
+ lastDisconnCheck = scaduto;
+ TimingData.resetData();
+ // aggiungo altri defaults
+ setDefaults(resetQueue);
+ adpTryRestart = true;
+ lgDebug("startAdapter completed");
}
///
- /// Aggiorna un valore del dizionario in SOSTITUZIONE e lo restituisce
+ /// ferma l'adapter...
///
- ///
- ///
- ///
- /// Nuovo valore incrementato
- private void updateValUInt(int i, uint newVal, string searchString)
+ ///
+ /// indica se si debba tentare di riavviare l'adapter (con caduta connessione viene fermato
+ /// in automatico)
+ ///
+ /// indica se sia richeisto di SVUOTARE le code delel info
+ public virtual void stopAdapter(bool tryRestart, bool forceDequeue)
{
- // stringa da cercare..
- string keyVal = string.Format(searchString, i + 1);
- // salvo in ram!
- persistenceLayer[keyVal] = newVal.ToString();
+ if (forceDequeue)
+ {
+ // svuoto le code dei valori letti e non ancora trasmessi...
+ parentForm.displayTaskAndLog("[CLOSING] Svuotamento FORZATO coda segnali...");
+ while (QueueIN.Count > 0)
+ {
+ // INVIO COMUNQUE...!!!
+ string valore = "";
+ QueueIN.TryDequeue(out valore);
+ sendToMoonPro(urlType.SignIN, valore);
+ }
+ parentForm.displayTaskAndLog("[CLOSING] Svuotamento FORZATO coda FluxLOG...");
+ // se ho + di 2 elementi in coda --> uso invio JSON in blocco...
+ if (QueueFLog.Count > minJsonData)
+ {
+ while (QueueFLog.Count > 0)
+ {
+ List listaValori = new List();
+ // se ho + di maxJsonData elementi --> invio un set di dati alla volta
+ if (QueueFLog.Count > maxJsonData)
+ {
+ string currVal = "";
+ // prendoi primi maxJsonDataValori
+ for (int i = 0; i < maxJsonData; i++)
+ {
+ QueueFLog.TryDequeue(out currVal);
+ listaValori.Add(currVal);
+ }
+ sendDataBlock(urlType.FLog, listaValori);
+ }
+ else
+ {
+ // invio in blocco
+ listaValori = QueueFLog.ToList();
+ // invio
+ sendDataBlock(urlType.FLog, listaValori);
+ // svuoto!
+ QueueFLog = new ConcurrentQueue();
+ }
+ }
+ // HO FINITO invio di FLog...
+ }
+ else
+ {
+ string currVal = "";
+ while (QueueFLog.Count > 0)
+ {
+ // INVIO COMUNQUE...!!!
+ QueueFLog.TryDequeue(out currVal);
+ sendToMoonPro(urlType.FLog, currVal);
+ }
+ }
+
+ // svuoto coda ULog
+ while (QueueULog.Count > 0)
+ {
+ List listaValori = new List();
+ // se ho + di maxJsonData elementi --> invio un set di dati alla volta
+ if (QueueULog.Count > maxJsonData)
+ {
+ string currVal = "";
+ // prendoi primi maxJsonDataValori
+ for (int i = 0; i < maxJsonData; i++)
+ {
+ QueueULog.TryDequeue(out currVal);
+ listaValori.Add(currVal);
+ }
+ sendDataBlock(urlType.ULog, listaValori);
+ }
+ else
+ {
+ // invio in blocco
+ listaValori = QueueULog.ToList();
+ // invio
+ sendDataBlock(urlType.ULog, listaValori);
+ // svuoto!
+ QueueULog = new ConcurrentQueue();
+ }
+ }
+ }
+ parentForm.displayTaskAndLog("[STOP] Stopping adapter...");
+ adpTryRestart = false;
+
+ parentForm.displayTaskAndLog("[STOP] Stopping adapter - last periodic data read...");
+
+ // chiudo la connessione all'adapter...
+ tryDisconnect();
+ dtStopAdp = DateTime.Now;
+ adpTryRestart = tryRestart;
+ adpRunning = false;
+ // chiudo!
+ parentForm.displayTaskAndLog("Adapter Stopped.");
+ parentForm.commPlcActive = false;
}
///
- /// Aggiorna un valore del dizionario in INCREMENTO e lo restituisce
+ /// Processo la coda SignalIN...
///
- ///
- ///
- ///
- /// Nuovo valore incrementato
- private uint updateValUIntByIncr(int i, uint delta, string searchString)
+ public void svuotaCodaSignIN()
{
- // stringa da cercare..
- string keyVal = string.Format(searchString, i + 1);
- // recupero valore precedente...
- uint contAct = getStoredValUInt(keyVal);
- // nuovo valore...
- contAct += delta;
- // salvo in ram!
- persistenceLayer[keyVal] = contAct.ToString();
- // rendo il valore!
- return contAct;
+ // verifico SE la coda abbia dei valori...
+ if (QueueIN.Count > 0)
+ {
+ // invio pacchetto di dati (max da conf)
+ for (int i = 0; i < nMaxSend; i++)
+ {
+ if (QueueIN.Count > 0)
+ {
+ string currVal = "";
+ // se online provo
+ if (MPOnline)
+ {
+ if (IobOnline)
+ {
+ // se ho + di 2 elementi in coda --> uso invio JSON in blocco...
+ if (QueueIN.Count > 1)
+ {
+ List listaValori = new List();
+ // se ho + di maxJsonData elementi --> invio un set di dati alla volta
+ if (QueueIN.Count > maxJsonDataEv)
+ {
+ // prendoi primi maxJsonDataValori
+ for (int j = 0; j < maxJsonDataEv; j++)
+ {
+ QueueIN.TryDequeue(out currVal);
+ listaValori.Add(currVal);
+ }
+ sendDataBlock(urlType.SignIN, listaValori);
+ }
+ else
+ {
+ // invio in blocco
+ listaValori = QueueIN.ToList();
+ // invio
+ sendDataBlock(urlType.SignIN, listaValori);
+ // svuoto!
+ QueueIN = new ConcurrentQueue();
+ }
+ }
+ else
+ {
+ // INVIO SINGOLO...!!!
+ QueueIN.TryDequeue(out currVal);
+ sendToMoonPro(urlType.SignIN, currVal);
+ }
+ // salvo come last signal in il currVal ultimo... SE !=""
+ if (!string.IsNullOrEmpty(currVal))
+ {
+ lastSignInVal = currVal;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
}
- #endregion Private Methods
+ ///
+ /// Metodo base connessione...
+ ///
+ public virtual void tryConnect()
+ {
+ dtAvvioAdp = DateTime.Now;
+ }
+
+ ///
+ /// Metodo base disconnessione...
+ ///
+ public virtual void tryDisconnect()
+ {
+ }
+
+ ///
+ /// Effettua verifica se abilitato invio pezzi in blocco e nel caso
+ /// - invio in blocco pezzi
+ /// - aggiornamento del contapezzi (passato come ref) x nuovo valore post invio
+ ///
+ public void trySendPzCountBlock()
+ {
+ // in primis HA SENSO procedere SOLO SE server MP è Online...
+ if (MPOnline)
+ {
+ // SOLO SE online la macchina...
+ if (IobOnline)
+ {
+ int numIncr = 0;
+ int qtyAdded = 0;
+ // verifico se la funzione SIA abilitata
+ if (enableSendPzCountBlock)
+ {
+ int delta = contapezziPLC - contapezziIOB;
+ // se è abilitata verifico differenza: se ho DELTA > minSendPzCountBlock -->
+ // invio un blocco <= maxSendPzCountBlock
+ if (delta > minSendPzCountBlock)
+ {
+ // init obj display
+ newDisplayData currDispData = new newDisplayData();
+ // resta indietro di ALMENO minSendPzCountBlock pezzi x recuperare 1:1...
+ numIncr = delta > maxSendPzCountBlock + minSendPzCountBlock ? maxSendPzCountBlock : delta - minSendPzCountBlock;
+ // invio il num max di pezzi ammesso in blocco!
+ lastUrl = $"{urlAddPzCount}{numIncr}";
+ string resp = utils.callUrlNow(lastUrl);
+ if (!string.IsNullOrEmpty(resp))
+ {
+ // dalla risposta (come numero) capisco SE ha aggiunto i pezzi (e quanti)
+ int.TryParse(resp, out qtyAdded);
+ if (qtyAdded > 0)
+ {
+ // aggiorno IL MIO contapezzi...
+ contapezziIOB += qtyAdded;
+ lgInfo($"Inviato incremento contapezzi: send: {numIncr} | resp: {qtyAdded} | contapezziIOB: {contapezziIOB}");
+ // invio conferma contapezzi..
+ string retVal = utils.callUrl($"{urlSetPzCount}{contapezziIOB}");
+ // verifica se tutto OK
+ if (retVal != contapezziIOB.ToString())
+ {
+ // errore salvataggio contapezzi
+ lgError($"trySendPzCountBlock: errore salvataggio contapezzi: contapezziIOB {contapezziIOB} | risposta: {retVal}");
+ }
+ }
+ else
+ {
+ lgError($"Richiesto incremento {numIncr} ma NON registrato su server MP-IO");
+ }
+ }
+ currDispData.newUrlCallData = lastUrl;
+ currDispData.counter = contapezziIOB;
+ currDispData.semOut = Semaforo.SV;
+ raiseRefresh(currDispData);
+ }
+ }
+ }
+ else
+ {
+ lgError("Impossibile trySendPzCountBlock: IobOnline è false");
+ }
+ }
+ else
+ {
+ lgError("Impossibile trySendPzCountBlock: MPOnline è false");
+ }
+ }
+
+ ///
+ /// Inserimento/aggiornamento chiavi/valore in currProdData
+ ///
+ ///
+ ///
+ public void upsertKey(string chiave, string valore)
+ {
+ if (currProdData.ContainsKey(chiave))
+ {
+ currProdData[chiave] = valore;
+ }
+ else
+ {
+ currProdData.Add(chiave, valore);
+ }
+ }
+
+ ///
+ /// Formatta URL x invio in DataBlock Json dei dati FLog / eventi
+ ///
+ ///
+ ///
+ public string urlDataBlock(urlType tipoUrl)
+ {
+ // verifico la parte di link "tipoComando"
+ string tipoComando = "";
+ switch (tipoUrl)
+ {
+ case urlType.FLog:
+ tipoComando = cIobConf.serverData.CMDFLOG_JSON;
+ break;
+
+ case urlType.SignIN:
+ tipoComando = cIobConf.serverData.CMDBASE_JSON;
+ break;
+
+ case urlType.RawTransf:
+ tipoComando = cIobConf.serverData.CMDRAWTRANSF_JSON;
+ break;
+
+ case urlType.ULog:
+ tipoComando = cIobConf.serverData.CMDULOG_JSON;
+ break;
+
+ default:
+ break;
+ }
+ // URL base x input
+ string answ = $@"{cIobConf.serverData.TRANSP}://{cIobConf.serverData.MPIP}{cIobConf.serverData.MPURL}{tipoComando}{cIobConf.codIOB}";
+ return answ;
+ }
+
+ ///
+ /// Fornisce URL di tipo FluxLog
+ ///
+ /// valore salvato in coda nel formato dtEve#flux#valore#counter
+ ///
+ public string urlFLog(string queueVal)
+ {
+ // URL base x input
+ string answ = $@"{cIobConf.serverData.TRANSP}://{cIobConf.serverData.MPIP}{cIobConf.serverData.MPURL}{cIobConf.serverData.CMDFLOG}";
+ // decodifica valore!
+ string[] valori = qDecodeIN(queueVal);
+ // aggiungo macchina e valore...
+ answ += string.Format(@"{0}?flux={1}&&valore={2}", cIobConf.codIOB, valori[1], valori[2]);
+ // aggiondo dataOra evento e corrente + contatore...
+ answ += string.Format(@"&&dtEve={0}&&dtCurr={1:yyyyMMddHHmmssfff}&&cnt={2}", valori[0], DateTime.Now, valori[3]);
+ return answ;
+ }
+
+ ///
+ /// Fornisce URL INPUT per i parametri richiesti
+ ///
+ /// valore salvato in coda formato dtEve#valore#counter
+ ///
+ public string urlInput(string queueVal)
+ {
+ // URL base x input
+ string answ = $@"{cIobConf.serverData.TRANSP}://{cIobConf.serverData.MPIP}{cIobConf.serverData.MPURL}{cIobConf.serverData.CMDBASE}";
+ // decodifica valore!
+ string[] valori = qDecodeIN(queueVal);
+ // aggiungo macchina e valore...
+ answ += string.Format(@"{0}?valore={1}", cIobConf.codIOB, valori[1]);
+ // aggiondo dataOra evento e corrente + contatore...
+ answ += string.Format(@"&&dtEve={0}&&dtCurr={1:yyyyMMddHHmmssfff}&&cnt={2}", valori[0], DateTime.Now, valori[2]);
+ return answ;
+ }
+
+ ///
+ /// Fornisce URL di tipo UserLog
+ ///
+ /// valore salvato in coda nel formato dtEve#flux#valore#counter
+ ///
+ public string urlULog(string queueVal)
+ {
+ // URL base x input
+ string answ = $@"{cIobConf.serverData.TRANSP}://{cIobConf.serverData.MPIP}{cIobConf.serverData.MPURL}{cIobConf.serverData.CMDULOG}";
+ // decodifica valore!
+ string[] valori = qDecodeIN(queueVal);
+ // aggiungo macchina e valore...
+ answ += string.Format(@"{0}?flux={1}&&valore={2}", cIobConf.codIOB, valori[1], valori[2]);
+ // aggiondo dataOra evento e corrente + contatore...
+ answ += string.Format(@"&&dtEve={0}&&dtCurr={1:yyyyMMddHHmmssfff}&&cnt={2}", valori[0], DateTime.Now, valori[3]);
+ return answ;
+ }
+
+ #endregion Public Methods
+
+ #region Internal Properties
+
+ internal bool disDynDataRangeCheck { get; set; } = false;
+
+ #endregion Internal Properties
+
+ #region Protected Fields
+
+ ///
+ /// wrapper di log
+ ///
+ protected static Logger lg;
+
+ ///
+ /// Valore di attesa (random) dopo ogni invio x evitare congestione send...
+ ///
+ protected static int urlRandWait = 0;
+
+ protected bool _connOk = false;
+
+ ///
+ /// valore booleano di check se sia in fase di COMUNICAZIONE ATTIVA con il PLC/NC
+ ///
+ protected bool adpCommAct;
+
+ ///
+ /// porta x adapter (x restart)
+ ///
+ protected int adpPortNum;
+
+ ///
+ /// DataOra ultimo avvio adapter x watchdog
+ ///
+ protected DateTime adpStartRun;
+
+ ///
+ /// Vettore 32 BIT valori in ingresso al filtro
+ ///
+ protected int B_input;
+
+ ///
+ /// Vettore 32 BIT valori in uscita dal filtro
+ ///
+ protected int B_output;
+
+ ///
+ /// Vettore 32 BIT valori precedenti
+ ///
+ protected int B_previous;
+
+ ///
+ /// Num errori check alive
+ ///
+ protected int currAliveErrors = 0;
+
+ ///
+ /// Dizionario valori impostati x produzione
+ ///
+ protected Dictionary currProdData = new Dictionary();
+
+ ///
+ /// num corrente errori read PLC
+ ///
+ protected int currReadErrors = 0;
+
+ ///
+ /// num errori send
+ ///
+ protected int currSendErrors = 0;
+
+ ///
+ /// Fattore di demoltiplicazione dei DynData x ridurre campionamento
+ ///
+ protected int demFactDynData = 1;
+
+ ///
+ /// Array dei contatori x segnali blinking
+ ///
+ protected int[] i_counters;
+
+ ///
+ /// Indica impianto IN SETUP (fino a quando SMETTE di esserlo...)
+ ///
+ protected bool inSetup = false;
+
+ ///
+ /// ultimo tentativo connessione...
+ ///
+ protected DateTime lastConnectTry;
+
+ ///
+ /// Ultimo LOG registrazione avvio (x ridurre log notturni...)
+ ///
+ protected DateTime lastLogStartup = DateTime.Today.AddHours(-1);
+
+ ///
+ /// Dizionario ULTIMI valori impostati x produzione
+ ///
+ protected Dictionary lastProdData = new Dictionary();
+
+ ///
+ /// Ultimo invio contapezzi (x invio delayed)
+ ///
+ protected DateTime lastPzCountSend;
+
+ ///
+ /// Dizionario ultimi valori (string) delle TSS
+ ///
+ protected Dictionary LastTSS = new Dictionary();
+
+ ///
+ /// Dizionario ultimi valori (string) delle TSS
+ ///
+ protected Dictionary LastTSSSend = new Dictionary();
+
+ ///
+ /// Dizionario ultimi valori (double) delle TSVC
+ ///
+ protected Dictionary LastTSVC = new Dictionary();
+
+ ///
+ /// Ultima registrazione warning x ODL mancante (x scrivere solo ogni 15 secondi)
+ ///
+ protected DateTime lastWarnODL;
+
+ ///
+ /// Num massimo di errori in funzionalità check alive
+ ///
+ protected int maxAliveErrors = utils.CRI("maxAliveErrors");
+
+ ///
+ /// Soglia massima errori priam di disconnesisone automatica
+ ///
+ protected int maxErroriCheck = 100;
+
+ ///
+ /// Num massimo di errori di rete read (dal PLC)
+ ///
+ protected int maxReadErrors = utils.CRI("maxReadErrors");
+
+ ///
+ /// Num massimodi errori di rete send al server
+ ///
+ protected int maxSendErrors = utils.CRI("maxSendErrors");
+
+ ///
+ /// indica se serva refresh parametri e quindi PLC...
+ ///
+ protected bool needRefresh = true;
+
+ ///
+ /// Variabile numero errori vari (in lettura) --> se supera soglia maxErroriCheck --> disconnette
+ ///
+ protected int numErroriCheck = 0;
+
+ ///
+ /// Form chiamante
+ ///
+ protected AdapterForm parentForm;
+
+ ///
+ /// Timeout x ping al server
+ ///
+ protected int pingServerMsTimeout = utils.CRI("pingMsTimeout");
+
+ ///
+ /// Ritardo minimo x invio contapezzi
+ ///
+ protected int pzCountDelay;
+
+ ///
+ /// Dizionario di VC da trattare come TimeSeries (con conf decodificata + processing successivo...)
+ ///
+ protected Dictionary TSVC_Data = new Dictionary();
+
+ ///
+ /// Dizionario di VARIABILI da trattare come eventi (da inviare quando cambiano oppure a
+ /// scadenza periodo...)
+ ///
+ protected Dictionary VarArray = new Dictionary();
+
+ ///
+ /// Veto per registrazione completa log di startup (minuti)
+ ///
+ protected int vetoLogStartupDuration = 60;
+
+ ///
+ /// Periodo wathdog di default (2 sec se non specificato)
+ ///
+ protected int watchDogPeriod = 2;
+
+ #endregion Protected Fields
+
+ #region Protected Properties
+
+ ///
+ /// Valore del num max invii consecutivi da coda...
+ ///
+ protected static int nMaxSend
+ {
+ get
+ {
+ int answ = 5;
+ try
+ {
+ answ = utils.CRI("nMaxSend");
+ }
+ catch
+ { }
+ return answ;
+ }
+ }
+
+ ///
+ /// Indica il counter della key richiesta attiva
+ /// - gestito tramite Redis
+ /// - a scadenza 25h
+ /// - incrementato ogni invio di auto ODL
+ ///
+ protected int countKeyRichiesta
+ {
+ get
+ {
+ // calcolo key odierna
+ int answ = redisMan.getKReqCount(dailyKey);
+ return answ;
+ }
+ set
+ {
+ // calcolo key odierna
+ redisMan.setKReqCount(dailyKey, value);
+ }
+ }
+
+ protected string dailyKey
+ {
+ get
+ {
+ return DateTime.Today.ToString("yyMMdd");
+ }
+ }
+
+ ///
+ /// Variabile di appoggio GLOBALE x indicare che si può forzare reset contapezzi con
+ /// macchina in RUN
+ ///
+ protected bool forceResetInRun { get; set; } = false;
+
+ ///
+ /// Variabile di appoggio GLOBALE x indicare macchina RUN (es x gestione su reset pezzi)
+ ///
+ protected bool isRunning { get; set; } = false;
+
+ ///
+ /// Valore limite MASSIMO di invio di dati come array Json
+ ///
+ protected int maxJsonData { get; set; } = utils.CRI("maxJsonData");
+
+ ///
+ /// Valore limite MASSIMO di invio di dati come array Json x EVENTI
+ ///
+ protected int maxJsonDataEv { get; set; } = utils.CRI("maxJsonDataEv");
+
+ ///
+ /// Max tentativi ping permessi (default: 5)
+ ///
+ protected int maxPingRetry { get; set; } = 5;
+
+ /// Coda massima ammessa per FLog (se <=0 disattivata...)
+ protected int maxQueueFLog { get; set; } = utils.CRI("maxQueueFLog");
+
+ /// Coda massima ammessa per FLog (se <=0 disattivata...)
+ protected int maxQueueRawTransf { get; set; } = utils.CRI("maxQueueRawTransf");
+
+ ///
+ /// Valore MINIMO limite x decidere invio di dati come array Json
+ ///
+ protected int minJsonData { get; set; } = utils.CRI("minJsonData");
+
+ protected string nextKeyRich
+ {
+ get
+ {
+ return $"{dailyKey}{countKeyRichiesta:00}";
+ }
+ }
+
+ ///
+ /// Numero letture IN da avvio
+ ///
+ protected int nReadFilt { get; set; }
+
+ ///
+ /// Numero letture IN da avvio
+ ///
+ protected int nReadIN { get; set; }
+
+ ///
+ /// Numero invii OUT (svuotamento coda)
+ ///
+ protected int nSendOut { get; set; }
+
+ ///
+ /// Numero simulazioni ammesse...
+ ///
+ protected int numSim { get; set; }
+
+ ///
+ /// Indica se sia stato resettato un contapezzi
+ ///
+ protected bool pzCountResetted { get; set; } = false;
+
+ ///
+ /// Fornisce il valore letto da BITMAP in formato valido x messa in coda nel formato dtEve#value#cont
+ ///
+ protected string qEncodeIN
+ {
+ get
+ {
+ string answ = "";
+ try
+ {
+ answ = string.Format("{0:yyyyMMddHHmmssfff}#{1:X2}#{2}", DateTime.Now, B_output, counterSigIN);
+ }
+ catch
+ { }
+ return answ;
+ }
+ }
+
+ ///
+ /// Indica se vada inviata la key richiesta con lo split/autoODL
+ ///
+ protected bool sendKeyRichiesta { get; set; } = false;
+
+ ///
+ /// test ping all'indirizzo PLC/CNC impostato nei parametri
+ ///
+ ///
+ protected IPStatus testPingMachine
+ {
+ get
+ {
+ IPStatus answ = IPStatus.Unknown;
+ // se disabilitato salto...
+ if (pingDisabled)
+ {
+ answ = IPStatus.Success;
+ }
+ else
+ {
+ IPAddress address;
+ PingReply reply;
+ using (Ping pingSender = new Ping())
+ {
+ address = IPAddress.Loopback;
+ int pingMsTimeout = cIobConf.pingMsTimeout;
+ IPAddress.TryParse(cIobConf.cncIpAddr, out address);
+ try
+ {
+ // se != null --> uso address...
+ if (address != null)
+ {
+ reply = pingSender.Send(address, pingMsTimeout);
+ }
+ else
+ {
+ reply = pingSender.Send(cIobConf.cncIpAddr, pingMsTimeout);
+ }
+ }
+ catch
+ {
+ reply = pingSender.Send(IPAddress.Loopback, pingMsTimeout);
+ }
+ answ = reply.Status;
+ }
+ }
+ return answ;
+ }
+ }
+
+ ///
+ /// Secondi standard x veto check status e log
+ ///
+ protected int vetoSeconds { get; set; } = utils.CRI("vetoSeconds");
+
+ #endregion Protected Properties
#region Protected Methods
///
- /// Decodifica file MAP (caso .bit)
+ /// Decodifica file MAP (caso .bit)
///
///
///
@@ -2519,10 +4204,7 @@ namespace IOB_WIN_NEXT
}
///
- /// Decodifica valore della coda IN nel formato
- /// answ[0]=dtEve
- /// answ[1]=valore
- /// answ[2]=counter
+ /// Decodifica valore della coda IN nel formato answ[0]=dtEve answ[1]=valore answ[2]=counter
///
/// dtEve + '#' + value + '#' + cont
///
@@ -2555,7 +4237,7 @@ namespace IOB_WIN_NEXT
}
answ = utils.callUrlNow(url2call);
// se vuoto faccio seconda prova...
- if (string.IsNullOrEmpty(answ))
+ if (string.IsNullOrEmpty(answ) || answ == "[]")
{
answ = utils.callUrlNow(url2call);
}
@@ -2567,8 +4249,8 @@ namespace IOB_WIN_NEXT
/// - formato Json
/// - array di KVP / Dictionary
/// - formato definito da API x MP/IO/:
- /// - KEY: task
- /// - VALUE: array JSon KVP
+ /// - KEY: task
+ /// - VALUE: array JSon KVP
///
protected string getTask2exe()
{
@@ -2708,6 +4390,19 @@ namespace IOB_WIN_NEXT
sendToLogWatch("INFO", message);
}
}
+
+ ///
+ /// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere...
+ ///
+ ///
+ ///
+ protected void lgInfo(string message, params object[] args)
+ {
+ lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB;
+ lg.Info(message, args);
+ sendToLogWatch("INFO", message, args);
+ }
+
protected void lgInfoStartup(string message, bool sendToForm = true)
{
lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB;
@@ -2728,17 +4423,6 @@ namespace IOB_WIN_NEXT
}
}
- ///
- /// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere...
- ///
- ///
- ///
- protected void lgInfo(string message, params object[] args)
- {
- lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB;
- lg.Info(message, args);
- sendToLogWatch("INFO", message, args);
- }
///
/// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere...
///
@@ -2863,8 +4547,7 @@ namespace IOB_WIN_NEXT
}
///
- /// Lettura memorie conf speciali (json)
- /// ...SE inserito in [OPTPAR] come PARAM_CONF=nome.json
+ /// Lettura memorie conf speciali (json) ...SE inserito in [OPTPAR] come PARAM_CONF=nome.json
///
protected virtual void loadMemConf()
{
@@ -2886,11 +4569,19 @@ namespace IOB_WIN_NEXT
lgError("loadMemConf: parametro ENABLE_SEND_PZC_BLOCK non trovato, verificare anche MAX_SEND_PZC_BLOCK e MIN_SEND_PZC_BLOCK");
}
+ // disabilitazione controllo range valori DynData
+ if (!string.IsNullOrEmpty(getOptPar("disDynDataRangeCheck")))
+ {
+ bool checkDis = false;
+ bool.TryParse(getOptPar("disDynDataRangeCheck"), out checkDis);
+ disDynDataRangeCheck = checkDis;
+ }
+
// inizializzo LUT decodifica PARAMETRI
string jsonParams = getOptPar("PARAM_CONF");
if (!string.IsNullOrEmpty(jsonParams))
{
- string jsonFileName = $"{Application.StartupPath}/DATA/CONF/{jsonParams}";
+ string jsonFileName = $"{Application.StartupPath}\\DATA\\CONF\\{jsonParams}";
lgInfoStartup($"Apertura file {jsonFileName}");
StreamReader reader = new StreamReader(jsonFileName);
string jsonData = reader.ReadToEnd();
@@ -3186,6 +4877,7 @@ namespace IOB_WIN_NEXT
///
protected void setupMemMap()
{
+ bool serverOk = testPingServer == IPStatus.Success;
lgInfo($"setupMemMap | trovati {memMap.mMapRead.Count} parametri Read (TSVC)");
lgInfo($"setupMemMap | trovati {memMap.mMapWrite.Count} parametri Write");
if (utils.CRB("verbose"))
@@ -3228,7 +4920,15 @@ namespace IOB_WIN_NEXT
{
// invio su cloud conf memoria...
string rawData = JsonConvert.SerializeObject(memMap, Formatting.Indented);
- var resp = utils.callUrlNow($"{urlSaveMemMap}", rawData);
+ // controllo ping al server...
+ if (serverOk)
+ {
+ var resp = utils.callUrlNow($"{urlSaveMemMap}", rawData);
+ }
+ else
+ {
+ lgInfo($"Mancata risposta ping da server, salato step invio memMpa a {urlSaveMemMap}");
+ }
// salvo ANCHE come parametri i valori...
objItem currItem = new objItem();
List allParam = new List();
@@ -3249,22 +4949,34 @@ namespace IOB_WIN_NEXT
// valori READ
foreach (var item in memMap.mMapRead)
{
- currItem = new objItem()
+ // se non ci fosse aggiungo
+ var trovato = allParam.FirstOrDefault(x => x.uid == item.Value.name);
+ if (trovato == null)
{
- uid = item.Value.name,
- name = !string.IsNullOrEmpty(item.Value.description) ? item.Value.description : item.Value.name,
- writable = false,
- UM = item.Value.unit,
- valMin = item.Value.minVal,
- valMax = item.Value.maxVal
- };
- allParam.Add(currItem);
+ currItem = new objItem()
+ {
+ uid = item.Value.name,
+ name = !string.IsNullOrEmpty(item.Value.description) ? item.Value.description : item.Value.name,
+ writable = false,
+ UM = item.Value.unit,
+ valMin = item.Value.minVal,
+ valMax = item.Value.maxVal
+ };
+ allParam.Add(currItem);
+ }
}
- // invio su cloud parametri SE sono connesso...
- if (connectionOk)
+ // invio su cloud parametri SE sono connesso all'OPC-ua...
+ if (serverOk)
{
rawData = JsonConvert.SerializeObject(allParam, Formatting.Indented);
- utils.callUrl($"{urlSaveAllParams}", rawData);
+ if (serverOk)
+ {
+ var resp = utils.callUrl($"{urlSaveAllParams}", rawData);
+ }
+ else
+ {
+ lgInfo($"Mancata risposta ping server, non effettuata chiamata {urlSaveAllParams}");
+ }
}
lgInfo($"setupMemMap | salvata conf memoria R/W");
}
@@ -3272,2193 +4984,701 @@ namespace IOB_WIN_NEXT
#endregion Protected Methods
- #region Public Methods
+ #region Private Properties
///
- /// Effettua chiamata URL e restituisce risultato
+ /// Verifica se la IOB sia ENABLED (da server o Demo)
///
- ///
- /// invio in modalità async (NON GARANTITO ordine...)
- ///
- public static string callUrl(string URL, bool doAsync)
+ private bool checkIobEnabled
{
- string answ = "";
- // Chiamata ASINCRONA
- if (doAsync)
+ get
{
- //Task resp = utils.callUrlAsync(URL);
- //answ = resp.Result;
- answ = utils.callUrlAsync(URL);
- if (urlRandWait > 0)
+ bool answ = false;
+ // controllo se ho veto al check...
+ if (dtVetoCheckIOB < DateTime.Now)
{
- Random rnd = new Random();
- Thread.Sleep(rnd.Next(urlRandWait / 10, urlRandWait));
- }
- }
- // chiamata SOLO NORMALE SINCRONA...
- else
- {
- answ = utils.callUrl(URL);
- if (urlRandWait > 0)
- {
- Random rnd = new Random();
- Thread.Sleep(rnd.Next(urlRandWait / 10, urlRandWait));
- }
- }
- return answ;
- }
-
- ///
- /// Effettua chiamata URL e restituisce risultato
- ///
- ///
- ///
- /// invio in modalità async (NON GARANTITO ordine...)
- ///
- public static string callUrlWithPayload(string URL, string payload, bool doAsync)
- {
- string answ = "";
- // Chiamata ASINCRONA
- if (doAsync)
- {
- answ = utils.callUrlAsync(URL, payload);
- if (urlRandWait > 0)
- {
- Random rnd = new Random();
- Thread.Sleep(rnd.Next(urlRandWait / 10, urlRandWait));
- }
- }
- // chiamata SOLO NORMALE SINCRONA...
- else
- {
- answ = utils.callUrl(URL, payload);
- if (urlRandWait > 0)
- {
- Random rnd = new Random();
- Thread.Sleep(rnd.Next(urlRandWait / 10, urlRandWait));
- }
- }
- return answ;
- }
-
- ///
- /// processa dataLayer e se necessario salva/mostra
- ///
- public static void checkSavePersDataLayer()
- {
- }
-
- public static string GetMACAddress()
- {
- NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
- String sMacAddress = string.Empty;
- foreach (NetworkInterface adapter in nics)
- {
- if (string.IsNullOrEmpty(sMacAddress))// only return MAC Address from first card
- {
- IPInterfaceProperties properties = adapter.GetIPProperties();
- //sMacAddress = adapter.GetPhysicalAddress().ToString();
- sMacAddress = string.Join(":", (from z in adapter.GetPhysicalAddress().GetAddressBytes() select z.ToString("X2")).ToArray());
- }
- }
- return sMacAddress;
- }
-
- public static void resetDebugConsole()
- {
- }
-
- ///
- /// Reset dei webclients
- ///
- public static void resetWebClients()
- {
- utils.resetWebClients();
- }
-
- ///
- /// Accumula in coda i valori ALARM e logga...
- ///
- /// VALORE RAW (x display)
- /// VALORE già processato con qEncodeFLog(...)
- public void accodaAlarmLog(string val, string encodedVal)
- {
- // mostro dati variati letti...
- displayOtherData(val);
- // accodo IN PRIMIS al FluxLog --> accodo (valore già formattato)!
- QueueFLog.Enqueue(encodedVal);
- // accodo ANCHE alla coda allarmi che trasmetterò SOLO SE a scadenza impostata (10 sec?) ho allarmi perdurati...
-
- // loggo!
- lgInfo(string.Format("[QUEUE-ALARM-LOG] {0}", encodedVal));
- counterFLog++;
- if (counterFLog > 9999)
- {
- counterFLog = 0;
- }
- }
-
- ///
- /// Accumula in coda i valori Flux Log e logga...
- ///
- /// VALORE RAW (x display)
- /// VALORE già processato con qEncodeFLog(...)
- public void accodaFLog(string val, string encodedVal)
- {
- // mostro dati variati letti...
- displayOtherData(val);
- // --> accodo (valore già formattato)!
- QueueFLog.Enqueue(encodedVal);
- // se abilitato controllo coda FLog (superiore a 0...)
- if (maxQueueFLog > 0)
- {
- // se ho una coda superiore a max ammesso
- if (QueueFLog.Count > maxQueueFLog)
- {
- // elimino valori iniziali fino a tornare al max ammesso...
- while (QueueFLog.Count > maxQueueFLog)
+ if (DemoOut)
{
- string currVal = "";
- QueueFLog.TryDequeue(out currVal);
- lgInfo($"Eliminazione da coda FLog per superamento maxLengh: {currVal}");
- }
- }
- }
- // loggo!
- lgTrace(string.Format("[QUEUE-FLOG] {0}", encodedVal));
- counterFLog++;
- if (counterFLog > 9999)
- {
- counterFLog = 0;
- }
- }
-
- ///
- /// Accumula in coda i valori RawData logga...
- ///
- /// Dictionary pronto x invio
- public void accodaRawData(Dictionary sendObj)
- {
- //
-
- /*--------------------------------
- * nuova gestione coda dictionary
- * fixme todo da fare !!!
- *
- * - conterrà una lista di oggetti baseRawTransf
- * - i dati vanno poi "scodati" dal + vecchio ed inviati a MP/IO
- * - mostra un sunto delle info da inviare
- * - accodamento vero e proprio
- * - verifica (opzionale) coda massima x gestire roundRobin ultimi eventi
- * - trace della coda
- * - counter invio??? valutare se c'è dataora e poi sono da salvare su MongoDb / Redis
- *
- * */
-
-#if false
- // mostro dati variati letti...
- displayOtherData(val);
- // --> accodo (valore già formattato)!
- QueueFLog.Enqueue(encodedVal);
- // se abilitato controllo coda FLog (superiore a 0...)
- if (maxQueueFLog > 0)
- {
- // se ho una coda superiore a max ammesso
- if (QueueFLog.Count > maxQueueFLog)
- {
- // elimino valori iniziali fino a tornare al max ammesso...
- while (QueueFLog.Count > maxQueueFLog)
- {
- string currVal = "";
- QueueFLog.TryDequeue(out currVal);
- lgInfo($"Eliminazione da coda FLog per superamento maxLengh: {currVal}");
- }
- }
- }
- // loggo!
- lgTrace(string.Format("[QUEUE-FLOG] {0}", encodedVal));
- counterFLog++;
- if (counterFLog > 9999)
- {
- counterFLog = 0;
- }
-#endif
- }
-
- ///
- /// Accoda (visualizzando in cima allo stack) la nuova stringa di output per area OTHER DATA
- ///
- ///
- public void accodaOtherData(string newLine)
- {
- // inserisco in cima allo stack, trimmo e aggiorno display
- string strOtherData = limitLine2show(string.Format("{0}{1}{2}", newLine, Environment.NewLine, parentForm.dataMonitor_3));
- //parentForm.dataMonitor_3 = strOtherData;
- parentForm.WriteTextSafe(strOtherData);
- }
-
- ///
- /// Accumula in coda i valori Signal IN e logga...
- /// Parametri da aggiornare x display in form
- ///
- public void accodaSigIN(ref newDisplayData currDispData)
- {
- // mostro dati variati letti...
- displayInData(ref currDispData);
- // verifico veto a invio status macchina
- string keyName = "VETO_SIG_IN";
- if (getOptPar(keyName).ToUpper() == "TRUE")
- {
- lgTrace($"Filtrato accodamento valore da conf IOB | {keyName} | [QUEUE-IN] {qEncodeIN}");
- }
- else
- {
- // --> accodo (valore già formattato)!
- QueueIN.Enqueue(qEncodeIN);
- // loggo!
- lgTrace(string.Format("[QUEUE-IN] {0}", qEncodeIN));
- }
- // aggiorno counters ed eventuale reset
- nReadFilt++;
- if (nReadFilt > int.MaxValue - 1)
- {
- nReadFilt = 0; // per evitare buffer overflow...
- }
-
- counterSigIN++;
- if (counterSigIN > 9999)
- {
- counterSigIN = 0;
- }
- }
-
- ///
- /// Accumula in coda i valori USER LOG e logga...
- ///
- /// VALORE RAW (x display)
- /// VALORE già processato con qEncodeULog(...)
- public void accodaUserLog(string val, string encodedVal)
- {
- // mostro dati variati letti...
- displayOtherData(val);
- // accodo IN PRIMIS al FluxLog --> accodo (valore già formattato)!
- QueueULog.Enqueue(encodedVal);
-
- // loggo!
- lgInfo(string.Format("[QUEUE-USER-LOG] {0}", encodedVal));
- counterULog++;
- if (counterULog > 9999)
- {
- counterFLog = 0;
- }
- }
-
- ///
- /// Update visualizzaizone BIT in ingresso
- /// Parametri da aggiornare x display in form
- ///
- public void displayInData(ref newDisplayData currDispData)
- {
- if (currDispData != null)
- {
- // mostro update...
- string newString = string.Format("{0:0000}|{1}", counterSigIN, utils.IntToBinStr(B_output, 8));
- currDispData.newSignalData = newString;
- }
- }
-
- ///
- /// Mostra cosa ha/avrebbe inviato
- ///
- ///
- public void displayOtherData(string newData)
- {
- // mostro update...
- accodaOtherData(newData);
- }
-
- ///
- /// Esecuzione dei task richiesti e pulizia coda richieste eseguite
- ///
- ///
- public virtual Dictionary executeTasks(Dictionary task2exe)
- {
- // Verificare il protocollo: dovrebbe togliere SOLO i task eseguiti...
- Dictionary taskDone = new Dictionary();
- 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.nihil:
- case taskType.fixStopSetup:
- case taskType.forceSetPzCount:
- case taskType.sendWatchDogMes2Plc:
- taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
- lgInfo($"Chiamata senza processing: taskOk: {taskOk} | taskVal: {taskVal}");
- break;
-
- case taskType.setArt:
- case taskType.setComm:
- case taskType.setProg:
- case taskType.setPzComm:
- // recupero dati da memMap...
- if (memMap != null && memMap.mMapWrite != null)
- {
- if (memMap.mMapWrite.ContainsKey(item.Key))
- {
- dataConf currMem = memMap.mMapWrite[item.Key];
- string addr = currMem.memAddr;
- taskVal = $"SET task: {item.Key} --> {item.Value} | mem: {currMem.memAddr} - {currMem.size} byte";
- // salvo il nuovo valore nella memoria... così prox invio lo trasmetterÃ
- memMap.mMapWrite[item.Key].value = item.Value;
- }
- else
- {
- taskVal = $"NO DATA MEM, SET task: {item.Key} --> {item.Value}";
- }
- }
- else
- {
- taskVal = $"NO MemMap found, SET task: {item.Key} --> {item.Value}";
- }
- // salvo in currProd..
- saveProdData(new KeyValuePair(item.Key, item.Value));
-
- break;
-
- case taskType.forceResetPzCount:
- // reset contapezzi inizio setup
- taskOk = resetcontapezziPLC();
- taskVal = taskOk ? "RESET PZ COUNT OK" : "PZ RESET DISABLED | NO EXEC";
- lgInfo($"Chiamata forceResetPzCount: taskOk: {taskOk} | taskVal: {taskVal}");
- break;
-
- case taskType.startSetup:
- // reset contapezzi inizio setup
- taskOk = resetcontapezziPLC();
- taskVal = taskOk ? "RESET: SETUP START" : "PZ RESET DISABLED | NO EXEC";
- lgInfo($"Chiamata startSetup: taskOk: {taskOk} | taskVal: {taskVal}");
- break;
-
- case taskType.stopSetup:
- // reset contapezzi fine setup SE ESPLICITAMENTE IMPOSTATO
- if (cIobConf.optPar.Count > 0 && getOptPar("ENABLE_PZ_RESET_stopSetup") == "TRUE")
- {
- taskOk = resetcontapezziPLC();
- }
- taskVal = taskOk ? "RESET: SETUP END" : "PZ RESET DISABLED | NO EXEC";
- lgInfo($"Chiamata stopSetup: taskOk: {taskOk} | taskVal: {taskVal}");
- 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 = "SKIPPED | NO EXEC";
- lgInfo($"Chiamata default 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;
- }
-
- ///
- /// Effettua verifica delle memorie WRITE, se ci siano variazioni da riportare verso il PLC
- /// Da impiegare ad esempio in caso di chiamate complesse (ad 2 aree di memoria condivise sul PLC; coem commessa + articolo EWON)
- ///
- ///
- /// Cerca parametri opzionali in modalità "like" del nome
- ///
- ///
- ///
- public Dictionary findOptPar(string keyStartSearch = "")
- {
- Dictionary answ = new Dictionary();
- // controllo SE keySearch !=""
- if (!string.IsNullOrWhiteSpace(keyStartSearch))
- {
- if (cIobConf.optPar.Count > 0)
- {
- // ciclo su tutti e cerco occorrenze che INIZINO...
- foreach (var item in cIobConf.optPar)
- {
- if (item.Key.StartsWith(keyStartSearch))
- {
- answ.Add(item.Key, item.Value);
- }
- }
- }
- }
- return answ;
- }
-
- ///
- /// forza reset ODL
- ///
- public void forceResetOdl()
- {
- lgInfo("Registrato richiesta forzatura reset ODL");
- pzCountResetted = true;
- }
-
- ///
- /// Effettua chiamata x split ODL
- ///
- ///
- public bool forceSplitOdl()
- {
- bool fatto = false;
- if (vetoSplit < DateTime.Now)
- {
- lgInfo("Richiesto forceSplitOdl");
- // imposto veto x 1 minuto ad altre chiamate...
- vetoSplit = DateTime.Now.AddMinutes(1);
- // eseguo SOLO SE sono online...
- if (MPOnline && IobOnline)
- {
- string fullUrl = "";
- string rawSplit = "";
- string IOB_MULTI_CNAME = "";
- string[] elencoMulti = null;
-
- try
- {
- /***************************************************
- * Descrizione procedura (OK X SIMULATORI...)
- *
- * - chiamata su MP/IO
- * - verifica che su DB sia abilitato AUTO ODL
- * - il server inserisce un evento fine prod HW 1 minuto prima e inizio setup HW
- * - viene duplicato e chiuso ODL corrente
- * - viene fatto partire ODL nuovo ADESSO
- * - num pezzi come ODL precedente (o da media 3 ODL precedenti)
- * - conferme pezzi & co... gestione NULL (NON SERVONO si tratta di impianti SENZA gestione vera ODL)
- * - reset contapezzi PLC locale...
- *
- *
- *
- * DA VALUTARE (x macchine tipo linea con + impianti... es valvital) SE
- * - creare una gestione ALTERNATIVA sul server che preveda impianto LEADER e impianti follower (RIGIDAMENTE CONFIGURATI)
- * - ogni volta che si fa setup LEADER --> si ripete su impianti FOLLOWER (eventi!!!)
- * - viene fatto reset contapezzi sui follower (+ altre operazioni opzionali, ES imposstazione nome commessa, quantità , articolo...)
- * - viene fatto reset + nuovo ODL (con stessi articoli e quantità ) su follower, SENZA avere gestione x ODL di un codice esterno (quindi registra TUTTO ma NON RITORNERA' dati non avendo link verso esterno)
- * - serve NUOVA TABELLA delle macchine LEADER | FOLLOWER (1:n) e gestione da MP/IO
- *
- * ***************************************************/
-
- if (isMulti)
- {
- // devo chiamare cambio ODL x OGNI tavola: mi servono i parametri opzionali...
- IOB_MULTI_CNAME = getOptPar("IOB_MULTI_CNAME");
- elencoMulti = IOB_MULTI_CNAME.Split(',');
- }
- // se normale splitto!
- if (!isMulti)
- {
- // invio chiamata URL x reset ODL su macchina
- rawSplit = callUrl(urlForceSplit, false);
- fatto = (rawSplit != "KO") ? true : false;
- }
- // se multi gestisco il bit delle tavole...
- else
- {
- foreach (string item in elencoMulti)
- {
- // invio chiamata URL x reset ODL su macchina, ATTENZIONE scriviamo | al posto di "#" che in URL sarebbe filtrato...
- fullUrl = $"{urlForceSplit}&multi={item}";
- rawSplit = callUrl(fullUrl, false);
- lgDebug($"Esecuzione forceSplit | URL: {fullUrl} | esito: {rawSplit}");
- }
- fatto = (rawSplit == "OK") ? true : false;
- }
- }
- catch (Exception exc)
- {
- lgError($"Eccezione in forceSplitOdl{Environment.NewLine}{exc}");
- }
- // se fatto --> resetto contapezzi!!!
- if (fatto)
- {
- contapezziPLC = 0;
- contapezziIOB = 0;
- }
- }
- else
- {
- lgError("Richiesto forceSplitOdl ma MP/IOB offline --> NON eseguito");
- }
- }
- else
- {
- lgError("Richiesto forceSplitOdl ma veto attivo --> NON eseguito");
- }
- return fatto;
- }
-
- ///
- /// effettua recupero dati ed invio valori modificati...
- ///
- ///
- public void getAndSend(gatherCycle ciclo)
- {
- // init obj display
- newDisplayData currDispData = new newDisplayData();
- // IN OGNI CASO a prima di tutto EFFETTUO GESTIONE INVII dati da code!!!
- try
- {
- trySendValues();
- }
- catch (Exception exc)
- {
- lgError(exc, "Errore in gestione svuotamento/invio preliminare code memoria");
- currDispData.semOut = Semaforo.SR;
- }
- // controllo connessione/connettivitÃ
- if (connectionOk)
- {
- // controllo non sia già in esecuzione...
- if (!adpCommAct)
- {
- // provo ad avviare
- try
- {
- // imposto flag adapter running..
- adpCommAct = true;
- adpStartRun = DateTime.Now;
- }
- catch (Exception exc)
- {
- string errore = $"Adapter NOT STARTED!!!{Environment.NewLine}{exc}";
- adpCommAct = false;
- adpStartRun = DateTime.Now;
- currDispData.newLiveLogData = errore;
- }
- if (adpCommAct)
- {
- // try / catch generale altrimenti segno che è disconnesso...
- try
- {
- bool showDebugData = false;
- if (ciclo == gatherCycle.VHF)
- {
- processVHF();
- }
- // processing dati memoria (lettura, filtraggio, enqueque)
- else if (ciclo == gatherCycle.HF)
- {
- processWhatchDog();
- processAllMemory();
- processMode();
- }
- else if (ciclo == gatherCycle.MF)
- {
- processServerRequests();
- processOverride();
- processContapezzi();
- processCncAlarms();
- processDynData();
- processMem2Write();
- }
- else if (ciclo == gatherCycle.LF)
- {
- processCustomTaskLF();
- processOtherCounters();
- processProgram();
- // verifico se devo gestire cambio ODL in modo automatico
- processAutoOdl();
- }
- else if (ciclo == gatherCycle.VLF)
- {
- if (utils.CRB("enableContapezzi"))
- {
- // rilettura contapezzi da server...
- lgTrace("Ciclo VLF: pzCntReload(true)");
- if (!isMulti)
- {
- pzCntReload(true);
- }
- // refresh associazione Macchina - IOB
- sendM2IOB();
- }
- // recupero dati SETUP (sysinfo) e li invio/mostro se variati...
- processSysInfo();
- // checkLogDir x shrink!
- checkShrinkDir();
- // eventuale log!
- if (utils.CRB("recTime"))
- {
- logTimeResults();
- }
- }
- // mostra eventuali altri dati di processo...
- reportDataProc();
- if (showDebugData)
- {
- // verifica se debba salvare e mostrare dati
- checkSavePersDataLayer();
- }
- }
- catch (Exception exc)
- {
- // segnalo eccezione e indico disconnesso...
- lgError(exc, string.Format("Errore in gestione ciclo principale ADP, fermo adapter{0}{1}", Environment.NewLine, exc));
- parentForm.fermaAdapter(true, false, true);
- }
- // tolgo flag running
- adpCommAct = false;
+ answ = (QueueIN.Count + QueueFLog.Count >= nMaxSend);
+ IobOnline = answ;
}
else
{
- if (periodicLog)
- {
- lgDebug("ADP not running...");
- }
- }
- }
- else
- {
- // log ADP running
- lgError("Non eseguo chiamata: ADP ancora in running");
- // se è bloccato da oltre maxSec lo sblocco...
- if (DateTime.Now.Subtract(adpStartRun).TotalSeconds > utils.CRI("maxAdapterLockSec"))
- {
- // tolgo flag running
- adpCommAct = false;
- adpStartRun = DateTime.Now;
- }
- }
- }
- else
- {
- // provo a riconnettere SE abilitato tryRestart...
- if (adpTryRestart && !connectionOk)
- {
- // controllo se sia scaduto periodi di veto al tryConnect...
- int waitRecMSec = utils.CRI("waitRecMSec") * 2;
- DateTime dtVeto = lastConnectTry.AddMilliseconds(waitRecMSec);
- if (DateTime.Now > dtVeto)
- {
- lgInfo($"Veto Time Elapsed | lastConnectTry: {lastConnectTry} | waitRecMSec {waitRecMSec} ms) | NOW tryConnect");
- lastConnectTry = DateTime.Now;
- tryConnect();
- }
- }
- currDispData.semIn = Semaforo.SR;
- processDisconnectedTask();
- }
- raiseRefresh(currDispData);
- }
-
- ///
- /// Effettua processing CUSTOM x l'IOB corrente (ed invia ad IO)
- /// (task svolto tipicamente ogni 5 sec se base timer 10ms, vedere app.config)
- ///
- public virtual void processCustomTaskLF()
- { }
-
- ///
- /// Recupera eventuali allarmi CNC...
- ///
- public virtual Dictionary getCncAlarms()
- {
- Dictionary outVal = new Dictionary();
- return outVal;
- }
-
- ///
- /// Restituisce info DINAMICHE
- ///
- ///
- public virtual Dictionary getDynData()
- {
- Dictionary outVal = new Dictionary();
- return outVal;
- }
-
- ///
- /// Cerca se esiste il parametro opzionale e lo restituisce
- ///
- ///
- ///
- public string getOptPar(string key)
- {
- string answ = "";
- if (cIobConf.optPar.Count > 0)
- {
- // controllo SE HO il parametro
- if (cIobConf.optPar.ContainsKey(key))
- {
- answ = cIobConf.optPar[key];
- }
- }
- return answ;
- }
-
- ///
- /// Restituisce info OVERRIDES
- ///
- ///
- public virtual Dictionary getOverrides()
- {
- Dictionary outVal = new Dictionary();
- return outVal;
- }
-
- ///
- /// Restituisce programma in esecuzione
- ///
- public virtual string getPrgName()
- {
- return "";
- }
-
- ///
- /// Restituisce info sistema
- ///
- ///
- public virtual Dictionary getSysInfo()
- {
- Dictionary outVal = new Dictionary();
- return outVal;
- }
-
- ///
- /// Recupera la VC x TS, svuotando lista e resettando periodo partenza
- ///
- /// Nome della VC
- /// Reimposta e resetta array VC
- ///
- public double getVal_TSVC(string VCName, bool doReset)
- {
- double answ = -999999;
- // cerco VC...
- if (TSVC_Data.ContainsKey(VCName))
- {
- try
- {
- switch (TSVC_Data[VCName].Funzione)
- {
- case VC_func.POINT:
- // prendo PRIMO
- answ = TSVC_Data[VCName].dataArray.FirstOrDefault();
- break;
-
- case VC_func.AVG:
- answ = TSVC_Data[VCName].dataArray.Average();
- break;
-
- case VC_func.MEDIAN:
- answ = TSVC_Data[VCName].dataArray.Median();
- break;
-
- case VC_func.MIN:
- answ = TSVC_Data[VCName].dataArray.Min();
- break;
-
- case VC_func.MAX:
- default:
- answ = TSVC_Data[VCName].dataArray.Max();
- break;
- }
- }
- catch
- { }
- // ora resetto... SE richiesto...
- if (doReset)
- {
- TSVC_Data[VCName].dataArray = new List();
- TSVC_Data[VCName].DTStart = DateTime.Now;
- }
- }
- return answ;
- }
-
- ///
- /// Recupera la VC x TS, svuotando lista e resettando periodo partenza
- ///
- /// Nome della VC
- /// Reimposta e resetta array VC
- ///
- public int getVal_TSVC_int(string VCName, bool doReset)
- {
- int answ = 0;
- // cerco VC...
- if (TSVC_Data.ContainsKey(VCName))
- {
- // !!!FARE!!! vero calcolo... x ora FIX a MAX...
- foreach (var item in TSVC_Data[VCName].dataArray)
- {
- answ = (int)item > answ ? (int)item : answ;
- }
- // ora resetto... SE richiesto..
- if (doReset)
- {
- TSVC_Data[VCName].dataArray = new List();
- TSVC_Data[VCName].DTStart = DateTime.Now;
- }
- }
- return answ;
- }
-
- ///
- /// Restituisce un payload in formato json della lista di valori ricevuta
- ///
- /// Tipo di URL (eventi / FLog)
- /// elenco di valori da coda string salvata
- ///
- public string jsonPayload(urlType tipoUrl, List elencoValori)
- {
- string answ = "";
- if (elencoValori != null)
- {
- string[] valori;
- int counter = 0;
- DateTime dtEve = DateTime.Now;
- switch (tipoUrl)
- {
- case urlType.FLog:
- flogData currFlData = new flogData();
- flogJsonPayload fullFlObj = new flogJsonPayload();
- fullFlObj.fluxData = new List();
- // inizio processando ogni valore
- foreach (var item in elencoValori)
- {
- valori = qDecodeIN(item);
- CultureInfo provider = CultureInfo.InvariantCulture;
- DateTime.TryParseExact(valori[0], "yyyyMMddHHmmssfff", provider, DateTimeStyles.AssumeLocal, out dtEve);
- int.TryParse(valori[3], out counter);
- currFlData = new flogData()
- {
- flux = valori[1],
- valore = valori[2],
- dtEve = dtEve,
- dtCurr = DateTime.Now,
- cnt = counter
- };
- fullFlObj.fluxData.Add(currFlData);
- }
- // conversione finale
try
{
- answ = JsonConvert.SerializeObject(fullFlObj);
- }
- catch (Exception exc)
- {
- lgError($"FLog Errore in costruzione jsonPayload:{Environment.NewLine}{exc}");
- }
- break;
-
- case urlType.SignIN:
- evData currSigData = new evData();
- evJsonPayload fullEvObj = new evJsonPayload();
- fullEvObj.eventList = new List();
- // inizio processando ogni valore
- foreach (var item in elencoValori)
- {
- valori = qDecodeIN(item);
- CultureInfo provider = CultureInfo.InvariantCulture;
- DateTime.TryParseExact(valori[0], "yyyyMMddHHmmssfff", provider, DateTimeStyles.AssumeLocal, out dtEve);
- int.TryParse(valori[2], out counter);
- currSigData = new evData()
+ // chiamo URL, se restituisce "OK" è enabled!
+ string callResp = callUrl(urlIobEnabled, true);
+ answ = (callResp == "OK");
+ // attesa casuale se necessario
+ var rand = new Random();
+ // primi 2 test
+ int maxTry = 2;
+ while (maxTry > 0 && !answ)
{
- valore = valori[1],
- dtEve = dtEve,
- dtCurr = DateTime.Now,
- cnt = counter
- };
- fullEvObj.eventList.Add(currSigData);
- }
- // conversione finale
- try
- {
- answ = JsonConvert.SerializeObject(fullEvObj);
- }
- catch (Exception exc)
- {
- lgError($"SignIN Errore in costruzione jsonPayload:{Environment.NewLine}{exc}");
- }
- break;
-
- case urlType.ULog:
- int numVal = 0;
- int matrOp = 0;
- ulogData currUlData = new ulogData();
- ulogJsonPayload fullUlObj = new ulogJsonPayload();
- fullUlObj.fluxData = new List();
- // inizio processando ogni valore
- foreach (var item in elencoValori)
- {
- valori = qDecodeIN(item);
- CultureInfo provider = CultureInfo.InvariantCulture;
- DateTime.TryParseExact(valori[0], "yyyyMMddHHmmssfff", provider, DateTimeStyles.AssumeLocal, out dtEve);
- int.TryParse(valori[3], out matrOp);
- int.TryParse(valori[5], out numVal);
- int.TryParse(valori[6], out counter);
- currUlData = new ulogData()
- {
- flux = valori[1],
- valore = valori[2],
- dtEve = dtEve,
- dtCurr = DateTime.Now,
- cnt = counter,
- matrOpr = matrOp,
- label = valori[4],
- valNum = numVal
- };
- fullUlObj.fluxData.Add(currUlData);
- }
- // conversione finale
- try
- {
- answ = JsonConvert.SerializeObject(fullUlObj);
- }
- catch (Exception exc)
- {
- lgError($"ULog Errore in costruzione jsonPayload:{Environment.NewLine}{exc}");
- }
- break;
-
- default:
- break;
- }
- }
- return answ;
- }
-
- ///
- /// Effettua un trim della stringa al numero max di linee da mostrare a video
- ///
- ///
- ///
- public string limitLine2show(string newString)
- {
- // se num righe superiore a limite trimmo...
- if (newString.Split('\n').Length > parentForm.nLine2show)
- {
- //int idx = newString.LastIndexOf('\r');
- int idx = newString.LastIndexOf(Environment.NewLine);
- newString = newString.Substring(0, idx);
- }
- return newString;
- }
-
- ///
- /// riporta il log di tutti i dati di results temporali registrati
- ///
- public void logTimeResults()
- {
- if (TimingData.results.Count > 0)
- {
- lgInfo("{0}--------------- START TIMING DATA ---------------", Environment.NewLine);
- int globNumCall = 0;
- TimeSpan globAvgMsec = new TimeSpan(0);
- foreach (TimeRec item in TimingData.results)
- {
- // loggo SOLO se del mio IOB corrente...
- if (item.classCall == cIobConf.codIOB)
- {
- lgInfo("{4}|Chiamate {0}: effettuate {1}, tempo medio {2:N2} msec | impegno canale {3:P3}", item.codCall, item.numCall, item.avgMsec, item.totMsec.TotalSeconds / DateTime.Now.Subtract(dtAvvioAdp).TotalSeconds, cIobConf.codIOB);
- globNumCall += item.numCall;
- globAvgMsec += item.totMsec;
- }
- }
- // riporto conteggio medio al secondo...
- lgInfo("{4}|Chiamate GLOBALI: {0}, periodo: {1:N2} minuti.cent, tempo medio {2:N2} msec | impegno canale {3:P3}", globNumCall, DateTime.Now.Subtract(dtAvvioAdp).TotalMinutes, globAvgMsec.TotalMilliseconds / globNumCall, globAvgMsec.TotalSeconds / DateTime.Now.Subtract(dtAvvioAdp).TotalSeconds, cIobConf.codIOB);
- lgInfo("{0}--------------- STOP TIMING DATA ---------------{0}", Environment.NewLine);
- // mostro in form statistiche globali!
- parentForm.updateComStats(string.Format("Periodo: {0:N2}min | {1} x {2:N2}ms | canale {3:P3}", DateTime.Now.Subtract(dtAvvioAdp).TotalMinutes, globNumCall, globAvgMsec.TotalMilliseconds / globNumCall, globAvgMsec.TotalSeconds / DateTime.Now.Subtract(dtAvvioAdp).TotalSeconds));
- }
- }
-
- ///
- /// Processa un monitoredItem, e ritorna boolean SE richiede invio (cambio o scadenza)
- ///
- ///
- ///
- ///
- public bool monItem2Send(string newVal, DynDataItem item)
- {
- bool answ = false;
- if (item != null)
- {
- // controllo in base al tipo di function...
- switch (item.func)
- {
- case "SAMPLE":
- // controllo se scaduto sample period...
- if (item.DTScad < DateTime.Now)
- {
- answ = true;
- }
- break;
-
- case "CHANGE":
- default:
- // controllo se scaduto o se variato...
- if (newVal != item.actVal || item.DTScad < DateTime.Now)
- {
- // aggiorno scadenza e che vada inviato
- answ = true;
- }
- break;
- }
- }
- return answ;
- }
-
- ///
- /// Verifica e processing x gestione ODL automatica
- ///
- public void processAutoOdl()
- {
- bool fatto = false;
- if (!string.IsNullOrEmpty(getOptPar("AUTO_CHANGE_ODL")))
- {
- lgTrace("Richiesta processAutoOdl");
- string IOB_MULTI_CNAME = "";
- string[] elencoMulti = null;
- string fullUrl = "";
- if (isMulti)
- {
- // devo chiamare cambio ODL x OGNI tavola: mi servono i parametri opzionali...
- IOB_MULTI_CNAME = getOptPar("IOB_MULTI_CNAME");
- elencoMulti = IOB_MULTI_CNAME.Split(',');
- }
- // controllo SIA abilitato...
- bool doProc = false;
- DateTime adesso = DateTime.Now;
- bool.TryParse(getOptPar("AUTO_CHANGE_ODL"), out doProc);
- if (doProc)
- {
- lgTrace("AUTO_CHANGE_ODL abilitato");
- bool callChangeODL = false;
- // modalità change ODL
- string CHANGE_ODL_MODE = "TIME";
- if (!string.IsNullOrEmpty(getOptPar("CHANGE_ODL_MODE")))
- {
- CHANGE_ODL_MODE = getOptPar("CHANGE_ODL_MODE");
- }
- if (CHANGE_ODL_MODE == "PZCOUNT_RESET")
- {
- /* verifico se sia "armato" il reset cambio ODL, DEVO essere :
- * - NON in produzione
- * - contapezzi ACT < contapezzi LAST
- * */
- lgTrace("processAutoOdl: caso PZCOUNT_RESET");
- if ((!isRunning || forceResetInRun) && pzCountResetted)
- {
- callChangeODL = true;
- lgInfo("Attivato cambio ODL da PZCOUNT_RESET");
- }
- else
- {
- lgInfo($"isRunning: {isRunning} | pzCountResetted: {pzCountResetted} | forceResetInRun: {forceResetInRun} | contapezziIOB: {contapezziIOB} | contapezziPLC: {contapezziPLC}");
- }
- }
- else if (CHANGE_ODL_MODE == "TIME")
- {
- // carico i parametri di configurazione x reset ODL...
- string CHANGE_ODL_HOURS = getOptPar("CHANGE_ODL_HOURS");
- string CHANGE_ODL_IDLE_MIN = getOptPar("CHANGE_ODL_IDLE_MIN");
- if (!string.IsNullOrEmpty(CHANGE_ODL_HOURS) && !string.IsNullOrEmpty(CHANGE_ODL_IDLE_MIN))
- {
- int minOdlDurHours = -1;
- int minPlcIdelMin = -1;
- int.TryParse(CHANGE_ODL_HOURS, out minOdlDurHours);
- int.TryParse(CHANGE_ODL_IDLE_MIN, out minPlcIdelMin);
- // controllo parametri validi
- if (minOdlDurHours > 0 && minPlcIdelMin >= 0)
- {
- // leggo da server inizio ODL... se non multi 1 solo...
- DateTime inizioOdl = DateTime.Now;
- string rawDataInizio = "";
- if (!isMulti)
- {
- rawDataInizio = callUrl(urlInizioOdlIob, false);
- DateTime.TryParse(rawDataInizio, out inizioOdl);
- }
- else
- {
- DateTime tmpData = DateTime.Now;
- // prendo il + vecchio...
- foreach (var item in elencoMulti)
- {
- fullUrl = $"{urlInizioOdlIob}|{item}";
- rawDataInizio = callUrl(fullUrl, false);
- DateTime.TryParse(rawDataInizio, out tmpData);
- inizioOdl = (tmpData < inizioOdl) ? tmpData : inizioOdl;
- }
- }
- // verifico se sia scaduto...
- if (inizioOdl.AddHours(minOdlDurHours) < adesso)
- {
- string rawIdle = "";
- int idlePeriod = 0;
- if (!isMulti)
- {
- // controllo SE sono fermo (spento o in manuale) per il periodo minimo richiesto...
- rawIdle = callUrl(urlIdleTime, false);
- int.TryParse(rawIdle, out idlePeriod);
- }
- else
- {
- int tmpIdle = 0;
- // prendo il + grande...
- foreach (var item in elencoMulti)
- {
- fullUrl = $"{urlIdleTime}|{item}";
- rawIdle = callUrl(fullUrl, false);
- int.TryParse(rawIdle, out tmpIdle);
- idlePeriod = tmpIdle > idlePeriod ? tmpIdle : idlePeriod;
- }
- }
- if (idlePeriod >= minPlcIdelMin)
- {
- callChangeODL = true;
- }
- }
+ Thread.Sleep(rand.Next(250, 500));
+ callResp = callUrl(urlIobEnabled, true);
+ answ = (callResp == "OK");
+ maxTry--;
}
- }
- }
-
- // vero processing...
- if (callChangeODL)
- {
- lgTrace("Chiamata: processAutoOdl --> forceSplitODL");
- fatto = forceSplitOdl();
- pzCountResetted = false;
- lgInfo("Esecuzione processAutoOdl completata --> pzCountResetted = false");
- }
- }
- else
- {
- lgTrace("AUTO_CHANGE_ODL DISABILITATO");
- }
- }
- // loggo se fatto
- if (fatto)
- {
- lgTrace("Effettuato processAutoOdl");
- }
- }
-
- ///
- /// Effettua processing degli allarmi CNC SE disponibili
- ///
- public void processCncAlarms()
- {
- if (utils.CRB("enableAlarms"))
- {
- Dictionary currAlarms = new Dictionary();
- if (connectionOk)
- {
- currAlarms = getCncAlarms();
- }
- else
- {
- lgError("Errore connessione mancante x getCncAlarms");
- }
- // verifico SE sia cambiato il programma...
- if (currAlarms.Count > 0)
- {
- try
- {
- string sVal = "";
- if (lastAlarm != currAlarms["CNC_ALARM"])
- {
- // salvo!
- lastAlarm = currAlarms["CNC_ALARM"];
- // per ogni valore del dizionario mostro ed accodo!
- foreach (var item in currAlarms)
+ // se NON OK riprovo ANCORA 1 volta...
+ if (!answ)
{
- sVal = string.Format("[CNC_ALARM]{0}|{1}", item.Key, item.Value);
- // chiamo accodamento...
- accodaFLog(sVal, qEncodeFLog(item.Key, item.Value));
+ resetWebClients();
+ Thread.Sleep(rand.Next(250, 1000));
+ callResp = callUrl(urlIobEnabled, false);
+ answ = (callResp == "OK");
}
- }
- // accodo ALTRI allarmi NON CNC...
- foreach (var item in currAlarms.Where(X => X.Key != "CNC_ALARM"))
- {
- sVal = $"{item.Key} | {item.Value}";
- accodaFLog(sVal, qEncodeFLog(item.Key, item.Value));
- }
- }
- catch (Exception exc)
- {
- lgError("Eccezione in processCncAlarms{0}{1}", Environment.NewLine, exc);
- }
- }
- }
- }
-
- ///
- /// Effettua processing contapezzi (ed eventualmente alza il bit di contapezzo...)
- ///
- public virtual void processContapezzi()
- { }
-
- ///
- /// Task periodici SE disconnesso
- ///
- public virtual void processDisconnectedTask()
- {
- }
-
- ///
- /// Effettua processing del recupero dei valori dinamici:
- /// es: speed (RPM, feedrate) degli assi, valori pressioni, temeprature
- ///
- public void processDynData()
- {
- bool enableByApp = utils.CRB("enableDynData");
- bool enableByIob = (getOptPar("ENABLE_DYN_DATA") == "TRUE");
- bool forceSendByIob = (getOptPar("FORCE_DYN_DATA") == "TRUE");
- Dictionary currDynData = new Dictionary();
-
- if (enableByApp || enableByIob)
- {
- lgInfo("Inizio processDynData");
- if (connectionOk)
- {
- currDynData = getDynData();
- try
- {
- string sVal = "";
- // se richiesto send diretto...
- if (forceSendByIob)
- {
- // per ogni valore del dizionario mostro ed accodo!
- foreach (var item in currDynData)
+ // altri 2
+ maxTry = 2;
+ while (maxTry > 0 && !answ)
{
- sVal = string.Format("[DYNDATA]{0}|{1}", item.Key, item.Value);
- // chiamo accodamento...
- accodaFLog(sVal, qEncodeFLog(item.Key, item.Value));
+ Thread.Sleep(rand.Next(250, 500));
+ callResp = callUrl(urlIobEnabled, false);
+ answ = (callResp == "OK");
+ maxTry--;
}
- }
- // altrimenti verifico SE sia cambiato il valore dei DynData...
- else if (lastDynDataCtrlVal != currDynData["DYNDATA"])
- {
- // salvo!
- lastDynDataCtrlVal = currDynData["DYNDATA"];
- // per ogni valore del dizionario mostro ed accodo!
- foreach (var item in currDynData)
+ // salvo status...
+ IobOnline = answ;
+ // se online imposto veto check a 5 x tempo reinvio...
+ if (answ)
{
- sVal = string.Format("[DYNDATA]{0}|{1}", item.Key, item.Value);
- // chiamo accodamento...
- accodaFLog(sVal, qEncodeFLog(item.Key, item.Value));
- }
- }
- // salvo array...
- lastDynData = currDynData;
- }
- catch (Exception exc)
- {
- lgError(exc, "Eccezione in processDynData");
- }
- }
- else
- {
- lgError("Errore connessione mancante x getDynData");
- }
- }
- }
-
- ///
- /// Processa gestione memoria x invio dati QUANDO IOB è disconnesso da CNC...
- ///
- public void processMemoryDiscon()
- {
- // init obj display
- newDisplayData currDispData = new newDisplayData();
- // controllo contatore invio "keepalive"... invio solo a scadenza
- if (DateTime.Now.Subtract(lastDisconnCheck).TotalSeconds > utils.CRI("disconMaxSec"))
- {
- // resetto tutti i vlaori BYTE IN/PREV/OUT... così invio macchina spenta...
- B_input = 0;
- B_output = 0;
- B_previous = 0;
- accodaSigIN(ref currDispData);
- // update controllo
- lastDisconnCheck = DateTime.Now;
- }
- raiseRefresh(currDispData);
- }
-
- ///
- /// Effettua processing mode/status (EDIT/MDI/...)
- ///
- public virtual void processMode()
- { }
-
- ///
- /// Effettua processing ALTRI contatori/parametri (ed invia ad IO)
- ///
- public virtual void processOtherCounters()
- { }
-
- ///
- /// Effettua processing del recupero delle OVERRIDE (spindle, feedrate, rapid)
- ///
- public virtual void processOverride()
- {
- bool enableByApp = utils.CRB("enableOverrides");
- bool enableByIob = (getOptPar("ENABLE_OVERRIDES") == "TRUE");
- Dictionary currOverride = new Dictionary();
- if (enableByApp || enableByIob)
- {
- lgInfo("Inizio processOverride");
- if (connectionOk)
- {
- currOverride = getOverrides();
- }
- else
- {
- lgError("Errore connessione mancante x getOverrides");
- }
-
- // SE sono connesso...
- if (connectionOk)
- {
- // se HO dei valori override...
- if (currOverride.Count > 0)
- {
- // verifico SE sia cambiato il programma...
- if (lastOverrideFS != currOverride["FEED_OVER"] || lastOverrideRapid != currOverride["RAPID_OVER"])
- {
- // salvo!
- lastOverrideFS = currOverride["FEED_OVER"];
- lastOverrideRapid = currOverride["RAPID_OVER"];
- // per ogni valore del dizionario mostro ed accodo!
- string sVal = "";
- foreach (var item in currOverride)
- {
- sVal = string.Format("[OVERRIDES]{0}|{1}", item.Key, item.Value);
- // chiamo accodamento...
- accodaFLog(sVal, qEncodeFLog(item.Key, item.Value));
- }
- }
- }
- }
- }
- }
-
- ///
- /// Effettua ciclo controllo richieste server
- ///
- public void processServerRequests()
- {
- Dictionary task2exe = new Dictionary();
- Dictionary taskDone = new Dictionary();
- // recupero elenco delle cose da fare
- string resp = getTask2exe();
- if (!string.IsNullOrEmpty(resp))
- {
- try
- {
- task2exe = JsonConvert.DeserializeObject>(resp);
- // se ho da fare chiamo esecuzione..
- if (task2exe.Count > 0)
- {
- taskDone = processTask(task2exe);
- }
- }
- catch (Exception exc)
- {
- lgError($"Eccezione in processServerRequests:{Environment.NewLine}{exc}");
- }
- }
- }
-
- public Dictionary processTask(Dictionary task2exe)
- {
- Dictionary taskDone = new Dictionary();
- if (task2exe != null)
- {
- lgInfo($"Task2Exe S01: {task2exe.Count} task ricevuti:");
- int idTask = 0;
- foreach (var item in task2exe)
- {
- idTask++;
- lgInfo($"[{idTask:00}] - {item.Key} --> {item.Value}");
- }
- // chiamo procedura esecutiva (diversa x ogni IOB)
- taskDone = executeTasks(task2exe);
- lgInfo($"Task2Exe S02: eseguiti {taskDone.Count} task");
- // loggo tutti i task done...
- foreach (var item in taskDone)
- {
- sendToTaskWatch(item.Key, item.Value);
- }
- // ora chiamo la cancellazione dei task eseguiti...
- foreach (var item in taskDone)
- {
- remTask2exe(item.Key, item.Value);
- }
- }
- return taskDone;
- }
-
- ///
- /// Classe fittizia in caso di processing task in VHF
- ///
- public virtual void processVHF()
- {
- }
-
- ///
- /// Classe fittizia in caso di processing watchdog data
- ///
- public virtual void processWhatchDog()
- {
- }
-
- ///
- /// Effettua rilettura del contapezzi dal server MP/IO
- ///
- /// Forza rilettura da DB tempi ciclo rilevati
- public void pzCntReload(bool forceCountRec)
- {
- // legge da IO server ULTIMO valore CONTPEZZI al riavvio...
- string currServerCount = "";
- string lastIdxODL = "";
- if (checkServerAlive)
- {
- // leggo PRIMA ODL ....
- lastIdxODL = utils.callUrl(urlGetCurrODL);
- lgTrace("Lettura ODL dall'url {0} --> {1}", urlGetCurrODL, lastIdxODL);
- // se ho valori in coda da trasmettere uso dati REDIS
- if (forceCountRec)
- {
- // uso dati da TCiclo registrati...
- currServerCount = utils.callUrl(urlGetPzCountRec);
- lgInfo("Lettura contapezzi da TCiclo dall'url {0} --> num pz: {1}", urlGetPzCountRec, currServerCount);
- }
- else
- {
- // uso il contapezzi dichiarato dall'IOB stesso
- currServerCount = utils.callUrl(urlGetPzCount);
- lgInfo("Lettura contapezzi dall'url {0}", urlGetPzCount);
- }
- // controllo: SE NON HO ODL...
- if (string.IsNullOrEmpty(lastIdxODL) || lastIdxODL == "0")
- {
- // NON AGGIORNO
- contapezziIOB = contapezziPLC;
- lgError($"Errore lettura ODL (vuoto) resta tutto invariato contapezzi: {contapezziIOB} | contapezziPLC {contapezziPLC}");
- }
- else
- {
- if (!string.IsNullOrEmpty(currServerCount))
- {
- // se "-1" resto a ultimo...
- if (currServerCount != "-1")
- {
- int newVal = -1;
- Int32.TryParse(currServerCount, out newVal);
- contapezziIOB = newVal > -1 ? newVal : contapezziIOB;
- lgInfo("Ricevuta conferma da server di {0} pezzi registrati per ODL", currServerCount);
- }
- else
- {
- // NON AGGIORNO
- contapezziIOB = contapezziPLC;
- lgError($"Errore lettura contapezzi (-1) - uso contapezziPLC --> {contapezziPLC}");
- }
- }
- else
- {
- // registro che ho UN NUOVO ODL
- lgInfo($"Lettura ODL in pzCntReload, currIdxODL {currIdxODL} --> lastIdxODL {lastIdxODL}");
- // se ODL differente e NUOVO è zero --> resetto!
- if (currIdxODL.ToString() != lastIdxODL && lastIdxODL == "0")
- {
- // cambiato ODL quindi reset...
- contapezziIOB = 0;
- lgInfo("Nuovo ODL==0, RESET contapezzi (-->ZERO)");
- }
- // provo a salvare nuovo ODL
- int.TryParse(lastIdxODL, out currIdxODL);
- }
- }
- }
- else
- {
- // se server NON pronto...
- contapezziIOB = contapezziPLC;
- lgError("Errore server NON pronto in pzCntReload");
- }
- }
-
- ///
- /// Fornisce il valore di flusso e valore in formato valido x messa in coda nel formato
- /// dtEve#flusso#valore#cont
- /// Flusso dati
- /// Valore da salvare
- ///
- public string qEncodeFLog(string flusso, string valore)
- {
- string answ = "";
- try
- {
- answ = $"{DateTime.Now:yyyyMMddHHmmssfff}#{flusso}#{valore}#{counterULog}";
- }
- catch
- { }
- return answ;
- }
-
- ///
- /// Fornisce il valore di flusso e valore in formato valido x messa in coda nel formato dtEve#flux#value#cont
- /// DataOra evento registrato
- /// Flusso dati
- /// Valore da salvare
- ///
- public string qEncodeFLog(DateTime eventDT, string flusso, string valore)
- {
- string answ = "";
- try
- {
- answ = $"{eventDT:yyyyMMddHHmmssfff}#{flusso}#{valore}#{counterFLog}";
- }
- catch
- { }
- return answ;
- }
-
- ///
- /// Fornisce il valore di UserLog e valore in formato valido x messa in coda nel formato:
- /// dtEve#flusso#value#cont#matrOpr#label#valNum
- /// Flusso dati (RC/RS/DI)
- /// Valore da inviare (valString
- /// Matricola operatore
- /// Valore etichetta: causale scarto / tagCode
- /// Valore numerico: esitoOk (0/1) / nuo scarti
- ///
- public string qEncodeULog(string flusso, string valore, int matrOpr, string label, int valNum)
- {
- string answ = "";
- try
- {
- answ = $"{DateTime.Now:yyyyMMddHHmmssfff}#{flusso}#{valore}#{matrOpr}#{label}#{valNum}#{counterULog}";
- }
- catch
- { }
- return answ;
- }
-
- ///
- /// Effettua lettura dati
- /// Parametri da aggiornare x display in form
- ///
- public virtual void readAllData(ref newDisplayData currDispData)
- {
- if (currDispData == null)
- {
- currDispData = new newDisplayData();
- }
- try
- {
- if (DemoIn)
- {
- // segnalo che sono in Demo
- currDispData.semIn = Semaforo.SV;
- }
- if (connectionOk)
- {
- readSemafori(ref currDispData);
- }
- else
- {
- lgError("Errore connessione mancante x readSemafori");
- }
-
- nReadIN++;
- // aggiorno valore mostrato...
- displayRawData(ref currDispData);
- }
- catch
- {
- currDispData.semIn = Semaforo.SR;
- }
- raiseRefresh(currDispData);
- }
-
- ///
- /// Effettua lettura semafori principale
- /// Parametri da aggiornare x display in form
- ///
- public virtual void readSemafori(ref newDisplayData currDispData)
- {
- lastReadPLC = DateTime.Now;
- }
-
- ///
- /// Aggiunge ai dati da inviare alla parentform i valori di RawInput rilevati (32bit)
- /// 2021.08.27: filtrati secondo i valori setup start/size RawDataInput
- ///
- public virtual void reportRawInput(ref newDisplayData currDispData)
- {
- // processo eventualmente aggiungendo ad elementi esistenti...
- if (currDispData == null)
- {
- currDispData = new newDisplayData();
- }
- try
- {
- StringBuilder sb = new StringBuilder();
- sb.Append($"B_input --> {(short)B_input}{Environment.NewLine}");
- sb.Append($"{baseUtils.binaryForm(B_input)}{Environment.NewLine}");
- sb.Append($"{Environment.NewLine}");
- sb.Append($"----------- RAW Data Memory -----------{Environment.NewLine}");
- // Do x scontato siano VALIDI i valori di RawDataInputStart / size --> filtro...
- var filtRawData = new byte[RawDataInputSize];
- Array.Copy(RawInput, RawDataInputStart, filtRawData, 0, RawDataInputSize);
- int i = RawDataInputStart;
- foreach (var item in filtRawData)
- {
- sb.Append($"B{i:00} --> {baseUtils.binaryForm(item)} = {(short)item}{Environment.NewLine}");
- i++;
- }
- sb.Append("-------------------------------");
- currDispData.currBitmap = sb.ToString();
- }
- catch
- { }
- }
-
- ///
- /// Metodo generico di reset contapezzi...
- ///
- ///
- public virtual bool resetcontapezziPLC()
- {
- return false;
- }
-
- ///
- /// metodo dummy x salvataggio aree memoria conf x CN
- ///
- /// tipo di DUMP
- public virtual void saveMemDump(dumpType tipo)
- {
- }
-
- ///
- /// Salva valori indicati in prod data
- ///
- /// Item KVP di cui salvare i dati in currProdData come chiave/valore
- ///
- public void saveProdData(KeyValuePair item)
- {
- // imposto i valori...
- if (currProdData.ContainsKey(item.Key))
- {
- currProdData[item.Key] = item.Value;
- }
- else
- {
- currProdData.Add(item.Key, item.Value);
- }
- }
-
- ///
- /// Effettua salvataggio in LUT del valore ricevuto
- ///
- ///
- ///
- ///
- ///
- public virtual void saveValue(ref Dictionary outVal, double valore, string chiave)
- {
- //check obj preliminare
- if (outVal == null)
- {
- outVal = new Dictionary();
- }
- bool scaduto = stackVal_TSVC(chiave, valore);
- // recupero VC
- valore = getVal_TSVC(chiave, scaduto);
- if (scaduto)
- {
- // limite a 3 digit x valore float
- outVal.Add(chiave, $"{valore:N3}");
- }
- LastTSVC[chiave] = valore;
- }
-
- ///
- /// Invio la variazione dello stato allarmi (se avvenuta)
- ///
- /// COD memoria allarmi
- /// Indice memoria allarmi
- /// ultimo stato rilevato
- /// stato corrente
- /// Lista allarmi validi per l'area
- ///
- public bool sendAlarmVariations(string memAddr, int index, uint lastStatus, uint currStatus, List AlarmList)
- {
- bool fatto = false;
- if (lastStatus != currStatus)
- {
- List ActiveAlarmList = new List();
- // invio GET del MemoryAddress, del banco e del valore currStatus
- lastUrl = $"{urlSendAlarm}?memAddr={memAddr}&index={index}&currStatus={currStatus}";
- if (currStatus == 0)
- {
- ActiveAlarmList.Add("ALL OK");
- }
- else
- {
- // calcolo quali allarmi mostrare dato currStatus ed elenco allarmi
- string bitMap = Convert.ToString(currStatus, 2);
- int bitLen = bitMap.Length;
- // ciclo x associare tutti gli allarmi
- for (int i = 0; i < bitLen; i++)
- {
- // se è 1 --> aggiungo!
- if (bitMap[bitLen - i - 1] == '1')
- {
- // se sono entro limiti
- if (AlarmList.Count >= i)
- {
- ActiveAlarmList.Add($"{i:000}-{AlarmList.ElementAt(i)}");
- }
- //else
- //{
- // ActiveAlarmList.Add($"Unknown Bit.{i}");
- //}
- }
- }
- }
-
- string rawData = JsonConvert.SerializeObject(ActiveAlarmList);
-
- //string resp = utils.callUrlNow(lastUrl, rawData);
- string resp = utils.callUrlAsync(lastUrl, rawData);
- if (!string.IsNullOrEmpty(resp))
- {
- if (resp.ToUpper() == "OK")
- {
- // segnalo fatto
- fatto = true;
- }
- }
- else
- {
- lgError($"Errore in invio richiesta registrazione allarme: URL: {lastUrl}{Environment.NewLine}Payload:{Environment.NewLine}{rawData}");
- }
- }
- return fatto;
- }
-
- ///
- /// Invia una LISTA di valori
- ///
- ///
- ///
- public void sendDataBlock(urlType tipoUrl, List listQueueVal)
- {
- // init obj display
- newDisplayData currDispData = new newDisplayData();
- if (listQueueVal != null)
- {
- try
- {
- // recupero e formatto URL dati da coda...
- lastUrl = urlDataBlock(tipoUrl);
- // in base al tipo di dato compongo il payload Json da inviare
- string payload = jsonPayload(tipoUrl, listQueueVal);
- // async a true SE FLog
- bool doAsync = tipoUrl == urlType.FLog ? true : false;
- // se NON sono in demo effettuo invio!
- if (!DemoOut)
- {
- // SE server alive...
- if (checkServerAlive)
- {
- // chiamo URL!
- string answ = callUrlWithPayload(lastUrl, payload, doAsync);
- // attesa opzionale se configurata
-
- // loggo!
- lgInfo($"[SEND payload] TipoURL: {tipoUrl} | {listQueueVal.Count} records --> {answ}");
- // se "OK" verde, altrimenti errore --> ROSSO
- if (answ.Contains("OK"))
- {
- currDispData.semOut = Semaforo.SV;
- // se oltre 1 min NON era online --> check pezzi!
- if (DateTime.Now.Subtract(lastIobOnline).TotalMinutes > 1 && !isMulti)
- {
- lgInfo($"sendDataBlock --> offline timeout ({lastIobOnline}) --> pzCntReload(true)");
- pzCntReload(true);
- }
lastIobOnline = DateTime.Now;
}
+ dtVetoCheckIOB = DateTime.Now.AddMilliseconds(baseUtils.nextPauseSendMSec * 5);
+ }
+ catch
+ { }
+ }
+ // verifico SE è variato stato online/offline...
+ if (IobOnline != answ)
+ {
+ // se ORA sono online riporto...
+ if (answ)
+ {
+ lgInfo("IOB ONLINE for server MP/IO");
+ }
+ else
+ {
+ lgInfo("IOB OFFLINE for server MP/IO");
+ }
+ }
+ // fix colore
+ if (answ)
+ {
+ parentForm.commSrvActive = 2;
+ }
+ else
+ {
+ parentForm.commSrvActive = 1;
+ }
+ }
+ else
+ {
+ // altrimenti passo ultimo valore noto
+ answ = IobOnline;
+ }
+ return answ;
+ }
+ }
+
+ ///
+ /// test ping all'indirizzo impostato nei parametri
+ ///
+ ///
+ private IPStatus testPingServer
+ {
+ get
+ {
+ IPStatus answ = IPStatus.Unknown;
+ // se disabilitato salto...
+ if (pingDisabled)
+ {
+ answ = IPStatus.Success;
+ }
+ else
+ {
+ IPAddress address;
+ PingReply reply;
+ var rand = new Random();
+ int pingTOut = 500;
+ using (Ping pingSender = new Ping())
+ {
+ address = IPAddress.Loopback;
+ int maxRetry = maxPingRetry + 1;
+ int numRetry = 1;
+ string ipAddr = cIobConf.serverData.MPIP.Replace($"{cIobConf.serverData.TRANSP}://", "");
+ // fix se fosse ip + porta...
+ if (ipAddr.IndexOf(":") >= 0)
+ {
+ ipAddr = ipAddr.Substring(0, ipAddr.IndexOf(":"));
+ }
+ IPAddress.TryParse(ipAddr, out address);
+ // se null --> provo DNS...
+ if (address == null)
+ {
+ var rawAddresses = Dns.GetHostAddresses(ipAddr);
+ if (rawAddresses.Length > 0)
+ {
+ address = rawAddresses[0];
+ }
+ }
+ try
+ {
+ // se != null --> uso address...
+ if (address != null)
+ {
+ pingTOut = rand.Next(200, 400);
+ reply = pingSender.Send(address, pingTOut);
+ }
else
{
- currDispData.semOut = Semaforo.SR;
+ pingTOut = rand.Next(300, 600);
+ reply = pingSender.Send(cIobConf.cncIpAddr, pingTOut);
}
}
- else
+ catch (Exception exc)
{
- lgInfo($"[SERVER KO] {listQueueVal.Count}");
+ pingTOut = rand.Next(100, 200);
+ reply = pingSender.Send(IPAddress.Loopback, pingTOut);
+ lgError($"ping to loopback addres per eccezione:{Environment.NewLine}{exc}");
+ }
+ // se ho timeout riprovo...
+ while (reply.Status != IPStatus.Success && numRetry < maxRetry)
+ {
+ Thread.Sleep(rand.Next(50, 200));
+ pingTOut = pingServerMsTimeout * numRetry / 2;
+ reply = pingSender.Send(address, pingTOut);
+ numRetry++;
+ if (reply.Status == IPStatus.Success)
+ {
+ lgInfo("Server PING OK!");
+ break;
+ }
+ else
+ {
+ lgInfo($"Server Ping KO | reply: {reply.Status} --> retry | TimeOut: {pingTOut}");
+ }
}
}
- else
- {
- currDispData.semOut = Semaforo.SV;
- // loggo!
- lgInfo($"{listQueueVal.Count} records --> [SIM]");
- }
- nSendOut += listQueueVal.Count;
- // riporto cosa inviato
- currDispData.newUrlCallData = lastUrl;
- // aggiorno data ultimo watchdog...
- lastWatchDog = DateTime.Now;
- }
- catch
- {
- currDispData.semOut = Semaforo.SR;
+ answ = reply.Status;
}
+ return answ;
}
- raiseRefresh(currDispData);
+ }
+
+ #endregion Private Properties
+
+ #region Private Methods
+
+ ///
+ /// Verifica e se necessario comprime directory log...
+ ///
+ private void checkShrinkDir()
+ {
+ // comprimo x prima cosa la folder dell'IOB corrente
+ string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs", cIobConf.codIOB);
+ //string path = string.Format("{0}logs\\{1}", AppDomain.CurrentDomain.BaseDirectory, cIobConf.codIOB);
+ baseUtils.shrinkDir(path);
+ // provo a comprimere anche la folder MAIN....
+ path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs", "MAIN");
+ baseUtils.shrinkDir(path);
}
///
- /// Effettua invio a MoonPro del valore richiesto
+ /// Mostra i dati grezzi letti in esadecimale Parametri da
+ /// aggiornare x display in form
///
- ///
- /// Valore da trasmettere: es
- /// INPUT: lo status rilevato in HEX
- /// FLog: il valore da trasmettere per il flusso indicato
- public void sendToMoonPro(urlType tipoUrl, string queueVal)
+ private void displayRawData(ref newDisplayData currDispData)
{
- // init obj display
- newDisplayData currDispData = new newDisplayData();
+ // mostro update...
+ string newString = string.Format("{0:X}", B_input);
+ currDispData.newInData = newString;
+ }
+
+ ///
+ /// Esegue filtraggio dati x bit blinking!!!
+ ///
+ private void filterData()
+ {
+ // effettuo filtraggio dei valori letti... inizializzo OUT!
+ B_output = 0;
+ // in primis verifico SE ci siano bit blinkng... se non ci sono OUT=IN...
+ if (cIobConf.BLINK_FILT == 0)
+ {
+ B_output = B_input;
+ }
+ else
+ {
+ // incomincio con i valori NON blinking: questi "passano invariati", inizio a
+ // sommare nel valore OUT...
+ B_output = B_input & ~cIobConf.BLINK_FILT;
+ // calcolo il valore dei BIT che "passano la maschera"
+ int iBlink = B_input & cIobConf.BLINK_FILT;
+ // ...aggiungo i "bit che passano"
+ B_output += iBlink;
+
+ // calcolo QUALI valori (tra quelli blink) siano PASSATI da 0 a 1 --> init counters...
+ BitArray bBlinkStart = new BitArray(new byte[] { Convert.ToByte(iBlink) });
+ int[] bitsUp = bBlinkStart.Cast().Select(bit => bit ? 1 : 0).ToArray();
+ for (int i = 0; i < bitsUp.Length; i++)
+ {
+ // SE 1... impostiamo contatori al MAX
+ if (bitsUp[i] == 1)
+ {
+ // se era zero indico START blink...
+ if (i_counters[i] == 0)
+ {
+ lgTrace("START BLINK: B{0}", i);
+ }
+ // imposto comunque contatore al cambio fronte...
+ i_counters[i] = cIobConf.MAX_COUNTER_BLINK;
+ }
+ }
+
+ // quelli che sono zero... LI RECUPERO E LI PROCESSO...
+ int iZero = ~B_input & cIobConf.BLINK_FILT;
+ BitArray bBlinkEnd = new BitArray(new byte[] { Convert.ToByte(iZero) });
+ int[] bitsDown = bBlinkEnd.Cast().Select(bit => bit ? 1 : 0).ToArray();
+ for (int i = 0; i < bitsDown.Length; i++)
+ {
+ // se era a zero (invertito...)
+ if (bitsDown[i] == 1)
+ {
+ // SE è in corso il conteggio...
+ if (i_counters[i] > 0)
+ {
+ // decremento!
+ i_counters[i] -= 1;
+ // se è zero NON faccio nulla, altrimenti SOMMO...
+ if (i_counters[i] > 0)
+ {
+ B_output += 1 << i;
+ }
+ else
+ {
+ lgTrace("END BLINK: B{0}", i);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ ///
+ /// Imposta eventuali altri valori default
+ ///
+ private void fixDefaultPar()
+ {
+ // parametro max tentativi PING...
+ string s_maxPingRetry = getOptPar("MAX_PING_RETRY");
+ if (!string.IsNullOrEmpty(s_maxPingRetry))
+ {
+ int numRetry = 5;
+ int.TryParse(s_maxPingRetry, out numRetry);
+ maxPingRetry = numRetry;
+ }
+
+ string s_maxErrCheck = getOptPar("MAX_ERR_CHECK");
+ if (!string.IsNullOrEmpty(s_maxErrCheck))
+ {
+ int numErr = 50;
+ int.TryParse(s_maxErrCheck, out numErr);
+ maxErroriCheck = numErr;
+ }
+
+ string s_watchDogPer = getOptPar("WATCHDOG_PERIOD");
+ if (!string.IsNullOrEmpty(s_watchDogPer))
+ {
+ int numPer = 3;
+ int.TryParse(s_watchDogPer, out numPer);
+ watchDogPeriod = numPer;
+ }
+ }
+
+ ///
+ /// Legge da conf il valore di demoltiplica lettura dynData (se presente) o ignora e pone a 1...
+ ///
+ private void fixDemFactDynData()
+ {
+ var rawDemFact = getOptPar("DEM_FACT_DYN_DATA");
+ if (string.IsNullOrEmpty(rawDemFact))
+ {
+ demFactDynData = 1;
+ }
+ else
+ {
+ int.TryParse(rawDemFact, out demFactDynData);
+ }
+ }
+
+ ///
+ /// recupera valore salvato in persistence layer (se non c'è crea...)
+ ///
+ ///
+ ///
+ private string getStoredVal(string keyVal)
+ {
+ string value = "";
try
{
- // recupero e formatto URL dati da coda...
- switch (tipoUrl)
+ if (persistenceLayer != null)
{
- case urlType.FLog:
- lastUrl = urlFLog(queueVal);
- break;
-
- case urlType.SignIN:
- lastUrl = urlInput(queueVal);
- break;
-
- default:
- lastUrl = "";
- break;
- }
- // se NON sono in demo effettuo invio!
- if (!DemoOut)
- {
- // SE server alive...
- if (checkServerAlive)
+ if (!persistenceLayer.TryGetValue(keyVal, out value))
{
- // chiamo URL!
- string answ = callUrl(lastUrl, false);
- // loggo!
- lgDebug(string.Format("[SEND] {0} -> {1}", queueVal, answ));
- // se oltre 1 min NON era online --> check pezzi!
- if (DateTime.Now.Subtract(lastIobOnline).TotalMinutes > 1 && !isMulti)
- {
- lgInfo($"sendToMoonPro --> offline timeout ({lastIobOnline}) --> pzCntReload(true)");
- pzCntReload(true);
- }
- // se richiesto effettuo refresh contapezzi
- if (needRefreshPzCount && !isMulti)
- {
- pzCntReload(true);
- needRefreshPzCount = false;
- }
- lastIobOnline = DateTime.Now;
- // se "OK" verde, altrimenti errore --> ROSSO
- if (answ == "OK")
- {
- currDispData.semOut = Semaforo.SV;
- }
- else
- {
- currDispData.semOut = Semaforo.SR;
- }
- }
- else
- {
- lgError(string.Format("[SERVER KO] {0}", queueVal));
+ persistenceLayer.Add(keyVal, "0");
}
}
- else
- {
- currDispData.semOut = Semaforo.SV;
- // loggo!
- lgDebug(string.Format("{0} -> [SIM]", queueVal));
- }
- nSendOut++;
- currDispData.newUrlCallData = lastUrl;
- // aggiorno data ultimo watchdog...
- lastWatchDog = DateTime.Now;
}
- catch
+ catch (Exception exc)
{
- currDispData.semOut = Semaforo.SR;
+ lgError(string.Format("Eccezione in getStoredVal: {0}{1}", Environment.NewLine, exc));
}
- raiseRefresh(currDispData);
+ return value;
}
///
- /// Metodo generico di IMPOSTAZIONE FORZATA del contapezzi...
+ /// recupera valore salvato in persistence layer (se non c'è crea...) come double
///
- /// Pezzi richiesti
+ ///
///
- public virtual bool setcontapezziPLC(int newPzCount)
+ private double getStoredValDouble(string keyVal)
{
- return false;
- }
-
- ///
- /// Processing di Variabili Campionarie x TimeSeries, accoda valori x la VC (se esiste) e restituisce bool val se SCADUTO periodo controllo
- ///
- /// Nome della VC
- /// Valore (nuovo) delal VC
- ///
- public bool stackVal_TSVC(string VCName, double VCVal)
- {
- bool answ = false;
- // cerco VC...
- if (TSVC_Data.ContainsKey(VCName))
+ double answ = 0;
+ try
{
- TSVC_Data[VCName].dataArray.Add(VCVal);
- // ora verifico scadenza...
- if (TSVC_Data[VCName].DTStart.AddSeconds(TSVC_Data[VCName].Period) < DateTime.Now)
- {
- answ = true;
- }
+ answ = Convert.ToDouble(getStoredVal(keyVal));
}
+ catch (Exception exc)
+ {
+ lgError(string.Format("Eccezione in getStoredValDouble: {0}{1}", Environment.NewLine, exc));
+ }
+ answ = (answ < (double.MaxValue / 10 * 9)) ? answ : 0;
return answ;
}
///
- /// Avvia l'adapter sulla porta richiesta
+ /// recupera valore salvato in persistence layer (se non c'è crea...) come INT
///
- /// indica se sia richeisto di SVUOTARE le code delel info
- public virtual void startAdapter(bool resetQueue)
+ ///
+ ///
+ private long getStoredValLong(string keyVal)
{
- lgInfo("Starting adapter...");
- maxJsonData = utils.CRI("maxJsonData");
- maxJsonDataEv = utils.CRI("maxJsonDataEv");
- parentForm.commPlcActive = false;
- adpRunning = true;
- dtAvvioAdp = DateTime.Now;
- lastWatchDog = dtAvvioAdp;
- lastPING = dtAvvioAdp;
- lastReadPLC = dtAvvioAdp.AddMinutes(-1);
- lastDisconnCheck = dtAvvioAdp;
- TimingData.resetData();
- // aggiungo altri defaults
- setDefaults(resetQueue);
- adpTryRestart = true;
- lgDebug("startAdapter completed");
+ long answ = 0;
+ try
+ {
+ answ = Convert.ToInt64(getStoredVal(keyVal));
+ }
+ catch
+ { }
+ // verifico che il valore sia minore di 9/10 del valore massimo...
+ answ = (answ < (long.MaxValue / 10 * 9)) ? answ : 0;
+ return answ;
}
///
- /// ferma l'adapter...
+ /// recupera valore salvato in persistence layer (se non c'è crea...) come UINT
///
- /// indica se si debba tentare di riavviare l'adapter (con caduta connessione viene fermato in automatico)
- /// indica se sia richeisto di SVUOTARE le code delel info
- public virtual void stopAdapter(bool tryRestart, bool forceDequeue)
+ ///
+ ///
+ private uint getStoredValUInt(string keyVal)
{
- if (forceDequeue)
+ uint answ = 0;
+ try
{
- // svuoto le code dei valori letti e non ancora trasmessi...
- parentForm.displayTaskAndLog("[CLOSING] Svuotamento FORZATO coda segnali...");
- while (QueueIN.Count > 0)
+ answ = Convert.ToUInt32(getStoredVal(keyVal));
+ }
+ catch (Exception exc)
+ {
+ lgError(string.Format("Eccezione in getStoredValUInt: {0}{1}", Environment.NewLine, exc));
+ }
+ // verifico che il valore sia minore di 9/10 del valore massimo...
+ answ = (answ < (uint.MaxValue / 10 * 9)) ? answ : 0;
+ return answ;
+ }
+
+ ///
+ /// Classe fittizia in caso di processing GLOBALE di tutto in 1 solo colpo...
+ ///
+ private void processAllMemory()
+ {
+ // init obj display
+ newDisplayData currDispData = new newDisplayData();
+ // in primis SALVO valori previous/precedenti
+ B_previous = B_output;
+ // poi faccio lettura NUOVI valori
+ readAllData(ref currDispData);
+ // eseguo il filtering dei valori (per i bit "blinking")
+ filterData();
+ // effettuo confronto valori vecchi/nuovi... SE trovo variazione OPPURE se è passato +
+ // di un timeout di controllo...
+ if (B_output != B_previous)
+ {
+ accodaSigIN(ref currDispData);
+ }
+ raiseRefresh(currDispData);
+ }
+
+ private void processMem2Write()
+ {
+ List updatedPar = new List();
+ // ciclo tutti gli oggetti write x vedere se modificati...
+ foreach (var item in currProdData)
+ {
+ bool needWrite = false;
+ // li cerco su last... se non ci sono o modificati --> salvo da scrivere e copio
+ if (lastProdData.ContainsKey(item.Key))
{
- // INVIO COMUNQUE...!!!
- string valore = "";
- QueueIN.TryDequeue(out valore);
- sendToMoonPro(urlType.SignIN, valore);
- }
- parentForm.displayTaskAndLog("[CLOSING] Svuotamento FORZATO coda FluxLOG...");
- // se ho + di 2 elementi in coda --> uso invio JSON in blocco...
- if (QueueFLog.Count > minJsonData)
- {
- while (QueueFLog.Count > 0)
+ // verifico se variato...
+ if (!item.Value.Equals(lastProdData[item.Key]))
{
- List listaValori = new List();
- // se ho + di maxJsonData elementi --> invio un set di dati alla volta
- if (QueueFLog.Count > maxJsonData)
- {
- string currVal = "";
- // prendoi primi maxJsonDataValori
- for (int i = 0; i < maxJsonData; i++)
- {
- QueueFLog.TryDequeue(out currVal);
- listaValori.Add(currVal);
- }
- sendDataBlock(urlType.FLog, listaValori);
- }
- else
- {
- // invio in blocco
- listaValori = QueueFLog.ToList();
- // invio
- sendDataBlock(urlType.FLog, listaValori);
- // svuoto!
- QueueFLog = new ConcurrentQueue();
- }
+ needWrite = true;
+ lastProdData[item.Key] = item.Value;
}
- // HO FINITO invio di FLog...
}
+ // aggiungo
else
{
- string currVal = "";
- while (QueueFLog.Count > 0)
- {
- // INVIO COMUNQUE...!!!
- QueueFLog.TryDequeue(out currVal);
- sendToMoonPro(urlType.FLog, currVal);
- }
+ needWrite = true;
+ lastProdData.Add(item.Key, item.Value);
}
-
- // svuoto coda ULog
- while (QueueULog.Count > 0)
+ // se devo scrivere --> riporto
+ if (needWrite)
{
- List listaValori = new List();
- // se ho + di maxJsonData elementi --> invio un set di dati alla volta
- if (QueueULog.Count > maxJsonData)
+ if (memMap.mMapWrite.ContainsKey(item.Key))
{
- string currVal = "";
- // prendoi primi maxJsonDataValori
- for (int i = 0; i < maxJsonData; i++)
+ // preparo obj da scrivere
+ objItem newWrite = new objItem()
{
- QueueULog.TryDequeue(out currVal);
- listaValori.Add(currVal);
- }
- sendDataBlock(urlType.ULog, listaValori);
- }
- else
- {
- // invio in blocco
- listaValori = QueueULog.ToList();
- // invio
- sendDataBlock(urlType.ULog, listaValori);
- // svuoto!
- QueueULog = new ConcurrentQueue();
+ uid = item.Key,
+ name = item.Key,
+ reqValue = memMap.mMapWrite[item.Key].value,
+ lastRequest = DateTime.Now,
+ writable = true
+ };
+ updatedPar.Add(newWrite);
}
}
}
- parentForm.displayTaskAndLog("[STOP] Stopping adapter...");
- adpTryRestart = false;
-
- parentForm.displayTaskAndLog("[STOP] Stopping adapter - last periodic data read...");
-
- // chiudo la connessione all'adapter...
- tryDisconnect();
- dtStopAdp = DateTime.Now;
- adpTryRestart = tryRestart;
- adpRunning = false;
- // chiudo!
- parentForm.displayTaskAndLog("Adapter Stopped.");
- parentForm.commPlcActive = false;
+ // se ho da scrivere... scrivo TUTTI!
+ if (updatedPar.Count > 0)
+ {
+ // scrivo valore!
+ lgInfo("Chiamata di plcWriteParams da processMem2Write");
+ plcWriteParams(ref updatedPar);
+ // invio su cloud parametri!
+ string rawData = JsonConvert.SerializeObject(updatedPar);
+ utils.callUrl($"{urlUpdateWriteParams}", rawData);
+ lgInfo($"Notificato a server scrittura {updatedPar.Count} parametri");
+ }
}
///
- /// Processo la coda SignalIN...
+ /// Effettua gestioen programma: legge e mostra su display...
///
- public void svuotaCodaSignIN()
+ private void processProgram()
{
+ string currPrgName = "";
+ // se abilitata lettura prgName
+ if (enablePrgName)
+ {
+ if (connectionOk)
+ {
+ currPrgName = getPrgName();
+ }
+ else
+ {
+ lgError("Errore connessione mancante x getPrgName");
+ }
+ }
+ else
+ {
+ currPrgName = lastPrgName;
+ }
+ // verifico SE sia cambiato il programma...
+ if (lastPrgName != currPrgName)
+ {
+ // salvo!
+ lastPrgName = currPrgName;
+ string sVal = string.Format("[PROG]{0}", currPrgName);
+
+ // chiamo accodamento...
+ accodaFLog(sVal, qEncodeFLog("PROG", currPrgName));
+ }
+ }
+
+ ///
+ /// Processo lettura dati sysinfo
+ ///
+ private void processSysInfo()
+ {
+ if (utils.CRB("enableSysInfo"))
+ {
+ Dictionary currSysInfo = new Dictionary();
+
+ if (connectionOk)
+ {
+ currSysInfo = getSysInfo();
+ }
+ else
+ {
+ lgError("Errore connessione mancante x getSysInfo");
+ }
+ // verifico SE sia cambiato il programma...
+ if (lastSysInfo != currSysInfo["SYSINFO"])
+ {
+ // salvo!
+ lastSysInfo = currSysInfo["SYSINFO"];
+ // per ogni valore del dizionario mostro ed accodo!
+ string sVal = "";
+ foreach (var item in currSysInfo)
+ {
+ sVal = string.Format("[SYSINFO]{0}|{1}", item.Key, item.Value);
+ // chiamo accodamento...
+ accodaFLog(sVal, qEncodeFLog(item.Key, item.Value));
+ }
+ }
+ }
+ }
+
+ private void reportDataProc()
+ {
+ // update valori visualizzazione...
+ parentForm.dataProcLabel = string.Format("RAW: {0} --> IN: {1} --> OUT: {2}", nReadIN, nReadFilt, nSendOut);
+ }
+
+ ///
+ /// Imposto alcuni valori di default
+ ///
+ /// indica se sia richeisto di SVUOTARE le code delel info
+ private void setDefaults(bool resetQueue)
+ {
+ numSim = utils.CRI("numSim");
+ lastPrgName = "";
+ nReadIN = 0;
+ nReadFilt = 0;
+ nSendOut = 0;
+ currMode = 0;
+ lastAlarm = "";
+ doStartMemDump = utils.CRB("doStartMemDump");
+ doSampleMemory = utils.CRB("doSampleMemory");
+ // fix url wait random...
+ urlRandWait = utils.CRI("urlRandWait");
+ // fix fattore demoltiplica dynData
+ fixDemFactDynData();
+
+ // svuoto code se richiesto
+ if (resetQueue)
+ {
+ QueueAlarm = new ConcurrentQueue();
+ QueueIN = new ConcurrentQueue();
+ QueueFLog = new ConcurrentQueue();
+ QueueMessages = new ConcurrentQueue();
+ QueueRawTransf = new ConcurrentQueue();
+ QueueULog = new ConcurrentQueue();
+ }
+ // imposto contatori blink a zero...
+ i_counters = new int[32];
+ lastPeriodicLog = DateTime.Now;
+ // fix parametri generali...
+ enablePrgName = true;
+ }
+
+ private void svuotaCodaContapezzi()
+ {
+ // permetto al max 2 tentativi infruttuosi...
+ int maxTry = 2;
+ int oldContapezzi = contapezziIOB;
+ // se ho contapezzi OLTRE limite...
+ while ((MPOnline) && (contapezziPLC > contapezziIOB + minSendPzCountBlock))
+ {
+ lgInfo($"Ciclo svuotaCodaContapezzi --> contapezziPLC: {contapezziPLC} | contapezziIOB: {contapezziIOB}");
+ if (!isMulti)
+ {
+ pzCntReload(true);
+ }
+ // provo invio
+ trySendPzCountBlock();
+ // verifica per evitare loop infinito invio fallito
+ if (oldContapezzi == contapezziIOB)
+ {
+ maxTry--;
+ }
+ else
+ {
+ maxTry = 2;
+ oldContapezzi = contapezziIOB;
+ }
+ // verifico maxTry: se li ho esauriti esco!
+ if (maxTry <= 0)
+ {
+ return;
+ }
+ // aspetto x dare tempo calcolo
+ Thread.Sleep(400);
+ }
+ }
+
+ ///
+ /// Processo la coda FLog...
+ ///
+ private void svuotaCodaFLog()
+ {
+ // controllo se è passato oltre watchdog e non ho inviato nulla --> RE-INVIO (ultimo inviato)!!!!
+ if (DateTime.Now.Subtract(lastWatchDog).TotalSeconds > utils.CRI("watchdogMaxSec"))
+ {
+ string wdStatus = "elapsed";
+ string sVal = string.Format("[WDST]{0}", wdStatus);
+ // chiamo accodamento...
+ accodaFLog(sVal, qEncodeFLog("WDST", wdStatus));
+ lastWatchDog = DateTime.Now;
+ }
// verifico SE la coda abbia dei valori...
- if (QueueIN.Count > 0)
+ if (QueueFLog.Count > 0)
{
// invio pacchetto di dati (max da conf)
for (int i = 0; i < nMaxSend; i++)
{
- if (QueueIN.Count > 0)
+ // SE ho qualcosa in coda...
+ if (QueueFLog.Count > 0)
{
string currVal = "";
- // se online provo
if (MPOnline)
{
if (IobOnline)
{
// se ho + di 2 elementi in coda --> uso invio JSON in blocco...
- if (QueueIN.Count > 1)
+ if (QueueFLog.Count > 1)
{
List listaValori = new List();
// se ho + di maxJsonData elementi --> invio un set di dati alla volta
- if (QueueIN.Count > maxJsonDataEv)
+ if (QueueFLog.Count > maxJsonData)
{
// prendoi primi maxJsonDataValori
- for (int j = 0; j < maxJsonDataEv; j++)
+ for (int j = 0; j < maxJsonData; j++)
{
- QueueIN.TryDequeue(out currVal);
+ QueueFLog.TryDequeue(out currVal);
listaValori.Add(currVal);
}
- sendDataBlock(urlType.SignIN, listaValori);
+ sendDataBlock(urlType.FLog, listaValori);
+ lastWatchDog = DateTime.Now;
}
else
{
// invio in blocco
- listaValori = QueueIN.ToList();
+ listaValori = QueueFLog.ToList();
// invio
- sendDataBlock(urlType.SignIN, listaValori);
+ sendDataBlock(urlType.FLog, listaValori);
// svuoto!
- QueueIN = new ConcurrentQueue();
+ QueueFLog = new ConcurrentQueue();
+ lastWatchDog = DateTime.Now;
}
}
else
{
// INVIO SINGOLO...!!!
- QueueIN.TryDequeue(out currVal);
- sendToMoonPro(urlType.SignIN, currVal);
- }
- // salvo come last signal in il currVal ultimo... SE !=""
- if (!string.IsNullOrEmpty(currVal))
- {
- lastSignInVal = currVal;
+ QueueFLog.TryDequeue(out currVal);
+ sendToMoonPro(urlType.FLog, currVal);
+ lastWatchDog = DateTime.Now;
}
}
else
@@ -5480,193 +5700,302 @@ namespace IOB_WIN_NEXT
}
///
- /// Metodo base connessione...
+ /// Processo la coda RawTransf...
///
- public virtual void tryConnect()
+ private void svuotaCodaRawTransf()
{
- dtAvvioAdp = DateTime.Now;
- }
-
- ///
- /// Metodo base disconnessione...
- ///
- public virtual void tryDisconnect()
- {
- }
-
- ///
- /// Effettua verifica se abilitato invio pezzi in blocco e nel caso
- /// - invio in blocco pezzi
- /// - aggiornamento del contapezzi (passato come ref) x nuovo valore post invio
- ///
- public void trySendPzCountBlock()
- {
- // in primis HA SENSO procedere SOLO SE server MP è Online...
- if (MPOnline)
+ // verifico SE la coda abbia dei valori...
+ if (QueueRawTransf.Count > 0)
{
- // SOLO SE online la macchina...
- if (IobOnline)
+ // invio pacchetto di dati (max da conf)
+ for (int i = 0; i < nMaxSend; i++)
{
- int numIncr = 0;
- int qtyAdded = 0;
- // verifico se la funzione SIA abilitata
- if (enableSendPzCountBlock)
+ // SE ho qualcosa in coda...
+ if (QueueRawTransf.Count > 0)
{
- int delta = contapezziPLC - contapezziIOB;
- // se è abilitata verifico differenza: se ho DELTA > minSendPzCountBlock --> invio un blocco <= maxSendPzCountBlock
- if (delta > minSendPzCountBlock)
+ string currVal = "";
+ if (MPOnline)
{
- // init obj display
- newDisplayData currDispData = new newDisplayData();
- // resta indietro di ALMENO minSendPzCountBlock pezzi x recuperare 1:1...
- numIncr = delta > maxSendPzCountBlock + minSendPzCountBlock ? maxSendPzCountBlock : delta - minSendPzCountBlock;
- // invio il num max di pezzi ammesso in blocco!
- lastUrl = $"{urlAddPzCount}{numIncr}";
- string resp = utils.callUrlNow(lastUrl);
- if (!string.IsNullOrEmpty(resp))
+ if (IobOnline)
{
- // dalla risposta (come numero) capisco SE ha aggiunto i pezzi (e quanti)
- int.TryParse(resp, out qtyAdded);
- if (qtyAdded > 0)
+ List listaValori = new List();
+ // se ho + di maxJsonData elementi --> invio un set di dati alla volta
+ if (QueueRawTransf.Count > maxJsonData)
{
- // aggiorno IL MIO contapezzi...
- contapezziIOB += qtyAdded;
- lgInfo($"Inviato incremento contapezzi: send: {numIncr} | resp: {qtyAdded} | contapezziIOB: {contapezziIOB}");
- // invio conferma contapezzi..
- string retVal = utils.callUrl($"{urlSetPzCount}{contapezziIOB}");
- // verifica se tutto OK
- if (retVal != contapezziIOB.ToString())
+ // prendoi primi maxJsonDataValori
+ for (int j = 0; j < maxJsonData; j++)
{
- // errore salvataggio contapezzi
- lgError($"trySendPzCountBlock: errore salvataggio contapezzi: contapezziIOB {contapezziIOB} | risposta: {retVal}");
+ QueueRawTransf.TryDequeue(out currVal);
+ listaValori.Add(currVal);
}
+ sendDataBlock(urlType.RawTransf, listaValori);
}
else
{
- lgError($"Richiesto incremento {numIncr} ma NON registrato su server MP-IO");
+ // invio in blocco
+ listaValori = QueueRawTransf.ToList();
+ // invio
+ sendDataBlock(urlType.RawTransf, listaValori);
+ // svuoto!
+ QueueRawTransf = new ConcurrentQueue();
}
}
- currDispData.newUrlCallData = lastUrl;
+ else
+ {
+ break;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Processo la coda UserLog...
+ ///
+ private void svuotaCodaULog()
+ {
+ // verifico SE la coda abbia dei valori...
+ if (QueueULog.Count > 0)
+ {
+ // invio pacchetto di dati (max da conf)
+ for (int i = 0; i < nMaxSend; i++)
+ {
+ // SE ho qualcosa in coda...
+ if (QueueULog.Count > 0)
+ {
+ string currVal = "";
+ if (MPOnline)
+ {
+ if (IobOnline)
+ {
+ List listaValori = new List();
+ // se ho + di maxJsonData elementi --> invio un set di dati alla volta
+ if (QueueULog.Count > maxJsonData)
+ {
+ // prendoi primi maxJsonDataValori
+ for (int j = 0; j < maxJsonData; j++)
+ {
+ QueueULog.TryDequeue(out currVal);
+ listaValori.Add(currVal);
+ }
+ sendDataBlock(urlType.ULog, listaValori);
+ }
+ else
+ {
+ // invio in blocco
+ listaValori = QueueULog.ToList();
+ // invio
+ sendDataBlock(urlType.ULog, listaValori);
+ // svuoto!
+ QueueULog = new ConcurrentQueue();
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Cerca di inviare su un altro thread i vari dati accumulati...
+ ///
+ private void trySendValues()
+ {
+ // init obj display
+ newDisplayData currDispData = new newDisplayData();
+ try
+ {
+ // verifico se risponde il server...
+ if (checkServerAlive)
+ {
+ bool iobOk = false;
+ if (utils.CRB("sendDataByThread"))
+ {
+ Task taskCheck = Task.Run(() => iobOk = checkIobEnabled);
+ }
+ else
+ {
+ iobOk = checkIobEnabled;
+ }
+ // verifico SE posso inviare dati
+ if (iobOk)
+ {
+ currDispData.semOut = Semaforo.SV;
+ // verificare come gestire il task secondario senza interferenza (chiamate
+ // update su FORM da thread secondari danno errori)
+ if (utils.CRB("sendDataByThread"))
+ {
+ // invio con thread separato...
+ Task taskSigIN = Task.Run(() => svuotaCodaSignIN());
+ Task taskFLog = Task.Run(() => svuotaCodaFLog());
+ Task taskRawTransf = Task.Run(() => svuotaCodaRawTransf());
+ Task taskULog = Task.Run(() => svuotaCodaULog());
+ }
+ else
+ {
+ // gestione queue SignalIN (invio, display)
+ svuotaCodaSignIN();
currDispData.counter = contapezziIOB;
- currDispData.semOut = Semaforo.SV;
raiseRefresh(currDispData);
+ // provo a svuotare coda contapezzi
+ svuotaCodaContapezzi();
+ currDispData.counter = contapezziIOB;
+ raiseRefresh(currDispData);
+ // gestione queue FluxLog (invio, display)
+ svuotaCodaFLog();
+ // coda RawTransf
+ svuotaCodaRawTransf();
+ // coda UserLog
+ svuotaCodaULog();
+ // refresh
+ raiseRefresh(currDispData);
+ }
+ // se arrivo è tutto ok...
+ currSendErrors = 0;
+ }
+ else
+ {
+ // mostro VETO-SEND x invio... GIALLO
+ currDispData.semOut = Semaforo.SG;
+ if (periodicLog)
+ {
+ lgInfo("IOB - VETO SEND");
}
}
}
else
{
- lgError("Impossibile trySendPzCountBlock: IobOnline è false");
+ // mostro SERVER KO x invio... ROSSO
+ currDispData.semOut = Semaforo.SR;
+ if (periodicLog)
+ {
+ lgError("IOB - SERVER NOT READY");
+ }
}
}
- else
+ catch (Exception exc)
{
- lgError("Impossibile trySendPzCountBlock: MPOnline è false");
+ lgError($"Errore in fase trySendValues | currSendErrors: {currSendErrors}{Environment.NewLine}{exc}");
+ currDispData.semOut = Semaforo.SR;
}
+ raiseRefresh(currDispData);
}
///
- /// Inserimento/aggiornamento chiavi/valore in currProdData
+ /// Aggiorna un valore del dizionario in INCREMENTO e lo restituisce
///
- ///
- ///
- public void upsertKey(string chiave, string valore)
+ ///
+ ///
+ ///
+ /// Nuovo valore incrementato
+ private double updateValDoubleByIncr(int i, double delta, string searchString)
{
- if (currProdData.ContainsKey(chiave))
- {
- currProdData[chiave] = valore;
- }
- else
- {
- currProdData.Add(chiave, valore);
- }
+ // stringa da cercare..
+ string keyVal = string.Format(searchString, i + 1);
+ // recupero valore precedente...
+ double contAct = getStoredValDouble(keyVal);
+ // nuovo valore...
+ contAct += delta;
+ // salvo in ram!
+ persistenceLayer[keyVal] = contAct.ToString();
+ // rendo il valore!
+ return contAct;
}
///
- /// Formatta URL x invio in DataBlock Json dei dati FLog / eventi
+ /// Aggiorna un valore del dizionario in INCREMENTO e lo restituisce
///
- ///
- ///
- public string urlDataBlock(urlType tipoUrl)
+ ///
+ ///
+ ///
+ /// Nuovo valore incrementato
+ private long updateValLongByIncr(int i, long delta, string searchString)
{
- // verifico la parte di link "tipoComando"
- string tipoComando = "";
- switch (tipoUrl)
- {
- case urlType.FLog:
- tipoComando = cIobConf.serverData.CMDFLOG_JSON;
- break;
-
- case urlType.SignIN:
- tipoComando = cIobConf.serverData.CMDBASE_JSON;
- break;
-
- case urlType.ULog:
- tipoComando = cIobConf.serverData.CMDULOG_JSON;
- break;
-
- default:
- break;
- }
- // URL base x input
- string answ = $@"{cIobConf.serverData.TRANSP}://{cIobConf.serverData.MPIP}{cIobConf.serverData.MPURL}{tipoComando}{cIobConf.codIOB}";
- return answ;
+ // stringa da cercare..
+ string keyVal = string.Format(searchString, i + 1);
+ // recupero valore precedente...
+ long contAct = getStoredValLong(keyVal);
+ // nuovo valore...
+ contAct += delta;
+ // salvo in ram!
+ persistenceLayer[keyVal] = contAct.ToString();
+ // rendo il valore!
+ return contAct;
}
///
- /// Fornisce URL di tipo FluxLog
+ /// Aggiorna un valore del dizionario in SOSTITUZIONE
///
- /// valore salvato in coda nel formato dtEve#flux#valore#counter
- ///
- public string urlFLog(string queueVal)
+ ///
+ ///
+ ///
+ /// Nuovo valore incrementato
+ private void updateValString(int i, string newVal, string searchString)
{
- // URL base x input
- string answ = $@"{cIobConf.serverData.TRANSP}://{cIobConf.serverData.MPIP}{cIobConf.serverData.MPURL}{cIobConf.serverData.CMDFLOG}";
- // decodifica valore!
- string[] valori = qDecodeIN(queueVal);
- // aggiungo macchina e valore...
- answ += string.Format(@"{0}?flux={1}&&valore={2}", cIobConf.codIOB, valori[1], valori[2]);
- // aggiondo dataOra evento e corrente + contatore...
- answ += string.Format(@"&&dtEve={0}&&dtCurr={1:yyyyMMddHHmmssfff}&&cnt={2}", valori[0], DateTime.Now, valori[3]);
- return answ;
+ // stringa da cercare..
+ string keyVal = string.Format(searchString, i + 1);
+ // salvo in ram!
+ persistenceLayer[keyVal] = newVal;
}
///
- /// Fornisce URL INPUT per i parametri richiesti
+ /// Aggiorna un valore del dizionario in SOSTITUZIONE e lo restituisce
///
- /// valore salvato in coda formato dtEve#valore#counter
- ///
- public string urlInput(string queueVal)
+ ///
+ ///
+ ///
+ /// Nuovo valore incrementato
+ private void updateValUInt(int i, uint newVal, string searchString)
{
- // URL base x input
- string answ = $@"{cIobConf.serverData.TRANSP}://{cIobConf.serverData.MPIP}{cIobConf.serverData.MPURL}{cIobConf.serverData.CMDBASE}";
- // decodifica valore!
- string[] valori = qDecodeIN(queueVal);
- // aggiungo macchina e valore...
- answ += string.Format(@"{0}?valore={1}", cIobConf.codIOB, valori[1]);
- // aggiondo dataOra evento e corrente + contatore...
- answ += string.Format(@"&&dtEve={0}&&dtCurr={1:yyyyMMddHHmmssfff}&&cnt={2}", valori[0], DateTime.Now, valori[2]);
- return answ;
+ // stringa da cercare..
+ string keyVal = string.Format(searchString, i + 1);
+ // salvo in ram!
+ persistenceLayer[keyVal] = newVal.ToString();
}
///
- /// Fornisce URL di tipo UserLog
+ /// Aggiorna un valore del dizionario in INCREMENTO e lo restituisce
///
- /// valore salvato in coda nel formato dtEve#flux#valore#counter
- ///
- public string urlULog(string queueVal)
+ ///
+ ///
+ ///
+ /// Nuovo valore incrementato
+ private uint updateValUIntByIncr(int i, uint delta, string searchString)
{
- // URL base x input
- string answ = $@"{cIobConf.serverData.TRANSP}://{cIobConf.serverData.MPIP}{cIobConf.serverData.MPURL}{cIobConf.serverData.CMDULOG}";
- // decodifica valore!
- string[] valori = qDecodeIN(queueVal);
- // aggiungo macchina e valore...
- answ += string.Format(@"{0}?flux={1}&&valore={2}", cIobConf.codIOB, valori[1], valori[2]);
- // aggiondo dataOra evento e corrente + contatore...
- answ += string.Format(@"&&dtEve={0}&&dtCurr={1:yyyyMMddHHmmssfff}&&cnt={2}", valori[0], DateTime.Now, valori[3]);
- return answ;
+ // stringa da cercare..
+ string keyVal = string.Format(searchString, i + 1);
+ // recupero valore precedente...
+ uint contAct = getStoredValUInt(keyVal);
+ // nuovo valore...
+ contAct += delta;
+ // salvo in ram!
+ persistenceLayer[keyVal] = contAct.ToString();
+ // rendo il valore!
+ return contAct;
}
- #endregion Public Methods
+ #endregion Private Methods
}
///
@@ -5674,15 +6003,6 @@ namespace IOB_WIN_NEXT
///
public class iobRefreshedEventArgs : EventArgs
{
- #region Private Fields
-
- ///
- /// classe obj privata
- ///
- private readonly newDisplayData _newDisplayData;
-
- #endregion Private Fields
-
#region Public Constructors
///
@@ -5707,5 +6027,14 @@ namespace IOB_WIN_NEXT
}
#endregion Public Properties
+
+ #region Private Fields
+
+ ///
+ /// classe obj privata
+ ///
+ private readonly newDisplayData _newDisplayData;
+
+ #endregion Private Fields
}
}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/IobIcoelDb.cs b/IOB-WIN-NEXT/IobIcoelDb.cs
index f7c969b2..7508a23b 100644
--- a/IOB-WIN-NEXT/IobIcoelDb.cs
+++ b/IOB-WIN-NEXT/IobIcoelDb.cs
@@ -1,19 +1,24 @@
-using System;
+using EgwProxy.Icoel;
+using IOB_UT_NEXT;
+using MapoSDK;
+using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.Diagnostics;
+using System.Net.NetworkInformation;
namespace IOB_WIN_NEXT
-{ ///
- /// Adapter specializzato per ICOEL e le chiamate tramite DB per i dati
- /// - accettazione lotti prodotto (frontiera / entrata ciliegie)
- /// - export (totale per prodotti)
- /// - tracciabilità (confezioni
- ///
+{
+ ///
+ /// Adapter specializzato per ICOEL e le chiamate tramite DB per i dati
+ /// - accettazione lotti prodotto (frontiera / entrata ciliegie)
+ /// - export (totale per prodotti)
+ /// - tracciabilità (confezioni
+ ///
public class IobIcoelDb : IobGeneric
{
+ #region Public Constructors
+
///
/// Costruttore dell'IOB Icoel DB
///
@@ -21,11 +26,260 @@ namespace IOB_WIN_NEXT
/// Configurazione IOB per avvio
public IobIcoelDb(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
{
+ /* --------------------------------------
+ * todo's
+ * --------------------------------------
+ * - init obj comunicazione da conf e nuget
+ * - lanciare sync e verifica stato sync
+ */
+
+ string SyncStateDb = getOptPar("SyncStateDb");
+ string SyncStateUser = getOptPar("SyncStateUser");
+ string SyncStatePwd = getOptPar("SyncStatePwd");
+ string SyncStateCTout = getOptPar("SyncStateCTout");
+
+
+ string connSyncState = $"data source={SyncStateDb};initial catalog=MoonPro_ISF;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
+
+ ///
+ /// Implementazione custom esecuzione task specifici
+ ///
+ ///
+ ///
public override Dictionary executeTasks(Dictionary task2exe)
{
- return base.executeTasks(task2exe);
+ // unico task ammissibile: fare un SYNC forzato...
+ Dictionary taskDone = new Dictionary();
+ 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;
}
+
+ ///
+ /// Recupero dati dinamici...
+ ///
+ public override Dictionary getDynData()
+ {
+ // valore non presente in vers default... se gestito fare override
+ Dictionary outVal = new Dictionary();
+ // recupero da DB locale stato sync attuale
+ var elencoSyncStateCurr = dbProxy.DataController.SyncStateGetAll();
+ foreach (var item in elencoSyncStateCurr)
+ {
+ saveValue(ref outVal, item.NumRec, $"{item.TableName}_NumRec");
+ saveValue(ref outVal, item.NumRecIn, $"{item.TableName}_NumRecIn");
+ saveValue(ref outVal, item.LastIdx, $"{item.TableName}_LastIdx");
+ saveValue(ref outVal, item.LastIdxIn, $"{item.TableName}_LastIdxIn");
+ }
+
+ // aggiungo anche i campi currData
+ var currData = dbProxy.DataController.CurrDataGetAll();
+ foreach (var item in currData)
+ {
+ saveValue(ref outVal, (double)item.CurrVal, item.Topic);
+ }
+
+ lastReadPLC = DateTime.Now;
+ return outVal;
+ }
+
+ ///
+ /// Effettua processing CUSTOM x Icoel:
+ /// - recupera elenco batch delle 2 linee
+ /// - invia al sistema
+ ///
+ public override void processCustomTaskLF()
+ {
+ lgInfo($"Richiesto processCustomTaskLF");
+ // effettua sync
+ refreshElencoStati();
+ lastReadPLC = DateTime.Now;
+ }
+
+ ///
+ /// Effettua lettura semafori principale Parametri da
+ /// aggiornare x display in form
+ ///
+ 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;
+ }
+ }
+
+ ///
+ /// Override connessione
+ ///
+ 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)
+ {
+ 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.cncIpAddr}");
+ }
+ }
+ }
+ }
+ else
+ {
+ needRefresh = true;
+ }
+ }
+
+ public override void tryDisconnect()
+ {
+ // registro solo che è disconnesso
+ connectionOk = false;
+ }
+
+ #endregion Public Methods
+
+ #region Protected Properties
+
+ protected EgwProxy.Icoel.DbProxy dbProxy { get; set; } = null;
+
+ ///
+ /// Stato di sync delle tab gestite
+ ///
+ protected List elencoSyncState { get; set; } = new List();
+
+ #endregion Protected Properties
+
+ #region Private Methods
+
+ private void refreshElencoStati()
+ {
+ Stopwatch sw = new Stopwatch();
+ sw.Start();
+ elencoSyncState = dbProxy.DataController.SyncStateDoImportAll();
+ sw.Stop();
+ 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
}
-}
+}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/IobIcoelSoap.cs b/IOB-WIN-NEXT/IobIcoelSoap.cs
index d14ae42e..93309c38 100644
--- a/IOB-WIN-NEXT/IobIcoelSoap.cs
+++ b/IOB-WIN-NEXT/IobIcoelSoap.cs
@@ -2,7 +2,6 @@
using EgwProxy.Icoel.SizerService;
using IOB_UT_NEXT;
using MapoSDK;
-using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.NetworkInformation;
@@ -40,32 +39,7 @@ namespace IOB_WIN_NEXT
*/
IcoelSizer = new Connector(IOBConf.cncIpAddr, IOBConf.cncPort);
- }
-
- ///
- /// Effettua lettura semafori principale
- /// Parametri da aggiornare x display in form
- ///
- public override void readSemafori(ref newDisplayData currDispData)
- {
- if (connectionOk)
- {
- B_input = 1;
- currDispData.semIn = Semaforo.SV;
- if (currBatchList != null)
- {
- // se ho batch NON chiusi (data = minValue) allora lavora
- if (currBatchList[1].EndTime == DateTime.MinValue || currBatchList[1].EndTime == DateTime.MinValue)
- {
- B_input = 3;
- }
- }
- }
- else
- {
- B_input = 0;
- currDispData.semIn = Semaforo.SR;
- }
+ lastPING = DateTime.Now.AddHours(-1);
}
#endregion Public Constructors
@@ -90,7 +64,203 @@ namespace IOB_WIN_NEXT
*
*---------------------------------------*/
- return base.executeTasks(task2exe);
+ // Verificare il protocollo: dovrebbe togliere SOLO i task eseguiti...
+ Dictionary taskDone = new Dictionary();
+ 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;
+ }
+
+ 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();
+ 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;
+ }
+
+ ///
+ /// Metodo da overridare x scrivere DAVVERO i parametri sul PLC
+ ///
+ ///
+ protected override void plcWriteParams(ref List 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 = "";
+ }
+ }
+
+ }
+ }
+
+ ///
+ /// Dizionario parametri correnti
+ ///
+ protected Dictionary perfParamDict { get; set; } = new Dictionary();
+
+ ///
+ /// Dizionario dati Batch correnti
+ ///
+ protected Dictionary batchDataDict { get; set; } = new Dictionary();
+
+ ///
+ /// Recupero dati dinamici...
+ ///
+ public override Dictionary getDynData()
+ {
+ // valore non presente in vers default... se gestito fare override
+ Dictionary outVal = new Dictionary();
+ // 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.Value, item.Key);
+ }
+ // ora leggo i batch data
+ batchDataDict = IcoelSizer.GetCurrBatchData();
+ lgTrace("SOAP: effettuata chiamata IcoelSizer.GetCurrBatchData()");
+ foreach (var item in batchDataDict)
+ {
+ saveValueString(ref outVal, item.Value, item.Key);
+ }
+
+ lastReadPLC = DateTime.Now;
+ return outVal;
}
///
@@ -102,6 +272,7 @@ namespace IOB_WIN_NEXT
{
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...
@@ -111,23 +282,77 @@ namespace IOB_WIN_NEXT
foreach (var item in currBatch)
{
// se variato ID è cambiato
- doSend = (currBatchList[item.Key].Id != item.Value.Id);
+ doSend = doSend || (currBatchList[item.Key].Id != item.Value.Id);
}
}
// se devo inviare impacchetto dati
if (doSend)
{
- // serializzo ed invio al sistema il risultato
- string rawData = JsonConvert.SerializeObject(currBatch);
- // invio come tipo "IcoelBatch"
- Dictionary sendObj = new Dictionary();
- sendObj.Add(IOB_UT_NEXT.rawTransfType.IcoelBatch, rawData);
-
- // accodo per invio...
- accodaRawData(sendObj);
+ accodaRawData(rawTransfType.IcoelBatch, currBatch);
currBatchList = currBatch;
}
}
+
+ lastReadPLC = DateTime.Now;
+ }
+
+ ///
+ /// Effettua lettura semafori principale Parametri da
+ /// aggiornare x display in form
+ ///
+ 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;
+ }
}
///
@@ -156,6 +381,7 @@ namespace IOB_WIN_NEXT
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");
@@ -228,13 +454,14 @@ namespace IOB_WIN_NEXT
///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);
- // invio dai al server IO
-
+ lgTrace("SOAP: effettuata chiamata IcoelSizer.GetLayoutForVarietyList()");
}
+ lastReadPLC = DateTime.Now;
}
#endregion Protected Methods
diff --git a/IOB-WIN-NEXT/IobModbusTCP.cs b/IOB-WIN-NEXT/IobModbusTCP.cs
index 4c1d8279..6f6de41f 100644
--- a/IOB-WIN-NEXT/IobModbusTCP.cs
+++ b/IOB-WIN-NEXT/IobModbusTCP.cs
@@ -169,6 +169,11 @@ namespace IOB_WIN_NEXT
///
public override Dictionary getDynData()
{
+ Random rnd = new Random();
+ int minWait = 50;
+ int maxWait = 50;
+ int.TryParse(getOptPar("minWait"), out minWait);
+ int.TryParse(getOptPar("maxWait"), out maxWait);
// valore non presente in vers default... se gestito fare override
Dictionary outVal = new Dictionary();
if (utils.CRB("enableTSVC"))
@@ -189,7 +194,8 @@ namespace IOB_WIN_NEXT
foreach (var item in memSetR)
{
readBlockHoldingReg(item.Key, item.Value, parametri.holdRegBaseAddr);
- Thread.Sleep(100);
+ int waitTime = rnd.Next(minWait, maxWait);
+ Thread.Sleep(waitTime);
}
}
// procedo ...
@@ -237,6 +243,23 @@ namespace IOB_WIN_NEXT
outVal = new Dictionary();
tryConnect();
}
+ // ora aggiungo (se ci fossero) gli allarmi...
+ if (alarmMaps != null && alarmMaps.Count > 0)
+ {
+ if (hasAlarms)
+ {
+ string bankVal = "";
+ foreach (var item in alarmMaps)
+ {
+ bankVal = "";
+ var currState = currAlarmsState(item);
+ // calcolo vettore stringa degli allarmi...
+ bankVal = getAlarmState(item, currState);
+ bankVal = string.IsNullOrEmpty(bankVal) ? "OK" : bankVal;
+ saveAlarmString(ref outVal, bankVal, item.description);
+ }
+ }
+ }
}
}
else
@@ -525,7 +548,7 @@ namespace IOB_WIN_NEXT
{
try
{
- currPLC.WriteMultipleRegisters(startAddr, currRegVal);
+ currPLC.WriteMultipleRegisters(startAddr + deltaBase, currRegVal);
answ = true;
}
catch
@@ -626,7 +649,7 @@ namespace IOB_WIN_NEXT
// bit status:
// - allarmi che iniziano per # IGNORATI
// - altri allarmi con un countdown da MAX_COUNTER_BLINK a 0 per il
- // fronte di discesa
+ // fronte di discesa
if (item.isChanged(i, (uint)currStatus))
{
// registro gli allarmi attivi e trasmetto...
@@ -654,6 +677,56 @@ namespace IOB_WIN_NEXT
#region Protected Methods
+ ///
+ /// Restituisce stato allarmi in formato byte[]
+ ///
+ ///
+ ///
+ protected byte[] currAlarmsState(BaseAlarmConf item)
+ {
+ byte[] answ = new byte[item.size];
+ int currStatus = 0;
+ int[] listInt = new int[2];
+ // banchi in array Int16 --> scompongo
+ for (int i = 0; i < item.size / 2; i++)
+ {
+ // verifico se usare LUT
+ bool useLUT = memSetR != null && memSetR.Count > 0;
+ if (useLUT)
+ {
+ int lutAddress = 40000 + item.index;
+ if (HoldingRegisterLUT.ContainsKey(lutAddress))
+ {
+ try
+ {
+ listInt = HoldingRegisterLUT[lutAddress];
+ }
+ catch (Exception exc)
+ {
+ lgError($"Errore in lettura da HoldingRegisterLUT per indirizzo {lutAddress} | item {item.memAddr}{Environment.NewLine}{exc}");
+ }
+ }
+ }
+ else
+ {
+ listInt = readInputReg(item.index, item.size);
+ }
+ currStatus = ModbusClient.ConvertRegistersToInt(listInt);
+
+ // aggiornamento blink counters dato nuovo valore
+ item.checkBlinkCounter(i, (uint)currStatus);
+
+ // calcolo indice errori
+ if ((uint)(item.alarmsMask[i] & currStatus) > 0)
+ {
+ var currByte = BitConverter.GetBytes(currStatus);
+ // salvo nell'array di byte
+ Buffer.BlockCopy(currByte, 0, answ, i * 2, 2);
+ }
+ }
+ return answ;
+ }
+
///
/// Decodifica il resto dell'area x i dati accessori (allarmi, ...)
///
@@ -714,13 +787,21 @@ namespace IOB_WIN_NEXT
break;
case plcDataType.Int:
- valInt = getScaledInt(currMem);
- CurrVal = ModbusClient.ConvertIntToRegisters(valInt);
+ valInt = getScaledInt(currMem, true);
+ if (byteSize == 1)
+ {
+ CurrVal[0] = valInt;
+ }
+ else
+ {
+ CurrVal = ModbusClient.ConvertIntToRegisters(valInt);
+ }
+
fatto = writeInputReg(currMem.index, CurrVal);
break;
case plcDataType.DInt:
- valUInt = getScaledUInt(currMem);
+ valUInt = getScaledUInt(currMem, true);
CurrVal = ModbusClient.ConvertLongToRegisters(valInt);
fatto = writeInputReg(currMem.index, CurrVal);
break;
@@ -811,12 +892,14 @@ namespace IOB_WIN_NEXT
parametri.memSizeRead = fIni.ReadInteger("MEMORY", "SIZE_READ", 0);
parametri.memSizeWrite = fIni.ReadInteger("MEMORY", "SIZE_WRITE", 0);
parametri.holdRegBaseAddr = fIni.ReadInteger("MEMORY", "HR_BASE_ADDR", 40001);
+ // valore delta base
+ deltaBase = fIni.ReadInteger("MEMORY", "DELTA_BASE", 0);
// salvo vettori memoria...
lgInfoStartup("Set RawInput dimensions...");
RawInput = new byte[parametri.memSizeRead];
RawOutput = new byte[parametri.memSizeWrite];
// salvo parametri conn!
- lgInfoStartup(string.Format("Parametri memoria: memAddrRead: {0} | memAddrWrite: {1} | memSizeRead: {2} | memSizeWrite: {3}", parametri.memAddrRead, parametri.memAddrWrite, parametri.memSizeRead, parametri.memSizeWrite));
+ lgInfoStartup($"Parametri memoria: memAddrRead: {parametri.memAddrRead} | memAddrWrite: {parametri.memAddrWrite} | memSizeRead: {parametri.memSizeRead} | memSizeWrite: {parametri.memSizeWrite} | deltaBase: {deltaBase}");
}
catch (Exception exc)
{
@@ -1027,13 +1110,17 @@ namespace IOB_WIN_NEXT
///
private double deltaVal = 0;
- ///
- /// Indirizzo di base x fare il calcolo di dove leggere in ModBus
- ///
- private int HoldRegBaseAddr = 40001;
-
#endregion Private Fields
+ #region Private Properties
+
+ ///
+ /// Valore da gestire come delta degli indirizzi configurati
+ ///
+ private int deltaBase { get; set; } = 0;
+
+ #endregion Private Properties
+
#region Private Methods
///
@@ -1050,6 +1137,7 @@ namespace IOB_WIN_NEXT
switch (tipoMem)
{
case plcDataType.Real:
+ case plcDataType.FloatABCD:
if (size == 4)
{
valore = ModbusClient.ConvertRegistersToDouble(listInt);
@@ -1060,6 +1148,21 @@ namespace IOB_WIN_NEXT
}
break;
+ case plcDataType.FloatCDAB:
+ if (size == 4)
+ {
+ // invero array...
+ Array.Reverse(listInt);
+ valore = ModbusClient.ConvertRegistersToDouble(listInt);
+ }
+ else if (size == 2)
+ {
+ // non serve cambaire nulla...
+ Array.Reverse(listInt);
+ valore = ModbusClient.ConvertRegistersToFloat(listInt);
+ }
+ break;
+
// caso speciale x Cedax, che usa HighVal moltiplicato x 32768...
case plcDataType.HLPInt:
if (size == 4)
@@ -1083,6 +1186,10 @@ namespace IOB_WIN_NEXT
{
valore = ModbusClient.ConvertRegistersToInt(listInt);
}
+ else if (size == 1)
+ {
+ valore = listInt[0];
+ }
break;
}
return valore;
@@ -1100,28 +1207,58 @@ namespace IOB_WIN_NEXT
return valDouble;
}
-
- private static int getScaledInt(dataConf currMem)
+ ///
+ /// Effettua scalatura valore secondo fattore
+ /// Read --> * (moltiplico)
+ /// Write --> / (divido)
+ ///
+ ///
+ ///
+ ///
+ private static int getScaledInt(dataConf currMem, bool isWrite = false)
{
- int valInt;
+ int valInt = 0;
+ double temp;
// prima faccio eventuale fattore di scala...
- int.TryParse(currMem.value, out valInt);
+ double.TryParse(currMem.value.Replace(".", ","), out temp);
+ //int.TryParse(currMem.value, out valInt);
if (currMem.factor != 1)
{
- valInt = (int)(valInt * currMem.factor);
+ if (isWrite)
+ {
+ valInt = (int)(temp * 10 / currMem.factor) / 10;
+ }
+ else
+ {
+ valInt = (int)(temp * 10 * currMem.factor) / 10;
+ }
}
return valInt;
}
- private static uint getScaledUInt(dataConf currMem)
+ ///
+ /// Effettua scalatura valore secondo fattore
+ /// Read --> * (moltiplico)
+ /// Write --> / (divido)
+ ///
+ ///
+ ///
+ private static uint getScaledUInt(dataConf currMem, bool isWrite = false)
{
uint valUInt;
// prima faccio eventuale fattore di scala...
uint.TryParse(currMem.value, out valUInt);
if (currMem.factor != 1)
{
- valUInt = valUInt * (uint)currMem.factor;
+ if (isWrite)
+ {
+ valUInt = valUInt / (uint)currMem.factor;
+ }
+ else
+ {
+ valUInt = valUInt * (uint)currMem.factor;
+ }
}
return valUInt;
@@ -1188,16 +1325,33 @@ namespace IOB_WIN_NEXT
case modBusAddrType.HoldingRegister:
if (useLUT)
{
- int lutAddress = 40000 + item.Value.index;
- if (HoldingRegisterLUT.ContainsKey(lutAddress))
+ int lutAddress = 40000 + item.Value.index + deltaBase;
+ // se size = 1 --> devo cambiare modo recupero
+ if (item.Value.size == 1)
{
- try
+ if (item.Value.index % 2 == 0)
{
- listInt = HoldingRegisterLUT[lutAddress];
+ //Array.Copy(HoldingRegisterLUT[lutAddress], listInt, 1);
+ Array.Copy(HoldingRegisterLUT[lutAddress], 0, listInt, 0, 1);
}
- catch (Exception exc)
+ else
{
- lgError($"Errore in lettura da HoldingRegisterLUT per indirizzo {lutAddress} | item {item.Key}{Environment.NewLine}{exc}");
+ lutAddress--;
+ Array.Copy(HoldingRegisterLUT[lutAddress], 1, listInt, 0, 1);
+ }
+ }
+ else
+ {
+ if (HoldingRegisterLUT.ContainsKey(lutAddress))
+ {
+ try
+ {
+ listInt = HoldingRegisterLUT[lutAddress];
+ }
+ catch (Exception exc)
+ {
+ lgError($"Errore in lettura da HoldingRegisterLUT per indirizzo {lutAddress} | item {item.Key}{Environment.NewLine}{exc}");
+ }
}
}
}
@@ -1213,16 +1367,16 @@ namespace IOB_WIN_NEXT
}
// verifica limite... con delta da impianto
dataOk = (valore > (item.Value.minVal + deltaVal) && valore < (item.Value.maxVal - deltaVal));
- if (dataOk)
+ if (dataOk || disDynDataRangeCheck)
{
// moltiplico x fattore conversione...
valoreScal = valore * item.Value.factor;
saveValue(ref outVal, valoreScal, item.Key);
- lgDebug($"getDynData: valore ricevuto | {item.Key} | val: {valore} | valoreScal: {valoreScal}");
+ lgDebug($"getDataDictionary: valore ricevuto | {item.Key} | val: {valore} | valoreScal: {valoreScal}");
}
else
{
- lgError($"getDynData: valore scartato x limiti min/max | {item.Key} | val: {valore} | valoreScal: {valoreScal} | min-max: {item.Value.minVal}-{item.Value.maxVal} | deltaVal: {deltaVal}");
+ lgError($"getDataDictionary: valore scartato x limiti min/max | {item.Key} | val: {valore} | valoreScal: {valoreScal} | min-max: {item.Value.minVal}-{item.Value.maxVal} | deltaVal: {deltaVal}");
readErrorList.Add(item.Key, item.Value);
lgDebug($"--> rimesso in coda lettura | parametro: {item.Key} | index: {item.Value.index} | size: {item.Value.size}");
}
@@ -1264,7 +1418,7 @@ namespace IOB_WIN_NEXT
///
/// Effettua lettura blocco memoria indicato e lo salva in copia locale HoldingRegisterLUT
///
- /// Indirizzo di aprtenza
+ /// Indirizzo di partenza
/// NUm registri da leggere (max 120)
private void readBlockHoldingReg(int startAddr, int numReg, int baseAddr)
{
diff --git a/IOB-WIN-NEXT/IobModbusTCPCedax.cs b/IOB-WIN-NEXT/IobModbusTCPCedax.cs
index 1b64e300..a67ef056 100644
--- a/IOB-WIN-NEXT/IobModbusTCPCedax.cs
+++ b/IOB-WIN-NEXT/IobModbusTCPCedax.cs
@@ -101,11 +101,15 @@ namespace IOB_WIN_NEXT
B_input = 0;
/* -----------------------------------------------------
- * bitmap MAPO STANDARD
+ * bitmap MAPO STANDARD 60
* B0: POWER_ON
* B1: RUN
* B2: pzCount
* B3: allarme
+ * B4: manuale
+ * B5: slowTC
+ * B6: WarmUpCoolDown
+ * B7: EmergArmata
*
----------------------------------------------------- */
@@ -128,6 +132,9 @@ namespace IOB_WIN_NEXT
byteSignals += (1 << 1);
}
+ // segnalo NON emergenza
+ byteSignals += (1 << 7);
+
// salvo!
B_input = byteSignals;
}
diff --git a/IOB-WIN-NEXT/IobModbusTCPCenterfrigo.cs b/IOB-WIN-NEXT/IobModbusTCPCenterfrigo.cs
new file mode 100644
index 00000000..47302ac3
--- /dev/null
+++ b/IOB-WIN-NEXT/IobModbusTCPCenterfrigo.cs
@@ -0,0 +1,147 @@
+using EasyModbus;
+using IOB_UT_NEXT;
+using MapoSDK;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.NetworkInformation;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace IOB_WIN_NEXT
+{
+ /* --------------------------------------------------------------------------------
+ * Controlli ModBusTCP Centerfrigo
+ * - protocollo ModBus TCP
+ * - specifico comportamento impianti Centerfrigo
+ * - gestione allarmi
+ * - gestione stati salvati come dynData
+ * - gestione valori analogici
+ *
+ * STRUTTURA MEMORIA a banchi di UInt16, convertiti successivamente in int EVENTUALMENTE divisi per 10/100/1000
+ * lettura: xxx byte,
+ * scrittura yyy byte
+ * G:\Drive condivisi\30_Clienti\Giacovelli - WIL\CenterFrigo
+ *
+ * ATTENZIONE! leggere al max 44 byte alla volta
+ *
+ * -------------------------------------------------------------------------------- */
+
+ public class IobModbusTCPCenterfrigo : IobModbusTCP
+ {
+ #region Public Constructors
+
+ ///
+ /// Classe base con i metodi x ModBusTCP
+ ///
+ ///
+ ///
+ public IobModbusTCPCenterfrigo(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
+ {
+ lgInfo("NEW IOB ModBus TCP Centerfrigo");
+
+ // provo lettura una prima volta i dati DYN
+ if (currPLC != null && currPLC.Connected)
+ {
+ try
+ {
+ processDynData();
+ }
+ catch (Exception exc)
+ {
+ lgError($"Eccezione in processDynData iniziale x ModBus TCP Cedax:{Environment.NewLine}{exc}");
+ }
+ }
+ }
+
+ #endregion Public Constructors
+
+ #region Private Methods
+
+ private void testBlockRead(int baseAddr, int numByte)
+ {
+ int baseHold = 40001;
+ int[] readTestFull = new int[2];
+ lgTrace($"-------------------- Inizio test lettura {baseAddr} --------------------");
+ try
+ {
+ stopwatch.Restart();
+ readTestFull = currPLC.ReadHoldingRegisters(baseAddr - baseHold, numByte);
+ stopwatch.Stop();
+ lgTrace($"Stats lettura | {readTestFull.Length} val | {stopwatch.ElapsedMilliseconds}ms");
+ }
+ catch
+ { }
+
+ for (int i = 0; i < readTestFull.Length / 2; i++)
+ {
+ int[] thisSet = new int[2];
+ Array.Copy(readTestFull, i * 2, thisSet, 0, 2);
+ lgTrace($"{baseAddr + i * 2:000} | HoldingRegisters: {thisSet[0]} / {thisSet[1]} | Val Real: {ModbusClient.ConvertRegistersToFloat(thisSet):N6}");
+ }
+ lgTrace("-------------------- Completato test lettura {baseAddr} --------------------");
+ }
+
+ private void testRead()
+ {
+ foreach (var item in memSetR)
+ {
+ testBlockRead(item.Key, item.Value);
+ }
+ }
+
+ #endregion Private Methods
+
+ #region Protected Methods
+
+ ///
+ /// Effettua decodifica aree memoria alla bitmap usata x MAPO
+ ///
+ protected override void decodeToBaseBitmap()
+ {
+ // init a zero...
+ B_input = 0;
+
+ /* -----------------------------------------------------
+ * bitmap MAPO STANDARD 60
+ * B0: POWER_ON
+ * B1: RUN
+ * B2: pzCount
+ * B3: allarme
+ * B4: manuale
+ * B5: slowTC
+ * B6: WarmUpCoolDown
+ * B7: EmergArmata
+ *
+ ----------------------------------------------------- */
+
+ var MemInt = new byte[2];
+
+ int byteSignals = 0;
+ // bit 0 (poweron) imposto a 1 SE connected...
+ if (currPLC.Connected)
+ {
+ byteSignals += (1 << 0);
+ }
+
+ // processo dagli stati + gravi...
+ if (hasAlarms)
+ {
+ byteSignals += (1 << 3);
+ }
+ else
+ {
+ byteSignals += (1 << 1);
+ }
+
+ // segnalo NON emergenza
+ byteSignals += (1 << 7);
+
+ // salvo!
+ B_input = byteSignals;
+ }
+
+ #endregion Protected Methods
+ }
+}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/IobOpcUa.cs b/IOB-WIN-NEXT/IobOpcUa.cs
index e3049e89..dfa8e7e5 100644
--- a/IOB-WIN-NEXT/IobOpcUa.cs
+++ b/IOB-WIN-NEXT/IobOpcUa.cs
@@ -549,7 +549,7 @@ namespace IOB_WIN_NEXT
protected DateTime lastCurrent = DateTime.Now;
///
- /// Oggetto MAIN x connessione MTC
+ /// Oggetto MAIN x connessione OPC-UA
///
protected UAClient UA_ref;
diff --git a/IOB-WIN-NEXT/IobOpcUaOmronIcoel.cs b/IOB-WIN-NEXT/IobOpcUaOmronIcoel.cs
index 91803e95..bc31f488 100644
--- a/IOB-WIN-NEXT/IobOpcUaOmronIcoel.cs
+++ b/IOB-WIN-NEXT/IobOpcUaOmronIcoel.cs
@@ -415,7 +415,7 @@ namespace IOB_WIN_NEXT
B_input = powerOnOk ? 1 : 0;
// decodifico da currData
- if (currData.Varie.InEmergenza)
+ if (!currData.Varie.InEmergenza)
{
B_input += (1 << 7);
}
@@ -427,6 +427,7 @@ namespace IOB_WIN_NEXT
{
B_input += (1 << 3);
}
+
}
// controllo se sono poweroff e se non ho dati buoni da > 2 minuti --> disconnetto
diff --git a/IOB-WIN-NEXT/IobSiemens.cs b/IOB-WIN-NEXT/IobSiemens.cs
index fe0abcac..c97c504f 100644
--- a/IOB-WIN-NEXT/IobSiemens.cs
+++ b/IOB-WIN-NEXT/IobSiemens.cs
@@ -844,6 +844,16 @@ namespace IOB_WIN_NEXT
case plcDataType.String:
valString = S7.Net.Types.String.FromByteArray(RawInput.Skip(item.Value.index).Take(item.Value.size).ToArray());
+ saveValueString(ref outVal, valString, item.Key);
+ break;
+
+ case plcDataType.BitMap:
+ byte[] byteState = RawInput.Skip(item.Value.index).Take(item.Value.size).ToArray();
+ // calcolo valore string come unione delle bitmap attive...
+ valString = getBitmapState(item.Value, byteState);
+ // se vuoto segno "OK"
+ valString = string.IsNullOrEmpty(valString) ? "OK" : valString;
+ saveValueString(ref outVal, valString, item.Key);
break;
default:
@@ -924,7 +934,8 @@ namespace IOB_WIN_NEXT
///
public override void processContapezzi()
{
- if (utils.CRB("enableContapezzi"))
+ bool disableByIob = (getOptPar("DISABLE_PZCOUNT") == "TRUE");
+ if (utils.CRB("enableContapezzi") && !disableByIob)
{
try
{
@@ -1727,5 +1738,51 @@ namespace IOB_WIN_NEXT
}
#endregion Public Methods
+
+ ///
+ /// Verifica presenza allarmi (tra quelli configurati)
+ ///
+ protected bool hasAlarms
+ {
+ get
+ {
+ bool answ = false;
+ int numErrors = 0;
+ uint currStatus = 0;
+ if (alarmMaps != null)
+ {
+ // leggo a ciclo le aree degli allarmi CONFIGURATI, se ne trovo --> segnalo allarme...
+ foreach (var item in alarmMaps)
+ {
+ // banchi in WORD (2 byte) --> scompongo
+ for (int i = 0; i < item.size / 2; i++)
+ {
+ currStatus = S7.Net.Types.Counter.FromByteArray(RawInput.Skip(item.index + 2 * i).Take(2).ToArray());
+ // verifica e decremento blink...
+ item.checkBlinkCounter(i, (uint)currStatus);
+
+ // verifico SE sia variato... confronto allarmi filtrato stile blink per bit status:
+ // - allarmi che iniziano per # IGNORATI
+ // - altri allarmi con un countdown da MAX_COUNTER_BLINK a 0 per il fronte di discesa
+ if (item.isChanged(i, currStatus))
+ {
+ if (currStatus > 0)
+ {
+ numErrors++;
+ }
+ // registro gli allarmi attivi e trasmetto...
+ if (sendAlarmVariations(item.memAddr, i, item.alarmsState[i], (uint)(item.alarmsMask[i] & currStatus), item.messages))
+ {
+ // se inviato --> salvo stato da current...
+ item.updStatusVal(i, (uint)(item.alarmsMask[i] & currStatus));
+ }
+ }
+ }
+ }
+ }
+ answ = numErrors > 0;
+ return answ;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/IobSiemensComeca.cs b/IOB-WIN-NEXT/IobSiemensComeca.cs
index 948d5656..e4416c40 100644
--- a/IOB-WIN-NEXT/IobSiemensComeca.cs
+++ b/IOB-WIN-NEXT/IobSiemensComeca.cs
@@ -57,6 +57,7 @@ namespace IOB_WIN_NEXT
#region Protected Properties
+#if false
protected bool hasAlarms
{
get
@@ -98,7 +99,8 @@ namespace IOB_WIN_NEXT
answ = numErrors > 0;
return answ;
}
- }
+ }
+#endif
#endregion Protected Properties
diff --git a/IOB-WIN-NEXT/IobSiemensNWSE.cs b/IOB-WIN-NEXT/IobSiemensNWSE.cs
new file mode 100644
index 00000000..a96f3a0a
--- /dev/null
+++ b/IOB-WIN-NEXT/IobSiemensNWSE.cs
@@ -0,0 +1,222 @@
+using MapoSDK;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+
+namespace IOB_WIN_NEXT
+{
+ ///
+ /// Controllo Siemens specifico x impianti RobotSerice (es Smerigliature DONATI)
+ ///
+ public class IobSiemensNWSE : IobSiemens
+ {
+ /* --------------------------------------------------------------------------------
+ * Controlli SIEMENS NWS
+ * - basasto su SIEMENS
+ * - S7 vers 1200
+ *
+ * STRUTTURA MEMORIA DB100: (lettura) 50byte,
+ * G:\Drive condivisi\30_Clienti\Giacovelli - WIL\NWS
+ *
+ *
+ * DB100
+ * B00..B15 --> 16 byte di allarmi (osmosi, depurazione, 6 x filtri)
+ * B20..B35 --> 16 byte di stati (osmosi, depurazione, 6 x filtri)
+ * B40..B49 --> 5 valori uint lettura parametri
+ *
+ *
+ *
+ * STRUTTURA MEMORIA DB101: (scrittura) 14byte, solo 2 impiegati x ora
+ * NB: segnali da tenere attivi ALMENO 3 secondi x farli recepire
+ *
+ * B0.0 Bit Azzeramento volume acqua OSMOSI
+ * B0.1 Bit Azzeramento volume acqua DEPURAZIONE
+ *
+ * B1.7 Bit Attivazione modo DEMO (0 = disattivato)
+ *
+ * -------------------------------------------------------------------------------- */
+
+ #region Protected Fields
+
+ protected bool EmergencyBypass = false;
+
+ #endregion Protected Fields
+
+ #region Public Constructors
+
+ ///
+ /// Classe base con i metodi x Siemens
+ ///
+ ///
+ ///
+ public IobSiemensNWSE(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
+ {
+ lgInfo("NEW IOB SIEMENS versione NWS");
+
+ if (IOBConf.optPar.ContainsKey("EMERGENCY_BYPASS"))
+ {
+ bool.TryParse(IOBConf.optPar["EMERGENCY_BYPASS"], out EmergencyBypass);
+ lgInfo($"Override EmergencyBypass da conf: {IOBConf.optPar["EMERGENCY_BYPASS"]} --> {EmergencyBypass}");
+ }
+ }
+
+ #endregion Public Constructors
+
+ #region Protected Methods
+
+ ///
+ /// Effettua decodifica aree memoria alla bitmap usata x MAPO
+ ///
+ protected override void decodeToBaseBitmap()
+ {
+ // init a zero...
+ B_input = 0;
+
+ /* -----------------------------------------------------
+ * bitmap MAPO STANDARD 60
+ * B0: POWER_ON
+ * B1: RUN
+ * B2: pzCount - NON usato
+ * B3: allarme (almeno 1 presente)
+ * B4: manuale - non usato
+ * B5: slowTC - non usato
+ * B6: WarmUpCoolDown - no usato
+ * B7: Emergenza armata (1)
+ *
+ ----------------------------------------------------- */
+
+ int byteSignals = 0;
+ // bit 0 (poweron) imposto a 1 SE connected...
+ if (currPLC.IsConnected)
+ {
+ byteSignals += (1 << 0);
+ }
+
+ // processo dagli stati + gravi...
+ if (hasAlarms)
+ {
+ byteSignals += (1 << 3);
+ }
+ else
+ {
+ byteSignals += (1 << 1);
+ }
+
+ // se bypass emergenza attivo --> forzo a ARMED...
+ if (EmergencyBypass)
+ {
+ // segnalo NON emergenza
+ byteSignals += (1 << 7);
+ }
+
+ // salvo!
+ B_input = byteSignals;
+ }
+
+ #endregion Protected Methods
+
+ #region Public Methods
+
+ ///
+ /// Processo i task richiesti e li elimino dalla coda 1:1
+ ///
+ ///
+ public override Dictionary executeTasks(Dictionary task2exe)
+ {
+ lgInfo($"Chiamata executeTasks specifica IobSiemensNWS: {task2exe.Count} task ricevuti");
+ // Verificare il protocollo: dovrebeb togliere SOLO i task eseguiti...
+ Dictionary taskDone = new Dictionary();
+ bool taskOk = false;
+ string taskVal = "";
+ // inizio con 1 byte di default
+ byte[] MemBlock = new byte[1];
+ string memAddrWrite = "";
+ if (task2exe != null)
+ {
+ // cerco task specifici
+ 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.forceResetPzCount:
+ // usato x resettare i contatori osmosi inversa e depurazione
+ // processo scrittura BIT su DB101.DBB0 per
+ MemBlock = new byte[1];
+ // scrivo 3 x resettare entrambi i contatori
+ MemBlock = S7.Net.Types.Byte.ToByteArray(3);
+ memAddrWrite = "DB101.DB0";
+ // scrivo!
+ taskOk = S7WriteBB(ref MemBlock, memAddrWrite);
+ // attesa 3.5 sec sec
+ Thread.Sleep(3500);
+ // predispongo x reset valore 0...
+ MemBlock = S7.Net.Types.Byte.ToByteArray(0);
+
+ break;
+
+ // lasciato commentato, da rivalutare...
+#if false
+ case taskType.setParameter:
+ // richiedo da URL i parametri WRITE da popolare
+ lgInfo("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;
+#endif
+
+ default:
+ taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
+ break;
+ }
+
+ lgInfo($"executeTask | task name: {tName} | task value: {taskVal}");
+ // aggiungo task!
+ taskDone.Add(item.Key, taskVal);
+ if (!string.IsNullOrEmpty(memAddrWrite))
+ {
+ // scrivo!
+ taskOk = S7WriteBB(ref MemBlock, memAddrWrite);
+ }
+ if (taskOk)
+ {
+ // aggiorno valore memoria... SE presente
+ if (memMap.mMapWrite.ContainsKey(item.Key))
+ {
+ memMap.mMapWrite[item.Key].value = item.Value;
+ lgInfo($"Aggiornato valore in mMapWrite per {item.Key}");
+ }
+ lgInfo($"Eseguita con successo S7WriteBB per executeTasks: {item.Key} | {item.Value}");
+ }
+ else
+ {
+ lgError($"Errore in S7WriteBB durante executeTasks: {item.Key} | {item.Value}");
+ }
+ }
+ }
+ return taskDone;
+ }
+
+ #endregion Public Methods
+ }
+}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/IobSimula.cs b/IOB-WIN-NEXT/IobSimula.cs
index 92787889..e4c29f4d 100644
--- a/IOB-WIN-NEXT/IobSimula.cs
+++ b/IOB-WIN-NEXT/IobSimula.cs
@@ -57,6 +57,11 @@ namespace IOB_WIN_NEXT
///
protected DateTime lastSimData;
+ ///
+ /// Ultimo istante in cui sono stati ridotti dati simulazione duration
+ ///
+ protected DateTime lastRedDuration;
+
///
/// Matricola OPR simulato
///
@@ -139,13 +144,19 @@ namespace IOB_WIN_NEXT
lastWarnODL = adesso;
lastEvCheck = adesso;
lastSimData = adesso;
+ lastRedDuration = adesso;
+ // setup allarmi simulati
+ for (int i = 1; i <= 8; i++)
+ {
+ alarmMessages.Add($"Allarme {i:000}");
+ }
// sistemo parametri x simulazione...
if (cIobConf.optPar.Count > 0)
{
if (!string.IsNullOrEmpty(getOptPar("PER_BASE")))
{
int.TryParse(getOptPar("PER_BASE"), out periodoMSec);
- // aggiungo NOISE... +/- 20%
+ // aggiungo NOISE... +/- 10%
Random rnd = new Random();
int noise = rnd.Next(1, periodoMSec / 5);
periodoMSec += noise - (periodoMSec / 10);
@@ -198,6 +209,45 @@ namespace IOB_WIN_NEXT
{
}
+ private Random rnd = new Random();
+ private int currSimAlarmCode = 0;
+ private List alarmMessages = new List();
+
+ ///
+ /// Decremento duration del bit indicato secondo stesse regole di ritardo dei bit di wait
+ ///
+ ///
+ protected void tryRedDuration(int bit2proc)
+ {
+ if (lastRedDuration.AddMilliseconds(periodoMSec) < DateTime.Now)
+ {
+ switch (bit2proc)
+ {
+ case 2:
+ bit2.duration--;
+ break;
+ case 3:
+ bit3.duration--;
+ break;
+ case 4:
+ bit4.duration--;
+ break;
+ case 5:
+ bit5.duration--;
+ break;
+ case 6:
+ bit6.duration--;
+ break;
+ case 7:
+ bit7.duration--;
+ break;
+ default:
+ break;
+ }
+ lastRedDuration = DateTime.Now;
+ }
+ }
+
///
/// Effettua decodifica aree memoria alla bitmap usata x MAPO
///
@@ -329,12 +379,24 @@ namespace IOB_WIN_NEXT
{
// segnalo BIT
B_input += (1 << 3);
+ // se non ancora fatto, simulo insorgenza allarme
+ if (currSimAlarmCode == 0)
+ {
+ // simulo una bitmap di max 8 allarmi, 1..255
+ currSimAlarmCode = rnd.Next(1, 255);
+ // invio allarme, 0 --> sim
+ sendAlarmVariations("SIM_BANK", 0, 0, (uint)currSimAlarmCode, alarmMessages);
+ }
// decremento duration
- bit3.duration--;
+ tryRedDuration(3);
// controllo se sia scaduta la duration... in quel caso reset...
if (bit3.duration <= 0)
{
bit3 = setupSimPar("SIM_ALARM");
+ // invio fine allarme: sim --> 0
+ sendAlarmVariations("SIM_BANK", 0, (uint)currSimAlarmCode, 0, alarmMessages);
+ // simulo terminazione allarme
+ currSimAlarmCode = 0;
}
}
else if (bit6.wait <= 0)
@@ -342,7 +404,7 @@ namespace IOB_WIN_NEXT
// segnalo BIT
B_input += (1 << 6);
// decremento duration
- bit6.duration--;
+ tryRedDuration(6);
// controllo se sia scaduta la duration... in quel caso reset...
if (bit6.duration <= 0)
{
@@ -356,7 +418,7 @@ namespace IOB_WIN_NEXT
// segnalo BIT NEGATO (emergenza)
B_input -= (1 << 7);
// decremento duration
- bit7.duration--;
+ tryRedDuration(7);
// controllo se sia scaduta la duration... in quel caso reset...
if (bit7.duration <= 0)
{
@@ -370,7 +432,7 @@ namespace IOB_WIN_NEXT
// segnalo BIT
B_input += (1 << 4);
// decremento duration
- bit4.duration--;
+ tryRedDuration(4);
// controllo se sia scaduta la duration... in quel caso reset...
if (bit4.duration <= 0)
{
@@ -413,7 +475,7 @@ namespace IOB_WIN_NEXT
}
}
// decremento duration
- bit2.duration--;
+ tryRedDuration(2);
// controllo se sia scaduta la duration... in quel caso reset...
if (bit2.duration <= 0)
{
@@ -457,7 +519,7 @@ namespace IOB_WIN_NEXT
else
{
// decremento duration
- bit2.duration--;
+ tryRedDuration(2);
if (bit2.duration <= 0)
{
bit2 = setupSimPar("SIM_PZCNT");
@@ -469,7 +531,7 @@ namespace IOB_WIN_NEXT
// segnalo BIT
B_input += (1 << 5);
// decremento duration
- bit5.duration--;
+ tryRedDuration(5);
// controllo se sia scaduta la duration... in quel caso reset...
if (bit5.duration <= 0)
{
@@ -579,10 +641,13 @@ namespace IOB_WIN_NEXT
string[] param = fullVal.Split('|');
int.TryParse(param[0], out answ.wait);
int.TryParse(param[1], out answ.duration);
- // aggiongo noise, +/- 40%...
- Random rnd = new Random();
- int noise = rnd.Next(1, answ.wait * 40 / 100);
- answ.wait += noise - (answ.wait * 20 / 100);
+ // simulo valore wait: in media target, range +/- 80%
+ answ.wait = rnd.Next(answ.wait / 5, answ.wait * 9 / 5);
+ // simulo valore duration: in media target, range +/- 50%
+ answ.duration = rnd.Next(answ.duration / 2, answ.duration * 3 / 2);
+ // verifico siano > 0...
+ answ.wait = answ.wait > 1 ? answ.wait : 2;
+ answ.duration = answ.duration > 1 ? answ.duration : 2;
}
}
}
@@ -878,13 +943,31 @@ namespace IOB_WIN_NEXT
if (lastEvCheck.AddMilliseconds(periodoMSec) < DateTime.Now)
{
// decremento contatore ultimo evento
- bit2.wait--;
- bit3.wait--;
- bit4.wait--;
- bit5.wait--;
- simDich.wait--;
- simRC.wait--;
- simRS.wait--;
+ try
+ {
+ if (bit2 != null)
+ bit2.wait--;
+
+ if (bit3 != null)
+ bit3.wait--;
+
+ if (bit4 != null)
+ bit4.wait--;
+
+ if (bit5 != null)
+ bit5.wait--;
+
+ if (simDich != null)
+ simDich.wait--;
+
+ if (simRC != null)
+ simRC.wait--;
+
+ if (simRS != null)
+ simRS.wait--;
+ }
+ catch
+ { }
lastEvCheck = DateTime.Now;
}
}
diff --git a/IOB-WIN-NEXT/NLog.config b/IOB-WIN-NEXT/NLog.config
index 124f6170..351a1daa 100644
--- a/IOB-WIN-NEXT/NLog.config
+++ b/IOB-WIN-NEXT/NLog.config
@@ -21,9 +21,9 @@
/>
-
-
-
-
+
+
+
+
+