Files
activestep/Step.Core/ThreadsSupportFunctions.cs
2020-09-12 16:11:43 +02:00

285 lines
9.8 KiB
C#

using CMS_CORE_Library.Models;
using Step.NC;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using TeamDev.SDK.MVVM;
using static CMS_CORE_Library.Models.DataStructures;
using static Step.Config.ServerConfig;
using static Step.Model.Constants;
using static Step.Utils.ExceptionManager;
namespace Step.Core
{
internal static class ThreadsSupportFunctions
{
public static bool reconnectionIsRunning = false;
private static ConcurrentDictionary<string, long> Timers = new ConcurrentDictionary<string, long>();
private static ConcurrentDictionary<string, long> Counter = new ConcurrentDictionary<string, long>();
private static Thread ConnThread;
#region SupportFunctions
internal static void TryNcConnection()
{
// Stop all the NC threads
ThreadsHandler.Stop();
StatReset();
NcAdapter ncAdapter = new NcAdapter();
CmsError cmsError = NO_ERROR;
// Run loop until NC is connected
while (!ncAdapter.numericalControl.NC_IsConnected())
{
// Try reconnection
cmsError = ncAdapter.Connect();
if (cmsError.errorCode == CMS_ERROR_CODES.SIEMENS_ENVIRONMENT_NOT_FOUND || cmsError.errorCode == CMS_ERROR_CODES.SIEMENS_HMI_NOT_RUNNING || cmsError.errorCode == CMS_ERROR_CODES.OSAI_TT_FOLDER_NOT_FOUND)
ManageLibraryError(cmsError);
else if (cmsError.errorCode != CMS_ERROR_CODES.OK)
{
ncAdapter.Dispose();
}
if (cmsError.errorCode == CMS_ERROR_CODES.SIEMENS_TOOL_TABLE_ERROR)
ManageLibraryError(cmsError);
// Send status to UI
MessageServices.Current.Publish(SEND_NC_STATUS, null, ncAdapter.numericalControl.NC_IsConnected());
Thread.Sleep(1000);
}
if (NcConfig.NcVendor == NC_VENDOR.FANUC || NcConfig.NcVendor == NC_VENDOR.OSAI)
{
using (NcToolTableAdapter toolTable = new NcToolTableAdapter())
{
toolTable.Connect();
// After reconecction write option
cmsError = toolTable.SetupNcToolManager();
if (cmsError.IsError())
ManageLibraryError(cmsError);
// cmsError = toolTable.RestoreTableLock();
}
}
if (!cmsError.IsError())
{
if (ServerStartupConfig.AutoOpenCmsClient)
StartCMSClient();
// Start/Restart NC threads
ThreadsHandler.StartWorkers();
reconnectionIsRunning = false;
}
}
internal static void RestoreConnection()
{
if (reconnectionIsRunning == false)
{ // Set thread as running state
reconnectionIsRunning = true;
// Start reconnection thread
ConnThread = new Thread(() =>
TryNcConnection()
);
ConnThread.Start();
}
}
internal static void AbortNcConnection()
{
if (ConnThread != null && ConnThread.IsAlive)
ConnThread.Abort();
}
internal static void ManageLibraryError(CmsError cmsError)
{
switch (cmsError.errorCode)
{
case CMS_ERROR_CODES.NC_PROD_ERROR:
ManageError(ERROR_LEVEL.WARNING, cmsError.localizationKey);
break;
case CMS_ERROR_CODES.NOT_CONNECTED:
RestoreConnection(); // If not connected try reconnection
break;
case CMS_ERROR_CODES.SIEMENS_ENVIRONMENT_NOT_FOUND:
case CMS_ERROR_CODES.OSAI_TT_FOLDER_NOT_FOUND:
case CMS_ERROR_CODES.OPTION_NOT_CONSISTENT:
case CMS_ERROR_CODES.SIEMENS_TOOL_TABLE_ERROR:
ManageError(ERROR_LEVEL.FATAL, cmsError.localizationKey);
break;
case CMS_ERROR_CODES.SIEMENS_HMI_NOT_RUNNING:
ManageError(ERROR_LEVEL.FATAL, "SIEMENS HMI NOT RUNNING");
break;
case CMS_ERROR_CODES.SELECTED_PROCESS:
ManageError(ERROR_LEVEL.WARNING, cmsError.localizationKey);
break;
case CMS_ERROR_CODES.INTERNAL_ERROR:
ManageException(ERROR_LEVEL.FATAL, cmsError.exception);
break;
}
}
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]++;
}
internal static void 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";
Timers[value.Key] = 0;
Counter[value.Key] = 0;
}
}
MessageServices.Current.Publish(SEND_THREADS_STATUS, null, ThreadsHandler.RunningThreadStatus);
Thread.Sleep(2000);
}
}
private static void StatReset()
{
foreach (var value in Counter)
{
Timers[value.Key] = 0;
Counter[value.Key] = 0;
}
}
internal 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;
}
internal 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;
}
internal static Dictionary<string, string> GetPlcAlarmsTranslations(string language)
{
using (NcAdapter ncAdapter = new NcAdapter())
{
Dictionary<string, string> returnValue = new Dictionary<string, string>();
Dictionary<int, string> messages = new Dictionary<int, string>();
// 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);
#endregion SupportFunctions
}
}