diff --git a/Iob.Config/AdapterConf.cs b/Iob.Config/AdapterConf.cs new file mode 100644 index 0000000..cf48348 --- /dev/null +++ b/Iob.Config/AdapterConf.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Iob.Config +{ + public class AdapterConf + { + } +} diff --git a/Iob.Config/Data/commonSetup.json b/Iob.Config/Data/commonSetup.json new file mode 100644 index 0000000..0db3279 --- /dev/null +++ b/Iob.Config/Data/commonSetup.json @@ -0,0 +1,3 @@ +{ + +} diff --git a/Iob.Config/Iob.Config.csproj b/Iob.Config/Iob.Config.csproj new file mode 100644 index 0000000..8262188 --- /dev/null +++ b/Iob.Config/Iob.Config.csproj @@ -0,0 +1,59 @@ + + + + + Debug + AnyCPU + {ECD556AC-F81F-4D23-A02E-7555EEC3C0E9} + Library + Properties + Iob.Config + Iob.Config + v4.6.2 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + VersGen.cs + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Iob.Config/IobConf.cs b/Iob.Config/IobConf.cs new file mode 100644 index 0000000..4f44e4e --- /dev/null +++ b/Iob.Config/IobConf.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Iob.Config +{ + public class IobConf + { + } +} diff --git a/Iob.Config/Properties/AssemblyInfo.cs b/Iob.Config/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..8adb420 --- /dev/null +++ b/Iob.Config/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("Iob.Config")] +[assembly: AssemblyDescription("Config Management Class")] +[assembly: AssemblyConfiguration("")] +//[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Iob.Config")] +//[assembly: AssemblyCopyright("Copyright © 2020")] +[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("ecd556ac-f81f-4d23-a02e-7555eec3c0e9")] + +// 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")] \ No newline at end of file diff --git a/Iob.Config/ServerConf.cs b/Iob.Config/ServerConf.cs new file mode 100644 index 0000000..c89dac3 --- /dev/null +++ b/Iob.Config/ServerConf.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Iob.Config +{ + public class ServerConf + { + } +} diff --git a/Iob.Core/App_Readme/README_SteamWare.txt b/Iob.Core/App_Readme/README_SteamWare.txt new file mode 100644 index 0000000..bf60ed1 --- /dev/null +++ b/Iob.Core/App_Readme/README_SteamWare.txt @@ -0,0 +1,12 @@ +--------------------------------------------------------------- +------- SteamWareLib SDK ------- +--------------------------------------------------------------- + +Libreria di utility base di SteamWare. + +Le dipendenze inserite sono necessarie al funzionamento dell'SDK. + +Sono inclusi a titolo di esempio vari files di conf: + * example-NLog.config + +Attenzione a configurare correttamente il file NLog.xml includendo il rule per la classe, vedere ad esempio il file example-NLog.config allegato. \ No newline at end of file diff --git a/Iob.Core/App_Readme/SteamWare_demo/example-favicon.ico b/Iob.Core/App_Readme/SteamWare_demo/example-favicon.ico new file mode 100644 index 0000000..4f0e0ad Binary files /dev/null and b/Iob.Core/App_Readme/SteamWare_demo/example-favicon.ico differ diff --git a/Iob.Core/Core/Compression/Snappy/lib/win/snappy32.dll b/Iob.Core/Core/Compression/Snappy/lib/win/snappy32.dll new file mode 100644 index 0000000..afc82ca Binary files /dev/null and b/Iob.Core/Core/Compression/Snappy/lib/win/snappy32.dll differ diff --git a/Iob.Core/Core/Compression/Snappy/lib/win/snappy64.dll b/Iob.Core/Core/Compression/Snappy/lib/win/snappy64.dll new file mode 100644 index 0000000..36cd5fe Binary files /dev/null and b/Iob.Core/Core/Compression/Snappy/lib/win/snappy64.dll differ diff --git a/Iob.Core/Core/Compression/Zstandard/lib/win/libzstd.dll b/Iob.Core/Core/Compression/Zstandard/lib/win/libzstd.dll new file mode 100644 index 0000000..e669123 Binary files /dev/null and b/Iob.Core/Core/Compression/Zstandard/lib/win/libzstd.dll differ diff --git a/Iob.Core/ExceptionManager.cs b/Iob.Core/ExceptionManager.cs new file mode 100644 index 0000000..afa0084 --- /dev/null +++ b/Iob.Core/ExceptionManager.cs @@ -0,0 +1,172 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using static SteamWare.Logger.Logging; +using static SteamWare.Logger.Constants; +using Iob.Model; + +namespace Iob.Core +{ + public static class ExceptionManager + { + #region Private Fields + + private static bool MessageBoxShow = false; + + #endregion Private Fields + + + + #region Public Methods + + public static string GetExceptionMethodName(Exception ex) + { + var s = new StackTrace(ex, true); + var thisasm = Assembly.GetExecutingAssembly(); + + Console.WriteLine(s.GetFrames().Count()); + foreach (var a in s.GetFrames()) + { + var d = a.GetMethod(); + Console.WriteLine(d.Name); + } + + return s.GetFrames().FirstOrDefault()?.GetMethod().Name; + } + + public static void ManageError(ERROR_LEVEL errorLevel, string message, bool beforeFormReady = false) + { + switch (errorLevel) + { + case ERROR_LEVEL.INFO: + { + // Log + LogInfo(message); + // Notify users + NotifyUsers(CreateMessageModel("Info!", message, ERROR_LEVEL.INFO)); + } + break; + + case ERROR_LEVEL.WARNING: + { + LogWarning(message); + NotifyUsers(CreateMessageModel("Warning!", message, ERROR_LEVEL.WARNING)); + } + break; + + case ERROR_LEVEL.ERROR: + { + LogError(message); + NotifyUsersAndClose(CreateMessageModel("Error!", message, ERROR_LEVEL.ERROR)); + } + break; + + case ERROR_LEVEL.FATAL: + { + LogFatal(message); + if (!MessageBoxShow) + { + MessageBoxShow = true; + NotifyUsersAndClose(CreateMessageModel("Fatal Error!", message, ERROR_LEVEL.FATAL), beforeFormReady); + // Check if the server form is ready (if not i have to close manually) + if (beforeFormReady) + // Close the application + Environment.Exit(1); + } + } + break; + + default: + { + LogFatal(message); + if (!MessageBoxShow) + { + MessageBoxShow = true; + NotifyUsersAndClose(CreateMessageModel("Generic Error!", message, ERROR_LEVEL.FATAL), beforeFormReady); + } + } + break; + } + } + + public static void ManageException(ERROR_LEVEL errorLevel, Exception exception) + { + string message = exception.Message; + if (exception.InnerException != null) + { + // Add inner exception message (if exists) + message += " | " + exception.InnerException.Message; + } + + // Add method name + message += " | " + GetExceptionMethodName(exception); + + ManageError(errorLevel, message); + } + + #endregion Public Methods + + + + #region Private Methods + + private static ErrorMessageModel CreateMessageModel(string title, string message, ERROR_LEVEL level, string methodName = "") + { + if (methodName != "") + message = message + " | " + methodName; + + return new ErrorMessageModel() + { + Title = title, + Message = message, + ErrorLevel = level + }; + } + + private static void LogAndNotifyUsers(ErrorMessageModel error) + { + // Log + LogMessage(error.Message, (ERROR_LEVEL)error.ErrorLevel); + NotifyUsersAndClose(error); + } + + private static void NotifyUsers(ErrorMessageModel error, bool beforeFormReady = false) + { +#if false + if (beforeFormReady) + { + MessageBox.Show(new Form { TopMost = true }, error.Message, error.Title, MessageBoxButtons.OK, MessageBoxIcon.Error); + } + else + { + MessageServices.Current.Publish(SEND_MESSAGE, null, error); + } +#endif + } + + private static void NotifyUsersAndClose(ErrorMessageModel error, bool beforeFormReady = false) + { +#if false + if (beforeFormReady) + { + // Notify user + MessageServices.Current.Publish(SEND_STOP_THREADS); + MessageBox.Show(new Form { TopMost = true }, error.Message, error.Title, MessageBoxButtons.OK, MessageBoxIcon.Error); + MessageServices.Current.Publish(SEND_STOP_SERVER); + } + else + { + // Notify user + //MessageServices.Current.Publish(SEND_STOP_THREADS); + MessageServices.Current.Publish(SEND_MESSAGE, null, error); + } +#endif + } + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/Iob.Core/Iob.Core.csproj b/Iob.Core/Iob.Core.csproj new file mode 100644 index 0000000..f068497 --- /dev/null +++ b/Iob.Core/Iob.Core.csproj @@ -0,0 +1,193 @@ + + + + + Debug + AnyCPU + {E7373C65-E16A-4F99-8911-BFE72593133E} + Library + Properties + Iob.Core + Iob.Core + v4.6.2 + 512 + true + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Crc32C.NET.1.0.5.0\lib\net20\Crc32C.NET.dll + + + ..\packages\DnsClient.1.3.2\lib\net45\DnsClient.dll + + + ..\packages\SharpZipLib.1.2.0\lib\net45\ICSharpCode.SharpZipLib.dll + + + ..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.1\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\packages\MongoDB.Bson.2.11.2\lib\net452\MongoDB.Bson.dll + + + ..\packages\MongoDB.Driver.2.11.2\lib\net452\MongoDB.Driver.dll + + + ..\packages\MongoDB.Driver.Core.2.11.2\lib\net452\MongoDB.Driver.Core.dll + + + ..\packages\MongoDB.Libmongocrypt.1.0.0\lib\net452\MongoDB.Libmongocrypt.dll + + + ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll + + + ..\packages\NLog.4.7.4\lib\net45\NLog.dll + + + ..\packages\Pipelines.Sockets.Unofficial.2.1.16\lib\net461\Pipelines.Sockets.Unofficial.dll + + + ..\packages\SharpCompress.0.26.0\lib\net46\SharpCompress.dll + + + ..\packages\Snappy.NET.1.1.1.8\lib\net45\Snappy.NET.dll + + + ..\packages\StackExchange.Redis.2.1.58\lib\net461\StackExchange.Redis.dll + + + ..\packages\SteamWare.IO.4.9.2009.740\lib\net462\SteamWare.IO.dll + + + ..\packages\SteamWare.Logger.4.9.2009.740\lib\net462\SteamWare.Logger.dll + + + + ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + + + ..\packages\System.Diagnostics.PerformanceCounter.4.7.0\lib\net461\System.Diagnostics.PerformanceCounter.dll + + + ..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll + + + ..\packages\System.IO.Pipelines.4.7.2\lib\net461\System.IO.Pipelines.dll + + + ..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + ..\packages\System.Net.Http.4.3.4\lib\net46\System.Net.Http.dll + + + + ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\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.Cryptography.Algorithms.4.3.1\lib\net461\System.Security.Cryptography.Algorithms.dll + + + ..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll + + + ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll + + + ..\packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net461\System.Security.Cryptography.X509Certificates.dll + + + + ..\packages\System.Threading.Channels.4.7.1\lib\net461\System.Threading.Channels.dll + + + ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + + + + + + + + VersGen.cs + + + + + + + + + + + + + + {09fd3985-3898-4ad8-9472-2b84d117bbcd} + Iob.Adapter + + + {ecd556ac-f81f-4d23-a02e-7555eec3c0e9} + Iob.Config + + + {3da86f5d-0459-4d24-9b5e-a2c44e5019f3} + Iob.Model + + + + + + + + + + + + + + + + + + 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.Core/MessageQueues.cs b/Iob.Core/MessageQueues.cs new file mode 100644 index 0000000..03bb012 --- /dev/null +++ b/Iob.Core/MessageQueues.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Iob.Core +{ + public static class MessageQueues + { + } +} \ No newline at end of file diff --git a/Iob.Core/Properties/AssemblyInfo.cs b/Iob.Core/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..d9ba20f --- /dev/null +++ b/Iob.Core/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("Iob.Core")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +//[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Iob.Core")] +//[assembly: AssemblyCopyright("Copyright © 2020")] +[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("e7373c65-e16a-4f99-8911-bfe72593133e")] + +// 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")] \ No newline at end of file diff --git a/Iob.Core/ThreadsFunctions.cs b/Iob.Core/ThreadsFunctions.cs new file mode 100644 index 0000000..526459d --- /dev/null +++ b/Iob.Core/ThreadsFunctions.cs @@ -0,0 +1,1494 @@ +using Iob.Model; +using Newtonsoft.Json; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Threading; + +namespace Iob.Core +{ + public static class ThreadsFunctions + { +#if false + public static int axisRtCounter = 0; + public static int recipeRtCounter = 0; + public static int modulesRtCounter = 0; + public static bool reconnectionIsRunning = false; +#endif + + + + #region Private Fields + + private static Thread ConnThread; + private static ConcurrentDictionary Counter = new ConcurrentDictionary(); + private static ConcurrentDictionary Timers = new ConcurrentDictionary(); + + #endregion Private Fields + + + + #region Private Methods + + /// + /// restituisce il periodo di campionamento SE configurato, altrimenti 1000 ms + /// + /// + /// + private static int samplMsec(string threadName) + { + int answ = 500; +#if false + if (ThreadSamplingConfig.ContainsKey(threadName)) + { + answ = ThreadSamplingConfig[threadName]; + } +#endif + return answ; + } + + #endregion Private Methods + + #region Functions + + /// + /// Gestione watchdog verso adapter + /// + public static void ManageWatchdog() + { + Adapter.Driver myDriver = new Adapter.Driver(); + Stopwatch sw = new Stopwatch(); + int errorCounter = 0; + try + { + IobError libraryError = myDriver.Connect(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + + while (true) + { + sw.Restart(); + +#if false + // Check if client is connected + if (myDriver.numericalControl.NC_IsConnected()) + { + // Manage watchdog + libraryError = myDriver.ManageWatchdog(); + if (libraryError == PLC_NOT_RUNNING_ERROR) + { + if (errorCounter < MAX_NUM_OF_WATCHDOG_ERROR) + errorCounter++; + } + else if (libraryError == NO_ERROR) + errorCounter = 0; + } + else + RestoreConnection(); +#endif + + sw.Stop(); + + // Update thread timer + UpdateStat(MethodBase.GetCurrentMethod().Name, sw.ElapsedMilliseconds); + + // Wait + Thread.Sleep(CalcSleepTime(samplMsec("watchdog"), (int)sw.ElapsedMilliseconds)); + } + } + catch (ThreadAbortException ex) + { + myDriver.Dispose(); + } + } + + public static void ReadTestData() + { + SteamWare.IO.Redis myRedis = new SteamWare.IO.Redis(); + string currName = MethodBase.GetCurrentMethod().Name; + string myKey = myRedis.redHash("currName"); + + Adapter.Driver myDriver = new Adapter.Driver(); + Stopwatch sw = new Stopwatch(); + + try + { + // Try connection + IobError libraryError = myDriver.Connect(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + + while (true) + { + sw.Restart(); + +#if false + if (ncAdapter.numericalControl.NC_IsConnected()) + { + // Get softkey data from config and PLC + libraryError = ncAdapter.GetUserSoftKeys(out List softKeys); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + else + // Send through signalR + MessageServices.Current.Publish(SEND_USER_SOFTKEYS_DATA, null, softKeys); + } + else + RestoreConnection(); + +#endif + + // invio FAKE di valori letti su channel "ReadTestData" + Random rnd = new Random(); + int randNum = rnd.Next(0, 255); + myRedis.setRSV(myKey, JsonConvert.SerializeObject($"IN: {randNum}")); + Thread.Sleep(20); + + sw.Stop(); + + //Update thread timer + UpdateStat(currName, sw.ElapsedMilliseconds); + + // Wait + Thread.Sleep(CalcSleepTime(samplMsec("userSK"), (int)sw.ElapsedMilliseconds)); + } + } + catch (ThreadAbortException) + { + myDriver.Dispose(); + } + } + +#if false + /// + /// Manage status/command words for actions + /// + public static void ManageStatusCommand() + { + NcAdapter ncAdapter = new NcAdapter(); + Stopwatch sw = new Stopwatch(); + try + { + IobError libraryError = ncAdapter.Connect(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + + while (true) + { + sw.Restart(); + + // Check if client is connected + if (ncAdapter.numericalControl.NC_IsConnected()) + { + // Manage status command + libraryError = ncAdapter.ManageStatusCommand(); + } + else + RestoreConnection(); + + sw.Stop(); + + //Update thread timer + UpdateStat(MethodBase.GetCurrentMethod().Name, sw.ElapsedMilliseconds); + + // Wait + Thread.Sleep(CalcSleepTime(samplMsec("statusCommand"), (int)sw.ElapsedMilliseconds)); + } + } + catch (ThreadAbortException ex) + { + ncAdapter.Dispose(); + } + } + /// + /// Manage action for conf request + /// + public static void ManageConfRequest() + { + NcAdapter ncAdapter = new NcAdapter(); + Stopwatch sw = new Stopwatch(); + try + { + IobError libraryError = ncAdapter.Connect(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + + while (true) + { + sw.Restart(); + + // Check if client is connected + if (ncAdapter.numericalControl.NC_IsConnected()) + { + // Manage status command + libraryError = ncAdapter.ManageConfRequest(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + } + else + RestoreConnection(); + + sw.Stop(); + + //Update thread timer + UpdateStat(MethodBase.GetCurrentMethod().Name, sw.ElapsedMilliseconds); + + // Wait + Thread.Sleep(CalcSleepTime(samplMsec("confReq"), (int)sw.ElapsedMilliseconds)); + } + } + catch (ThreadAbortException ex) + { + ncAdapter.Dispose(); + } + } + public static void ReadAlarms() + { + NcAdapter ncAdapter = new NcAdapter(); + Stopwatch sw = new Stopwatch(); + + try + { + IobError libraryError = ncAdapter.Connect(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + + while (true) + { + sw.Restart(); + // Check if client is connected + if (ncAdapter.numericalControl.NC_IsConnected()) + { + // Get Alarms from NC + libraryError = ncAdapter.GetNcAlarms(out DTOAlarmsModel alarms); + if (libraryError.errorCode != 0) + { + ManageLibraryError(libraryError); + } + else + // Send through signalR + MessageServices.Current.Publish(SEND_ALARMS, null, alarms); + } + else + RestoreConnection(); + sw.Stop(); + + //Update thread timer + UpdateStat(MethodBase.GetCurrentMethod().Name, sw.ElapsedMilliseconds); + + // Wait + Thread.Sleep(CalcSleepTime(samplMsec("alarms"), (int)sw.ElapsedMilliseconds)); + } + } + catch (ThreadAbortException) + { + ncAdapter.Dispose(); + } + } + public static void ReadPowerOnData() + { + NcAdapter ncAdapter = new NcAdapter(); + Stopwatch sw = new Stopwatch(); + + try + { + IobError libraryError = ncAdapter.Connect(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + + while (true) + { + sw.Restart(); + // Check if client is connected + if (ncAdapter.numericalControl.NC_IsConnected()) + { + // Get Data from NC + libraryError = ncAdapter.GetPowerOnData(out DTOPowerOnDataModel powerOnData); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + else + // Send through signalR + MessageServices.Current.Publish(SEND_POWER_ON_DATA, null, powerOnData); + } + else + RestoreConnection(); + sw.Stop(); + + //Update thread timer + UpdateStat(MethodBase.GetCurrentMethod().Name, sw.ElapsedMilliseconds); + + // Wait + Thread.Sleep(CalcSleepTime(samplMsec("powerOn"), (int)sw.ElapsedMilliseconds)); + } + } + catch (ThreadAbortException) + { + ncAdapter.Dispose(); + } + } + public static void ReadProcessesPPStatus() + { + NcAdapter ncAdapter = new NcAdapter(); + Stopwatch sw = new Stopwatch(); + + try + { + // Try connection + IobError libraryError = ncAdapter.Connect(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + + while (true) + { + sw.Restart(); + + if (ncAdapter.numericalControl.NC_IsConnected()) + { + // Get Data from NC + libraryError = ncAdapter.GetProcessesData(out DTOProcessesDataModel processesPPData); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + else + { + // Send processes through signalR + MessageServices.Current.Publish(SEND_PROCESSES_DATA, null, processesPPData); + } + } + else + RestoreConnection(); + + sw.Stop(); + + //Update thread timer + UpdateStat(MethodBase.GetCurrentMethod().Name, sw.ElapsedMilliseconds); + + // Wait + Thread.Sleep(CalcSleepTime(200, (int)sw.ElapsedMilliseconds)); + } + } + catch (ThreadAbortException) + { + ncAdapter.Dispose(); + } + } + public static void ReadEnabledFunctionality() + { + NcAdapter ncAdapter = new NcAdapter(); + Stopwatch sw = new Stopwatch(); + + try + { + // Try connection + IobError libraryError = ncAdapter.Connect(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + + while (true) + { + sw.Restart(); + + if (ncAdapter.numericalControl.NC_IsConnected()) + { + // Get Data from NC + libraryError = ncAdapter.GetFunctionsMappedWithNC(out List functionsAccessList); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + else + // Send through signalR + MessageServices.Current.Publish(SEND_FUNCTIONALITY_DATA, null, functionsAccessList); + } + else + RestoreConnection(); + + sw.Stop(); + + //Update thread timer + UpdateStat(MethodBase.GetCurrentMethod().Name, sw.ElapsedMilliseconds); + + // Wait + Thread.Sleep(CalcSleepTime(samplMsec("functionEnab"), (int)sw.ElapsedMilliseconds)); + } + } + catch (ThreadAbortException) + { + ncAdapter.Dispose(); + } + } + public static void ReadExpiredMaintenances() + { + NcAdapter ncAdapter = new NcAdapter(); + Stopwatch sw = new Stopwatch(); + + try + { + // Try connection + IobError libraryError = ncAdapter.Connect(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + + while (true) + { + sw.Restart(); + + if (ncAdapter.numericalControl.NC_IsConnected()) + { + // Get Data from database and PLC + libraryError = ncAdapter.GetExpiredMaintenances(out List expiredMaintenances); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + else + // Send through signalR + MessageServices.Current.Publish(SEND_EXPIRED_MAINTENANCES_DATA, null, expiredMaintenances); + + // 2020.06.18 commentata da indicazione di Lucio Maranta (NON dovrebbe servire ora) +#if false + //Manage Candies + libraryError = ncAdapter.ManageCandies(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); +#endif + } + else + RestoreConnection(); + + sw.Stop(); + + //Update thread timer + UpdateStat(MethodBase.GetCurrentMethod().Name, sw.ElapsedMilliseconds); + + // Wait + Thread.Sleep(CalcSleepTime(samplMsec("expMan"), (int)sw.ElapsedMilliseconds)); + } + } + catch (ThreadAbortException) + { + ncAdapter.Dispose(); + } + catch (Exception ex) + { + } + } + public static void ReadUserSoftKeysData() + { + NcAdapter ncAdapter = new NcAdapter(); + Stopwatch sw = new Stopwatch(); + + try + { + // Try connection + IobError libraryError = ncAdapter.Connect(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + + while (true) + { + sw.Restart(); + + if (ncAdapter.numericalControl.NC_IsConnected()) + { + // Get softkey data from config and PLC + libraryError = ncAdapter.GetUserSoftKeys(out List softKeys); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + else + // Send through signalR + MessageServices.Current.Publish(SEND_USER_SOFTKEYS_DATA, null, softKeys); + } + else + RestoreConnection(); + + sw.Stop(); + + //Update thread timer + UpdateStat(MethodBase.GetCurrentMethod().Name, sw.ElapsedMilliseconds); + + // Wait + Thread.Sleep(CalcSleepTime(samplMsec("userSK"), (int)sw.ElapsedMilliseconds)); + } + } + catch (ThreadAbortException) + { + ncAdapter.Dispose(); + } + } + /// + /// Lettura valori ASSI (tutti i disponibili) + /// + public static void ReadAxisInfoData() + { + NcAdapter ncAdapter = new NcAdapter(); + Stopwatch sw = new Stopwatch(); + + try + { + // Try connection + IobError libraryError = ncAdapter.Connect(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + + while (true) + { + // ogni n counter leggo anche dati NON RT + axisRtCounter--; + bool onlyRt = axisRtCounter > 0; + //check reset... + axisRtCounter = axisRtCounter < 0 ? 4 : axisRtCounter; + + sw.Restart(); + + if (ncAdapter.numericalControl.NC_IsConnected()) + { + // Get Data from config and PLC + libraryError = ncAdapter.ReadAxisData(onlyRt, out Dictionary axisData); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + else + // Send through signalR + MessageServices.Current.Publish(SEND_AXIS_INFO, null, axisData); + } + else + RestoreConnection(); + + sw.Stop(); + + //Update thread timer + UpdateStat(MethodBase.GetCurrentMethod().Name, sw.ElapsedMilliseconds); + + // Wait + Thread.Sleep(CalcSleepTime(samplMsec("axis"), (int)sw.ElapsedMilliseconds)); + } + } + catch (ThreadAbortException) + { + ncAdapter.Dispose(); + } + } + public static void ReadScadaData() + { + NcAdapter ncAdapter = new NcAdapter(); + Stopwatch sw = new Stopwatch(); + + try + { + // Try connection + IobError libraryError = ncAdapter.Connect(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + + while (true) + { + sw.Restart(); + + // Check if client is connected + if (ncAdapter.numericalControl.NC_IsConnected()) + { + List scadaToRead = ProductionScadaSchema.Concat(SubscribedScada).ToList(); + + // Get new data from PLC + libraryError = ncAdapter.ReadScadasData(scadaToRead, out List scadas); + if (libraryError.IsError()) + ManageLibraryError(libraryError); + + MessageServices.Current.Publish(SEND_SCADA_DATA, null, scadas); + } + else + RestoreConnection(); + + sw.Stop(); + + //Update thread timer + UpdateStat(MethodBase.GetCurrentMethod().Name, sw.ElapsedMilliseconds); + // Wait + Thread.Sleep(CalcSleepTime(samplMsec("scada"), (int)sw.ElapsedMilliseconds)); + } + } + catch (ThreadAbortException) + { + ncAdapter.Dispose(); + } + } + public static void ReadGaugeData() + { + NcAdapter ncAdapter = new NcAdapter(); + Stopwatch sw = new Stopwatch(); + + try + { + // Try connection + IobError libraryError = ncAdapter.Connect(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + + while (true) + { + sw.Restart(); + + // Check if client is connected + if (ncAdapter.numericalControl.NC_IsConnected()) + { + // Get new data from PLC + libraryError = ncAdapter.ReadGaugeData(out Dictionary currentLiveProd); + if (libraryError.IsError()) + ManageLibraryError(libraryError); + + MessageServices.Current.Publish(SEND_THERMO_GAUGE_DATA, null, currentLiveProd); + } + else + RestoreConnection(); + + sw.Stop(); + + //Update thread timer + UpdateStat(MethodBase.GetCurrentMethod().Name, sw.ElapsedMilliseconds); + // Wait + Thread.Sleep(CalcSleepTime(samplMsec("gauges"), (int)sw.ElapsedMilliseconds)); + } + } + catch (ThreadAbortException) + { + ncAdapter.Dispose(); + } + } + public static void ReadProdPanelData() + { + NcAdapter ncAdapter = new NcAdapter(); + Stopwatch sw = new Stopwatch(); + + try + { + // Try connection + IobError libraryError = ncAdapter.Connect(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + + while (true) + { + sw.Restart(); + + // Check if client is connected + if (ncAdapter.numericalControl.NC_IsConnected()) + { + // Get new data from PLC (and log if changed...) + libraryError = ncAdapter.ReadProdPanel(out DTOThermoPanelProd currentProdPanel); + if (libraryError.IsError()) + ManageLibraryError(libraryError); + + MessageServices.Current.Publish(SEND_THERMO_PROD_PANEL_DATA, null, currentProdPanel); + } + else + RestoreConnection(); + + sw.Stop(); + + //Update thread timer + UpdateStat(MethodBase.GetCurrentMethod().Name, sw.ElapsedMilliseconds); + // Wait 500 ms + Thread.Sleep(CalcSleepTime(samplMsec("prodPanel"), (int)sw.ElapsedMilliseconds)); + } + } + catch (ThreadAbortException) + { + ncAdapter.Dispose(); + } + } + public static void ReadProdInfoData() + { + NcAdapter ncAdapter = new NcAdapter(); + Stopwatch sw = new Stopwatch(); + + try + { + // Try connection + IobError libraryError = ncAdapter.Connect(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + + while (true) + { + sw.Restart(); + + // Check if client is connected + if (ncAdapter.numericalControl.NC_IsConnected()) + { + // Get new data from PLC (and log if changed...) + libraryError = ncAdapter.ReadProdInfoData(out DTOProdInfo prodInfoData); + if (libraryError.IsError()) + ManageLibraryError(libraryError); + + MessageServices.Current.Publish(SEND_THERMO_PROD_INFO_DATA, null, prodInfoData); + } + else + RestoreConnection(); + + sw.Stop(); + + //Update thread timer + UpdateStat(MethodBase.GetCurrentMethod().Name, sw.ElapsedMilliseconds); + // Wait + Thread.Sleep(CalcSleepTime(samplMsec("prodInfo"), (int)sw.ElapsedMilliseconds)); + } + } + catch (ThreadAbortException) + { + ncAdapter.Dispose(); + } + } + public static void ReadProdCycleData() + { + NcAdapter ncAdapter = new NcAdapter(); + Stopwatch sw = new Stopwatch(); + + try + { + // Try connection + IobError libraryError = ncAdapter.Connect(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + + while (true) + { + sw.Restart(); + + // Check if client is connected + if (ncAdapter.numericalControl.NC_IsConnected()) + { + // Get new data from PLC + libraryError = ncAdapter.ReadProdCycleData(out ThermoModels.ProdCycleModel prodCycleData); + if (libraryError.IsError()) + ManageLibraryError(libraryError); + + MessageServices.Current.Publish(SEND_THERMO_PROD_CYCLE_DATA, null, prodCycleData); + } + else + RestoreConnection(); + + sw.Stop(); + + //Update thread timer + UpdateStat(MethodBase.GetCurrentMethod().Name, sw.ElapsedMilliseconds); + // Wait + Thread.Sleep(CalcSleepTime(samplMsec("prodCycle"), (int)sw.ElapsedMilliseconds)); + } + } + catch (ThreadAbortException) + { + ncAdapter.Dispose(); + } + } + public static void ReadRecipeData() + { + NcAdapter ncAdapter = new NcAdapter(); + Stopwatch sw = new Stopwatch(); + try + { + // Try connection + IobError libraryError = ncAdapter.Connect(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + + while (true) + { + // ogni n counter leggo anche dati NON RT + recipeRtCounter--; + bool onlyRt = recipeRtCounter > 0; + //check reset... + recipeRtCounter = recipeRtCounter < 0 ? 4 : recipeRtCounter; + + sw.Restart(); + + // Check if client is connected + if (ncAdapter.numericalControl.NC_IsConnected()) + { + // Get new data from PLC + libraryError = ncAdapter.ReadRecipeData(onlyRt, false, out Dictionary currRecipe); + if (libraryError.IsError()) + ManageLibraryError(libraryError); + + MessageServices.Current.Publish(SEND_THERMO_RECIPE_FULL, null, currRecipe); + + // ora gestisco la overview! + libraryError = ncAdapter.GetRecipeOverview(out Dictionary currOverview); + if (libraryError.IsError()) + ManageLibraryError(libraryError); + + MessageServices.Current.Publish(SEND_THERMO_RECIPE_OVERWIEW, null, currOverview); + + // ora gestisco la lettura della overview di "modificata + DTORecipeStatus message = new DTORecipeStatus() + { + recipeName = NcAdapter.RecipeLiveData.RecipeName, + hasChanged = NcAdapter.RecipeLiveData.hasChanged + }; + + MessageServices.Current.Publish(SEND_THERMO_RECIPE_CHANGED, null, message); + } + else + RestoreConnection(); + + sw.Stop(); + + // Update thread timer + UpdateStat(MethodBase.GetCurrentMethod().Name, sw.ElapsedMilliseconds); + // Wait + Thread.Sleep(CalcSleepTime(samplMsec("recipe"), (int)sw.ElapsedMilliseconds)); + } + } + catch (ThreadAbortException) + { + ncAdapter.Dispose(); + } + } + public static void ReadWarmersData() + { + NcAdapter ncAdapter = new NcAdapter(); + Stopwatch sw = new Stopwatch(); + try + { + // Try connection + IobError libraryError = ncAdapter.Connect(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + + while (true) + { + sw.Restart(); + + // Check if client is connected + if (ncAdapter.numericalControl.NC_IsConnected()) + { + // Get new data from PLC + libraryError = ncAdapter.ReadWarmers(out Dictionary currWarmers); + if (libraryError.IsError()) + ManageLibraryError(libraryError); + // pubblico + MessageServices.Current.Publish(SEND_THERMO_WARMERS_DATA, null, currWarmers); + } + else + RestoreConnection(); + + sw.Stop(); + + // Update thread timer + UpdateStat(MethodBase.GetCurrentMethod().Name, sw.ElapsedMilliseconds); + // Wait + Thread.Sleep(CalcSleepTime(samplMsec("warmers"), (int)sw.ElapsedMilliseconds)); + } + } + catch (ThreadAbortException) + { + ncAdapter.Dispose(); + } + } + public static void ReadAreaData() + { + NcAdapter ncAdapter = new NcAdapter(); + Stopwatch sw = new Stopwatch(); + try + { + // Try connection + IobError libraryError = ncAdapter.Connect(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + + while (true) + { + sw.Restart(); + + // Check if client is connected + if (ncAdapter.numericalControl.NC_IsConnected()) + { + // Get new data from PLC... info x area lastra... la % di X / Y + libraryError = ncAdapter.GetWarmMaterialArea(out Dictionary currAreaPerc); + if (libraryError.IsError()) + ManageLibraryError(libraryError); + // pubblico + MessageServices.Current.Publish(SEND_THERMO_AREA_DATA, null, currAreaPerc); + } + else + RestoreConnection(); + + sw.Stop(); + + // Update thread timer + UpdateStat(MethodBase.GetCurrentMethod().Name, sw.ElapsedMilliseconds); + // Wait + Thread.Sleep(CalcSleepTime(samplMsec("area"), (int)sw.ElapsedMilliseconds)); + } + } + catch (ThreadAbortException) + { + ncAdapter.Dispose(); + } + } + public static void ReadModulesData() + { + NcAdapter ncAdapter = new NcAdapter(); + Stopwatch sw = new Stopwatch(); + try + { + // Try connection + IobError libraryError = ncAdapter.Connect(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + + while (true) + { + sw.Restart(); + + // Check if client is connected + if (ncAdapter.numericalControl.NC_IsConnected()) + { + // Get new data from PLC + libraryError = ncAdapter.ReadModulesBlock(out Dictionary currModules); + if (libraryError.IsError()) + ManageLibraryError(libraryError); + + MessageServices.Current.Publish(SEND_THERMO_MODULE_DATA, null, currModules); + } + else + RestoreConnection(); + + sw.Stop(); + + // Update thread timer + UpdateStat(MethodBase.GetCurrentMethod().Name, sw.ElapsedMilliseconds); + // Wait + Thread.Sleep(CalcSleepTime(samplMsec("modules"), (int)sw.ElapsedMilliseconds)); + } + } + catch (ThreadAbortException) + { + ncAdapter.Dispose(); + } + } + public static void ReadMComandsData() + { + NcAdapter ncAdapter = new NcAdapter(); + Stopwatch sw = new Stopwatch(); + + try + { + // Try connection + IobError libraryError = ncAdapter.Connect(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + + while (true) + { + sw.Restart(); + + if (ncAdapter.numericalControl.NC_IsConnected()) + { + // solo x S7Net... + if (NcConfig.NcVendor == NC_VENDOR.S7NET) + { + libraryError = ncAdapter.GetM156Data(out List m156Data); + if (libraryError.IsError()) + ManageLibraryError(libraryError); + else + MessageServices.Current.Publish(SEND_M156_DATA, null, m156Data); + } + } + else + RestoreConnection(); + + sw.Stop(); + + //Update thread timer + UpdateStat(MethodBase.GetCurrentMethod().Name, sw.ElapsedMilliseconds); + + // Wait + Thread.Sleep(CalcSleepTime(samplMsec("mCommands"), (int)sw.ElapsedMilliseconds)); + } + } + catch (ThreadAbortException) + { + ncAdapter.Dispose(); + } + } + public static void ReadM154Data() + { + NcAdapter ncAdapter = new NcAdapter(); + Stopwatch sw = new Stopwatch(); + + try + { + // Try connection + IobError libraryError = ncAdapter.Connect(); + if (libraryError.errorCode != 0) + ManageLibraryError(libraryError); + + while (true) + { + sw.Restart(); + + // Check if client is connected + if (ncAdapter.numericalControl.NC_IsConnected()) + { + libraryError = ncAdapter.GetM154Data(out List data, out bool MTCStatus); + if (libraryError.IsError()) + ManageLibraryError(libraryError); + + string ApplicationPath = ServerStartupConfig.MTCFolderPath + "\\" + ServerStartupConfig.MTCApplicationName + ".exe"; + if (ServerStartupConfig.MTCFolderPath != "") + { + // Check if process exists + Process[] processes = Process.GetProcessesByName(ServerStartupConfig.MTCApplicationName); + if (!MTCStatus) + { + // Kill if is running + if (processes.Count() > 0) + processes[0].Kill(); + } + else + { + // if is already running ignore + if (processes.Count() == 0) + if (File.Exists(ApplicationPath)) + { + ProcessStartInfo PSI = new ProcessStartInfo(ApplicationPath); + var directory = new FileInfo(ApplicationPath).Directory; + if (directory != null) + { + PSI.WorkingDirectory = directory.FullName; + Process.Start(PSI); + } + } + } + } + + foreach (M154DataModel m154 in data) + { + //if (CmsConnectConfig.Enabled) + if (ServerStartupConfig.CmsConnectReady) + { + if (m154.Parameters.Count() >= 2 && m154.Parameters[0] == "SOUR") + { + // Convert tag string in Pascal Case and add to result string + switch (m154.Parameters[1].ToLower()) + { + case "currprog": + if (m154.Parameters.Count() < 3) + return; + RedisController.WriteProductionName(m154.Process, m154.Parameters[2]); + break; + + 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 = ncAdapter.WriteM154Ack((int)m154.Process); + if (libraryError.IsError()) + ManageLibraryError(libraryError); + } + else //MTC + { + string stringVal = "Path_0" + 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 = ncAdapter.WriteM154Ack((int)m154.Process); + if (libraryError.IsError()) + ManageLibraryError(libraryError); + } + } + } + } + else + RestoreConnection(); + sw.Stop(); + + //Update thread timer + UpdateStat(MethodBase.GetCurrentMethod().Name, sw.ElapsedMilliseconds); + + // Wait + Thread.Sleep(CalcSleepTime(samplMsec("m154"), (int)sw.ElapsedMilliseconds)); + } + } + catch (ThreadAbortException) + { + ncAdapter.Dispose(); + } + } + public static void SetupCmsConnect() + { + NcAdapter ncAdapter = new NcAdapter(); + try + { + List availableLanguages = LanguageController.GetLanguageListFromDirectory(); + if (availableLanguages == null) + return; + + ICollection cultureInfos = new List(); + + // Get nc available language + IobError libraryError = ncAdapter.numericalControl.NC_GetAvailableLanguages(ref cultureInfos); + if (libraryError.IsError()) + ManageLibraryError(libraryError); + + // Filter available language with + availableLanguages = availableLanguages.Where(x => cultureInfos.Any(y => y.TwoLetterISOLanguageName == x.IsoId)).ToList(); + + // Fill redis DB + int count = 1; + Dictionary defAlarmsNamesEn = null; + Dictionary defAlarmsNamesIt = null; + foreach (DTOLanguageModel lang in availableLanguages) + { + Dictionary alarmsNames = GetPlcAlarmsTranslations(lang.IsoId); + + if (lang.IsoId.ToLower() == "en") + { + defAlarmsNamesEn = alarmsNames; + if (!RedisController.WriteAlarmsConfigEn(alarmsNames)) + ManageError(ERROR_LEVEL.FATAL, CMS_CONNECT_SETUP_ALARM_MESSAGE); + } + else if (lang.IsoId.ToLower() == "it") + { + defAlarmsNamesIt = alarmsNames; + if (!RedisController.WriteAlarmsConfigIt(alarmsNames)) + ManageError(ERROR_LEVEL.FATAL, CMS_CONNECT_SETUP_ALARM_MESSAGE); + } + else + if (!RedisController.WriteAlarmsConfigCurr(alarmsNames)) + ManageError(ERROR_LEVEL.FATAL, CMS_CONNECT_SETUP_ALARM_MESSAGE); + + if (count == 3) + break; + else + count++; + } + + if (availableLanguages.Count < 3 && defAlarmsNamesEn != null) + if (!RedisController.WriteAlarmsConfigCurr(defAlarmsNamesEn)) + ManageError(ERROR_LEVEL.FATAL, CMS_CONNECT_SETUP_ALARM_MESSAGE); + else if (availableLanguages.Count < 3 && defAlarmsNamesIt != null) + if (!RedisController.WriteAlarmsConfigCurr(defAlarmsNamesIt)) + ManageError(ERROR_LEVEL.FATAL, CMS_CONNECT_SETUP_ALARM_MESSAGE); + } + catch (ThreadAbortException) + { + ncAdapter.Dispose(); + } + } +#endif + + #endregion Functions + + #region SupportFunctions + + public static void ManageLibraryError(IobError libraryError) + { +#if false + switch (libraryError.errorCode) + { + case IOB_ERROR_CODES.NC_PROD_ERROR: + ManageError(ERROR_LEVEL.WARNING, libraryError.localizationKey); + break; + + case IOB_ERROR_CODES.NOT_CONNECTED: + RestoreConnection(); // If not connected try reconnection + break; + + case IOB_ERROR_CODES.SIEMENS_ENVIRONMENT_NOT_FOUND: + case IOB_ERROR_CODES.OSAI_TT_FOLDER_NOT_FOUND: + case IOB_ERROR_CODES.OPTION_NOT_CONSISTENT: + ManageError(ERROR_LEVEL.FATAL, libraryError.localizationKey); + break; + + case IOB_ERROR_CODES.SIEMENS_HMI_NOT_RUNNING: + ManageError(ERROR_LEVEL.FATAL, "SIEMENS HMI NOT RUNNING"); + break; + + case IOB_ERROR_CODES.SELECTED_PROCESS: + ManageError(ERROR_LEVEL.WARNING, libraryError.localizationKey); + break; + + case IOB_ERROR_CODES.INTERNAL_ERROR: + ManageException(ERROR_LEVEL.FATAL, libraryError.exception); + break; + } +#endif + } + + internal static void StatThread() + { + SteamWare.IO.Redis myRedis = new SteamWare.IO.Redis(); + string myKey = myRedis.redHash("StatThread"); + while (true) + { + foreach (var value in Counter) + { + if (ThreadsHandler.RunningThreadStatus.ContainsKey(value.Key) && Counter[value.Key] != 0) + { + ThreadsHandler.RunningThreadStatus[value.Key] = $"{(Timers[value.Key] / Counter[value.Key])} ms x {Counter[value.Key]}"; + Timers[value.Key] = 0; + Counter[value.Key] = 0; + } + } + + myRedis.setRSV(myKey, JsonConvert.SerializeObject(ThreadsHandler.RunningThreadStatus)); + //MessageServices.Current.Publish(SEND_THREADS_STATUS, null, ThreadsHandler.RunningThreadStatus); + + Thread.Sleep(2000); + } + } + + internal static void UpdateStat(string functionName, long timer) + { + if (!Timers.ContainsKey(functionName)) + Timers.TryAdd(functionName, timer); + else + Timers[functionName] += timer; + + if (!Counter.ContainsKey(functionName)) + Counter.TryAdd(functionName, 1); + else + Counter[functionName]++; + } + + private static int CalcSleepTime(int maxSleep, int execTime) + { + int sleep = 0; + // Check if the execution time is greater than the half of the max sleep time + if (maxSleep - execTime < maxSleep / 2) + { + sleep = maxSleep; + } + else + { + sleep = maxSleep - execTime; + } + + return sleep; + } + + private static void StatReset() + { + foreach (var value in Counter) + { + Timers[value.Key] = 0; + Counter[value.Key] = 0; + } + } + +#if false + + private static void TryNcConnection() + { + // Stop all the NC threads + ThreadsHandler.Stop(); + StatReset(); + NcAdapter ncAdapter = new NcAdapter(); + IobError libraryError = NO_ERROR; + // Run loop until NC is connected + while (!ncAdapter.numericalControl.NC_IsConnected()) + { + // Try reconnection + libraryError = ncAdapter.Connect(); + if (libraryError.errorCode == IOB_ERROR_CODES.SIEMENS_ENVIRONMENT_NOT_FOUND || libraryError.errorCode == IOB_ERROR_CODES.SIEMENS_HMI_NOT_RUNNING || libraryError.errorCode == IOB_ERROR_CODES.OSAI_TT_FOLDER_NOT_FOUND) + ManageLibraryError(libraryError); + else if (libraryError.errorCode != IOB_ERROR_CODES.OK) + { + ncAdapter.Dispose(); + } + + // Send status to UI + MessageServices.Current.Publish(SEND_NC_STATUS_UI, null, ncAdapter.numericalControl.NC_IsConnected()); + // Send status to signalr + MessageServices.Current.Publish(SEND_NC_STATUS, null, ncAdapter.numericalControl.NC_IsConnected()); + + Thread.Sleep(1000); + } + + if (!libraryError.IsError()) + { + if (ServerStartupConfig.AutoOpenCmsClient) + StartCMSClient(); + + // Start/Restart NC threads + ThreadsHandler.StartWorkers(); + reconnectionIsRunning = false; + } + } + public static void RestoreConnection() + { + if (reconnectionIsRunning == false) + { // Set thread as running state + reconnectionIsRunning = true; + + // Start reconnection thread + ConnThread = new Thread(() => + TryNcConnection() + ); + + ConnThread.Start(); + } + } + public static void AbortNcConnection() + { + if (ConnThread != null && ConnThread.IsAlive) + ConnThread.Abort(); + } + + public static void StartCMSClient() + { + //Setup the Path Variable + if (!ClientIsRunning()) + { + ThreadsHandler.StartClient = new Thread(() => clientProcess()); + ThreadsHandler.StartClient.Start(); + } + } + private static void clientProcess() + { + string CMSClientPath = ""; + // Check if the system is 64/32 bit + if (Environment.Is64BitOperatingSystem && File.Exists(CLIENT_PATH_64)) + CMSClientPath = CLIENT_PATH_64; + else if (File.Exists(CLIENT_PATH_86)) + CMSClientPath = CLIENT_PATH_86; + + if (!String.IsNullOrEmpty(CMSClientPath)) + { + Process pr = Process.Start(CMSClientPath, null); + + if (ServerStartupConfig.AutoOpenCmsClient) + { + pr.WaitForExit(); + MessageServices.Current.Publish(SEND_STOP_SERVER); + } + } + } + private static bool ClientIsRunning() + { + Process[] p = Process.GetProcessesByName(CLIENT_EXE_NAME_NOEXT); + foreach (Process pr in p) + { + if (pr.MainWindowHandle != IntPtr.Zero) + { + ShowWindow(pr.MainWindowHandle, 9); + SetForegroundWindow(pr.MainWindowHandle); + return true; + } + } + return false; + } + private static Dictionary GetPlcAlarmsTranslations(string language) + { + using (NcAdapter ncAdapter = new NcAdapter()) + { + Dictionary returnValue = new Dictionary(); + + Dictionary messages = new Dictionary(); + // Read data from CN + ncAdapter.numericalControl.NC_GetTranslatedPlcMessages(language, ref messages); // Avoid checking error because in the worst case "messages" is empty + + // Id start from 1 + for (int i = 1; i <= 1024; i++) + { + // Get configurated alarms + var tmpAlarmConfig = InitialAlarmsConfig.Where(x => x.PlcId == i).FirstOrDefault(); + // Default string + string message = string.Format(NOT_CONFIGURATED_ALARM_MESSAGE, i); + // If is configurated + if (tmpAlarmConfig != null) + { + // Find translated string + message = messages.Where(x => x.Key == tmpAlarmConfig.AlarmId).FirstOrDefault().Value; + if (message == null) + message = string.Format(NOT_FOUND_ALARM_MESSAGE, i); + } + // Add to dictionary + returnValue.Add(i.ToString("D6") + "|900", message); + } + return returnValue; + } + } + + [DllImport("user32.dll")] + static extern bool SetForegroundWindow(IntPtr hWnd); + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); +#endif + + #endregion SupportFunctions + } +} \ No newline at end of file diff --git a/Iob.Core/ThreadsHandler.cs b/Iob.Core/ThreadsHandler.cs new file mode 100644 index 0000000..a757f85 --- /dev/null +++ b/Iob.Core/ThreadsHandler.cs @@ -0,0 +1,127 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Iob.Core +{ + /// + /// Gestore generale dei threads + /// + public static class ThreadsHandler + { + private static List ThreadsFunctionsList = new List + { +#if false + ThreadsFunctions.ManageWatchdog, + ThreadsFunctions.ReadAdapter, + ThreadsFunctions.SendData, + ThreadsFunctions.ExecuteMapoRequests, +#endif + ThreadsFunctions.StatThread + }; + +#if false + private static Action ThreadSetupCmsConnect = ThreadsFunctions.SetupCmsConnect; +#endif + + private volatile static List RunningThreadsList = new List(); + public static Thread StartClient; + + internal volatile static Dictionary RunningThreadStatus = new Dictionary(); + + public static void Start() + { +#if false + ThreadsFunctions.RestoreConnection(); + + if (Config.ServerConfig.ServerStartupConfig.CmsConnectReady) + { + Thread t = new Thread(() => ThreadSetupCmsConnect()); + t.Start(); + Thread.Sleep(30); + } +#endif + } + + public static void StartWorkers() + { + lock (RunningThreadStatus) + RunningThreadStatus.Clear(); + + SteamWare.IO.Redis myRedis = new SteamWare.IO.Redis(); + string myKey = myRedis.redHash("StatThread"); + + // For each function run in the list a thread + ThreadsFunctionsList.ForEach(threadFunction => + { + // Run new Thread in the list + Thread t = new Thread(() => + threadFunction() + ); + t.Start(); + // aggiungo pausa x evitare sovrapposizioni chiamate + Thread.Sleep(50); + // Add thread to running threads list + lock (RunningThreadsList) + RunningThreadsList.Add(t); + + RunningThreadStatus.Add(threadFunction.Method.Name, "---"); + }); + +#if false + MessageServices.Current.Publish(SEND_THREADS_STATUS, null, RunningThreadStatus); +#endif + + myRedis.setRSV(myKey, JsonConvert.SerializeObject(ThreadsHandler.RunningThreadStatus)); + } + + public static void Stop() + { + // Stop each thread + lock (RunningThreadsList) + RunningThreadsList.ForEach(thread => + { + thread.Abort(); + }); + + // Remove threads from running status + lock (RunningThreadsList) + RunningThreadsList.Clear(); + + lock (RunningThreadStatus) + { + RunningThreadStatus.Clear(); + RunningThreadStatus.Add("TryNcConnection", "---"); + } + +#if false + MessageServices.Current.Publish(SEND_THREADS_STATUS, null, RunningThreadStatus); +#endif + } + + public static void Close() + { + //Abort Nc Read Threads + RunningThreadsList.ForEach(thread => + { + thread.Abort(); + }); + + if (ThreadsHandler.StartClient != null) + ThreadsHandler.StartClient.Abort(); + +#if false + //Abort Connect Thread + ThreadsFunctions.AbortNcConnection(); +#endif + } + + public static void StartClientFromUI() + { +#if false + ThreadsFunctions.StartCMSClient(); +#endif + } + } +} \ No newline at end of file diff --git a/Iob.Core/app.config b/Iob.Core/app.config new file mode 100644 index 0000000..50915da --- /dev/null +++ b/Iob.Core/app.config @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Iob.Core/libzstd.dll b/Iob.Core/libzstd.dll new file mode 100644 index 0000000..e669123 Binary files /dev/null and b/Iob.Core/libzstd.dll differ diff --git a/Iob.Core/mongocrypt.dll b/Iob.Core/mongocrypt.dll new file mode 100644 index 0000000..3cc3634 Binary files /dev/null and b/Iob.Core/mongocrypt.dll differ diff --git a/Iob.Core/packages.config b/Iob.Core/packages.config new file mode 100644 index 0000000..6554bf5 --- /dev/null +++ b/Iob.Core/packages.config @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Iob.Core/snappy32.dll b/Iob.Core/snappy32.dll new file mode 100644 index 0000000..afc82ca Binary files /dev/null and b/Iob.Core/snappy32.dll differ diff --git a/Iob.Core/snappy64.dll b/Iob.Core/snappy64.dll new file mode 100644 index 0000000..36cd5fe Binary files /dev/null and b/Iob.Core/snappy64.dll differ diff --git a/Iob.Model/App_Readme/README_SteamWare.txt b/Iob.Model/App_Readme/README_SteamWare.txt new file mode 100644 index 0000000..bf60ed1 --- /dev/null +++ b/Iob.Model/App_Readme/README_SteamWare.txt @@ -0,0 +1,12 @@ +--------------------------------------------------------------- +------- SteamWareLib SDK ------- +--------------------------------------------------------------- + +Libreria di utility base di SteamWare. + +Le dipendenze inserite sono necessarie al funzionamento dell'SDK. + +Sono inclusi a titolo di esempio vari files di conf: + * example-NLog.config + +Attenzione a configurare correttamente il file NLog.xml includendo il rule per la classe, vedere ad esempio il file example-NLog.config allegato. \ No newline at end of file diff --git a/Iob.Model/App_Readme/SteamWare_demo/example-favicon.ico b/Iob.Model/App_Readme/SteamWare_demo/example-favicon.ico new file mode 100644 index 0000000..4f0e0ad Binary files /dev/null and b/Iob.Model/App_Readme/SteamWare_demo/example-favicon.ico differ diff --git a/Iob.Model/ErrorMessageModel.cs b/Iob.Model/ErrorMessageModel.cs new file mode 100644 index 0000000..e6e86ac --- /dev/null +++ b/Iob.Model/ErrorMessageModel.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static SteamWare.Logger.Constants; + +namespace Iob.Model +{ + public class ErrorMessageModel + { + #region Public Properties + + public ERROR_LEVEL ErrorLevel { get; set; } + public string Message { get; set; } + public string Title { get; set; } + + #endregion Public Properties + } +} \ No newline at end of file diff --git a/Iob.Model/Iob.Model.csproj b/Iob.Model/Iob.Model.csproj new file mode 100644 index 0000000..3ecbaf8 --- /dev/null +++ b/Iob.Model/Iob.Model.csproj @@ -0,0 +1,70 @@ + + + + + Debug + AnyCPU + {3DA86F5D-0459-4D24-9B5E-A2C44E5019F3} + Library + Properties + Iob.Model + Iob.Model + v4.6.2 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\NLog.4.7.4\lib\net45\NLog.dll + + + ..\packages\SteamWare.Logger.4.9.2009.740\lib\net462\SteamWare.Logger.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Iob.Model/IobError.cs b/Iob.Model/IobError.cs new file mode 100644 index 0000000..45915a3 --- /dev/null +++ b/Iob.Model/IobError.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Iob.Model +{ + public class IobError + { + public IOB_ERROR_CODES errorCode; + public string localizationKey; + public Exception exception; + + public IobError(IOB_ERROR_CODES errorCode, string message, Exception exception) + { + this.errorCode = errorCode; + this.localizationKey = message; + this.exception = exception; + } + + public IobError(IOB_ERROR_CODES errorCode, string message) + { + this.errorCode = errorCode; + this.localizationKey = message; + } + + public bool IsError() + { + if (errorCode == IOB_ERROR_CODES.OK) + return false; + else + return true; + } + + public static IobError InternalError(string message, Exception exception) + { + return new IobError(IOB_ERROR_CODES.INTERNAL_ERROR, message, exception); + } + + public static IobError NcError(string message) + { + return new IobError(IOB_ERROR_CODES.NC_PROD_ERROR, message); + } + } + + public enum IOB_ERROR_CODES : uint + { + OK = 0 + , NOT_CONNECTED + , INTERNAL_ERROR + , NC_PROD_ERROR + , PLC_PROD_ERROR + , BIT_NOT_IN_RANGE + , BYTE_NOT_IN_RANGE + , FUNCTION_NOT_ALLOWED + , INCORRECT_PARAMETERS + , FILE_NOT_FOUND + , PLC_NOT_RUNNING + , S7NET_READ_ERROR + , S7NET_WRITE_ERROR + } +} \ No newline at end of file diff --git a/Iob.Model/IobSample.cs b/Iob.Model/IobSample.cs new file mode 100644 index 0000000..e4a5dcf --- /dev/null +++ b/Iob.Model/IobSample.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Iob.Model +{ + internal class IobSample + { + } +} \ No newline at end of file diff --git a/Iob.Model/IobSignal.cs b/Iob.Model/IobSignal.cs new file mode 100644 index 0000000..dc93fc4 --- /dev/null +++ b/Iob.Model/IobSignal.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Iob.Model +{ + /// + /// Generico SEGNALE rilevato da IOB + /// Va gestito da successivo layer di trasformazione Ingressi --> eventi su MP.IO + /// + public class IobSignal + { + /// + /// Valore evento registrato (formato + /// + public string dataIN { get; set; } = ""; + + /// + /// DataOra evento registrato + /// + public DateTime TimeStamp { get; set; } = DateTime.Now; + } +} \ No newline at end of file diff --git a/Iob.Model/IobTask.cs b/Iob.Model/IobTask.cs new file mode 100644 index 0000000..ee0540e --- /dev/null +++ b/Iob.Model/IobTask.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Iob.Model +{ + class IobTask + { + } +} diff --git a/Iob.Model/Properties/AssemblyInfo.cs b/Iob.Model/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..3ac9fce --- /dev/null +++ b/Iob.Model/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("Iob.Model")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Iob.Model")] +[assembly: AssemblyCopyright("Copyright © 2020")] +[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("3da86f5d-0459-4d24-9b5e-a2c44e5019f3")] + +// 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/Iob.Model/packages.config b/Iob.Model/packages.config new file mode 100644 index 0000000..b270f0f --- /dev/null +++ b/Iob.Model/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file