diff --git a/Step.Config/Config/serverConfig.xml b/Step.Config/Config/serverConfig.xml
index c372901b..d1d81b8a 100644
--- a/Step.Config/Config/serverConfig.xml
+++ b/Step.Config/Config/serverConfig.xml
@@ -18,6 +18,7 @@
false
C:\CMS\MTC\ADAPTER\
SCMA
+ true
50000
5000
diff --git a/Step.Config/Config/serverConfigValidator.xsd b/Step.Config/Config/serverConfigValidator.xsd
index f2561e5d..a3dd243b 100644
--- a/Step.Config/Config/serverConfigValidator.xsd
+++ b/Step.Config/Config/serverConfigValidator.xsd
@@ -28,6 +28,7 @@
+
diff --git a/Step.Config/ServerConfigController.cs b/Step.Config/ServerConfigController.cs
index 7afe413c..d34c1b43 100644
--- a/Step.Config/ServerConfigController.cs
+++ b/Step.Config/ServerConfigController.cs
@@ -247,7 +247,8 @@ namespace Step.Config
MTCFolderPath = x.Element("MTCFolderPath").Value,
MTCApplicationName = x.Element("MTCApplicationName").Value,
MaxAlarmsRows = Convert.ToInt32(x.Element("maxAlarmsRows").Value),
- AlarmToDelete = Convert.ToInt32(x.Element("alarmToDelete").Value)
+ AlarmToDelete = Convert.ToInt32(x.Element("alarmToDelete").Value),
+ CMSConnectReady = Convert.ToBoolean(x.Element("CMSConnectReady").Value)
}).FirstOrDefault();
}
diff --git a/Step.Core/Step.Core.csproj b/Step.Core/Step.Core.csproj
index fd61eed3..d3940693 100644
--- a/Step.Core/Step.Core.csproj
+++ b/Step.Core/Step.Core.csproj
@@ -1,94 +1,98 @@
-
-
-
-
- Debug
- AnyCPU
- {DE54FF4C-8390-4489-882A-1BC7D99EF185}
- Library
- Properties
- Step.Core
- Step.Core
- v4.6.2
- 512
-
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
- false
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
-
- ..\Libs\CMS_CORE_Library.dll
-
-
-
-
-
-
-
-
-
-
-
- ..\Libs\TeamDev.SDK.6.dll
-
-
- ..\Libs\TeamDev.SDK.WPF.dll
-
-
-
-
-
- True
- True
- Resources.resx
-
-
-
-
-
-
-
- {3f5c2483-fc87-43ef-92a8-66ff7d0e440f}
- Step.Config
-
-
- {631375DD-06D3-49BB-8130-D9DDB34C429D}
- Step.Model
-
-
- {b2366b08-96bd-4f6b-b748-b45089b87a14}
- Step.NC
-
-
- {cbeb631b-abfa-4042-9779-c0060b0dfefe}
- Step.Utils
-
-
-
-
- ResXFileCodeGenerator
- Resources.Designer.cs
-
-
-
-
-
-
-
+
+
+
+
+ Debug
+ AnyCPU
+ {DE54FF4C-8390-4489-882A-1BC7D99EF185}
+ Library
+ Properties
+ Step.Core
+ Step.Core
+ v4.6.2
+ 512
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ false
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\Libs\CMS_CORE_Library.dll
+
+
+
+
+
+
+
+
+
+
+
+ ..\Libs\TeamDev.SDK.6.dll
+
+
+ ..\Libs\TeamDev.SDK.WPF.dll
+
+
+
+
+
+ True
+ True
+ Resources.resx
+
+
+
+
+
+
+
+ {3f5c2483-fc87-43ef-92a8-66ff7d0e440f}
+ Step.Config
+
+
+ {357d5ee1-ffc8-489b-9232-22cf474d9a6f}
+ Step.Database
+
+
+ {631375DD-06D3-49BB-8130-D9DDB34C429D}
+ Step.Model
+
+
+ {b2366b08-96bd-4f6b-b748-b45089b87a14}
+ Step.NC
+
+
+ {cbeb631b-abfa-4042-9779-c0060b0dfefe}
+ Step.Utils
+
+
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Step.Core/ThreadsFunctions.cs b/Step.Core/ThreadsFunctions.cs
index 091bd311..a050b7a1 100644
--- a/Step.Core/ThreadsFunctions.cs
+++ b/Step.Core/ThreadsFunctions.cs
@@ -1,6 +1,7 @@
using CMS_CORE_Library.Models;
using Step.Config;
using Step.Core;
+using Step.Database.Controllers;
using Step.Model.DTOModels;
using Step.Model.DTOModels.AlarmModels;
using Step.Model.DTOModels.Scada;
@@ -807,65 +808,109 @@ public static class ThreadsFunctions
}
foreach (M154DataModel m154 in data)
- {
- string stringVal = "Path_" + m154.Process + "_";
- string val = "";
- // Check if command is MTC
- if (m154.Parameters[0] == "MTC")
+ {
+ if(ServerStartupConfig.CMSConnectReady)
{
- // Convert tag string in Pascal Case and add to result string
- switch (m154.Parameters[1].ToLower())
+
+ if (m154.Parameters.Count() >= 2 && m154.Parameters[0] == "SOUR")
{
- case "currprog":
- stringVal += "CurrProg";
- break;
-
- case "partid":
- stringVal += "PartId";
- break;
-
- default:
- stringVal += m154.Parameters[1];
- break;
- }
- // Set value
- if (m154.Parameters.Count() > 2)
- val = m154.Parameters[2];
-
- // Create MTC Directory if not exist
- if (!Directory.Exists(ServerStartupConfig.MTCFolderPath))
- Directory.CreateDirectory(ServerStartupConfig.MTCFolderPath);
-
- string outputFileName = ServerStartupConfig.MTCFolderPath + "\\DATA\\CmsGeneralStatus.mtc";
- // Create file if not exits
- if (!File.Exists(outputFileName))
- using (var f = File.Create(outputFileName)) { };
- // Read file
- List fileLines = File.ReadAllLines(outputFileName).ToList();
- string[] parametersInLine;
- bool found = false;
- for (int i = 0; i < fileLines.Count() && !found; i++)
- {
- // Get tag & value from row
- parametersInLine = fileLines[i].Split('|');
- if (parametersInLine[0] == stringVal)
+ // Convert tag string in Pascal Case and add to result string
+ switch (m154.Parameters[1].ToLower())
{
- found = true;
- fileLines[i] = stringVal + "|" + val;
- }
- }
- // If tag doesn't exists, append new line
- if (!found)
- fileLines.Add(stringVal + "|" + val);
+ case "currprog":
+ if (m154.Parameters.Count() < 3)
+ return;
+ RedisController.WriteProductionName(m154.Process, m154.Parameters[2]);
+ break;
- // Write file
- File.WriteAllLines(outputFileName, fileLines.ToArray());
+ case "repstarget":
+ if (m154.Parameters.Count() < 3)
+ return;
+ RedisController.WriteProductionRepsTarget(m154.Process, m154.Parameters[2]);
+ break;
+
+ case "repsdone":
+ if (m154.Parameters.Count() < 3)
+ return;
+ RedisController.WriteProductionRepsDone(m154.Process, m154.Parameters[2]);
+ break;
+
+ default:
+ string notif = m154.Parameters[1];
+ if (m154.Parameters.Count() > 2)
+ notif += m154.Parameters[2];
+ RedisController.WriteProductionNotification(m154.Process, notif);
+ break;
+ }
+ }
// Write ack
libraryError = ncHandler.WriteM154Ack((int)m154.Process);
if (libraryError.IsError())
ManageLibraryError(libraryError);
}
+ else //MTC
+ {
+ string stringVal = "Path_" + m154.Process + "_";
+ string val = "";
+
+ // Check if command is MTC
+ if (m154.Parameters[0] == "MTC")
+ {
+ // Convert tag string in Pascal Case and add to result string
+ switch (m154.Parameters[1].ToLower())
+ {
+ case "currprog":
+ stringVal += "CurrProg";
+ break;
+
+ case "partid":
+ stringVal += "PartId";
+ break;
+
+ default:
+ stringVal += m154.Parameters[1];
+ break;
+ }
+ // Set value
+ if (m154.Parameters.Count() > 2)
+ val = m154.Parameters[2];
+
+ // Create MTC Directory if not exist
+ if (!Directory.Exists(ServerStartupConfig.MTCFolderPath))
+ Directory.CreateDirectory(ServerStartupConfig.MTCFolderPath);
+
+ string outputFileName = ServerStartupConfig.MTCFolderPath + "\\DATA\\CmsGeneralStatus.mtc";
+ // Create file if not exits
+ if (!File.Exists(outputFileName))
+ using (var f = File.Create(outputFileName)) { };
+ // Read file
+ List fileLines = File.ReadAllLines(outputFileName).ToList();
+ string[] parametersInLine;
+ bool found = false;
+ for (int i = 0; i < fileLines.Count() && !found; i++)
+ {
+ // Get tag & value from row
+ parametersInLine = fileLines[i].Split('|');
+ if (parametersInLine[0] == stringVal)
+ {
+ found = true;
+ fileLines[i] = stringVal + "|" + val;
+ }
+ }
+ // If tag doesn't exists, append new line
+ if (!found)
+ fileLines.Add(stringVal + "|" + val);
+
+ // Write file
+ File.WriteAllLines(outputFileName, fileLines.ToArray());
+
+ // Write ack
+ libraryError = ncHandler.WriteM154Ack((int)m154.Process);
+ if (libraryError.IsError())
+ ManageLibraryError(libraryError);
+ }
+ }
}
}
}
diff --git a/Step.Core/app.config b/Step.Core/app.config
index b65ec51d..a6a17a68 100644
--- a/Step.Core/app.config
+++ b/Step.Core/app.config
@@ -1,11 +1,11 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Step.Database/App.config b/Step.Database/App.config
index 218f15ca..2b93020e 100644
--- a/Step.Database/App.config
+++ b/Step.Database/App.config
@@ -1,30 +1,30 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Step.Database/Controllers/RedisController.cs b/Step.Database/Controllers/RedisController.cs
new file mode 100644
index 00000000..b94e6394
--- /dev/null
+++ b/Step.Database/Controllers/RedisController.cs
@@ -0,0 +1,43 @@
+using Step.Database.Redis;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Step.Database.Controllers
+{
+ public static class RedisController
+ {
+ private const String redisNotificationAddress = "Machine:ProductionProcesses:%NN%:Notification";
+ private const String redisProdNameAddress = "Machine:ProductionProcesses:%NN%:Programs:01:Name";
+ private const String redisRepsTargetAddress = "Machine:ProductionProcesses:%NN%:Programs:01:RepsTarget";
+ private const String redisRepsDoneAddress = "Machine:ProductionProcesses:%NN%:Programs:01:RepsDone";
+
+ public static void WriteProductionNotification(uint ProductionProcess, string Notification)
+ {
+ string redisHash = redUtil.man.redHash(redisNotificationAddress).Replace("%NN%", ProductionProcess.ToString());
+ redUtil.man.setRSV(redisHash, Notification);
+ }
+
+ public static void WriteProductionName(uint ProductionProcess, string Name)
+ {
+ string redisHash = redUtil.man.redHash(redisProdNameAddress).Replace("%NN%", ProductionProcess.ToString());
+ redUtil.man.setRSV(redisHash, Name);
+ }
+
+ public static void WriteProductionRepsTarget(uint ProductionProcess, string RepsTarget)
+ {
+ string redisHash = redUtil.man.redHash(redisRepsTargetAddress).Replace("%NN%", ProductionProcess.ToString());
+ redUtil.man.setRSV(redisHash, RepsTarget);
+ }
+
+ public static void WriteProductionRepsDone(uint ProductionProcess, string RepsDone)
+ {
+ string redisHash = redUtil.man.redHash(redisRepsDoneAddress).Replace("%NN%", ProductionProcess.ToString());
+ redUtil.man.setRSV(redisHash, RepsDone);
+ }
+
+
+ }
+}
diff --git a/Step.Database/Redis/redUtil.cs b/Step.Database/Redis/redUtil.cs
new file mode 100644
index 00000000..9a7b66ce
--- /dev/null
+++ b/Step.Database/Redis/redUtil.cs
@@ -0,0 +1,805 @@
+
+using NLog;
+using StackExchange.Redis;
+using System;
+using System.Collections.Generic;
+
+namespace Step.Database.Redis
+{
+
+ public class redUtil
+ {
+ ///
+ /// wrapper di log
+ ///
+ public static Logger lg;
+ private const string baseHash = "SOUR";
+
+
+ public redUtil()
+ {
+ lg = LogManager.GetCurrentClassLogger();
+ }
+ ///
+ /// Metodo accesso statico
+ ///
+ public static redUtil man = new redUtil();
+
+ #region gestione valori in RedisCache
+
+
+ ///
+ /// Nome della variabile HASH da utilizzare (dato CodModulo / Server / DB impiegato da funzionalita' DbConfig) + keyName richiesto...
+ ///
+ public string redHash(string keyName)
+ {
+ string answ = keyName;
+ try
+ {
+ answ = string.Format("{0}:{1}", baseHash, keyName);
+ }
+ catch
+ { }
+ return answ;
+ }
+
+ ///
+ /// Connessione lazy a redis...
+ ///
+ private static Lazy lazyConnection = new Lazy(() =>
+ {
+ return ConnectionMultiplexer.Connect("127.0.0.1,abortConnect=false,ssl=false");
+ });
+ ///
+ /// Connessione lazy a redis...
+ ///
+ private static Lazy lazyConnectionAdmin = new Lazy(() =>
+ {
+ return ConnectionMultiplexer.Connect("127.0.0.1,abortConnect=false,ssl=false,allowAdmin=true");
+ });
+ ///
+ /// Oggetto statico connessione redis
+ ///
+ public static ConnectionMultiplexer connRedis
+ {
+ get
+ {
+ return lazyConnection.Value;
+ }
+ }
+ ///
+ /// Oggetto statico connessione redis
+ ///
+ public static ConnectionMultiplexer connRedisAdmin
+ {
+ get
+ {
+ return lazyConnectionAdmin.Value;
+ }
+ }
+ ///
+ /// Restituisce info dei server connessi...
+ ///
+ ///
+ public IServer[] redServInfo()
+ {
+ IServer[] answ = new IServer[1];
+ if (connRedisAdmin.IsConnected)
+ {
+ try
+ {
+ answ = new IServer[connRedisAdmin.GetEndPoints().Length];
+ int i = 0;
+ foreach (var ep in connRedisAdmin.GetEndPoints())
+ {
+ var server = connRedisAdmin.GetServer(ep);
+ answ[i] = server;
+ i++;
+ }
+ }
+ catch (Exception exc)
+ {
+ lg.Error("Eccezione in redServInfo: " + exc.ToString());
+ }
+ }
+ else
+ {
+ lg.Error("Server REDIS Admin non disponibile");
+ }
+ return answ;
+ }
+
+ ///
+ /// Restituisce una chiave salvata in RedisCache
+ ///
+ ///
+ ///
+ public string getRSV(string chiave)
+ {
+ string answ = "";
+ if (connRedis.IsConnected)
+ {
+ try
+ {
+ IDatabase cache = connRedis.GetDatabase();
+ answ = cache.StringGet(chiave);
+ }
+ catch (Exception exc)
+ {
+ lg.Info(string.Format("Errore in getRSV:{0}{1}", Environment.NewLine, exc));
+ }
+ }
+ else
+ {
+ lg.Error("Server REDIS non disponibile per getRSV");
+ }
+ return answ;
+ }
+ ///
+ /// Salva una chiave in RedisCache
+ ///
+ ///
+ ///
+ ///
+ public bool setRSV(string chiave, string valore)
+ {
+ bool answ = false;
+ if (connRedis.IsConnected)
+ {
+ try
+ {
+ IDatabase cache = connRedis.GetDatabase();
+ cache.StringSet(chiave, valore);
+ answ = true;
+ }
+ catch (Exception exc)
+ {
+ lg.Info(string.Format("Errore in setRSV:{0}{1}", Environment.NewLine, exc));
+ }
+ }
+ else
+ {
+ lg.Error("Server REDIS non disponibile (setRSV)");
+ }
+ return answ;
+ }
+ ///
+ /// Salva una chiave in RedisCache
+ ///
+ ///
+ ///
+ /// in secondi
+ ///
+ public bool setRSV(string chiave, string valore, int TTL_sec)
+ {
+ bool answ = false;
+ if (connRedis.IsConnected)
+ {
+ try
+ {
+ IDatabase cache = connRedis.GetDatabase();
+ TimeSpan expT = new TimeSpan(0, 0, TTL_sec);
+ // salvo con expyry...
+ cache.StringSet(chiave, valore, expT);
+ answ = true;
+ }
+ catch (Exception exc)
+ {
+ lg.Info(string.Format("Errore in setRSV:{0}{1}", Environment.NewLine, exc));
+ }
+ }
+ else
+ {
+ lg.Error("Server REDIS non disponibile (setRSV:TTL)");
+ }
+ return answ;
+ }
+ ///
+ /// Incrementa un contatore in Redis
+ ///
+ ///
+ ///
+ public long setRCntI(string chiave)
+ {
+ long answ = 0;
+ try
+ {
+ IDatabase cache = connRedis.GetDatabase();
+ answ = cache.StringIncrement(chiave, 1);
+ }
+ catch (Exception exc)
+ {
+ lg.Info(string.Format("Errore in setRCI:{0}{1}", Environment.NewLine, exc));
+ }
+ return answ;
+ }
+ ///
+ /// Decrementa un contatore in Redis
+ ///
+ ///
+ ///
+ public long setRCntD(string chiave)
+ {
+ long answ = 0;
+ try
+ {
+ IDatabase cache = connRedis.GetDatabase();
+ answ = cache.StringDecrement(chiave, 1);
+ }
+ catch (Exception exc)
+ {
+ lg.Info(string.Format("Errore in setRCD:{0}{1}", Environment.NewLine, exc));
+ }
+ return answ;
+ }
+ ///
+ /// Restituisce una chiave COUNTER in RedisCache
+ ///
+ ///
+ ///
+ public int getRCnt(string chiave)
+ {
+ int answInt = 0;
+ string answ = "";
+ try
+ {
+ IDatabase cache = connRedis.GetDatabase();
+ answ = cache.StringGet(chiave);
+ answInt = Convert.ToInt32(answ);
+ }
+ catch (Exception exc)
+ {
+ lg.Info(string.Format("Errore in getRSV:{0}{1}", Environment.NewLine, exc));
+ }
+ return answInt;
+ }
+ ///
+ /// Resetta (elimina) un contatore in Redis
+ ///
+ ///
+ ///
+ public bool resetRCnt(string chiave)
+ {
+ bool answ = false;
+ try
+ {
+ IDatabase cache = connRedis.GetDatabase();
+ answ = cache.KeyDelete(chiave);
+ }
+ catch (Exception exc)
+ {
+ lg.Info(string.Format("Errore in resetRCnt:{0}{1}", Environment.NewLine, exc));
+ }
+ return answ;
+ }
+ ///
+ /// Restituisce un set KVP (Key Value Pair) salvati in RedisCache
+ ///
+ ///
+ ///
+ public RedisValue[] getRKeys(RedisKey[] chiavi)
+ {
+ RedisValue[] answ = null;
+ try
+ {
+ IDatabase cache = connRedis.GetDatabase();
+ answ = cache.StringGet(chiavi);
+ }
+ catch (Exception exc)
+ {
+ lg.Info(string.Format("Errore in getRKeys:{0}{1}", Environment.NewLine, exc));
+ }
+ return answ;
+ }
+ ///
+ /// Salva un set KVP (Key Value Pair) in RedisCache
+ ///
+ /// Set KVP chiave-valore da salvare
+ ///
+ public bool setRKeys(KeyValuePair[] valori)
+ {
+ bool answ = false;
+ try
+ {
+ IDatabase cache = connRedis.GetDatabase();
+ cache.StringSet(valori);
+ answ = true;
+ }
+ catch (Exception exc)
+ {
+ lg.Info(string.Format("Errore in setRKeys:{0}{1}", Environment.NewLine, exc));
+ }
+ return answ;
+ }
+ ///
+ /// Verifica se ci siano valori nella hash indicata...
+ ///
+ ///
+ ///
+ public bool redHashPresent(RedisKey key)
+ {
+ bool answ = false;
+ // cerco se ci sia valore in redis...
+ IDatabase cache = connRedis.GetDatabase();
+ try
+ {
+ answ = cache.HashGetAll(key).Length > 0;
+ }
+ catch
+ { }
+ return answ;
+ }
+ ///
+ /// Verifica se ci siano valori nella hash indicata (string)
+ ///
+ ///
+ ///
+ public bool redHashPresentSz(string key)
+ {
+ bool answ = false;
+ try
+ {
+ RedisKey chiave = key;
+ answ = redHashPresent(chiave);
+ }
+ catch
+ { }
+ return answ;
+ }
+ ///
+ /// Recupera tutti i valori dalla hash
+ ///
+ ///
+ ///
+ public KeyValuePair[] redGetHash(string hashKey)
+ {
+ KeyValuePair[] answ = new KeyValuePair[1];
+ // cerco se ci sia valore in redis...
+ IDatabase cache = connRedis.GetDatabase();
+ try
+ {
+ RedisKey chiave = hashKey;
+ HashEntry[] valori = cache.HashGetAll(chiave);
+ answ = new KeyValuePair[valori.Length];
+ int i = 0;
+ foreach (HashEntry item in valori)
+ {
+ answ[i] = new KeyValuePair(item.Name, item.Value);
+ i++;
+ }
+ }
+ catch
+ { }
+ return answ;
+ }
+ ///
+ /// Recupera tutti i valori dalla hash in formato Dictionary
+ ///
+ ///
+ ///
+ public Dictionary redGetHashDict(string hashKey)
+ {
+ Dictionary answ = new Dictionary();
+ // cerco se ci sia valore in redis...
+ IDatabase cache = connRedis.GetDatabase();
+ try
+ {
+ RedisKey chiave = hashKey;
+ HashEntry[] valori = cache.HashGetAll(chiave);
+ foreach (HashEntry item in valori)
+ {
+ answ.Add(item.Name, item.Value);
+ }
+ }
+ catch
+ { }
+ return answ;
+ }
+ ///
+ /// Recupera UN SINGOLO VALORE dalla hash per un dato field
+ ///
+ ///
+ ///
+ ///
+ public string redGetHashField(string hashKey, string hashField)
+ {
+ string answ = "";
+ // cerco se ci sia valore in redis...
+ IDatabase cache = connRedis.GetDatabase();
+ try
+ {
+ RedisKey chiave = hashKey;
+ RedisValue campo = hashField;
+ RedisValue valOut = cache.HashGet(chiave, campo);
+ answ = valOut.ToString();
+ }
+ catch
+ { }
+ return answ;
+ }
+ ///
+ /// Salvataggio di una hash di valori
+ ///
+ /// chiave
+ /// valori
+ ///
+ public bool redSaveHash(string hashKey, KeyValuePair[] hashFields)
+ {
+ bool answ = false;
+ if (connRedis.IsConnected)
+ {
+ // cerco se ci sia valore in redis...
+ IDatabase cache = connRedis.GetDatabase();
+ try
+ {
+ RedisKey chiave = hashKey;
+ HashEntry[] valori = new HashEntry[hashFields.Length];
+ int i = 0;
+ foreach (KeyValuePair kvp in hashFields)
+ {
+ valori[i] = new HashEntry(kvp.Key, kvp.Value);
+ i++;
+ }
+ cache.HashSet(chiave, valori);
+ answ = true;
+ }
+ catch
+ { }
+ }
+ else
+ {
+ lg.Error("Server REDIS non disponibile (redSaveHash)");
+ }
+ return answ;
+ }
+ ///
+ /// Salvataggio di una hash di valori
+ ///
+ /// chiave
+ /// valori come lista KVP
+ ///
+ public bool redSaveHashList(string hashKey, List> hashListKVP)
+ {
+ bool answ = false;
+ if (connRedis.IsConnected)
+ {
+ // cerco se ci sia valore in redis...
+ IDatabase cache = connRedis.GetDatabase();
+ try
+ {
+ RedisKey chiave = hashKey;
+ HashEntry[] valori = new HashEntry[hashListKVP.Count];
+ int i = 0;
+ foreach (KeyValuePair kvp in hashListKVP)
+ {
+ valori[i] = new HashEntry(kvp.Key, kvp.Value);
+ i++;
+ }
+ cache.HashSet(chiave, valori);
+ answ = true;
+ }
+ catch
+ { }
+ }
+ else
+ {
+ lg.Error("Server REDIS non disponibile (redSaveHashList)");
+ }
+ return answ;
+ }
+ ///
+ /// Salvataggio di una hash di valori in formato Dictionary
+ ///
+ /// chiave
+ /// valori
+ ///
+ public bool redSaveHashDict(string hashKey, Dictionary hashFields)
+ {
+ bool answ = false;
+ // cerco se ci sia valore in redis...
+ IDatabase cache = connRedis.GetDatabase();
+ try
+ {
+ RedisKey chiave = hashKey;
+ HashEntry[] valori = new HashEntry[hashFields.Count];
+ int i = 0;
+ foreach (KeyValuePair kvp in hashFields)
+ {
+ valori[i] = new HashEntry(kvp.Key, kvp.Value);
+ i++;
+ }
+ cache.HashSet(chiave, valori);
+ answ = true;
+ }
+ catch
+ { }
+ return answ;
+ }
+ ///
+ /// Salvataggio di una hash di valori
+ ///
+ /// chiave
+ /// valori
+ /// scadenza preimpostata hash (secondi) | defaoult = -1 (non scade)
+ ///
+ public bool redSaveHash(string hashKey, KeyValuePair[] hashFields, double expireSeconds = -1)
+ {
+ bool answ = false;
+ // cerco se ci sia valore in redis...
+ IDatabase cache = connRedis.GetDatabase();
+ try
+ {
+ RedisKey chiave = hashKey;
+ answ = redSaveHash(hashKey, hashFields);
+ if (expireSeconds > 0)
+ {
+ cache.KeyExpire(chiave, DateTime.Now.AddSeconds(expireSeconds));
+ }
+ //answ = true;
+ }
+ catch
+ { }
+ return answ;
+ }
+ ///
+ /// Salvataggio di una hash di valori in formato Dictionary
+ ///
+ /// chiave
+ /// valori
+ /// scadenza preimpostata hash (secondi) | defaoult = -1 (non scade)
+ ///
+ public bool redSaveHashDict(string hashKey, Dictionary hashFields, double expireSeconds = -1)
+ {
+ bool answ = false;
+ // cerco se ci sia valore in redis...
+ IDatabase cache = connRedis.GetDatabase();
+ try
+ {
+ RedisKey chiave = hashKey;
+ answ = redSaveHashDict(hashKey, hashFields);
+ if (expireSeconds > 0)
+ {
+ cache.KeyExpire(chiave, DateTime.Now.AddSeconds(expireSeconds));
+ }
+ //answ = true;
+ }
+ catch
+ { }
+ return answ;
+ }
+ ///
+ /// Elimina una key (hash, string)
+ ///
+ ///
+ ///
+ public bool redDelKey(string key)
+ {
+ bool answ = false;
+ // cerco se ci sia valore in redis...
+ IDatabase cache = connRedis.GetDatabase();
+ try
+ {
+ RedisKey chiave = key;
+ cache.KeyDelete(chiave);
+ answ = true;
+ }
+ catch
+ { }
+ return answ;
+ }
+ ///
+ /// Flush completo cache redis
+ ///
+ /// ** = tutti
+ ///
+ public bool redFlushKey(string keyPattern)
+ {
+ bool answ = false;
+ // cerco se ci sia valore in redis...
+ IDatabase cache = connRedis.GetDatabase();
+ // se vuoto = ALL...
+ keyPattern = keyPattern == "" ? "**" : keyPattern;
+ try
+ {
+ foreach (var ep in connRedis.GetEndPoints())
+ {
+ var server = connRedis.GetServer(ep);
+ foreach (var key in server.Keys(pattern: keyPattern))
+ {
+ cache.KeyDelete(key);
+ }
+ }
+ answ = true;
+ }
+ catch (Exception exc)
+ {
+ lg.Error(string.Format("Eccezione: {0}", exc));
+ }
+ return answ;
+ }
+ ///
+ /// Conta num oggetti cache redis che rispondono a pattern
+ ///
+ /// ** = tutti
+ ///
+ public int redCountKey(string keyPattern)
+ {
+ int answ = 0;
+ // cerco se ci sia valore in redis...
+ IDatabase cache = connRedis.GetDatabase();
+ // se vuoto = ALL...
+ keyPattern = keyPattern == "" ? "**" : keyPattern;
+ try
+ {
+ foreach (var ep in connRedis.GetEndPoints())
+ {
+ var server = connRedis.GetServer(ep);
+ foreach (var key in server.Keys(pattern: keyPattern))
+ {
+ answ++;
+ }
+ }
+ }
+ catch (Exception exc)
+ {
+ lg.Error(string.Format("Eccezione: {0}", exc));
+ }
+ return answ;
+ }
+
+ ///
+ /// Restituisce numero record in Redis DB
+ ///
+ public long numRecRedis
+ {
+ get
+ {
+ long answ = 0;
+ try
+ {
+ foreach (var ep in connRedis.GetEndPoints())
+ {
+ var server = connRedis.GetServer(ep);
+ answ += server.DatabaseSize();
+ }
+ }
+ catch
+ { }
+ return answ;
+ }
+ }
+ ///
+ /// Restituisce oggetti cache redis che rispondono a pattern
+ ///
+ /// ** = tutti
+ /// Tipo di ordinamento per kvp
+ ///
+ public List> redGetCounterByKey(string keyPattern, kvpOrderBy orderBy)
+ {
+ int numAnsw = redCountKey(keyPattern);
+ RedisKey[] chiavi = new RedisKey[numAnsw];
+ List> answ = new List>();
+ // se vuoto = ALL...
+ keyPattern = keyPattern == "" ? "**" : keyPattern;
+
+ // recupero in primis elenco chiavi
+ try
+ {
+ int i = 0;
+ foreach (var ep in connRedis.GetEndPoints())
+ {
+ var server = connRedis.GetServer(ep);
+ foreach (var key in server.Keys(pattern: keyPattern))
+ {
+ chiavi[i] = key;
+ i++;
+ }
+ }
+ }
+ catch (Exception exc)
+ {
+ lg.Error(string.Format("Eccezione: {0}", exc));
+ }
+ // ora recupero valori!
+ var valori = getRKeys(chiavi);
+ int currVal = 0;
+ // popolo rispsota
+ try
+ {
+ for (int i = 0; i < numAnsw; i++)
+ {
+ Int32.TryParse(valori[i], out currVal);
+ answ.Add(new KeyValuePair(chiavi[i], currVal));
+ }
+ }
+ catch
+ { }
+ // se richiesto riordino...
+ switch (orderBy)
+ {
+ case kvpOrderBy.KeyAsc:
+ answ.Sort(CompareKey);
+ break;
+ case kvpOrderBy.KeyDesc:
+ answ.Sort(CompareKeyDesc);
+ break;
+ case kvpOrderBy.ValAsc:
+ answ.Sort(CompareVal);
+ break;
+ case kvpOrderBy.ValDesc:
+ answ.Sort(CompareValDesc);
+ break;
+ default:
+ break;
+ }
+ return answ;
+ }
+ ///
+ /// Effettua comaprazione x CHIAVE in KVP ASC
+ ///
+ ///
+ ///
+ ///
+ private int CompareKey(KeyValuePair x, KeyValuePair y)
+ {
+ return x.Key.CompareTo(y.Key);
+ }
+ ///
+ /// Effettua comaprazione x VALORE in KVP ASC
+ ///
+ ///
+ ///
+ ///
+ public int CompareVal(KeyValuePair x, KeyValuePair y)
+ {
+ return x.Value.CompareTo(y.Value);
+ }
+ ///
+ /// Effettua comaprazione x CHIAVE in KVP DESC
+ ///
+ ///
+ ///
+ ///
+ private int CompareKeyDesc(KeyValuePair x, KeyValuePair y)
+ {
+ return y.Key.CompareTo(x.Key);
+ }
+ ///
+ /// Effettua comaprazione x VALORE in KVP DESC
+ ///
+ ///
+ ///
+ ///
+ public int CompareValDesc(KeyValuePair x, KeyValuePair y)
+ {
+ return y.Value.CompareTo(x.Value);
+ }
+
+ ///
+ /// Tipologia di ordinamento x liste KVP
+ ///
+ public enum kvpOrderBy
+ {
+ ///
+ /// Ordinamento ASCending per KEY
+ ///
+ KeyAsc,
+ ///
+ /// Ordinamento DESCending per KEY
+ ///
+ KeyDesc,
+ ///
+ /// Ordinamento ASCending per VAL
+ ///
+ ValAsc,
+ ///
+ /// Ordinamento DESCending per VAL
+ ///
+ ValDesc
+ }
+
+
+
+ #endregion
+ }
+}
diff --git a/Step.Database/Step.Database.csproj b/Step.Database/Step.Database.csproj
index a2413ba0..787e2f50 100644
--- a/Step.Database/Step.Database.csproj
+++ b/Step.Database/Step.Database.csproj
@@ -1,127 +1,170 @@
-
-
-
-
- Debug
- AnyCPU
- {357D5EE1-FFC8-489B-9232-22CF474D9A6F}
- Library
- Properties
- Step.Database
- Step.Database
- v4.6.2
- 512
-
-
-
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
- false
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
-
- ..\Libs\CMS_CORE_Library.dll
-
-
- ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll
-
-
- ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll
-
-
- ..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll
-
-
- ..\packages\Microsoft.AspNet.Identity.EntityFramework.2.2.1\lib\net45\Microsoft.AspNet.Identity.EntityFramework.dll
-
-
- ..\packages\MySql.Data.6.10.4\lib\net452\MySql.Data.dll
- True
-
-
- ..\packages\MySql.Data.Entity.6.9.10\lib\net45\MySql.Data.Entity.EF6.dll
-
-
-
-
-
- ..\packages\System.Web.Helpers.Crypto.3.2.3\lib\net40\System.Web.Helpers.Crypto.dll
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 201902121508312_InitMigration.cs
-
-
-
-
-
-
- {3f5c2483-fc87-43ef-92a8-66ff7d0e440f}
- Step.Config
-
-
- {631375dd-06d3-49bb-8130-d9ddb34c429d}
- Step.Model
-
-
- {cbeb631b-abfa-4042-9779-c0060b0dfefe}
- Step.Utils
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 201902121508312_InitMigration.cs
-
-
-
+
+
+
+
+ Debug
+ AnyCPU
+ {357D5EE1-FFC8-489B-9232-22CF474D9A6F}
+ Library
+ Properties
+ Step.Database
+ Step.Database
+ v4.6.2
+ 512
+
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ false
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\Libs\CMS_CORE_Library.dll
+
+
+ ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll
+
+
+ ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll
+
+
+ ..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll
+
+
+ ..\packages\Microsoft.AspNet.Identity.EntityFramework.2.2.1\lib\net45\Microsoft.AspNet.Identity.EntityFramework.dll
+
+
+ ..\packages\MySql.Data.6.10.4\lib\net452\MySql.Data.dll
+ True
+
+
+ ..\packages\MySql.Data.Entity.6.9.10\lib\net45\MySql.Data.Entity.EF6.dll
+
+
+ ..\packages\NLog.4.5.11\lib\net45\NLog.dll
+
+
+ ..\packages\Pipelines.Sockets.Unofficial.1.0.7\lib\net461\Pipelines.Sockets.Unofficial.dll
+
+
+ ..\packages\StackExchange.Redis.2.0.519\lib\net461\StackExchange.Redis.dll
+
+
+
+ ..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll
+
+
+
+
+
+ ..\packages\System.Diagnostics.PerformanceCounter.4.5.0\lib\net461\System.Diagnostics.PerformanceCounter.dll
+
+
+
+ ..\packages\System.IO.Pipelines.4.5.1\lib\netstandard2.0\System.IO.Pipelines.dll
+
+
+ ..\packages\System.Memory.4.5.1\lib\netstandard2.0\System.Memory.dll
+
+
+
+ ..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll
+
+
+ ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll
+
+
+
+
+ ..\packages\System.Threading.Channels.4.5.0\lib\netstandard2.0\System.Threading.Channels.dll
+
+
+ ..\packages\System.Threading.Tasks.Extensions.4.5.1\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll
+
+
+
+ ..\packages\System.Web.Helpers.Crypto.3.2.3\lib\net40\System.Web.Helpers.Crypto.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 201902121508312_InitMigration.cs
+
+
+
+
+
+
+
+ {3f5c2483-fc87-43ef-92a8-66ff7d0e440f}
+ Step.Config
+
+
+ {631375dd-06d3-49bb-8130-d9ddb34c429d}
+ Step.Model
+
+
+ {cbeb631b-abfa-4042-9779-c0060b0dfefe}
+ Step.Utils
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 201902121508312_InitMigration.cs
+
+
+
+
\ No newline at end of file
diff --git a/Step.Database/packages.config b/Step.Database/packages.config
index ff002506..1b9d1792 100644
--- a/Step.Database/packages.config
+++ b/Step.Database/packages.config
@@ -1,9 +1,20 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Step.Model/ConfigModels/ServerConfigModel.cs b/Step.Model/ConfigModels/ServerConfigModel.cs
index 7ea76f73..a2f5dbb7 100644
--- a/Step.Model/ConfigModels/ServerConfigModel.cs
+++ b/Step.Model/ConfigModels/ServerConfigModel.cs
@@ -18,7 +18,7 @@ namespace Step.Model.ConfigModels
public string MTCFolderPath { get; set; }
public string MTCApplicationName { get; set; }
-
+ public Boolean CMSConnectReady { get; set; }
public int MaxAlarmsRows { get; set; }
public int AlarmToDelete { get; set; }
diff --git a/Step.NC/app.config b/Step.NC/app.config
index b65ec51d..a6a17a68 100644
--- a/Step.NC/app.config
+++ b/Step.NC/app.config
@@ -1,11 +1,11 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Step.Utils/Step.Utils.csproj b/Step.Utils/Step.Utils.csproj
index 1f54984e..1463258c 100644
--- a/Step.Utils/Step.Utils.csproj
+++ b/Step.Utils/Step.Utils.csproj
@@ -1,116 +1,120 @@
-
-
-
-
- Debug
- AnyCPU
- {CBEB631B-ABFA-4042-9779-C0060B0DFEFE}
- Library
- Properties
- Step.Utils
- Step.Utils
- v4.6.2
- 512
-
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
- false
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
-
- False
- ..\Libs\CMS_CORE_Library.dll
-
-
- ..\packages\MySql.Data.6.10.4\lib\net452\MySql.Data.dll
-
-
- ..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll
-
-
- ..\packages\NLog.4.4.12\lib\net45\NLog.dll
-
-
-
-
-
-
-
-
-
-
-
-
-
- ..\Libs\TeamDev.SDK.6.dll
-
-
- ..\Libs\TeamDev.SDK.WPF.dll
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- Always
-
-
-
-
-
- Designer
- Always
-
-
- Designer
-
-
-
-
-
- {631375DD-06D3-49BB-8130-D9DDB34C429D}
- Step.Model
-
-
-
+
+
+
+
+ Debug
+ AnyCPU
+ {CBEB631B-ABFA-4042-9779-C0060B0DFEFE}
+ Library
+ Properties
+ Step.Utils
+ Step.Utils
+ v4.6.2
+ 512
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ false
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ False
+ ..\Libs\CMS_CORE_Library.dll
+
+
+ ..\packages\MySql.Data.6.10.4\lib\net452\MySql.Data.dll
+
+
+ ..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll
+
+
+ ..\packages\NLog.4.5.11\lib\net45\NLog.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\Libs\TeamDev.SDK.6.dll
+
+
+ ..\Libs\TeamDev.SDK.WPF.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ Always
+
+
+
+
+
+ Designer
+ Always
+
+
+ Designer
+
+
+
+
+
+ {631375DD-06D3-49BB-8130-D9DDB34C429D}
+ Step.Model
+
+
+
\ No newline at end of file
diff --git a/Step.Utils/packages.config b/Step.Utils/packages.config
index 34a77645..9ce80806 100644
--- a/Step.Utils/packages.config
+++ b/Step.Utils/packages.config
@@ -1,6 +1,6 @@
-
-
-
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/Step/App.config b/Step/App.config
index e16fc1fd..2bc9b8f8 100644
--- a/Step/App.config
+++ b/Step/App.config
@@ -1,7 +1,7 @@
-